1 /* Copyright (c) 2008, 2015, 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
21   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22 
23 #ifndef PFS_TABLE_HELPER_H
24 #define PFS_TABLE_HELPER_H
25 
26 #include "pfs_column_types.h"
27 #include "pfs_stat.h"
28 #include "pfs_timer.h"
29 #include "pfs_engine_table.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_digest.h"
32 
33 /*
34   Write MD5 hash value in a string to be used
35   as DIGEST for the statement.
36 */
37 #define MD5_HASH_TO_STRING(_hash, _str)                    \
38   sprintf(_str, "%02x%02x%02x%02x%02x%02x%02x%02x"         \
39                 "%02x%02x%02x%02x%02x%02x%02x%02x",        \
40           _hash[0], _hash[1], _hash[2], _hash[3],          \
41           _hash[4], _hash[5], _hash[6], _hash[7],          \
42           _hash[8], _hash[9], _hash[10], _hash[11],        \
43           _hash[12], _hash[13], _hash[14], _hash[15])
44 
45 #define MD5_HASH_TO_STRING_LENGTH 32
46 
47 struct PFS_host;
48 struct PFS_user;
49 struct PFS_account;
50 
51 /**
52   @file storage/perfschema/table_helper.h
53   Performance schema table helpers (declarations).
54 */
55 
56 /**
57   @addtogroup Performance_schema_tables
58   @{
59 */
60 
61 /** Namespace, internal views used within table setup_instruments. */
62 struct PFS_instrument_view_constants
63 {
64   static const uint FIRST_VIEW= 1;
65   static const uint VIEW_MUTEX= 1;
66   static const uint VIEW_RWLOCK= 2;
67   static const uint VIEW_COND= 3;
68   static const uint VIEW_FILE= 4;
69   static const uint VIEW_TABLE= 5;
70   static const uint VIEW_SOCKET= 6;
71   static const uint VIEW_IDLE= 7;
72   static const uint LAST_VIEW= 7;
73 };
74 
75 /** Namespace, internal views used within object summaries. */
76 struct PFS_object_view_constants
77 {
78   static const uint FIRST_VIEW= 1;
79   static const uint VIEW_TABLE= 1;
80   static const uint LAST_VIEW= 1;
81 
82   /* Future use */
83   static const uint VIEW_EVENT= 2;
84   static const uint VIEW_PROCEDURE= 3;
85   static const uint VIEW_FUNCTION= 4;
86 };
87 
88 /** Row fragment for column HOST. */
89 struct PFS_host_row
90 {
91   /** Column HOST. */
92   char m_hostname[HOSTNAME_LENGTH];
93   /** Length in bytes of @c m_hostname. */
94   uint m_hostname_length;
95 
96   /** Build a row from a memory buffer. */
97   int make_row(PFS_host *pfs);
98   /** Set a table field from the row. */
99   void set_field(Field *f);
100 };
101 
102 /** Row fragment for column USER. */
103 struct PFS_user_row
104 {
105   /** Column USER. */
106   char m_username[USERNAME_LENGTH];
107   /** Length in bytes of @c m_username. */
108   uint m_username_length;
109 
110   /** Build a row from a memory buffer. */
111   int make_row(PFS_user *pfs);
112   /** Set a table field from the row. */
113   void set_field(Field *f);
114 };
115 
116 /** Row fragment for columns USER, HOST. */
117 struct PFS_account_row
118 {
119   /** Column USER. */
120   char m_username[USERNAME_LENGTH];
121   /** Length in bytes of @c m_username. */
122   uint m_username_length;
123   /** Column HOST. */
124   char m_hostname[HOSTNAME_LENGTH];
125   /** Length in bytes of @c m_hostname. */
126   uint m_hostname_length;
127 
128   /** Build a row from a memory buffer. */
129   int make_row(PFS_account *pfs);
130   /** Set a table field from the row. */
131   void set_field(uint index, Field *f);
132 };
133 
134 /** Row fragment for columns DIGEST, DIGEST_TEXT. */
135 struct PFS_digest_row
136 {
137   /** Column SCHEMA_NAME. */
138   char m_schema_name[NAME_LEN];
139   /** Length in bytes of @c m_schema_name. */
140   uint m_schema_name_length;
141   /** Column DIGEST. */
142   char m_digest[COL_DIGEST_SIZE];
143   /** Length in bytes of @c m_digest. */
144   uint m_digest_length;
145   /** Column DIGEST_TEXT. */
146   String m_digest_text;
147 
148   /** Build a row from a memory buffer. */
149   int make_row(PFS_statements_digest_stat*);
150   /** Set a table field from the row. */
151   void set_field(uint index, Field *f);
152 };
153 
154 /** Row fragment for column EVENT_NAME. */
155 struct PFS_event_name_row
156 {
157   /** Column EVENT_NAME. */
158   const char *m_name;
159   /** Length in bytes of @c m_name. */
160   uint m_name_length;
161 
162   /** Build a row from a memory buffer. */
make_rowPFS_event_name_row163   inline void make_row(PFS_instr_class *pfs)
164   {
165     m_name= pfs->m_name;
166     m_name_length= pfs->m_name_length;
167   }
168 
169   /** Set a table field from the row. */
set_fieldPFS_event_name_row170   inline void set_field(Field *f)
171   {
172     PFS_engine_table::set_field_varchar_utf8(f, m_name, m_name_length);
173   }
174 };
175 
176 /** Row fragment for columns OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME. */
177 struct PFS_object_row
178 {
179   /** Column OBJECT_TYPE. */
180   enum_object_type m_object_type;
181   /** Column SCHEMA_NAME. */
182   char m_schema_name[NAME_LEN];
183   /** Length in bytes of @c m_schema_name. */
184   uint m_schema_name_length;
185   /** Column OBJECT_NAME. */
186   char m_object_name[NAME_LEN];
187   /** Length in bytes of @c m_object_name. */
188   uint m_object_name_length;
189 
190   /** Build a row from a memory buffer. */
191   int make_row(PFS_table_share *pfs);
192   /** Set a table field from the row. */
193   void set_field(uint index, Field *f);
194 };
195 
196 /** Row fragment for columns OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME, INDEX_NAME. */
197 struct PFS_index_row
198 {
199   PFS_object_row m_object_row;
200   /** Column INDEX_NAME. */
201   char m_index_name[NAME_LEN];
202   /** Length in bytes of @c m_index_name. */
203   uint m_index_name_length;
204 
205   /** Build a row from a memory buffer. */
206   int make_row(PFS_table_share *pfs, uint table_index);
207   /** Set a table field from the row. */
208   void set_field(uint index, Field *f);
209 };
210 
211 /** Row fragment for single statistics columns (COUNT, SUM, MIN, AVG, MAX) */
212 struct PFS_stat_row
213 {
214   /** Column COUNT_STAR. */
215   ulonglong m_count;
216   /** Column SUM_TIMER_WAIT. */
217   ulonglong m_sum;
218   /** Column MIN_TIMER_WAIT. */
219   ulonglong m_min;
220   /** Column AVG_TIMER_WAIT. */
221   ulonglong m_avg;
222   /** Column MAX_TIMER_WAIT. */
223   ulonglong m_max;
224 
225   /** Build a row with timer fields from a memory buffer. */
setPFS_stat_row226   inline void set(time_normalizer *normalizer, const PFS_single_stat *stat)
227   {
228     m_count= stat->m_count;
229 
230     if ((m_count != 0) && stat->has_timed_stats())
231     {
232       m_sum= normalizer->wait_to_pico(stat->m_sum);
233       m_min= normalizer->wait_to_pico(stat->m_min);
234       m_max= normalizer->wait_to_pico(stat->m_max);
235       m_avg= normalizer->wait_to_pico(stat->m_sum / m_count);
236     }
237     else
238     {
239       m_sum= 0;
240       m_min= 0;
241       m_avg= 0;
242       m_max= 0;
243     }
244   }
245 
246   /** Set a table field from the row. */
set_fieldPFS_stat_row247   void set_field(uint index, Field *f)
248   {
249     switch (index)
250     {
251       case 0: /* COUNT */
252         PFS_engine_table::set_field_ulonglong(f, m_count);
253         break;
254       case 1: /* SUM */
255         PFS_engine_table::set_field_ulonglong(f, m_sum);
256         break;
257       case 2: /* MIN */
258         PFS_engine_table::set_field_ulonglong(f, m_min);
259         break;
260       case 3: /* AVG */
261         PFS_engine_table::set_field_ulonglong(f, m_avg);
262         break;
263       case 4: /* MAX */
264         PFS_engine_table::set_field_ulonglong(f, m_max);
265         break;
266       default:
267         DBUG_ASSERT(false);
268     }
269   }
270 };
271 
272 /** Row fragment for timer and byte count stats. Corresponds to PFS_byte_stat */
273 struct PFS_byte_stat_row
274 {
275   PFS_stat_row m_waits;
276   ulonglong    m_bytes;
277 
278   /** Build a row with timer and byte count fields from a memory buffer. */
setPFS_byte_stat_row279   inline void set(time_normalizer *normalizer, const PFS_byte_stat *stat)
280   {
281     m_waits.set(normalizer, stat);
282     m_bytes= stat->m_bytes;
283   }
284 };
285 
286 /** Row fragment for table io statistics columns. */
287 struct PFS_table_io_stat_row
288 {
289   PFS_stat_row m_all;
290   PFS_stat_row m_all_read;
291   PFS_stat_row m_all_write;
292   PFS_stat_row m_fetch;
293   PFS_stat_row m_insert;
294   PFS_stat_row m_update;
295   PFS_stat_row m_delete;
296 
297   /** Build a row from a memory buffer. */
setPFS_table_io_stat_row298   inline void set(time_normalizer *normalizer, const PFS_table_io_stat *stat)
299   {
300     PFS_single_stat all_read;
301     PFS_single_stat all_write;
302     PFS_single_stat all;
303 
304     m_fetch.set(normalizer, & stat->m_fetch);
305 
306     all_read.aggregate(& stat->m_fetch);
307 
308     m_insert.set(normalizer, & stat->m_insert);
309     m_update.set(normalizer, & stat->m_update);
310     m_delete.set(normalizer, & stat->m_delete);
311 
312     all_write.aggregate(& stat->m_insert);
313     all_write.aggregate(& stat->m_update);
314     all_write.aggregate(& stat->m_delete);
315 
316     all.aggregate(& all_read);
317     all.aggregate(& all_write);
318 
319     m_all_read.set(normalizer, & all_read);
320     m_all_write.set(normalizer, & all_write);
321     m_all.set(normalizer, & all);
322   }
323 };
324 
325 /** Row fragment for table lock statistics columns. */
326 struct PFS_table_lock_stat_row
327 {
328   PFS_stat_row m_all;
329   PFS_stat_row m_all_read;
330   PFS_stat_row m_all_write;
331   PFS_stat_row m_read_normal;
332   PFS_stat_row m_read_with_shared_locks;
333   PFS_stat_row m_read_high_priority;
334   PFS_stat_row m_read_no_insert;
335   PFS_stat_row m_read_external;
336   PFS_stat_row m_write_allow_write;
337   PFS_stat_row m_write_concurrent_insert;
338   PFS_stat_row m_write_delayed;
339   PFS_stat_row m_write_low_priority;
340   PFS_stat_row m_write_normal;
341   PFS_stat_row m_write_external;
342 
343   /** Build a row from a memory buffer. */
setPFS_table_lock_stat_row344   inline void set(time_normalizer *normalizer, const PFS_table_lock_stat *stat)
345   {
346     PFS_single_stat all_read;
347     PFS_single_stat all_write;
348     PFS_single_stat all;
349 
350     m_read_normal.set(normalizer, & stat->m_stat[PFS_TL_READ]);
351     m_read_with_shared_locks.set(normalizer, & stat->m_stat[PFS_TL_READ_WITH_SHARED_LOCKS]);
352     m_read_high_priority.set(normalizer, & stat->m_stat[PFS_TL_READ_HIGH_PRIORITY]);
353     m_read_no_insert.set(normalizer, & stat->m_stat[PFS_TL_READ_NO_INSERT]);
354     m_read_external.set(normalizer, & stat->m_stat[PFS_TL_READ_EXTERNAL]);
355 
356     all_read.aggregate(& stat->m_stat[PFS_TL_READ]);
357     all_read.aggregate(& stat->m_stat[PFS_TL_READ_WITH_SHARED_LOCKS]);
358     all_read.aggregate(& stat->m_stat[PFS_TL_READ_HIGH_PRIORITY]);
359     all_read.aggregate(& stat->m_stat[PFS_TL_READ_NO_INSERT]);
360     all_read.aggregate(& stat->m_stat[PFS_TL_READ_EXTERNAL]);
361 
362     m_write_allow_write.set(normalizer, & stat->m_stat[PFS_TL_WRITE_ALLOW_WRITE]);
363     m_write_concurrent_insert.set(normalizer, & stat->m_stat[PFS_TL_WRITE_CONCURRENT_INSERT]);
364     m_write_delayed.set(normalizer, & stat->m_stat[PFS_TL_WRITE_DELAYED]);
365     m_write_low_priority.set(normalizer, & stat->m_stat[PFS_TL_WRITE_LOW_PRIORITY]);
366     m_write_normal.set(normalizer, & stat->m_stat[PFS_TL_WRITE]);
367     m_write_external.set(normalizer, & stat->m_stat[PFS_TL_WRITE_EXTERNAL]);
368 
369     all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_ALLOW_WRITE]);
370     all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_CONCURRENT_INSERT]);
371     all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_DELAYED]);
372     all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_LOW_PRIORITY]);
373     all_write.aggregate(& stat->m_stat[PFS_TL_WRITE]);
374     all_write.aggregate(& stat->m_stat[PFS_TL_WRITE_EXTERNAL]);
375 
376     all.aggregate(& all_read);
377     all.aggregate(& all_write);
378 
379     m_all_read.set(normalizer, & all_read);
380     m_all_write.set(normalizer, & all_write);
381     m_all.set(normalizer, & all);
382   }
383 };
384 
385 /** Row fragment for stage statistics columns. */
386 struct PFS_stage_stat_row
387 {
388   PFS_stat_row m_timer1_row;
389 
390   /** Build a row from a memory buffer. */
setPFS_stage_stat_row391   inline void set(time_normalizer *normalizer, const PFS_stage_stat *stat)
392   {
393     m_timer1_row.set(normalizer, & stat->m_timer1_stat);
394   }
395 
396   /** Set a table field from the row. */
set_fieldPFS_stage_stat_row397   void set_field(uint index, Field *f)
398   {
399      m_timer1_row.set_field(index, f);
400   }
401 };
402 
403 /** Row fragment for statement statistics columns. */
404 struct PFS_statement_stat_row
405 {
406   PFS_stat_row m_timer1_row;
407   ulonglong m_error_count;
408   ulonglong m_warning_count;
409   ulonglong m_rows_affected;
410   ulonglong m_lock_time;
411   ulonglong m_rows_sent;
412   ulonglong m_rows_examined;
413   ulonglong m_created_tmp_disk_tables;
414   ulonglong m_created_tmp_tables;
415   ulonglong m_select_full_join;
416   ulonglong m_select_full_range_join;
417   ulonglong m_select_range;
418   ulonglong m_select_range_check;
419   ulonglong m_select_scan;
420   ulonglong m_sort_merge_passes;
421   ulonglong m_sort_range;
422   ulonglong m_sort_rows;
423   ulonglong m_sort_scan;
424   ulonglong m_no_index_used;
425   ulonglong m_no_good_index_used;
426 
427   /** Build a row from a memory buffer. */
setPFS_statement_stat_row428   inline void set(time_normalizer *normalizer, const PFS_statement_stat *stat)
429   {
430     m_timer1_row.set(normalizer, & stat->m_timer1_stat);
431 
432     m_error_count= stat->m_error_count;
433     m_warning_count= stat->m_warning_count;
434     m_lock_time= stat->m_lock_time * MICROSEC_TO_PICOSEC;
435     m_rows_affected= stat->m_rows_affected;
436     m_rows_sent= stat->m_rows_sent;
437     m_rows_examined= stat->m_rows_examined;
438     m_created_tmp_disk_tables= stat->m_created_tmp_disk_tables;
439     m_created_tmp_tables= stat->m_created_tmp_tables;
440     m_select_full_join= stat->m_select_full_join;
441     m_select_full_range_join= stat->m_select_full_range_join;
442     m_select_range= stat->m_select_range;
443     m_select_range_check= stat->m_select_range_check;
444     m_select_scan= stat->m_select_scan;
445     m_sort_merge_passes= stat->m_sort_merge_passes;
446     m_sort_range= stat->m_sort_range;
447     m_sort_rows= stat->m_sort_rows;
448     m_sort_scan= stat->m_sort_scan;
449     m_no_index_used= stat->m_no_index_used;
450     m_no_good_index_used= stat->m_no_good_index_used;
451   }
452 
453   /** Set a table field from the row. */
454   void set_field(uint index, Field *f);
455 };
456 
457 struct PFS_connection_stat_row
458 {
459   ulonglong m_current_connections;
460   ulonglong m_total_connections;
461 
setPFS_connection_stat_row462   inline void set(const PFS_connection_stat *stat)
463   {
464     m_current_connections= stat->m_current_connections;
465     m_total_connections= stat->m_total_connections;
466   }
467 
468   /** Set a table field from the row. */
469   void set_field(uint index, Field *f);
470 };
471 
472 void set_field_object_type(Field *f, enum_object_type object_type);
473 
474 /** Row fragment for socket io statistics columns. */
475 struct PFS_socket_io_stat_row
476 {
477   PFS_byte_stat_row m_read;
478   PFS_byte_stat_row m_write;
479   PFS_byte_stat_row m_misc;
480   PFS_byte_stat_row m_all;
481 
setPFS_socket_io_stat_row482   inline void set(time_normalizer *normalizer, const PFS_socket_io_stat *stat)
483   {
484     PFS_byte_stat all;
485 
486     m_read.set(normalizer, &stat->m_read);
487     m_write.set(normalizer, &stat->m_write);
488     m_misc.set(normalizer, &stat->m_misc);
489 
490     /* Combine stats for all operations */
491     all.aggregate(&stat->m_read);
492     all.aggregate(&stat->m_write);
493     all.aggregate(&stat->m_misc);
494 
495     m_all.set(normalizer, &all);
496   }
497 };
498 
499 /** Row fragment for file io statistics columns. */
500 struct PFS_file_io_stat_row
501 {
502   PFS_byte_stat_row m_read;
503   PFS_byte_stat_row m_write;
504   PFS_byte_stat_row m_misc;
505   PFS_byte_stat_row m_all;
506 
setPFS_file_io_stat_row507   inline void set(time_normalizer *normalizer, const PFS_file_io_stat *stat)
508   {
509     PFS_byte_stat all;
510 
511     m_read.set(normalizer, &stat->m_read);
512     m_write.set(normalizer, &stat->m_write);
513     m_misc.set(normalizer, &stat->m_misc);
514 
515     /* Combine stats for all operations */
516     all.aggregate(&stat->m_read);
517     all.aggregate(&stat->m_write);
518     all.aggregate(&stat->m_misc);
519 
520     m_all.set(normalizer, &all);
521   }
522 };
523 
524 /** @} */
525 
526 #endif
527 
528