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