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