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