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