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 St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /**
24   @file storage/perfschema/table_esms_by_thread_by_event_name.cc
25   Table EVENTS_STATEMENTS_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_esms_by_thread_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_esms_by_thread_by_event_name::m_table_lock;
40 
41 static const TABLE_FIELD_TYPE field_types[]=
42 {
43   {
44     { C_STRING_WITH_LEN("THREAD_ID") },
45     { C_STRING_WITH_LEN("bigint(20)") },
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("SUM_LOCK_TIME") },
80     { C_STRING_WITH_LEN("bigint(20)") },
81     { NULL, 0}
82   },
83   {
84     { C_STRING_WITH_LEN("SUM_ERRORS") },
85     { C_STRING_WITH_LEN("bigint(20)") },
86     { NULL, 0}
87   },
88   {
89     { C_STRING_WITH_LEN("SUM_WARNINGS") },
90     { C_STRING_WITH_LEN("bigint(20)") },
91     { NULL, 0}
92   },
93   {
94     { C_STRING_WITH_LEN("SUM_ROWS_AFFECTED") },
95     { C_STRING_WITH_LEN("bigint(20)") },
96     { NULL, 0}
97   },
98   {
99     { C_STRING_WITH_LEN("SUM_ROWS_SENT") },
100     { C_STRING_WITH_LEN("bigint(20)") },
101     { NULL, 0}
102   },
103   {
104     { C_STRING_WITH_LEN("SUM_ROWS_EXAMINED") },
105     { C_STRING_WITH_LEN("bigint(20)") },
106     { NULL, 0}
107   },
108   {
109     { C_STRING_WITH_LEN("SUM_CREATED_TMP_DISK_TABLES") },
110     { C_STRING_WITH_LEN("bigint(20)") },
111     { NULL, 0}
112   },
113   {
114     { C_STRING_WITH_LEN("SUM_CREATED_TMP_TABLES") },
115     { C_STRING_WITH_LEN("bigint(20)") },
116     { NULL, 0}
117   },
118   {
119     { C_STRING_WITH_LEN("SUM_SELECT_FULL_JOIN") },
120     { C_STRING_WITH_LEN("bigint(20)") },
121     { NULL, 0}
122   },
123   {
124     { C_STRING_WITH_LEN("SUM_SELECT_FULL_RANGE_JOIN") },
125     { C_STRING_WITH_LEN("bigint(20)") },
126     { NULL, 0}
127   },
128   {
129     { C_STRING_WITH_LEN("SUM_SELECT_RANGE") },
130     { C_STRING_WITH_LEN("bigint(20)") },
131     { NULL, 0}
132   },
133   {
134     { C_STRING_WITH_LEN("SUM_SELECT_RANGE_CHECK") },
135     { C_STRING_WITH_LEN("bigint(20)") },
136     { NULL, 0}
137   },
138   {
139     { C_STRING_WITH_LEN("SUM_SELECT_SCAN") },
140     { C_STRING_WITH_LEN("bigint(20)") },
141     { NULL, 0}
142   },
143   {
144     { C_STRING_WITH_LEN("SUM_SORT_MERGE_PASSES") },
145     { C_STRING_WITH_LEN("bigint(20)") },
146     { NULL, 0}
147   },
148   {
149     { C_STRING_WITH_LEN("SUM_SORT_RANGE") },
150     { C_STRING_WITH_LEN("bigint(20)") },
151     { NULL, 0}
152   },
153   {
154     { C_STRING_WITH_LEN("SUM_SORT_ROWS") },
155     { C_STRING_WITH_LEN("bigint(20)") },
156     { NULL, 0}
157   },
158   {
159     { C_STRING_WITH_LEN("SUM_SORT_SCAN") },
160     { C_STRING_WITH_LEN("bigint(20)") },
161     { NULL, 0}
162   },
163   {
164     { C_STRING_WITH_LEN("SUM_NO_INDEX_USED") },
165     { C_STRING_WITH_LEN("bigint(20)") },
166     { NULL, 0}
167   },
168   {
169     { C_STRING_WITH_LEN("SUM_NO_GOOD_INDEX_USED") },
170     { C_STRING_WITH_LEN("bigint(20)") },
171     { NULL, 0}
172   }
173 };
174 
175 TABLE_FIELD_DEF
176 table_esms_by_thread_by_event_name::m_field_def=
177 { 26, field_types };
178 
179 PFS_engine_table_share
180 table_esms_by_thread_by_event_name::m_share=
181 {
182   { C_STRING_WITH_LEN("events_statements_summary_by_thread_by_event_name") },
183   &pfs_truncatable_acl,
184   table_esms_by_thread_by_event_name::create,
185   NULL, /* write_row */
186   table_esms_by_thread_by_event_name::delete_all_rows,
187   table_esms_by_thread_by_event_name::get_row_count,
188   sizeof(pos_esms_by_thread_by_event_name),
189   &m_table_lock,
190   &m_field_def,
191   false, /* checked */
192   false  /* perpetual */
193 };
194 
195 PFS_engine_table*
create(void)196 table_esms_by_thread_by_event_name::create(void)
197 {
198   return new table_esms_by_thread_by_event_name();
199 }
200 
201 int
delete_all_rows(void)202 table_esms_by_thread_by_event_name::delete_all_rows(void)
203 {
204   reset_events_statements_by_thread();
205   return 0;
206 }
207 
208 ha_rows
get_row_count(void)209 table_esms_by_thread_by_event_name::get_row_count(void)
210 {
211   return global_thread_container.get_row_count() * statement_class_max;
212 }
213 
table_esms_by_thread_by_event_name()214 table_esms_by_thread_by_event_name::table_esms_by_thread_by_event_name()
215   : PFS_engine_table(&m_share, &m_pos),
216     m_row_exists(false), m_pos(), m_next_pos()
217 {}
218 
reset_position(void)219 void table_esms_by_thread_by_event_name::reset_position(void)
220 {
221   m_pos.reset();
222   m_next_pos.reset();
223 }
224 
rnd_init(bool scan)225 int table_esms_by_thread_by_event_name::rnd_init(bool scan)
226 {
227   m_normalizer= time_normalizer::get(statement_timer);
228   return 0;
229 }
230 
rnd_next(void)231 int table_esms_by_thread_by_event_name::rnd_next(void)
232 {
233   PFS_thread *thread;
234   PFS_statement_class *statement_class;
235   bool has_more_thread= true;
236 
237   for (m_pos.set_at(&m_next_pos);
238        has_more_thread;
239        m_pos.next_thread())
240   {
241     thread= global_thread_container.get(m_pos.m_index_1, & has_more_thread);
242     if (thread != NULL)
243     {
244       statement_class= find_statement_class(m_pos.m_index_2);
245       if (statement_class)
246       {
247         make_row(thread, statement_class);
248         m_next_pos.set_after(&m_pos);
249         return 0;
250       }
251     }
252   }
253 
254   return HA_ERR_END_OF_FILE;
255 }
256 
257 int
rnd_pos(const void * pos)258 table_esms_by_thread_by_event_name::rnd_pos(const void *pos)
259 {
260   PFS_thread *thread;
261   PFS_statement_class *statement_class;
262 
263   set_position(pos);
264 
265   thread= global_thread_container.get(m_pos.m_index_1);
266   if (thread != NULL)
267   {
268     statement_class= find_statement_class(m_pos.m_index_2);
269     if (statement_class)
270     {
271       make_row(thread, statement_class);
272       return 0;
273     }
274   }
275 
276   return HA_ERR_RECORD_DELETED;
277 }
278 
279 void table_esms_by_thread_by_event_name
make_row(PFS_thread * thread,PFS_statement_class * klass)280 ::make_row(PFS_thread *thread, PFS_statement_class *klass)
281 {
282   pfs_optimistic_state lock;
283   m_row_exists= false;
284 
285   if (klass->is_mutable())
286     return;
287 
288   /* Protect this reader against a thread termination */
289   thread->m_lock.begin_optimistic_lock(&lock);
290 
291   m_row.m_thread_internal_id= thread->m_thread_internal_id;
292 
293   m_row.m_event_name.make_row(klass);
294 
295   PFS_connection_statement_visitor visitor(klass);
296   PFS_connection_iterator::visit_thread(thread, & visitor);
297 
298   if (! thread->m_lock.end_optimistic_lock(&lock))
299     return;
300 
301   m_row_exists= true;
302   m_row.m_stat.set(m_normalizer, & visitor.m_stat);
303 }
304 
305 int table_esms_by_thread_by_event_name
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)306 ::read_row_values(TABLE *table, unsigned char *, Field **fields,
307                   bool read_all)
308 {
309   Field *f;
310 
311   if (unlikely(! m_row_exists))
312     return HA_ERR_RECORD_DELETED;
313 
314   /* Set the null bits */
315   assert(table->s->null_bytes == 0);
316 
317   for (; (f= *fields) ; fields++)
318   {
319     if (read_all || bitmap_is_set(table->read_set, f->field_index))
320     {
321       switch(f->field_index)
322       {
323       case 0: /* THREAD_ID */
324         set_field_ulonglong(f, m_row.m_thread_internal_id);
325         break;
326       case 1: /* EVENT_NAME */
327         m_row.m_event_name.set_field(f);
328         break;
329       default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
330         m_row.m_stat.set_field(f->field_index - 2, f);
331         break;
332       }
333     }
334   }
335 
336   return 0;
337 }
338 
339