1 /* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
22
23 /**
24 @file storage/perfschema/table_os_global_by_type.cc
25 Table OBJECTS_SUMMARY_GLOBAL_BY_TYPE (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_pthread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_os_global_by_type.h"
34 #include "pfs_global.h"
35
36 THR_LOCK table_os_global_by_type::m_table_lock;
37
38 PFS_engine_table_share
39 table_os_global_by_type::m_share=
40 {
41 { C_STRING_WITH_LEN("objects_summary_global_by_type") },
42 &pfs_truncatable_acl,
43 table_os_global_by_type::create,
44 NULL, /* write_row */
45 table_os_global_by_type::delete_all_rows,
46 NULL, /* get_row_count */
47 1000, /* records */
48 sizeof(pos_os_global_by_type),
49 &m_table_lock,
50 { C_STRING_WITH_LEN("CREATE TABLE objects_summary_global_by_type("
51 "OBJECT_TYPE VARCHAR(64) comment 'Groups records together with OBJECT_SCHEMA and OBJECT_NAME.',"
52 "OBJECT_SCHEMA VARCHAR(64) comment 'Groups records together with OBJECT_TYPE and OBJECT_NAME.',"
53 "OBJECT_NAME VARCHAR(64) comment 'Groups records together with OBJECT_SCHEMA and OBJECT_TYPE.',"
54 "COUNT_STAR BIGINT unsigned not null comment 'Number of summarized events',"
55 "SUM_TIMER_WAIT BIGINT unsigned not null comment 'Total wait time of the summarized events that are timed.',"
56 "MIN_TIMER_WAIT BIGINT unsigned not null comment 'Minimum wait time of the summarized events that are timed.',"
57 "AVG_TIMER_WAIT BIGINT unsigned not null comment 'Average wait time of the summarized events that are timed.',"
58 "MAX_TIMER_WAIT BIGINT unsigned not null comment 'Maximum wait time of the summarized events that are timed.')") }
59 };
60
61 PFS_engine_table*
create(void)62 table_os_global_by_type::create(void)
63 {
64 return new table_os_global_by_type();
65 }
66
67 int
delete_all_rows(void)68 table_os_global_by_type::delete_all_rows(void)
69 {
70 reset_table_waits_by_table_handle();
71 reset_table_waits_by_table();
72 return 0;
73 }
74
table_os_global_by_type()75 table_os_global_by_type::table_os_global_by_type()
76 : PFS_engine_table(&m_share, &m_pos),
77 m_row_exists(false), m_pos(), m_next_pos()
78 {}
79
reset_position(void)80 void table_os_global_by_type::reset_position(void)
81 {
82 m_pos.reset();
83 m_next_pos.reset();
84 }
85
rnd_next(void)86 int table_os_global_by_type::rnd_next(void)
87 {
88 PFS_table_share *table_share;
89
90 for (m_pos.set_at(&m_next_pos);
91 m_pos.has_more_view();
92 m_pos.next_view())
93 {
94 switch (m_pos.m_index_1) {
95 case pos_os_global_by_type::VIEW_TABLE:
96 for ( ; m_pos.m_index_2 < table_share_max; m_pos.m_index_2++)
97 {
98 table_share= &table_share_array[m_pos.m_index_2];
99 if (table_share->m_lock.is_populated())
100 {
101 make_row(table_share);
102 m_next_pos.set_after(&m_pos);
103 return 0;
104 }
105 }
106 break;
107 default:
108 break;
109 }
110 }
111
112 return HA_ERR_END_OF_FILE;
113 }
114
115 int
rnd_pos(const void * pos)116 table_os_global_by_type::rnd_pos(const void *pos)
117 {
118 PFS_table_share *table_share;
119
120 set_position(pos);
121
122 switch (m_pos.m_index_1) {
123 case pos_os_global_by_type::VIEW_TABLE:
124 DBUG_ASSERT(m_pos.m_index_2 < table_share_max);
125 table_share= &table_share_array[m_pos.m_index_2];
126 if (table_share->m_lock.is_populated())
127 {
128 make_row(table_share);
129 return 0;
130 }
131 break;
132 default:
133 break;
134 }
135
136 return HA_ERR_RECORD_DELETED;
137 }
138
make_row(PFS_table_share * share)139 void table_os_global_by_type::make_row(PFS_table_share *share)
140 {
141 pfs_lock lock;
142 PFS_single_stat cumulated_stat;
143 uint safe_key_count;
144
145 m_row_exists= false;
146
147 share->m_lock.begin_optimistic_lock(&lock);
148
149 m_row.m_object_type= share->get_object_type();
150 memcpy(m_row.m_schema_name, share->m_schema_name, share->m_schema_name_length);
151 m_row.m_schema_name_length= share->m_schema_name_length;
152 memcpy(m_row.m_object_name, share->m_table_name, share->m_table_name_length);
153 m_row.m_object_name_length= share->m_table_name_length;
154
155 /* This is a dirty read, some thread can write data while we are reading it */
156 safe_key_count= sanitize_index_count(share->m_key_count);
157
158 share->m_table_stat.sum(& cumulated_stat, safe_key_count);
159
160 if (! share->m_lock.end_optimistic_lock(&lock))
161 return;
162
163 m_row_exists= true;
164
165 if (share->get_refcount() > 0)
166 {
167 /* For all the table handles still opened ... */
168 PFS_table *table= table_array;
169 PFS_table *table_last= table_array + table_max;
170 for ( ; table < table_last ; table++)
171 {
172 if ((table->m_share == share) && (table->m_lock.is_populated()))
173 {
174 /*
175 If the opened table handle is for this table share,
176 aggregate the table handle statistics.
177 */
178 table->m_table_stat.sum(& cumulated_stat, safe_key_count);
179 }
180 }
181 }
182
183 time_normalizer *normalizer= time_normalizer::get(wait_timer);
184 m_row.m_stat.set(normalizer, &cumulated_stat);
185 }
186
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)187 int table_os_global_by_type::read_row_values(TABLE *table,
188 unsigned char *buf,
189 Field **fields,
190 bool read_all)
191 {
192 Field *f;
193
194 if (unlikely(! m_row_exists))
195 return HA_ERR_RECORD_DELETED;
196
197 /* Set the null bits */
198 DBUG_ASSERT(table->s->null_bytes == 1);
199 buf[0]= 0;
200
201 for (; (f= *fields) ; fields++)
202 {
203 if (read_all || bitmap_is_set(table->read_set, f->field_index))
204 {
205 switch(f->field_index)
206 {
207 case 0: /* OBJECT_TYPE */
208 set_field_object_type(f, m_row.m_object_type);
209 break;
210 case 1: /* SCHEMA_NAME */
211 set_field_varchar_utf8(f, m_row.m_schema_name,
212 m_row.m_schema_name_length);
213 break;
214 case 2: /* OBJECT_NAME */
215 set_field_varchar_utf8(f, m_row.m_object_name,
216 m_row.m_object_name_length);
217 break;
218 case 3: /* COUNT */
219 set_field_ulonglong(f, m_row.m_stat.m_count);
220 break;
221 case 4: /* SUM */
222 set_field_ulonglong(f, m_row.m_stat.m_sum);
223 break;
224 case 5: /* MIN */
225 set_field_ulonglong(f, m_row.m_stat.m_min);
226 break;
227 case 6: /* AVG */
228 set_field_ulonglong(f, m_row.m_stat.m_avg);
229 break;
230 case 7: /* MAX */
231 set_field_ulonglong(f, m_row.m_stat.m_max);
232 break;
233 default:
234 DBUG_ASSERT(false);
235 }
236 }
237 }
238
239 return 0;
240 }
241
242