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_by_thread_by_event_name.cc
25   Table EVENTS_WAITS_SUMMARY_BY_HOST_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_by_thread_by_event_name.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_ews_by_thread_by_event_name::m_table_lock;
40 
41 static const TABLE_FIELD_TYPE field_types[]=
42 {
43   {
44     { C_STRING_WITH_LEN("THREAD_ID") },
45     { C_STRING_WITH_LEN("bigint(20)") },
46     { NULL, 0}
47   },
48   {
49     { C_STRING_WITH_LEN("EVENT_NAME") },
50     { C_STRING_WITH_LEN("varchar(128)") },
51     { NULL, 0}
52   },
53   {
54     { C_STRING_WITH_LEN("COUNT_STAR") },
55     { C_STRING_WITH_LEN("bigint(20)") },
56     { NULL, 0}
57   },
58   {
59     { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
60     { C_STRING_WITH_LEN("bigint(20)") },
61     { NULL, 0}
62   },
63   {
64     { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
65     { C_STRING_WITH_LEN("bigint(20)") },
66     { NULL, 0}
67   },
68   {
69     { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
70     { C_STRING_WITH_LEN("bigint(20)") },
71     { NULL, 0}
72   },
73   {
74     { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
75     { C_STRING_WITH_LEN("bigint(20)") },
76     { NULL, 0}
77   }
78 };
79 
80 TABLE_FIELD_DEF
81 table_ews_by_thread_by_event_name::m_field_def=
82 { 7, field_types };
83 
84 PFS_engine_table_share
85 table_ews_by_thread_by_event_name::m_share=
86 {
87   { C_STRING_WITH_LEN("events_waits_summary_by_thread_by_event_name") },
88   &pfs_truncatable_acl,
89   table_ews_by_thread_by_event_name::create,
90   NULL, /* write_row */
91   table_ews_by_thread_by_event_name::delete_all_rows,
92   table_ews_by_thread_by_event_name::get_row_count,
93   sizeof(pos_ews_by_thread_by_event_name),
94   &m_table_lock,
95   &m_field_def,
96   false, /* checked */
97   false  /* perpetual */
98 };
99 
100 PFS_engine_table*
create(void)101 table_ews_by_thread_by_event_name::create(void)
102 {
103   return new table_ews_by_thread_by_event_name();
104 }
105 
106 int
delete_all_rows(void)107 table_ews_by_thread_by_event_name::delete_all_rows(void)
108 {
109   reset_events_waits_by_thread();
110   return 0;
111 }
112 
113 ha_rows
get_row_count(void)114 table_ews_by_thread_by_event_name::get_row_count(void)
115 {
116   return global_thread_container.get_row_count() * wait_class_max;
117 }
118 
table_ews_by_thread_by_event_name()119 table_ews_by_thread_by_event_name::table_ews_by_thread_by_event_name()
120   : PFS_engine_table(&m_share, &m_pos),
121     m_row_exists(false), m_pos(), m_next_pos()
122 {}
123 
reset_position(void)124 void table_ews_by_thread_by_event_name::reset_position(void)
125 {
126   m_pos.reset();
127   m_next_pos.reset();
128 }
129 
rnd_next(void)130 int table_ews_by_thread_by_event_name::rnd_next(void)
131 {
132   PFS_thread *thread;
133   PFS_instr_class *instr_class;
134   bool has_more_thread= true;
135 
136   for (m_pos.set_at(&m_next_pos);
137        has_more_thread;
138        m_pos.next_thread())
139   {
140     thread= global_thread_container.get(m_pos.m_index_1, & has_more_thread);
141     if (thread != NULL)
142     {
143       for ( ;
144            m_pos.has_more_view();
145            m_pos.next_view())
146       {
147         switch (m_pos.m_index_2)
148         {
149         case pos_ews_by_thread_by_event_name::VIEW_MUTEX:
150           instr_class= find_mutex_class(m_pos.m_index_3);
151           break;
152         case pos_ews_by_thread_by_event_name::VIEW_RWLOCK:
153           instr_class= find_rwlock_class(m_pos.m_index_3);
154           break;
155         case pos_ews_by_thread_by_event_name::VIEW_COND:
156           instr_class= find_cond_class(m_pos.m_index_3);
157           break;
158         case pos_ews_by_thread_by_event_name::VIEW_FILE:
159           instr_class= find_file_class(m_pos.m_index_3);
160           break;
161         case pos_ews_by_thread_by_event_name::VIEW_TABLE:
162           instr_class= find_table_class(m_pos.m_index_3);
163           break;
164         case pos_ews_by_thread_by_event_name::VIEW_SOCKET:
165           instr_class= find_socket_class(m_pos.m_index_3);
166           break;
167         case pos_ews_by_thread_by_event_name::VIEW_IDLE:
168           instr_class= find_idle_class(m_pos.m_index_3);
169           break;
170         case pos_ews_by_thread_by_event_name::VIEW_METADATA:
171           instr_class= find_metadata_class(m_pos.m_index_3);
172           break;
173         default:
174           assert(false);
175           instr_class= NULL;
176           break;
177         }
178 
179         if (instr_class != NULL)
180         {
181           make_row(thread, instr_class);
182           m_next_pos.set_after(&m_pos);
183           return 0;
184         }
185       }
186     }
187   }
188 
189   return HA_ERR_END_OF_FILE;
190 }
191 
192 int
rnd_pos(const void * pos)193 table_ews_by_thread_by_event_name::rnd_pos(const void *pos)
194 {
195   PFS_thread *thread;
196   PFS_instr_class *instr_class;
197 
198   set_position(pos);
199 
200   thread= global_thread_container.get(m_pos.m_index_1);
201   if (thread != NULL)
202   {
203     switch (m_pos.m_index_2)
204     {
205     case pos_ews_by_thread_by_event_name::VIEW_MUTEX:
206       instr_class= find_mutex_class(m_pos.m_index_3);
207       break;
208     case pos_ews_by_thread_by_event_name::VIEW_RWLOCK:
209       instr_class= find_rwlock_class(m_pos.m_index_3);
210       break;
211     case pos_ews_by_thread_by_event_name::VIEW_COND:
212       instr_class= find_cond_class(m_pos.m_index_3);
213       break;
214     case pos_ews_by_thread_by_event_name::VIEW_FILE:
215       instr_class= find_file_class(m_pos.m_index_3);
216       break;
217     case pos_ews_by_thread_by_event_name::VIEW_TABLE:
218       instr_class= find_table_class(m_pos.m_index_3);
219       break;
220     case pos_ews_by_thread_by_event_name::VIEW_SOCKET:
221       instr_class= find_socket_class(m_pos.m_index_3);
222       break;
223     case pos_ews_by_thread_by_event_name::VIEW_IDLE:
224       instr_class= find_idle_class(m_pos.m_index_3);
225       break;
226     case pos_ews_by_thread_by_event_name::VIEW_METADATA:
227       instr_class= find_metadata_class(m_pos.m_index_3);
228       break;
229     default:
230       assert(false);
231       instr_class= NULL;
232     }
233 
234     if (instr_class)
235     {
236       make_row(thread, instr_class);
237       return 0;
238     }
239   }
240 
241   return HA_ERR_RECORD_DELETED;
242 }
243 
244 void table_ews_by_thread_by_event_name
make_row(PFS_thread * thread,PFS_instr_class * klass)245 ::make_row(PFS_thread *thread, PFS_instr_class *klass)
246 {
247   pfs_optimistic_state lock;
248   m_row_exists= false;
249 
250   /* Protect this reader against a thread termination */
251   thread->m_lock.begin_optimistic_lock(&lock);
252 
253   m_row.m_thread_internal_id= thread->m_thread_internal_id;
254 
255   m_row.m_event_name.make_row(klass);
256 
257   PFS_connection_wait_visitor visitor(klass);
258   PFS_connection_iterator::visit_thread(thread, &visitor);
259 
260   /*
261     If the aggregation for this class is deferred, then we must pull the
262     current wait stats from the instances associated with this thread.
263   */
264   if (klass->is_deferred())
265   {
266     /* Visit instances owned by this thread. Do not visit the class. */
267     PFS_instance_wait_visitor inst_visitor;
268     PFS_instance_iterator::visit_instances(klass, &inst_visitor,
269                                            thread, false);
270     /* Combine the deferred stats and global stats */
271     visitor.m_stat.aggregate(&inst_visitor.m_stat);
272   }
273 
274   if (! thread->m_lock.end_optimistic_lock(&lock))
275     return;
276 
277   m_row_exists= true;
278 
279   get_normalizer(klass);
280   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
281 }
282 
283 int table_ews_by_thread_by_event_name
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)284 ::read_row_values(TABLE *table, unsigned char *, Field **fields,
285                   bool read_all)
286 {
287   Field *f;
288 
289   if (unlikely(! m_row_exists))
290     return HA_ERR_RECORD_DELETED;
291 
292   /* Set the null bits */
293   assert(table->s->null_bytes == 0);
294 
295   for (; (f= *fields) ; fields++)
296   {
297     if (read_all || bitmap_is_set(table->read_set, f->field_index))
298     {
299       switch(f->field_index)
300       {
301       case 0: /* THREAD_ID */
302         set_field_ulonglong(f, m_row.m_thread_internal_id);
303         break;
304       case 1: /* EVENT_NAME */
305         m_row.m_event_name.set_field(f);
306         break;
307       default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
308         m_row.m_stat.set_field(f->field_index - 2, f);
309         break;
310       }
311     }
312   }
313 
314   return 0;
315 }
316 
317