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