1 /* Copyright (c) 2010, 2021, Oracle and/or its affiliates.
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-1301, 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_thread.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 #include "pfs_buffer_container.h"
36 #include "field.h"
37
38 THR_LOCK table_os_global_by_type::m_table_lock;
39
40 static const TABLE_FIELD_TYPE field_types[]=
41 {
42 {
43 { C_STRING_WITH_LEN("OBJECT_TYPE") },
44 { C_STRING_WITH_LEN("varchar(64)") },
45 { NULL, 0}
46 },
47 {
48 { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
49 { C_STRING_WITH_LEN("varchar(64)") },
50 { NULL, 0}
51 },
52 {
53 { C_STRING_WITH_LEN("OBJECT_NAME") },
54 { C_STRING_WITH_LEN("varchar(64)") },
55 { NULL, 0}
56 },
57 {
58 { C_STRING_WITH_LEN("COUNT_STAR") },
59 { C_STRING_WITH_LEN("bigint(20)") },
60 { NULL, 0}
61 },
62 {
63 { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
64 { C_STRING_WITH_LEN("bigint(20)") },
65 { NULL, 0}
66 },
67 {
68 { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
69 { C_STRING_WITH_LEN("bigint(20)") },
70 { NULL, 0}
71 },
72 {
73 { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
74 { C_STRING_WITH_LEN("bigint(20)") },
75 { NULL, 0}
76 },
77 {
78 { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
79 { C_STRING_WITH_LEN("bigint(20)") },
80 { NULL, 0}
81 }
82 };
83
84 TABLE_FIELD_DEF
85 table_os_global_by_type::m_field_def=
86 { 8, field_types };
87
88 PFS_engine_table_share
89 table_os_global_by_type::m_share=
90 {
91 { C_STRING_WITH_LEN("objects_summary_global_by_type") },
92 &pfs_truncatable_acl,
93 table_os_global_by_type::create,
94 NULL, /* write_row */
95 table_os_global_by_type::delete_all_rows,
96 table_os_global_by_type::get_row_count,
97 sizeof(pos_os_global_by_type),
98 &m_table_lock,
99 &m_field_def,
100 false, /* checked */
101 false /* perpetual */
102 };
103
104 PFS_engine_table*
create(void)105 table_os_global_by_type::create(void)
106 {
107 return new table_os_global_by_type();
108 }
109
110 int
delete_all_rows(void)111 table_os_global_by_type::delete_all_rows(void)
112 {
113 reset_table_waits_by_table_handle();
114 reset_table_waits_by_table();
115 return 0;
116 }
117
118 ha_rows
get_row_count(void)119 table_os_global_by_type::get_row_count(void)
120 {
121 return global_table_share_container.get_row_count() +
122 global_program_container.get_row_count();
123 }
124
table_os_global_by_type()125 table_os_global_by_type::table_os_global_by_type()
126 : PFS_engine_table(&m_share, &m_pos),
127 m_row_exists(false), m_pos(), m_next_pos()
128 {}
129
reset_position(void)130 void table_os_global_by_type::reset_position(void)
131 {
132 m_pos.reset();
133 m_next_pos.reset();
134 }
135
rnd_next(void)136 int table_os_global_by_type::rnd_next(void)
137 {
138 for (m_pos.set_at(&m_next_pos);
139 m_pos.has_more_view();
140 m_pos.next_view())
141 {
142 switch (m_pos.m_index_1) {
143 case pos_os_global_by_type::VIEW_TABLE:
144 {
145 PFS_table_share *table_share;
146 bool has_more_share= true;
147
148 for (;
149 has_more_share;
150 m_pos.m_index_2++)
151 {
152 table_share= global_table_share_container.get(m_pos.m_index_2, & has_more_share);
153 if (table_share != NULL)
154 {
155 make_table_row(table_share);
156 m_next_pos.set_after(&m_pos);
157 return 0;
158 }
159 }
160 }
161 break;
162 case pos_os_global_by_type::VIEW_PROGRAM:
163 {
164 PFS_program *pfs_program;
165 bool has_more_program= true;
166
167 for (;
168 has_more_program;
169 m_pos.m_index_2++)
170 {
171 pfs_program= global_program_container.get(m_pos.m_index_2, & has_more_program);
172 if (pfs_program != NULL)
173 {
174 make_program_row(pfs_program);
175 m_next_pos.set_after(&m_pos);
176 return 0;
177 }
178 }
179 }
180 break;
181 default:
182 break;
183 }
184 }
185
186 return HA_ERR_END_OF_FILE;
187 }
188
189 int
rnd_pos(const void * pos)190 table_os_global_by_type::rnd_pos(const void *pos)
191 {
192 set_position(pos);
193
194 switch (m_pos.m_index_1) {
195 case pos_os_global_by_type::VIEW_TABLE:
196 {
197 PFS_table_share *table_share;
198 table_share= global_table_share_container.get(m_pos.m_index_2);
199 if (table_share != NULL)
200 {
201 make_table_row(table_share);
202 return 0;
203 }
204 }
205 break;
206 case pos_os_global_by_type::VIEW_PROGRAM:
207 {
208 PFS_program *pfs_program;
209 pfs_program= global_program_container.get(m_pos.m_index_2);
210 if (pfs_program != NULL)
211 {
212 make_program_row(pfs_program);
213 return 0;
214 }
215 }
216 break;
217 default:
218 break;
219 }
220
221 return HA_ERR_RECORD_DELETED;
222 }
223
make_program_row(PFS_program * pfs_program)224 void table_os_global_by_type::make_program_row(PFS_program *pfs_program)
225 {
226 pfs_optimistic_state lock;
227 PFS_single_stat cumulated_stat;
228
229 m_row_exists= false;
230
231 pfs_program->m_lock.begin_optimistic_lock(&lock);
232
233 m_row.m_object.make_row(pfs_program);
234
235 time_normalizer *normalizer= time_normalizer::get(wait_timer);
236 m_row.m_stat.set(normalizer, &pfs_program->m_sp_stat.m_timer1_stat);
237
238 if (! pfs_program->m_lock.end_optimistic_lock(&lock))
239 return;
240
241 m_row_exists= true;
242 }
243
make_table_row(PFS_table_share * share)244 void table_os_global_by_type::make_table_row(PFS_table_share *share)
245 {
246 pfs_optimistic_state lock;
247 PFS_single_stat cumulated_stat;
248 uint safe_key_count;
249
250 m_row_exists= false;
251
252 share->m_lock.begin_optimistic_lock(&lock);
253
254 m_row.m_object.make_row(share);
255
256 /* This is a dirty read, some thread can write data while we are reading it */
257 safe_key_count= sanitize_index_count(share->m_key_count);
258
259 share->sum(& cumulated_stat, safe_key_count);
260
261 if (! share->m_lock.end_optimistic_lock(&lock))
262 return;
263
264 m_row_exists= true;
265
266 if (share->get_refcount() > 0)
267 {
268 /* For all the table handles still opened ... */
269 PFS_table_iterator it= global_table_container.iterate();
270 PFS_table *table= it.scan_next();
271
272 while (table != NULL)
273 {
274 if (table->m_share == share)
275 {
276 /*
277 If the opened table handle is for this table share,
278 aggregate the table handle statistics.
279 */
280 table->m_table_stat.sum(& cumulated_stat, safe_key_count);
281 }
282 table= it.scan_next();
283 }
284 }
285
286 time_normalizer *normalizer= time_normalizer::get(wait_timer);
287 m_row.m_stat.set(normalizer, &cumulated_stat);
288 }
289
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)290 int table_os_global_by_type::read_row_values(TABLE *table,
291 unsigned char *buf,
292 Field **fields,
293 bool read_all)
294 {
295 Field *f;
296
297 if (unlikely(! m_row_exists))
298 return HA_ERR_RECORD_DELETED;
299
300 /* Set the null bits */
301 assert(table->s->null_bytes == 1);
302 buf[0]= 0;
303
304 for (; (f= *fields) ; fields++)
305 {
306 if (read_all || bitmap_is_set(table->read_set, f->field_index))
307 {
308 switch(f->field_index)
309 {
310 case 0: /* OBJECT_TYPE */
311 set_field_object_type(f, m_row.m_object.m_object_type);
312 break;
313 case 1: /* SCHEMA_NAME */
314 set_field_varchar_utf8(f, m_row.m_object.m_schema_name,
315 m_row.m_object.m_schema_name_length);
316 break;
317 case 2: /* OBJECT_NAME */
318 set_field_varchar_utf8(f, m_row.m_object.m_object_name,
319 m_row.m_object.m_object_name_length);
320 break;
321 case 3: /* COUNT */
322 set_field_ulonglong(f, m_row.m_stat.m_count);
323 break;
324 case 4: /* SUM */
325 set_field_ulonglong(f, m_row.m_stat.m_sum);
326 break;
327 case 5: /* MIN */
328 set_field_ulonglong(f, m_row.m_stat.m_min);
329 break;
330 case 6: /* AVG */
331 set_field_ulonglong(f, m_row.m_stat.m_avg);
332 break;
333 case 7: /* MAX */
334 set_field_ulonglong(f, m_row.m_stat.m_max);
335 break;
336 default:
337 assert(false);
338 }
339 }
340 }
341
342 return 0;
343 }
344
345