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, Suite 500, Boston, MA 02110-1335 USA */
22
23 /**
24 @file storage/perfschema/table_ets_by_user_by_event_name.cc
25 Table EVENTS_TRANSACTIONS_SUMMARY_BY_USER_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_ets_by_user_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_ets_by_user_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("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 { C_STRING_WITH_LEN("COUNT_READ_WRITE") },
80 { C_STRING_WITH_LEN("bigint(20)") },
81 { NULL, 0}
82 },
83 {
84 { C_STRING_WITH_LEN("SUM_TIMER_READ_WRITE") },
85 { C_STRING_WITH_LEN("bigint(20)") },
86 { NULL, 0}
87 },
88 {
89 { C_STRING_WITH_LEN("MIN_TIMER_READ_WRITE") },
90 { C_STRING_WITH_LEN("bigint(20)") },
91 { NULL, 0}
92 },
93 {
94 { C_STRING_WITH_LEN("AVG_TIMER_READ_WRITE") },
95 { C_STRING_WITH_LEN("bigint(20)") },
96 { NULL, 0}
97 },
98 {
99 { C_STRING_WITH_LEN("MAX_TIMER_READ_WRITE") },
100 { C_STRING_WITH_LEN("bigint(20)") },
101 { NULL, 0}
102 },
103 {
104 { C_STRING_WITH_LEN("COUNT_READ_ONLY") },
105 { C_STRING_WITH_LEN("bigint(20)") },
106 { NULL, 0}
107 },
108 {
109 { C_STRING_WITH_LEN("SUM_TIMER_READ_ONLY") },
110 { C_STRING_WITH_LEN("bigint(20)") },
111 { NULL, 0}
112 },
113 {
114 { C_STRING_WITH_LEN("MIN_TIMER_READ_ONLY") },
115 { C_STRING_WITH_LEN("bigint(20)") },
116 { NULL, 0}
117 },
118 {
119 { C_STRING_WITH_LEN("AVG_TIMER_READ_ONLY") },
120 { C_STRING_WITH_LEN("bigint(20)") },
121 { NULL, 0}
122 },
123 {
124 { C_STRING_WITH_LEN("MAX_TIMER_READ_ONLY") },
125 { C_STRING_WITH_LEN("bigint(20)") },
126 { NULL, 0}
127 }
128 };
129
130 TABLE_FIELD_DEF
131 table_ets_by_user_by_event_name::m_field_def=
132 { 17, field_types };
133
134 PFS_engine_table_share
135 table_ets_by_user_by_event_name::m_share=
136 {
137 { C_STRING_WITH_LEN("events_transactions_summary_by_user_by_event_name") },
138 &pfs_truncatable_acl,
139 table_ets_by_user_by_event_name::create,
140 NULL, /* write_row */
141 table_ets_by_user_by_event_name::delete_all_rows,
142 table_ets_by_user_by_event_name::get_row_count,
143 sizeof(pos_ets_by_user_by_event_name),
144 &m_table_lock,
145 &m_field_def,
146 false, /* checked */
147 false /* perpetual */
148 };
149
150 PFS_engine_table*
create(void)151 table_ets_by_user_by_event_name::create(void)
152 {
153 return new table_ets_by_user_by_event_name();
154 }
155
156 int
delete_all_rows(void)157 table_ets_by_user_by_event_name::delete_all_rows(void)
158 {
159 reset_events_transactions_by_thread();
160 reset_events_transactions_by_account();
161 reset_events_transactions_by_user();
162 return 0;
163 }
164
165 ha_rows
get_row_count(void)166 table_ets_by_user_by_event_name::get_row_count(void)
167 {
168 return global_user_container.get_row_count() * transaction_class_max;
169 }
170
table_ets_by_user_by_event_name()171 table_ets_by_user_by_event_name::table_ets_by_user_by_event_name()
172 : PFS_engine_table(&m_share, &m_pos),
173 m_row_exists(false), m_pos(), m_next_pos()
174 {}
175
reset_position(void)176 void table_ets_by_user_by_event_name::reset_position(void)
177 {
178 m_pos.reset();
179 m_next_pos.reset();
180 }
181
rnd_init(bool scan)182 int table_ets_by_user_by_event_name::rnd_init(bool scan)
183 {
184 m_normalizer= time_normalizer::get(transaction_timer);
185 return 0;
186 }
187
rnd_next(void)188 int table_ets_by_user_by_event_name::rnd_next(void)
189 {
190 PFS_user *user;
191 PFS_transaction_class *transaction_class;
192 bool has_more_user= true;
193
194 for (m_pos.set_at(&m_next_pos);
195 has_more_user;
196 m_pos.next_user())
197 {
198 user= global_user_container.get(m_pos.m_index_1, & has_more_user);
199 if (user != NULL)
200 {
201 transaction_class= find_transaction_class(m_pos.m_index_2);
202 if (transaction_class)
203 {
204 make_row(user, transaction_class);
205 m_next_pos.set_after(&m_pos);
206 return 0;
207 }
208 }
209 }
210
211 return HA_ERR_END_OF_FILE;
212 }
213
214 int
rnd_pos(const void * pos)215 table_ets_by_user_by_event_name::rnd_pos(const void *pos)
216 {
217 PFS_user *user;
218 PFS_transaction_class *transaction_class;
219
220 set_position(pos);
221
222 user= global_user_container.get(m_pos.m_index_1);
223 if (user != NULL)
224 {
225 transaction_class= find_transaction_class(m_pos.m_index_2);
226 if (transaction_class)
227 {
228 make_row(user, transaction_class);
229 return 0;
230 }
231 }
232
233 return HA_ERR_RECORD_DELETED;
234 }
235
236 void table_ets_by_user_by_event_name
make_row(PFS_user * user,PFS_transaction_class * klass)237 ::make_row(PFS_user *user, PFS_transaction_class *klass)
238 {
239 pfs_optimistic_state lock;
240 m_row_exists= false;
241
242 user->m_lock.begin_optimistic_lock(&lock);
243
244 if (m_row.m_user.make_row(user))
245 return;
246
247 m_row.m_event_name.make_row(klass);
248
249 PFS_connection_transaction_visitor visitor(klass);
250 PFS_connection_iterator::visit_user(user,
251 true, /* accounts */
252 true, /* threads */
253 false, /* THDs */
254 & visitor);
255
256 if (! user->m_lock.end_optimistic_lock(&lock))
257 return;
258
259 m_row_exists= true;
260 m_row.m_stat.set(m_normalizer, & visitor.m_stat);
261 }
262
263 int table_ets_by_user_by_event_name
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)264 ::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
265 bool read_all)
266 {
267 Field *f;
268
269 if (unlikely(! m_row_exists))
270 return HA_ERR_RECORD_DELETED;
271
272 /* Set the null bits */
273 assert(table->s->null_bytes == 1);
274 buf[0]= 0;
275
276 for (; (f= *fields) ; fields++)
277 {
278 if (read_all || bitmap_is_set(table->read_set, f->field_index))
279 {
280 switch(f->field_index)
281 {
282 case 0: /* USER */
283 m_row.m_user.set_field(f);
284 break;
285 case 1: /* EVENT_NAME */
286 m_row.m_event_name.set_field(f);
287 break;
288 default:
289 /**
290 COUNT_STAR, SUM/MIN/AVG/MAX_TIMER_WAIT,
291 COUNT_READ_WRITE, SUM/MIN/AVG/MAX_TIMER_READ_WRITE,
292 COUNT_READ_ONLY, SUM/MIN/AVG/MAX_TIMER_READ_ONLY
293 */
294 m_row.m_stat.set_field(f->field_index-2, f);
295 break;
296 }
297 }
298 }
299
300 return 0;
301 }
302
303