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