1 /* Copyright (c) 2008, 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 Foundation,
21   51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
22 
23 /**
24   @file storage/perfschema/table_socket_summary_by_instance.cc
25   Table SOCKET_SUMMARY_BY_INSTANCE (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_socket_summary_by_instance.h"
34 #include "pfs_global.h"
35 #include "pfs_buffer_container.h"
36 #include "field.h"
37 
38 THR_LOCK table_socket_summary_by_instance::m_table_lock;
39 
40 PFS_engine_table_share
41 table_socket_summary_by_instance::m_share=
42 {
43   { C_STRING_WITH_LEN("socket_summary_by_instance") },
44   &pfs_readonly_acl,
45   table_socket_summary_by_instance::create,
46   NULL, /* write_row */
47   table_socket_summary_by_instance::delete_all_rows,
48   table_socket_summary_by_instance::get_row_count,
49   sizeof(PFS_simple_index),
50   &m_table_lock,
51   { C_STRING_WITH_LEN("CREATE TABLE socket_summary_by_instance("
52                       "EVENT_NAME VARCHAR(128) not null comment 'Socket instrument.',"
53                       "OBJECT_INSTANCE_BEGIN BIGINT unsigned not null comment 'Address in memory.',"
54                       "COUNT_STAR BIGINT unsigned not null comment 'Number of summarized events',"
55                       "SUM_TIMER_WAIT BIGINT unsigned not null comment 'Total wait time of the summarized events that are timed.',"
56                       "MIN_TIMER_WAIT BIGINT unsigned not null comment 'Minimum wait time of the summarized events that are timed.',"
57                       "AVG_TIMER_WAIT BIGINT unsigned not null comment 'Average wait time of the summarized events that are timed.',"
58                       "MAX_TIMER_WAIT BIGINT unsigned not null comment 'Maximum wait time of the summarized events that are timed.',"
59                       "COUNT_READ BIGINT unsigned not null comment 'Number of all read operations, including RECV, RECVFROM, and RECVMSG.',"
60                       "SUM_TIMER_READ BIGINT unsigned not null comment 'Total wait time of all read operations that are timed.',"
61                       "MIN_TIMER_READ BIGINT unsigned not null comment 'Minimum wait time of all read operations that are timed.',"
62                       "AVG_TIMER_READ BIGINT unsigned not null comment 'Average wait time of all read operations that are timed.',"
63                       "MAX_TIMER_READ BIGINT unsigned not null comment 'Maximum wait time of all read operations that are timed.',"
64                       "SUM_NUMBER_OF_BYTES_READ BIGINT unsigned not null comment 'Bytes read by read operations.',"
65                       "COUNT_WRITE BIGINT unsigned not null comment 'Number of all write operations, including SEND, SENDTO, and SENDMSG.',"
66                       "SUM_TIMER_WRITE BIGINT unsigned not null comment 'Total wait time of all write operations that are timed.',"
67                       "MIN_TIMER_WRITE BIGINT unsigned not null comment 'Minimum wait time of all write operations that are timed.',"
68                       "AVG_TIMER_WRITE BIGINT unsigned not null comment 'Average wait time of all write operations that are timed.',"
69                       "MAX_TIMER_WRITE BIGINT unsigned not null comment 'Maximum wait time of all write operations that are timed.',"
70                       "SUM_NUMBER_OF_BYTES_WRITE BIGINT unsigned not null comment 'Bytes written by write operations.',"
71                       "COUNT_MISC BIGINT unsigned not null comment 'Number of all miscellaneous operations not counted above, including CONNECT, LISTEN, ACCEPT, CLOSE, and SHUTDOWN.',"
72                       "SUM_TIMER_MISC BIGINT unsigned not null comment 'Total wait time of all miscellaneous operations that are timed.',"
73                       "MIN_TIMER_MISC BIGINT unsigned not null comment 'Minimum wait time of all miscellaneous operations that are timed.',"
74                       "AVG_TIMER_MISC BIGINT unsigned not null comment 'Average wait time of all miscellaneous operations that are timed.',"
75                       "MAX_TIMER_MISC BIGINT unsigned not null comment 'Maximum wait time of all miscellaneous operations that are timed.')") },
76   false  /* perpetual */
77 };
78 
create(void)79 PFS_engine_table* table_socket_summary_by_instance::create(void)
80 {
81   return new table_socket_summary_by_instance();
82 }
83 
table_socket_summary_by_instance()84 table_socket_summary_by_instance::table_socket_summary_by_instance()
85   : PFS_engine_table(&m_share, &m_pos),
86   m_row_exists(false), m_pos(0), m_next_pos(0)
87 {}
88 
delete_all_rows(void)89 int table_socket_summary_by_instance::delete_all_rows(void)
90 {
91   reset_socket_instance_io();
92   return 0;
93 }
94 
95 ha_rows
get_row_count(void)96 table_socket_summary_by_instance::get_row_count(void)
97 {
98   return global_socket_container.get_row_count();
99 }
100 
reset_position(void)101 void table_socket_summary_by_instance::reset_position(void)
102 {
103   m_pos.m_index= 0;
104   m_next_pos.m_index= 0;
105 }
106 
rnd_next(void)107 int table_socket_summary_by_instance::rnd_next(void)
108 {
109   PFS_socket *pfs;
110 
111   m_pos.set_at(&m_next_pos);
112   PFS_socket_iterator it= global_socket_container.iterate(m_pos.m_index);
113   pfs= it.scan_next(& m_pos.m_index);
114   if (pfs != NULL)
115   {
116     make_row(pfs);
117     m_next_pos.set_after(&m_pos);
118     return 0;
119   }
120 
121   return HA_ERR_END_OF_FILE;
122 }
123 
rnd_pos(const void * pos)124 int table_socket_summary_by_instance::rnd_pos(const void *pos)
125 {
126   PFS_socket *pfs;
127 
128   set_position(pos);
129 
130   pfs= global_socket_container.get(m_pos.m_index);
131   if (pfs != NULL)
132   {
133     make_row(pfs);
134     return 0;
135   }
136 
137   return HA_ERR_RECORD_DELETED;
138 }
139 
make_row(PFS_socket * pfs)140 void table_socket_summary_by_instance::make_row(PFS_socket *pfs)
141 {
142   pfs_optimistic_state lock;
143   PFS_socket_class *safe_class;
144 
145   m_row_exists= false;
146 
147   /* Protect this reader against a socket delete */
148   pfs->m_lock.begin_optimistic_lock(&lock);
149 
150   safe_class= sanitize_socket_class(pfs->m_class);
151   if (unlikely(safe_class == NULL))
152     return;
153 
154   m_row.m_event_name.make_row(safe_class);
155   m_row.m_identity= pfs->m_identity;
156 
157   time_normalizer *normalizer= time_normalizer::get(wait_timer);
158 
159   /* Collect timer and byte count stats */
160   m_row.m_io_stat.set(normalizer, &pfs->m_socket_stat.m_io_stat);
161 
162   if (!pfs->m_lock.end_optimistic_lock(&lock))
163     return;
164 
165   m_row_exists= true;
166 }
167 
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)168 int table_socket_summary_by_instance::read_row_values(TABLE *table,
169                                           unsigned char *,
170                                           Field **fields,
171                                           bool read_all)
172 {
173   Field *f;
174 
175   if (unlikely(!m_row_exists))
176     return HA_ERR_RECORD_DELETED;
177 
178   /* Set the null bits */
179   assert(table->s->null_bytes == 0);
180 
181   for (; (f= *fields) ; fields++)
182   {
183     if (read_all || bitmap_is_set(table->read_set, f->field_index))
184     {
185       switch(f->field_index)
186       {
187       case  0: /* EVENT_NAME */
188         m_row.m_event_name.set_field(f);
189         break;
190       case  1: /* OBJECT_INSTANCE */
191         set_field_ulonglong(f, (intptr)m_row.m_identity);
192         break;
193 
194       case  2:/* COUNT_STAR */
195         set_field_ulonglong(f, m_row.m_io_stat.m_all.m_waits.m_count);
196         break;
197       case  3:/* SUM_TIMER_WAIT */
198         set_field_ulonglong(f, m_row.m_io_stat.m_all.m_waits.m_sum);
199         break;
200       case  4: /* MIN_TIMER_WAIT */
201         set_field_ulonglong(f, m_row.m_io_stat.m_all.m_waits.m_min);
202         break;
203       case  5: /* AVG_TIMER_WAIT */
204         set_field_ulonglong(f, m_row.m_io_stat.m_all.m_waits.m_avg);
205         break;
206       case  6: /* MAX_TIMER_WAIT */
207         set_field_ulonglong(f, m_row.m_io_stat.m_all.m_waits.m_max);
208         break;
209 
210       case  7: /* COUNT_READ */
211         set_field_ulonglong(f, m_row.m_io_stat.m_read.m_waits.m_count);
212         break;
213       case  8: /* SUM_TIMER_READ */
214         set_field_ulonglong(f, m_row.m_io_stat.m_read.m_waits.m_sum);
215         break;
216       case  9: /* MIN_TIMER_READ */
217         set_field_ulonglong(f, m_row.m_io_stat.m_read.m_waits.m_min);
218         break;
219       case 10: /* AVG_TIMER_READ */
220         set_field_ulonglong(f, m_row.m_io_stat.m_read.m_waits.m_avg);
221         break;
222       case 11: /* MAX_TIMER_READ */
223         set_field_ulonglong(f, m_row.m_io_stat.m_read.m_waits.m_max);
224         break;
225       case 12: /* SUM_NUMBER_OF_BYTES_READ */
226         set_field_ulonglong(f, m_row.m_io_stat.m_read.m_bytes);
227         break;
228 
229       case 13: /* COUNT_WRITE */
230         set_field_ulonglong(f, m_row.m_io_stat.m_write.m_waits.m_count);
231         break;
232       case 14: /* SUM_TIMER_WRITE */
233         set_field_ulonglong(f, m_row.m_io_stat.m_write.m_waits.m_sum);
234         break;
235       case 15: /* MIN_TIMER_WRITE */
236         set_field_ulonglong(f, m_row.m_io_stat.m_write.m_waits.m_min);
237         break;
238       case 16: /* AVG_TIMER_WRITE */
239         set_field_ulonglong(f, m_row.m_io_stat.m_write.m_waits.m_avg);
240         break;
241       case 17: /* MAX_TIMER_WRITE */
242         set_field_ulonglong(f, m_row.m_io_stat.m_write.m_waits.m_max);
243         break;
244       case 18: /* SUM_NUMBER_OF_BYTES_WRITE */
245         set_field_ulonglong(f, m_row.m_io_stat.m_write.m_bytes);
246         break;
247 
248       case 19: /* COUNT_MISC */
249         set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_waits.m_count);
250         break;
251       case 20: /* SUM_TIMER_MISC */
252         set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_waits.m_sum);
253         break;
254       case 21: /* MIN_TIMER_MISC */
255         set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_waits.m_min);
256         break;
257       case 22: /* AVG_TIMER_MISC */
258         set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_waits.m_avg);
259         break;
260       case 23: /* MAX_TIMER_MISC */
261         set_field_ulonglong(f, m_row.m_io_stat.m_misc.m_waits.m_max);
262         break;
263       default:
264         assert(false);
265         break;
266       }
267     }
268   }
269 
270   return 0;
271 }
272