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_ews_global_by_event_name.cc
25   Table EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME (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_ews_global_by_event_name.h"
34 #include "pfs_global.h"
35 #include "pfs_instr.h"
36 #include "pfs_timer.h"
37 #include "pfs_visitor.h"
38 #include "field.h"
39 
40 THR_LOCK table_ews_global_by_event_name::m_table_lock;
41 
42 static const TABLE_FIELD_TYPE field_types[]=
43 {
44   {
45     { C_STRING_WITH_LEN("EVENT_NAME") },
46     { C_STRING_WITH_LEN("varchar(128)") },
47     { NULL, 0}
48   },
49   {
50     { C_STRING_WITH_LEN("COUNT_STAR") },
51     { C_STRING_WITH_LEN("bigint(20)") },
52     { NULL, 0}
53   },
54   {
55     { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
56     { C_STRING_WITH_LEN("bigint(20)") },
57     { NULL, 0}
58   },
59   {
60     { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
61     { C_STRING_WITH_LEN("bigint(20)") },
62     { NULL, 0}
63   },
64   {
65     { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
66     { C_STRING_WITH_LEN("bigint(20)") },
67     { NULL, 0}
68   },
69   {
70     { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
71     { C_STRING_WITH_LEN("bigint(20)") },
72     { NULL, 0}
73   }
74 };
75 
76 TABLE_FIELD_DEF
77 table_ews_global_by_event_name::m_field_def=
78 { 6, field_types };
79 
80 PFS_engine_table_share
81 table_ews_global_by_event_name::m_share=
82 {
83   { C_STRING_WITH_LEN("events_waits_summary_global_by_event_name") },
84   &pfs_truncatable_acl,
85   table_ews_global_by_event_name::create,
86   NULL, /* write_row */
87   table_ews_global_by_event_name::delete_all_rows,
88   table_ews_global_by_event_name::get_row_count,
89   sizeof(pos_ews_global_by_event_name),
90   &m_table_lock,
91   &m_field_def,
92   false, /* checked */
93   false  /* perpetual */
94 };
95 
96 PFS_engine_table*
create(void)97 table_ews_global_by_event_name::create(void)
98 {
99   return new table_ews_global_by_event_name();
100 }
101 
102 int
delete_all_rows(void)103 table_ews_global_by_event_name::delete_all_rows(void)
104 {
105   reset_events_waits_by_instance();
106   reset_table_waits_by_table_handle();
107   reset_table_waits_by_table();
108   reset_events_waits_by_class();
109   return 0;
110 }
111 
112 ha_rows
get_row_count(void)113 table_ews_global_by_event_name::get_row_count(void)
114 {
115   return wait_class_max;
116 }
117 
table_ews_global_by_event_name()118 table_ews_global_by_event_name::table_ews_global_by_event_name()
119   : PFS_engine_table(&m_share, &m_pos),
120     m_row_exists(false), m_pos(), m_next_pos()
121 {}
122 
reset_position(void)123 void table_ews_global_by_event_name::reset_position(void)
124 {
125   m_pos.reset();
126   m_next_pos.reset();
127 }
128 
rnd_next(void)129 int table_ews_global_by_event_name::rnd_next(void)
130 {
131   PFS_mutex_class *mutex_class;
132   PFS_rwlock_class *rwlock_class;
133   PFS_cond_class *cond_class;
134   PFS_file_class *file_class;
135   PFS_socket_class *socket_class;
136   PFS_instr_class *instr_class;
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     {
144     case pos_ews_global_by_event_name::VIEW_MUTEX:
145       mutex_class= find_mutex_class(m_pos.m_index_2);
146       if (mutex_class)
147       {
148         make_mutex_row(mutex_class);
149         m_next_pos.set_after(&m_pos);
150         return 0;
151       }
152       break;
153     case pos_ews_global_by_event_name::VIEW_RWLOCK:
154       rwlock_class= find_rwlock_class(m_pos.m_index_2);
155       if (rwlock_class)
156       {
157         make_rwlock_row(rwlock_class);
158         m_next_pos.set_after(&m_pos);
159         return 0;
160       }
161       break;
162     case pos_ews_global_by_event_name::VIEW_COND:
163       cond_class= find_cond_class(m_pos.m_index_2);
164       if (cond_class)
165       {
166         make_cond_row(cond_class);
167         m_next_pos.set_after(&m_pos);
168         return 0;
169       }
170       break;
171     case pos_ews_global_by_event_name::VIEW_FILE:
172       file_class= find_file_class(m_pos.m_index_2);
173       if (file_class)
174       {
175         make_file_row(file_class);
176         m_next_pos.set_after(&m_pos);
177         return 0;
178       }
179       break;
180     case pos_ews_global_by_event_name::VIEW_TABLE:
181       if (m_pos.m_index_2 == 1)
182       {
183         make_table_io_row(&global_table_io_class);
184         m_next_pos.set_after(&m_pos);
185         return 0;
186       }
187       if (m_pos.m_index_2 == 2)
188       {
189         make_table_lock_row(&global_table_lock_class);
190         m_next_pos.set_after(&m_pos);
191         return 0;
192       }
193       break;
194     case pos_ews_global_by_event_name::VIEW_SOCKET:
195       socket_class= find_socket_class(m_pos.m_index_2);
196       if (socket_class)
197       {
198         make_socket_row(socket_class);
199         m_next_pos.set_after(&m_pos);
200         return 0;
201       }
202       break;
203     case pos_ews_global_by_event_name::VIEW_IDLE:
204       instr_class= find_idle_class(m_pos.m_index_2);
205       if (instr_class)
206       {
207         make_idle_row(instr_class);
208         m_next_pos.set_after(&m_pos);
209         return 0;
210       }
211       break;
212     case pos_ews_global_by_event_name::VIEW_METADATA:
213       instr_class= find_metadata_class(m_pos.m_index_2);
214       if (instr_class)
215       {
216         make_metadata_row(instr_class);
217         m_next_pos.set_after(&m_pos);
218         return 0;
219       }
220       break;
221     default:
222       break;
223     }
224   }
225 
226   return HA_ERR_END_OF_FILE;
227 }
228 
229 int
rnd_pos(const void * pos)230 table_ews_global_by_event_name::rnd_pos(const void *pos)
231 {
232   PFS_mutex_class *mutex_class;
233   PFS_rwlock_class *rwlock_class;
234   PFS_cond_class *cond_class;
235   PFS_file_class *file_class;
236   PFS_socket_class *socket_class;
237   PFS_instr_class *instr_class;
238 
239   set_position(pos);
240 
241   switch (m_pos.m_index_1)
242   {
243   case pos_ews_global_by_event_name::VIEW_MUTEX:
244     mutex_class= find_mutex_class(m_pos.m_index_2);
245     if (mutex_class)
246     {
247       make_mutex_row(mutex_class);
248       return 0;
249     }
250     break;
251   case pos_ews_global_by_event_name::VIEW_RWLOCK:
252     rwlock_class= find_rwlock_class(m_pos.m_index_2);
253     if (rwlock_class)
254     {
255       make_rwlock_row(rwlock_class);
256       return 0;
257     }
258     break;
259   case pos_ews_global_by_event_name::VIEW_COND:
260     cond_class= find_cond_class(m_pos.m_index_2);
261     if (cond_class)
262     {
263       make_cond_row(cond_class);
264       return 0;
265     }
266     break;
267   case pos_ews_global_by_event_name::VIEW_FILE:
268     file_class= find_file_class(m_pos.m_index_2);
269     if (file_class)
270     {
271       make_file_row(file_class);
272       return 0;
273     }
274     break;
275   case pos_ews_global_by_event_name::VIEW_TABLE:
276     assert(m_pos.m_index_2 >= 1);
277     assert(m_pos.m_index_2 <= 2);
278     if (m_pos.m_index_2 == 1)
279       make_table_io_row(&global_table_io_class);
280     else
281       make_table_lock_row(&global_table_lock_class);
282     break;
283   case pos_ews_global_by_event_name::VIEW_SOCKET:
284     socket_class= find_socket_class(m_pos.m_index_2);
285     if (socket_class)
286     {
287       make_socket_row(socket_class);
288       return 0;
289     }
290     break;
291   case pos_ews_global_by_event_name::VIEW_IDLE:
292     instr_class= find_idle_class(m_pos.m_index_2);
293     if (instr_class)
294     {
295       make_idle_row(instr_class);
296       return 0;
297     }
298     break;
299   case pos_ews_global_by_event_name::VIEW_METADATA:
300     instr_class= find_metadata_class(m_pos.m_index_2);
301     if (instr_class)
302     {
303       make_metadata_row(instr_class);
304       return 0;
305     }
306     break;
307   default:
308     assert(false);
309     break;
310   }
311 
312   return HA_ERR_RECORD_DELETED;
313 }
314 
315 void table_ews_global_by_event_name
make_mutex_row(PFS_mutex_class * klass)316 ::make_mutex_row(PFS_mutex_class *klass)
317 {
318   m_row.m_event_name.make_row(klass);
319 
320   PFS_instance_wait_visitor visitor;
321   PFS_instance_iterator::visit_mutex_instances(klass, & visitor);
322 
323   get_normalizer(klass);
324   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
325   m_row_exists= true;
326 }
327 
328 void table_ews_global_by_event_name
make_rwlock_row(PFS_rwlock_class * klass)329 ::make_rwlock_row(PFS_rwlock_class *klass)
330 {
331   m_row.m_event_name.make_row(klass);
332 
333   PFS_instance_wait_visitor visitor;
334   PFS_instance_iterator::visit_rwlock_instances(klass, & visitor);
335 
336   get_normalizer(klass);
337   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
338   m_row_exists= true;
339 }
340 
341 void table_ews_global_by_event_name
make_cond_row(PFS_cond_class * klass)342 ::make_cond_row(PFS_cond_class *klass)
343 {
344   m_row.m_event_name.make_row(klass);
345 
346   PFS_instance_wait_visitor visitor;
347   PFS_instance_iterator::visit_cond_instances(klass, & visitor);
348 
349   get_normalizer(klass);
350   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
351   m_row_exists= true;
352 }
353 
354 void table_ews_global_by_event_name
make_file_row(PFS_file_class * klass)355 ::make_file_row(PFS_file_class *klass)
356 {
357   m_row.m_event_name.make_row(klass);
358 
359   PFS_instance_wait_visitor visitor;
360   PFS_instance_iterator::visit_file_instances(klass, & visitor);
361 
362   get_normalizer(klass);
363   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
364   m_row_exists= true;
365 }
366 
367 void table_ews_global_by_event_name
make_table_io_row(PFS_instr_class * klass)368 ::make_table_io_row(PFS_instr_class *klass)
369 {
370   m_row.m_event_name.make_row(klass);
371 
372   PFS_table_io_wait_visitor visitor;
373   PFS_object_iterator::visit_all_tables(& visitor);
374 
375   get_normalizer(klass);
376   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
377   m_row_exists= true;
378 }
379 
380 void table_ews_global_by_event_name
make_table_lock_row(PFS_instr_class * klass)381 ::make_table_lock_row(PFS_instr_class *klass)
382 {
383   m_row.m_event_name.make_row(klass);
384 
385   PFS_table_lock_wait_visitor visitor;
386   PFS_object_iterator::visit_all_tables(& visitor);
387 
388   get_normalizer(klass);
389   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
390   m_row_exists= true;
391 }
392 
393 void table_ews_global_by_event_name
make_socket_row(PFS_socket_class * klass)394 ::make_socket_row(PFS_socket_class *klass)
395 {
396   m_row.m_event_name.make_row(klass);
397 
398   PFS_instance_wait_visitor visitor;
399   PFS_instance_iterator::visit_socket_instances(klass, &visitor);
400 
401   get_normalizer(klass);
402   m_row.m_stat.set(m_normalizer, &visitor.m_stat);
403   m_row_exists= true;
404 }
405 
406 void table_ews_global_by_event_name
make_idle_row(PFS_instr_class * klass)407 ::make_idle_row(PFS_instr_class *klass)
408 {
409   m_row.m_event_name.make_row(klass);
410 
411   PFS_connection_wait_visitor visitor(klass);
412   PFS_connection_iterator::visit_global(false, /* hosts */
413                                         false, /* users */
414                                         false, /* accounts */
415                                         true,  /* threads */
416                                         false, /* THDs */
417                                         &visitor);
418   get_normalizer(klass);
419   m_row.m_stat.set(m_normalizer, &visitor.m_stat);
420   m_row_exists= true;
421 }
422 
423 void table_ews_global_by_event_name
make_metadata_row(PFS_instr_class * klass)424 ::make_metadata_row(PFS_instr_class *klass)
425 {
426   m_row.m_event_name.make_row(klass);
427 
428   PFS_connection_wait_visitor visitor(klass);
429   PFS_connection_iterator::visit_global(false, /* hosts */
430                                         true,  /* users */
431                                         true,  /* accounts */
432                                         true,  /* threads */
433                                         false, /* THDs */
434                                         &visitor);
435   get_normalizer(klass);
436   m_row.m_stat.set(m_normalizer, &visitor.m_stat);
437   m_row_exists= true;
438 }
439 
440 int table_ews_global_by_event_name
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)441 ::read_row_values(TABLE *table, unsigned char *, Field **fields,
442                   bool read_all)
443 {
444   Field *f;
445 
446   if (unlikely(! m_row_exists))
447     return HA_ERR_RECORD_DELETED;
448 
449   /* Set the null bits */
450   assert(table->s->null_bytes == 0);
451 
452   for (; (f= *fields) ; fields++)
453   {
454     if (read_all || bitmap_is_set(table->read_set, f->field_index))
455     {
456       switch(f->field_index)
457       {
458       case 0: /* EVENT_NAME */
459         m_row.m_event_name.set_field(f);
460         break;
461       default: /* 1, ... COUNT/SUM/MIN/AVG/MAX */
462         m_row.m_stat.set_field(f->field_index - 1, f);
463         break;
464       }
465     }
466   }
467 
468   return 0;
469 }
470 
471