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_tiws_by_table.cc
25 Table TABLE_IO_WAITS_SUMMARY_BY_TABLE (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_tiws_by_table.h"
34 #include "pfs_global.h"
35 #include "pfs_visitor.h"
36 #include "pfs_buffer_container.h"
37 #include "field.h"
38
39 THR_LOCK table_tiws_by_table::m_table_lock;
40
41 static const TABLE_FIELD_TYPE field_types[]=
42 {
43 {
44 { C_STRING_WITH_LEN("OBJECT_TYPE") },
45 { C_STRING_WITH_LEN("varchar(64)") },
46 { NULL, 0}
47 },
48 {
49 { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
50 { C_STRING_WITH_LEN("varchar(64)") },
51 { NULL, 0}
52 },
53 {
54 { C_STRING_WITH_LEN("OBJECT_NAME") },
55 { C_STRING_WITH_LEN("varchar(64)") },
56 { NULL, 0}
57 },
58 {
59 { C_STRING_WITH_LEN("COUNT_STAR") },
60 { C_STRING_WITH_LEN("bigint(20)") },
61 { NULL, 0}
62 },
63 {
64 { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
65 { C_STRING_WITH_LEN("bigint(20)") },
66 { NULL, 0}
67 },
68 {
69 { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
70 { C_STRING_WITH_LEN("bigint(20)") },
71 { NULL, 0}
72 },
73 {
74 { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
75 { C_STRING_WITH_LEN("bigint(20)") },
76 { NULL, 0}
77 },
78 {
79 { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
80 { C_STRING_WITH_LEN("bigint(20)") },
81 { NULL, 0}
82 },
83 {
84 { C_STRING_WITH_LEN("COUNT_READ") },
85 { C_STRING_WITH_LEN("bigint(20)") },
86 { NULL, 0}
87 },
88 {
89 { C_STRING_WITH_LEN("SUM_TIMER_READ") },
90 { C_STRING_WITH_LEN("bigint(20)") },
91 { NULL, 0}
92 },
93 {
94 { C_STRING_WITH_LEN("MIN_TIMER_READ") },
95 { C_STRING_WITH_LEN("bigint(20)") },
96 { NULL, 0}
97 },
98 {
99 { C_STRING_WITH_LEN("AVG_TIMER_READ") },
100 { C_STRING_WITH_LEN("bigint(20)") },
101 { NULL, 0}
102 },
103 {
104 { C_STRING_WITH_LEN("MAX_TIMER_READ") },
105 { C_STRING_WITH_LEN("bigint(20)") },
106 { NULL, 0}
107 },
108 {
109 { C_STRING_WITH_LEN("COUNT_WRITE") },
110 { C_STRING_WITH_LEN("bigint(20)") },
111 { NULL, 0}
112 },
113 {
114 { C_STRING_WITH_LEN("SUM_TIMER_WRITE") },
115 { C_STRING_WITH_LEN("bigint(20)") },
116 { NULL, 0}
117 },
118 {
119 { C_STRING_WITH_LEN("MIN_TIMER_WRITE") },
120 { C_STRING_WITH_LEN("bigint(20)") },
121 { NULL, 0}
122 },
123 {
124 { C_STRING_WITH_LEN("AVG_TIMER_WRITE") },
125 { C_STRING_WITH_LEN("bigint(20)") },
126 { NULL, 0}
127 },
128 {
129 { C_STRING_WITH_LEN("MAX_TIMER_WRITE") },
130 { C_STRING_WITH_LEN("bigint(20)") },
131 { NULL, 0}
132 },
133 {
134 { C_STRING_WITH_LEN("COUNT_FETCH") },
135 { C_STRING_WITH_LEN("bigint(20)") },
136 { NULL, 0}
137 },
138 {
139 { C_STRING_WITH_LEN("SUM_TIMER_FETCH") },
140 { C_STRING_WITH_LEN("bigint(20)") },
141 { NULL, 0}
142 },
143 {
144 { C_STRING_WITH_LEN("MIN_TIMER_FETCH") },
145 { C_STRING_WITH_LEN("bigint(20)") },
146 { NULL, 0}
147 },
148 {
149 { C_STRING_WITH_LEN("AVG_TIMER_FETCH") },
150 { C_STRING_WITH_LEN("bigint(20)") },
151 { NULL, 0}
152 },
153 {
154 { C_STRING_WITH_LEN("MAX_TIMER_FETCH") },
155 { C_STRING_WITH_LEN("bigint(20)") },
156 { NULL, 0}
157 },
158 {
159 { C_STRING_WITH_LEN("COUNT_INSERT") },
160 { C_STRING_WITH_LEN("bigint(20)") },
161 { NULL, 0}
162 },
163 {
164 { C_STRING_WITH_LEN("SUM_TIMER_INSERT") },
165 { C_STRING_WITH_LEN("bigint(20)") },
166 { NULL, 0}
167 },
168 {
169 { C_STRING_WITH_LEN("MIN_TIMER_INSERT") },
170 { C_STRING_WITH_LEN("bigint(20)") },
171 { NULL, 0}
172 },
173 {
174 { C_STRING_WITH_LEN("AVG_TIMER_INSERT") },
175 { C_STRING_WITH_LEN("bigint(20)") },
176 { NULL, 0}
177 },
178 {
179 { C_STRING_WITH_LEN("MAX_TIMER_INSERT") },
180 { C_STRING_WITH_LEN("bigint(20)") },
181 { NULL, 0}
182 },
183 {
184 { C_STRING_WITH_LEN("COUNT_UPDATE") },
185 { C_STRING_WITH_LEN("bigint(20)") },
186 { NULL, 0}
187 },
188 {
189 { C_STRING_WITH_LEN("SUM_TIMER_UPDATE") },
190 { C_STRING_WITH_LEN("bigint(20)") },
191 { NULL, 0}
192 },
193 {
194 { C_STRING_WITH_LEN("MIN_TIMER_UPDATE") },
195 { C_STRING_WITH_LEN("bigint(20)") },
196 { NULL, 0}
197 },
198 {
199 { C_STRING_WITH_LEN("AVG_TIMER_UPDATE") },
200 { C_STRING_WITH_LEN("bigint(20)") },
201 { NULL, 0}
202 },
203 {
204 { C_STRING_WITH_LEN("MAX_TIMER_UPDATE") },
205 { C_STRING_WITH_LEN("bigint(20)") },
206 { NULL, 0}
207 },
208 {
209 { C_STRING_WITH_LEN("COUNT_DELETE") },
210 { C_STRING_WITH_LEN("bigint(20)") },
211 { NULL, 0}
212 },
213 {
214 { C_STRING_WITH_LEN("SUM_TIMER_DELETE") },
215 { C_STRING_WITH_LEN("bigint(20)") },
216 { NULL, 0}
217 },
218 {
219 { C_STRING_WITH_LEN("MIN_TIMER_DELETE") },
220 { C_STRING_WITH_LEN("bigint(20)") },
221 { NULL, 0}
222 },
223 {
224 { C_STRING_WITH_LEN("AVG_TIMER_DELETE") },
225 { C_STRING_WITH_LEN("bigint(20)") },
226 { NULL, 0}
227 },
228 {
229 { C_STRING_WITH_LEN("MAX_TIMER_DELETE") },
230 { C_STRING_WITH_LEN("bigint(20)") },
231 { NULL, 0}
232 }
233 };
234
235 TABLE_FIELD_DEF
236 table_tiws_by_table::m_field_def=
237 { 38, field_types };
238
239 PFS_engine_table_share
240 table_tiws_by_table::m_share=
241 {
242 { C_STRING_WITH_LEN("table_io_waits_summary_by_table") },
243 &pfs_truncatable_acl,
244 table_tiws_by_table::create,
245 NULL, /* write_row */
246 table_tiws_by_table::delete_all_rows,
247 table_tiws_by_table::get_row_count,
248 sizeof(PFS_simple_index),
249 &m_table_lock,
250 &m_field_def,
251 false, /* checked */
252 false /* perpetual */
253 };
254
255 PFS_engine_table*
create(void)256 table_tiws_by_table::create(void)
257 {
258 return new table_tiws_by_table();
259 }
260
261 int
delete_all_rows(void)262 table_tiws_by_table::delete_all_rows(void)
263 {
264 reset_table_io_waits_by_table_handle();
265 reset_table_io_waits_by_table();
266 return 0;
267 }
268
269 ha_rows
get_row_count(void)270 table_tiws_by_table::get_row_count(void)
271 {
272 return global_table_share_container.get_row_count();
273 }
274
table_tiws_by_table()275 table_tiws_by_table::table_tiws_by_table()
276 : PFS_engine_table(&m_share, &m_pos),
277 m_row_exists(false), m_pos(0), m_next_pos(0)
278 {}
279
reset_position(void)280 void table_tiws_by_table::reset_position(void)
281 {
282 m_pos.m_index= 0;
283 m_next_pos.m_index= 0;
284 }
285
rnd_init(bool scan)286 int table_tiws_by_table::rnd_init(bool scan)
287 {
288 m_normalizer= time_normalizer::get(wait_timer);
289 return 0;
290 }
291
rnd_next(void)292 int table_tiws_by_table::rnd_next(void)
293 {
294 PFS_table_share *pfs;
295
296 m_pos.set_at(&m_next_pos);
297 PFS_table_share_iterator it= global_table_share_container.iterate(m_pos.m_index);
298 do
299 {
300 pfs= it.scan_next(& m_pos.m_index);
301 if (pfs != NULL)
302 {
303 if (pfs->m_enabled)
304 {
305 make_row(pfs);
306 m_next_pos.set_after(&m_pos);
307 return 0;
308 }
309 }
310 } while (pfs != NULL);
311
312 return HA_ERR_END_OF_FILE;
313 }
314
315 int
rnd_pos(const void * pos)316 table_tiws_by_table::rnd_pos(const void *pos)
317 {
318 PFS_table_share *pfs;
319
320 set_position(pos);
321
322 pfs= global_table_share_container.get(m_pos.m_index);
323 if (pfs != NULL)
324 {
325 if (pfs->m_enabled)
326 {
327 make_row(pfs);
328 return 0;
329 }
330 }
331
332 return HA_ERR_RECORD_DELETED;
333 }
334
make_row(PFS_table_share * share)335 void table_tiws_by_table::make_row(PFS_table_share *share)
336 {
337 pfs_optimistic_state lock;
338
339 m_row_exists= false;
340
341 share->m_lock.begin_optimistic_lock(&lock);
342
343 if (m_row.m_object.make_row(share))
344 return;
345
346 PFS_table_io_stat_visitor visitor;
347 PFS_object_iterator::visit_tables(share, & visitor);
348
349 if (! share->m_lock.end_optimistic_lock(&lock))
350 return;
351
352 m_row_exists= true;
353 m_row.m_stat.set(m_normalizer, &visitor.m_stat);
354 }
355
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)356 int table_tiws_by_table::read_row_values(TABLE *table,
357 unsigned char *buf,
358 Field **fields,
359 bool read_all)
360 {
361 Field *f;
362
363 if (unlikely(! m_row_exists))
364 return HA_ERR_RECORD_DELETED;
365
366 /* Set the null bits */
367 assert(table->s->null_bytes == 1);
368 buf[0]= 0;
369
370 for (; (f= *fields) ; fields++)
371 {
372 if (read_all || bitmap_is_set(table->read_set, f->field_index))
373 {
374 switch(f->field_index)
375 {
376 case 0: /* OBJECT_TYPE */
377 case 1: /* SCHEMA_NAME */
378 case 2: /* OBJECT_NAME */
379 m_row.m_object.set_field(f->field_index, f);
380 break;
381 case 3: /* COUNT_STAR */
382 set_field_ulonglong(f, m_row.m_stat.m_all.m_count);
383 break;
384 case 4: /* SUM */
385 set_field_ulonglong(f, m_row.m_stat.m_all.m_sum);
386 break;
387 case 5: /* MIN */
388 set_field_ulonglong(f, m_row.m_stat.m_all.m_min);
389 break;
390 case 6: /* AVG */
391 set_field_ulonglong(f, m_row.m_stat.m_all.m_avg);
392 break;
393 case 7: /* MAX */
394 set_field_ulonglong(f, m_row.m_stat.m_all.m_max);
395 break;
396 case 8: /* COUNT_READ */
397 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_count);
398 break;
399 case 9: /* SUM_READ */
400 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_sum);
401 break;
402 case 10: /* MIN_READ */
403 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_min);
404 break;
405 case 11: /* AVG_READ */
406 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_avg);
407 break;
408 case 12: /* MAX_READ */
409 set_field_ulonglong(f, m_row.m_stat.m_all_read.m_max);
410 break;
411 case 13: /* COUNT_WRITE */
412 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_count);
413 break;
414 case 14: /* SUM_WRITE */
415 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_sum);
416 break;
417 case 15: /* MIN_WRITE */
418 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_min);
419 break;
420 case 16: /* AVG_WRITE */
421 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_avg);
422 break;
423 case 17: /* MAX_WRITE */
424 set_field_ulonglong(f, m_row.m_stat.m_all_write.m_max);
425 break;
426 case 18: /* COUNT_FETCH */
427 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_count);
428 break;
429 case 19: /* SUM_FETCH */
430 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_sum);
431 break;
432 case 20: /* MIN_FETCH */
433 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_min);
434 break;
435 case 21: /* AVG_FETCH */
436 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_avg);
437 break;
438 case 22: /* MAX_FETCH */
439 set_field_ulonglong(f, m_row.m_stat.m_fetch.m_max);
440 break;
441 case 23: /* COUNT_INSERT */
442 set_field_ulonglong(f, m_row.m_stat.m_insert.m_count);
443 break;
444 case 24: /* SUM_INSERT */
445 set_field_ulonglong(f, m_row.m_stat.m_insert.m_sum);
446 break;
447 case 25: /* MIN_INSERT */
448 set_field_ulonglong(f, m_row.m_stat.m_insert.m_min);
449 break;
450 case 26: /* AVG_INSERT */
451 set_field_ulonglong(f, m_row.m_stat.m_insert.m_avg);
452 break;
453 case 27: /* MAX_INSERT */
454 set_field_ulonglong(f, m_row.m_stat.m_insert.m_max);
455 break;
456 case 28: /* COUNT_UPDATE */
457 set_field_ulonglong(f, m_row.m_stat.m_update.m_count);
458 break;
459 case 29: /* SUM_UPDATE */
460 set_field_ulonglong(f, m_row.m_stat.m_update.m_sum);
461 break;
462 case 30: /* MIN_UPDATE */
463 set_field_ulonglong(f, m_row.m_stat.m_update.m_min);
464 break;
465 case 31: /* AVG_UPDATE */
466 set_field_ulonglong(f, m_row.m_stat.m_update.m_avg);
467 break;
468 case 32: /* MAX_UPDATE */
469 set_field_ulonglong(f, m_row.m_stat.m_update.m_max);
470 break;
471 case 33: /* COUNT_DELETE */
472 set_field_ulonglong(f, m_row.m_stat.m_delete.m_count);
473 break;
474 case 34: /* SUM_DELETE */
475 set_field_ulonglong(f, m_row.m_stat.m_delete.m_sum);
476 break;
477 case 35: /* MIN_DELETE */
478 set_field_ulonglong(f, m_row.m_stat.m_delete.m_min);
479 break;
480 case 36: /* AVG_DELETE */
481 set_field_ulonglong(f, m_row.m_stat.m_delete.m_avg);
482 break;
483 case 37: /* MAX_DELETE */
484 set_field_ulonglong(f, m_row.m_stat.m_delete.m_max);
485 break;
486 default:
487 assert(false);
488 }
489 }
490 }
491
492 return 0;
493 }
494
495