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