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