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