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