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 Foundation,
14 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15
16/**
17 @file storage/perfschema/pfs_engine_table.cc
18 Performance schema tables (implementation).
19*/
20
21#include "my_global.h"
22#include "my_pthread.h"
23#include "hostname.h" /* For Host_entry */
24#include "pfs_engine_table.h"
25
26#include "table_events_waits.h"
27#include "table_setup_actors.h"
28#include "table_setup_consumers.h"
29#include "table_setup_instruments.h"
30#include "table_setup_objects.h"
31#include "table_setup_timers.h"
32#include "table_performance_timers.h"
33#include "table_events_waits_summary.h"
34#include "table_ews_by_thread_by_event_name.h"
35#include "table_ews_global_by_event_name.h"
36#include "table_host_cache.h"
37#include "table_os_global_by_type.h"
38#include "table_sync_instances.h"
39#include "table_file_instances.h"
40#include "table_file_summary_by_instance.h"
41#include "table_file_summary_by_event_name.h"
42#include "table_threads.h"
43
44#include "table_ews_by_host_by_event_name.h"
45#include "table_ews_by_user_by_event_name.h"
46#include "table_ews_by_account_by_event_name.h"
47#include "table_tiws_by_index_usage.h"
48#include "table_tiws_by_table.h"
49#include "table_tlws_by_table.h"
50
51#include "table_events_stages.h"
52#include "table_esgs_by_thread_by_event_name.h"
53#include "table_esgs_by_host_by_event_name.h"
54#include "table_esgs_by_user_by_event_name.h"
55#include "table_esgs_by_account_by_event_name.h"
56#include "table_esgs_global_by_event_name.h"
57
58#include "table_events_statements.h"
59#include "table_esms_by_thread_by_event_name.h"
60#include "table_esms_by_host_by_event_name.h"
61#include "table_esms_by_user_by_event_name.h"
62#include "table_esms_by_account_by_event_name.h"
63#include "table_esms_global_by_event_name.h"
64#include "table_esms_by_digest.h"
65
66#include "table_users.h"
67#include "table_accounts.h"
68#include "table_hosts.h"
69
70#include "table_socket_instances.h"
71#include "table_socket_summary_by_instance.h"
72#include "table_socket_summary_by_event_name.h"
73#include "table_session_connect_attrs.h"
74#include "table_session_account_connect_attrs.h"
75
76/* For show status */
77#include "pfs_column_values.h"
78#include "pfs_instr_class.h"
79#include "pfs_instr.h"
80#include "pfs_setup_actor.h"
81#include "pfs_setup_object.h"
82#include "pfs_global.h"
83#include "pfs_digest.h"
84
85#include "sql_base.h" // close_thread_tables
86#include "lock.h" // MYSQL_LOCK_IGNORE_TIMEOUT
87
88/**
89 @addtogroup Performance_schema_engine
90 @{
91*/
92
93static PFS_engine_table_share *all_shares[]=
94{
95 &table_cond_instances::m_share,
96 &table_events_waits_current::m_share,
97 &table_events_waits_history::m_share,
98 &table_events_waits_history_long::m_share,
99 &table_ews_by_host_by_event_name::m_share,
100 &table_events_waits_summary_by_instance::m_share,
101 &table_ews_by_thread_by_event_name::m_share,
102 &table_ews_by_user_by_event_name::m_share,
103 &table_ews_by_account_by_event_name::m_share,
104 &table_ews_global_by_event_name::m_share,
105 &table_file_instances::m_share,
106 &table_file_summary_by_event_name::m_share,
107 &table_file_summary_by_instance::m_share,
108 &table_host_cache::m_share,
109 &table_mutex_instances::m_share,
110 &table_os_global_by_type::m_share,
111 &table_performance_timers::m_share,
112 &table_rwlock_instances::m_share,
113 &table_setup_actors::m_share,
114 &table_setup_consumers::m_share,
115 &table_setup_instruments::m_share,
116 &table_setup_objects::m_share,
117 &table_setup_timers::m_share,
118 &table_tiws_by_index_usage::m_share,
119 &table_tiws_by_table::m_share,
120 &table_tlws_by_table::m_share,
121 &table_threads::m_share,
122
123 &table_events_stages_current::m_share,
124 &table_events_stages_history::m_share,
125 &table_events_stages_history_long::m_share,
126 &table_esgs_by_thread_by_event_name::m_share,
127 &table_esgs_by_account_by_event_name::m_share,
128 &table_esgs_by_user_by_event_name::m_share,
129 &table_esgs_by_host_by_event_name::m_share,
130 &table_esgs_global_by_event_name::m_share,
131
132 &table_events_statements_current::m_share,
133 &table_events_statements_history::m_share,
134 &table_events_statements_history_long::m_share,
135 &table_esms_by_thread_by_event_name::m_share,
136 &table_esms_by_account_by_event_name::m_share,
137 &table_esms_by_user_by_event_name::m_share,
138 &table_esms_by_host_by_event_name::m_share,
139 &table_esms_global_by_event_name::m_share,
140 &table_esms_by_digest::m_share,
141
142 &table_users::m_share,
143 &table_accounts::m_share,
144 &table_hosts::m_share,
145
146 &table_socket_instances::m_share,
147 &table_socket_summary_by_instance::m_share,
148 &table_socket_summary_by_event_name::m_share,
149 &table_session_connect_attrs::m_share,
150 &table_session_account_connect_attrs::m_share,
151 NULL
152};
153
154/** Initialize all the table share locks. */
155void PFS_engine_table_share::init_all_locks(void)
156{
157 PFS_engine_table_share **current;
158
159 for (current= &all_shares[0]; (*current) != NULL; current++)
160 thr_lock_init((*current)->m_thr_lock_ptr);
161}
162
163/** Delete all the table share locks. */
164void PFS_engine_table_share::delete_all_locks(void)
165{
166 PFS_engine_table_share **current;
167
168 for (current= &all_shares[0]; (*current) != NULL; current++)
169 thr_lock_delete((*current)->m_thr_lock_ptr);
170}
171
172ha_rows PFS_engine_table_share::get_row_count(void) const
173{
174 /* If available, count the exact number or records */
175 if (m_get_row_count)
176 return m_get_row_count();
177 /* Otherwise, return an estimate */
178 return m_records;
179}
180
181int PFS_engine_table_share::write_row(TABLE *table, unsigned char *buf,
182 Field **fields) const
183{
184 my_bitmap_map *org_bitmap;
185
186 if (m_write_row == NULL)
187 {
188 return HA_ERR_WRONG_COMMAND;
189 }
190
191 /* We internally read from Fields to support the write interface */
192 org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
193 int result= m_write_row(table, buf, fields);
194 dbug_tmp_restore_column_map(table->read_set, org_bitmap);
195
196 return result;
197}
198
199static int compare_table_names(const char *name1, const char *name2)
200{
201 /*
202 The performance schema is implemented as a storage engine, in memory.
203 The current storage engine interface exposed by the server,
204 and in particular handlerton::discover, uses 'FRM' files to describe a
205 table structure, which are later stored on disk, by the server,
206 in ha_create_table_from_engine().
207 Because the table metadata is stored on disk, the table naming rules
208 used by the performance schema then have to comply with the constraints
209 imposed by the disk storage, and in particular with lower_case_table_names.
210 Once the server is changed to be able to discover a table in a storage engine
211 and then open the table without storing a FRM file on disk, this constraint
212 on the performance schema will be lifted, and the naming logic can be relaxed
213 to be simply my_strcasecmp(system_charset_info, name1, name2).
214 */
215 if (lower_case_table_names)
216 return strcasecmp(name1, name2);
217 return strcmp(name1, name2);
218}
219
220/**
221 Find a table share by name.
222 @param name The table name
223 @return table share
224*/
225const PFS_engine_table_share*
226PFS_engine_table::find_engine_table_share(const char *name)
227{
228 DBUG_ENTER("PFS_engine_table::find_table_share");
229
230 PFS_engine_table_share **current;
231
232 for (current= &all_shares[0]; (*current) != NULL; current++)
233 {
234 if (compare_table_names(name, (*current)->m_name.str) == 0)
235 DBUG_RETURN(*current);
236 }
237
238 DBUG_RETURN(NULL);
239}
240
241/**
242 Read a table row.
243 @param table Table handle
244 @param buf Row buffer
245 @param fields Table fields
246 @return 0 on success
247*/
248int PFS_engine_table::read_row(TABLE *table,
249 unsigned char *buf,
250 Field **fields)
251{
252 my_bitmap_map *org_bitmap;
253 Field *f;
254 Field **fields_reset;
255
256 /* We must read all columns in case a table is opened for update */
257 bool read_all= !bitmap_is_clear_all(table->write_set);
258
259 /* We internally write to Fields to support the read interface */
260 org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
261
262 /*
263 Some callers of the storage engine interface do not honor the
264 f->is_null() flag, and will attempt to read the data itself.
265 A known offender is mysql_checksum_table().
266 For robustness, reset every field.
267 */
268 for (fields_reset= fields; (f= *fields_reset) ; fields_reset++)
269 f->reset();
270
271 int result= read_row_values(table, buf, fields, read_all);
272 dbug_tmp_restore_column_map(table->write_set, org_bitmap);
273
274 return result;
275}
276
277/**
278 Update a table row.
279 @param table Table handle
280 @param old_buf old row buffer
281 @param new_buf new row buffer
282 @param fields Table fields
283 @return 0 on success
284*/
285int PFS_engine_table::update_row(TABLE *table,
286 const unsigned char *old_buf,
287 const unsigned char *new_buf,
288 Field **fields)
289{
290 my_bitmap_map *org_bitmap;
291
292 /* We internally read from Fields to support the write interface */
293 org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
294 int result= update_row_values(table, old_buf, new_buf, fields);
295 dbug_tmp_restore_column_map(table->read_set, org_bitmap);
296
297 return result;
298}
299
300int PFS_engine_table::delete_row(TABLE *table,
301 const unsigned char *buf,
302 Field **fields)
303{
304 my_bitmap_map *org_bitmap;
305
306 /* We internally read from Fields to support the delete interface */
307 org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
308 int result= delete_row_values(table, buf, fields);
309 dbug_tmp_restore_column_map(table->read_set, org_bitmap);
310
311 return result;
312}
313
314int PFS_engine_table::delete_row_values(TABLE *,
315 const unsigned char *,
316 Field **)
317{
318 return HA_ERR_WRONG_COMMAND;
319}
320
321/**
322 Get the position of the current row.
323 @param [out] ref position
324*/
325void PFS_engine_table::get_position(void *ref)
326{
327 memcpy(ref, m_pos_ptr, m_share_ptr->m_ref_length);
328}
329
330/**
331 Set the table cursor at a given position.
332 @param [in] ref position
333*/
334void PFS_engine_table::set_position(const void *ref)
335{
336 memcpy(m_pos_ptr, ref, m_share_ptr->m_ref_length);
337}
338
339/**
340 Get the timer normalizer and class type for the current row.
341 @param [in] instr_class class
342*/
343void PFS_engine_table::get_normalizer(PFS_instr_class *instr_class)
344{
345 if (instr_class->m_type != m_class_type)
346 {
347 m_normalizer= time_normalizer::get(*instr_class->m_timer);
348 m_class_type= instr_class->m_type;
349 }
350}
351
352void PFS_engine_table::set_field_ulong(Field *f, ulong value)
353{
354 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONG);
355 Field_long *f2= (Field_long*) f;
356 f2->store(value, true);
357}
358
359void PFS_engine_table::set_field_ulonglong(Field *f, ulonglong value)
360{
361 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONGLONG);
362 Field_longlong *f2= (Field_longlong*) f;
363 f2->store(value, true);
364}
365
366void PFS_engine_table::set_field_char_utf8(Field *f, const char* str,
367 uint len)
368{
369 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_STRING);
370 Field_string *f2= (Field_string*) f;
371 f2->store(str, len, &my_charset_utf8_bin);
372}
373
374void PFS_engine_table::set_field_varchar_utf8(Field *f, const char* str,
375 uint len)
376{
377 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
378 Field_varstring *f2= (Field_varstring*) f;
379 f2->store(str, len, &my_charset_utf8_bin);
380}
381
382void PFS_engine_table::set_field_longtext_utf8(Field *f, const char* str,
383 uint len)
384{
385 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_BLOB);
386 Field_blob *f2= (Field_blob*) f;
387 f2->store(str, len, &my_charset_utf8_bin);
388}
389
390void PFS_engine_table::set_field_enum(Field *f, ulonglong value)
391{
392 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_ENUM);
393 Field_enum *f2= (Field_enum*) f;
394 f2->store_type(value);
395}
396
397void PFS_engine_table::set_field_timestamp(Field *f, ulonglong value)
398{
399 DBUG_ASSERT(f->type_handler()->is_timestamp_type());
400 Field_timestamp *f2= (Field_timestamp*) f;
401 f2->store_TIME((long)(value / 1000000), (value % 1000000));
402}
403
404ulonglong PFS_engine_table::get_field_enum(Field *f)
405{
406 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_ENUM);
407 Field_enum *f2= (Field_enum*) f;
408 return f2->val_int();
409}
410
411String*
412PFS_engine_table::get_field_char_utf8(Field *f, String *val)
413{
414 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_STRING);
415 Field_string *f2= (Field_string*) f;
416 val= f2->val_str(NULL, val);
417 return val;
418}
419
420String*
421PFS_engine_table::get_field_varchar_utf8(Field *f, String *val)
422{
423 DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
424 Field_varstring *f2= (Field_varstring*) f;
425 val= f2->val_str(NULL, val);
426 return val;
427}
428
429int PFS_engine_table::update_row_values(TABLE *,
430 const unsigned char *,
431 const unsigned char *,
432 Field **)
433{
434 return HA_ERR_WRONG_COMMAND;
435}
436
437/** Implementation of internal ACL checks, for the performance schema. */
438class PFS_internal_schema_access : public ACL_internal_schema_access
439{
440public:
441 PFS_internal_schema_access()
442 {}
443
444 ~PFS_internal_schema_access()
445 {}
446
447 ACL_internal_access_result check(ulong want_access,
448 ulong *save_priv) const;
449
450 const ACL_internal_table_access *lookup(const char *name) const;
451};
452
453ACL_internal_access_result
454PFS_internal_schema_access::check(ulong want_access,
455 ulong *save_priv) const
456{
457 const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
458 | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | EXECUTE_ACL
459 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL
460 | EVENT_ACL | TRIGGER_ACL ;
461
462 if (unlikely(want_access & always_forbidden))
463 return ACL_INTERNAL_ACCESS_DENIED;
464
465 /*
466 Proceed with regular grant tables,
467 to give administrative control to the DBA.
468 */
469 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
470}
471
472const ACL_internal_table_access *
473PFS_internal_schema_access::lookup(const char *name) const
474{
475 const PFS_engine_table_share* share;
476 share= PFS_engine_table::find_engine_table_share(name);
477 if (share)
478 return share->m_acl;
479 /*
480 Do not return NULL, it would mean we are not interested
481 in privilege checks for unknown tables.
482 Instead, return an object that denies every actions,
483 to prevent users for creating their own tables in the
484 performance_schema database schema.
485 */
486 return &pfs_unknown_acl;
487}
488
489PFS_internal_schema_access pfs_internal_access;
490
491void initialize_performance_schema_acl(bool bootstrap)
492{
493 /*
494 ACL is always enforced, even if the performance schema
495 is not enabled (the tables are still visible).
496 */
497 if (! bootstrap)
498 {
499 ACL_internal_schema_registry::register_schema(&PERFORMANCE_SCHEMA_str,
500 &pfs_internal_access);
501 }
502}
503
504PFS_readonly_acl pfs_readonly_acl;
505
506ACL_internal_access_result
507PFS_readonly_acl::check(ulong want_access, ulong *save_priv) const
508{
509 const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
510 | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
511 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
512
513 if (unlikely(want_access & always_forbidden))
514 return ACL_INTERNAL_ACCESS_DENIED;
515
516 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
517}
518
519PFS_truncatable_acl pfs_truncatable_acl;
520
521ACL_internal_access_result
522PFS_truncatable_acl::check(ulong want_access, ulong *save_priv) const
523{
524 const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
525 | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
526 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
527
528 if (unlikely(want_access & always_forbidden))
529 return ACL_INTERNAL_ACCESS_DENIED;
530
531 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
532}
533
534PFS_updatable_acl pfs_updatable_acl;
535
536ACL_internal_access_result
537PFS_updatable_acl::check(ulong want_access, ulong *save_priv) const
538{
539 const ulong always_forbidden= INSERT_ACL | DELETE_ACL
540 | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
541 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
542
543 if (unlikely(want_access & always_forbidden))
544 return ACL_INTERNAL_ACCESS_DENIED;
545
546 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
547}
548
549PFS_editable_acl pfs_editable_acl;
550
551ACL_internal_access_result
552PFS_editable_acl::check(ulong want_access, ulong *save_priv) const
553{
554 const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
555 | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
556
557 if (unlikely(want_access & always_forbidden))
558 return ACL_INTERNAL_ACCESS_DENIED;
559
560 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
561}
562
563PFS_unknown_acl pfs_unknown_acl;
564
565ACL_internal_access_result
566PFS_unknown_acl::check(ulong want_access, ulong *save_priv) const
567{
568 const ulong always_forbidden= CREATE_ACL
569 | REFERENCES_ACL | INDEX_ACL | ALTER_ACL
570 | CREATE_VIEW_ACL | TRIGGER_ACL;
571
572 if (unlikely(want_access & always_forbidden))
573 return ACL_INTERNAL_ACCESS_DENIED;
574
575 /*
576 There is no point in hiding (by enforcing ACCESS_DENIED for SELECT_ACL
577 on performance_schema.*) tables that do not exist anyway.
578 When SELECT_ACL is granted on performance_schema.* or *.*,
579 SELECT * from performance_schema.wrong_table
580 will fail with a more understandable ER_NO_SUCH_TABLE error,
581 instead of ER_TABLEACCESS_DENIED_ERROR.
582 The same goes for other DML (INSERT_ACL | UPDATE_ACL | DELETE_ACL),
583 for ease of use: error messages will be less surprising.
584 */
585 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
586}
587
588/**
589 SHOW ENGINE PERFORMANCE_SCHEMA STATUS.
590 @param hton Storage engine handler
591 @param thd Current thread
592 @param print Print function
593 @param stat status to show
594*/
595bool pfs_show_status(handlerton *hton, THD *thd,
596 stat_print_fn *print, enum ha_stat_type stat)
597{
598 char buf[1024];
599 uint buflen;
600 const char *name;
601 int i;
602 size_t size;
603
604 DBUG_ENTER("pfs_show_status");
605
606 /*
607 Note about naming conventions:
608 - Internal buffers exposed as a table in the performance schema are named
609 after the table, as in 'events_waits_current'
610 - Internal buffers not exposed by a table are named with parenthesis,
611 as in '(pfs_mutex_class)'.
612 */
613 if (stat != HA_ENGINE_STATUS)
614 DBUG_RETURN(false);
615
616 size_t total_memory= 0;
617
618 for (i=0; /* empty */; i++)
619 {
620 switch (i){
621 case 0:
622 name= "events_waits_current.row_size";
623 size= sizeof(PFS_events_waits);
624 break;
625 case 1:
626 name= "events_waits_current.row_count";
627 size= WAIT_STACK_SIZE * thread_max;
628 break;
629 case 2:
630 name= "events_waits_history.row_size";
631 size= sizeof(PFS_events_waits);
632 break;
633 case 3:
634 name= "events_waits_history.row_count";
635 size= events_waits_history_per_thread * thread_max;
636 break;
637 case 4:
638 name= "events_waits_history.memory";
639 size= events_waits_history_per_thread * thread_max
640 * sizeof(PFS_events_waits);
641 total_memory+= size;
642 break;
643 case 5:
644 name= "events_waits_history_long.row_size";
645 size= sizeof(PFS_events_waits);
646 break;
647 case 6:
648 name= "events_waits_history_long.row_count";
649 size= events_waits_history_long_size;
650 break;
651 case 7:
652 name= "events_waits_history_long.memory";
653 size= events_waits_history_long_size * sizeof(PFS_events_waits);
654 total_memory+= size;
655 break;
656 case 8:
657 name= "(pfs_mutex_class).row_size";
658 size= sizeof(PFS_mutex_class);
659 break;
660 case 9:
661 name= "(pfs_mutex_class).row_count";
662 size= mutex_class_max;
663 break;
664 case 10:
665 name= "(pfs_mutex_class).memory";
666 size= mutex_class_max * sizeof(PFS_mutex_class);
667 total_memory+= size;
668 break;
669 case 11:
670 name= "(pfs_rwlock_class).row_size";
671 size= sizeof(PFS_rwlock_class);
672 break;
673 case 12:
674 name= "(pfs_rwlock_class).row_count";
675 size= rwlock_class_max;
676 break;
677 case 13:
678 name= "(pfs_rwlock_class).memory";
679 size= rwlock_class_max * sizeof(PFS_rwlock_class);
680 total_memory+= size;
681 break;
682 case 14:
683 name= "(pfs_cond_class).row_size";
684 size= sizeof(PFS_cond_class);
685 break;
686 case 15:
687 name= "(pfs_cond_class).row_count";
688 size= cond_class_max;
689 break;
690 case 16:
691 name= "(pfs_cond_class).memory";
692 size= cond_class_max * sizeof(PFS_cond_class);
693 total_memory+= size;
694 break;
695 case 17:
696 name= "(pfs_thread_class).row_size";
697 size= sizeof(PFS_thread_class);
698 break;
699 case 18:
700 name= "(pfs_thread_class).row_count";
701 size= thread_class_max;
702 break;
703 case 19:
704 name= "(pfs_thread_class).memory";
705 size= thread_class_max * sizeof(PFS_thread_class);
706 total_memory+= size;
707 break;
708 case 20:
709 name= "(pfs_file_class).row_size";
710 size= sizeof(PFS_file_class);
711 break;
712 case 21:
713 name= "(pfs_file_class).row_count";
714 size= file_class_max;
715 break;
716 case 22:
717 name= "(pfs_file_class).memory";
718 size= file_class_max * sizeof(PFS_file_class);
719 total_memory+= size;
720 break;
721 case 23:
722 name= "mutex_instances.row_size";
723 size= sizeof(PFS_mutex);
724 break;
725 case 24:
726 name= "mutex_instances.row_count";
727 size= mutex_max;
728 break;
729 case 25:
730 name= "mutex_instances.memory";
731 size= mutex_max * sizeof(PFS_mutex);
732 total_memory+= size;
733 break;
734 case 26:
735 name= "rwlock_instances.row_size";
736 size= sizeof(PFS_rwlock);
737 break;
738 case 27:
739 name= "rwlock_instances.row_count";
740 size= rwlock_max;
741 break;
742 case 28:
743 name= "rwlock_instances.memory";
744 size= rwlock_max * sizeof(PFS_rwlock);
745 total_memory+= size;
746 break;
747 case 29:
748 name= "cond_instances.row_size";
749 size= sizeof(PFS_cond);
750 break;
751 case 30:
752 name= "cond_instances.row_count";
753 size= cond_max;
754 break;
755 case 31:
756 name= "cond_instances.memory";
757 size= cond_max * sizeof(PFS_cond);
758 total_memory+= size;
759 break;
760 case 32:
761 name= "threads.row_size";
762 size= sizeof(PFS_thread);
763 break;
764 case 33:
765 name= "threads.row_count";
766 size= thread_max;
767 break;
768 case 34:
769 name= "threads.memory";
770 size= thread_max * sizeof(PFS_thread);
771 total_memory+= size;
772 break;
773 case 35:
774 name= "file_instances.row_size";
775 size= sizeof(PFS_file);
776 break;
777 case 36:
778 name= "file_instances.row_count";
779 size= file_max;
780 break;
781 case 37:
782 name= "file_instances.memory";
783 size= file_max * sizeof(PFS_file);
784 total_memory+= size;
785 break;
786 case 38:
787 name= "(pfs_file_handle).row_size";
788 size= sizeof(PFS_file*);
789 break;
790 case 39:
791 name= "(pfs_file_handle).row_count";
792 size= file_handle_max;
793 break;
794 case 40:
795 name= "(pfs_file_handle).memory";
796 size= file_handle_max * sizeof(PFS_file*);
797 total_memory+= size;
798 break;
799 case 41:
800 name= "events_waits_summary_by_thread_by_event_name.row_size";
801 size= sizeof(PFS_single_stat);
802 break;
803 case 42:
804 name= "events_waits_summary_by_thread_by_event_name.row_count";
805 size= thread_max * wait_class_max;
806 break;
807 case 43:
808 name= "events_waits_summary_by_thread_by_event_name.memory";
809 size= thread_max * wait_class_max * sizeof(PFS_single_stat);
810 total_memory+= size;
811 break;
812 case 44:
813 name= "(pfs_table_share).row_size";
814 size= sizeof(PFS_table_share);
815 break;
816 case 45:
817 name= "(pfs_table_share).row_count";
818 size= table_share_max;
819 break;
820 case 46:
821 name= "(pfs_table_share).memory";
822 size= table_share_max * sizeof(PFS_table_share);
823 total_memory+= size;
824 break;
825 case 47:
826 name= "(pfs_table).row_size";
827 size= sizeof(PFS_table);
828 break;
829 case 48:
830 name= "(pfs_table).row_count";
831 size= table_max;
832 break;
833 case 49:
834 name= "(pfs_table).memory";
835 size= table_max * sizeof(PFS_table);
836 total_memory+= size;
837 break;
838 case 50:
839 name= "setup_actors.row_size";
840 size= sizeof(PFS_setup_actor);
841 break;
842 case 51:
843 name= "setup_actors.row_count";
844 size= setup_actor_max;
845 break;
846 case 52:
847 name= "setup_actors.memory";
848 size= setup_actor_max * sizeof(PFS_setup_actor);
849 total_memory+= size;
850 break;
851 case 53:
852 name= "setup_objects.row_size";
853 size= sizeof(PFS_setup_object);
854 break;
855 case 54:
856 name= "setup_objects.row_count";
857 size= setup_object_max;
858 break;
859 case 55:
860 name= "setup_objects.memory";
861 size= setup_object_max * sizeof(PFS_setup_object);
862 total_memory+= size;
863 break;
864 case 56:
865 name= "(pfs_account).row_size";
866 size= sizeof(PFS_account);
867 break;
868 case 57:
869 name= "(pfs_account).row_count";
870 size= account_max;
871 break;
872 case 58:
873 name= "(pfs_account).memory";
874 size= account_max * sizeof(PFS_account);
875 total_memory+= size;
876 break;
877 case 59:
878 name= "events_waits_summary_by_account_by_event_name.row_size";
879 size= sizeof(PFS_single_stat);
880 break;
881 case 60:
882 name= "events_waits_summary_by_account_by_event_name.row_count";
883 size= account_max * wait_class_max;
884 break;
885 case 61:
886 name= "events_waits_summary_by_account_by_event_name.memory";
887 size= account_max * wait_class_max * sizeof(PFS_single_stat);
888 total_memory+= size;
889 break;
890 case 62:
891 name= "events_waits_summary_by_user_by_event_name.row_size";
892 size= sizeof(PFS_single_stat);
893 break;
894 case 63:
895 name= "events_waits_summary_by_user_by_event_name.row_count";
896 size= user_max * wait_class_max;
897 break;
898 case 64:
899 name= "events_waits_summary_by_user_by_event_name.memory";
900 size= user_max * wait_class_max * sizeof(PFS_single_stat);
901 total_memory+= size;
902 break;
903 case 65:
904 name= "events_waits_summary_by_host_by_event_name.row_size";
905 size= sizeof(PFS_single_stat);
906 break;
907 case 66:
908 name= "events_waits_summary_by_host_by_event_name.row_count";
909 size= host_max * wait_class_max;
910 break;
911 case 67:
912 name= "events_waits_summary_by_host_by_event_name.memory";
913 size= host_max * wait_class_max * sizeof(PFS_single_stat);
914 total_memory+= size;
915 break;
916 case 68:
917 name= "(pfs_user).row_size";
918 size= sizeof(PFS_user);
919 break;
920 case 69:
921 name= "(pfs_user).row_count";
922 size= user_max;
923 break;
924 case 70:
925 name= "(pfs_user).memory";
926 size= user_max * sizeof(PFS_user);
927 total_memory+= size;
928 break;
929 case 71:
930 name= "(pfs_host).row_size";
931 size= sizeof(PFS_host);
932 break;
933 case 72:
934 name= "(pfs_host).row_count";
935 size= host_max;
936 break;
937 case 73:
938 name= "(pfs_host).memory";
939 size= host_max * sizeof(PFS_host);
940 total_memory+= size;
941 break;
942 case 74:
943 name= "(pfs_stage_class).row_size";
944 size= sizeof(PFS_stage_class);
945 break;
946 case 75:
947 name= "(pfs_stage_class).row_count";
948 size= stage_class_max;
949 break;
950 case 76:
951 name= "(pfs_stage_class).memory";
952 size= stage_class_max * sizeof(PFS_stage_class);
953 total_memory+= size;
954 break;
955 case 77:
956 name= "events_stages_history.row_size";
957 size= sizeof(PFS_events_stages);
958 break;
959 case 78:
960 name= "events_stages_history.row_count";
961 size= events_stages_history_per_thread * thread_max;
962 break;
963 case 79:
964 name= "events_stages_history.memory";
965 size= events_stages_history_per_thread * thread_max
966 * sizeof(PFS_events_stages);
967 total_memory+= size;
968 break;
969 case 80:
970 name= "events_stages_history_long.row_size";
971 size= sizeof(PFS_events_stages);
972 break;
973 case 81:
974 name= "events_stages_history_long.row_count";
975 size= events_stages_history_long_size;
976 break;
977 case 82:
978 name= "events_stages_history_long.memory";
979 size= events_stages_history_long_size * sizeof(PFS_events_stages);
980 total_memory+= size;
981 break;
982 case 83:
983 name= "events_stages_summary_by_thread_by_event_name.row_size";
984 size= sizeof(PFS_stage_stat);
985 break;
986 case 84:
987 name= "events_stages_summary_by_thread_by_event_name.row_count";
988 size= thread_max * stage_class_max;
989 break;
990 case 85:
991 name= "events_stages_summary_by_thread_by_event_name.memory";
992 size= thread_max * stage_class_max * sizeof(PFS_stage_stat);
993 total_memory+= size;
994 break;
995 case 86:
996 name= "events_stages_summary_global_by_event_name.row_size";
997 size= sizeof(PFS_stage_stat);
998 break;
999 case 87:
1000 name= "events_stages_summary_global_by_event_name.row_count";
1001 size= stage_class_max;
1002 break;
1003 case 88:
1004 name= "events_stages_summary_global_by_event_name.memory";
1005 size= stage_class_max * sizeof(PFS_stage_stat);
1006 total_memory+= size;
1007 break;
1008 case 89:
1009 name= "events_stages_summary_by_account_by_event_name.row_size";
1010 size= sizeof(PFS_stage_stat);
1011 break;
1012 case 90:
1013 name= "events_stages_summary_by_account_by_event_name.row_count";
1014 size= account_max * stage_class_max;
1015 break;
1016 case 91:
1017 name= "events_stages_summary_by_account_by_event_name.memory";
1018 size= account_max * stage_class_max * sizeof(PFS_stage_stat);
1019 total_memory+= size;
1020 break;
1021 case 92:
1022 name= "events_stages_summary_by_user_by_event_name.row_size";
1023 size= sizeof(PFS_stage_stat);
1024 break;
1025 case 93:
1026 name= "events_stages_summary_by_user_by_event_name.row_count";
1027 size= user_max * stage_class_max;
1028 break;
1029 case 94:
1030 name= "events_stages_summary_by_user_by_event_name.memory";
1031 size= user_max * stage_class_max * sizeof(PFS_stage_stat);
1032 total_memory+= size;
1033 break;
1034 case 95:
1035 name= "events_stages_summary_by_host_by_event_name.row_size";
1036 size= sizeof(PFS_stage_stat);
1037 break;
1038 case 96:
1039 name= "events_stages_summary_by_host_by_event_name.row_count";
1040 size= host_max * stage_class_max;
1041 break;
1042 case 97:
1043 name= "events_stages_summary_by_host_by_event_name.memory";
1044 size= host_max * stage_class_max * sizeof(PFS_stage_stat);
1045 total_memory+= size;
1046 break;
1047 case 98:
1048 name= "(pfs_statement_class).row_size";
1049 size= sizeof(PFS_statement_class);
1050 break;
1051 case 99:
1052 name= "(pfs_statement_class).row_count";
1053 size= statement_class_max;
1054 break;
1055 case 100:
1056 name= "(pfs_statement_class).memory";
1057 size= statement_class_max * sizeof(PFS_statement_class);
1058 total_memory+= size;
1059 break;
1060 case 101:
1061 name= "events_statements_history.row_size";
1062 size= sizeof(PFS_events_statements);
1063 break;
1064 case 102:
1065 name= "events_statements_history.row_count";
1066 size= events_statements_history_per_thread * thread_max;
1067 break;
1068 case 103:
1069 name= "events_statements_history.memory";
1070 size= events_statements_history_per_thread * thread_max
1071 * sizeof(PFS_events_statements);
1072 total_memory+= size;
1073 break;
1074 case 104:
1075 name= "events_statements_history_long.row_size";
1076 size= sizeof(PFS_events_statements);
1077 break;
1078 case 105:
1079 name= "events_statements_history_long.row_count";
1080 size= events_statements_history_long_size;
1081 break;
1082 case 106:
1083 name= "events_statements_history_long.memory";
1084 size= events_statements_history_long_size * sizeof(PFS_events_statements);
1085 total_memory+= size;
1086 break;
1087 case 107:
1088 name= "events_statements_summary_by_thread_by_event_name.row_size";
1089 size= sizeof(PFS_statement_stat);
1090 break;
1091 case 108:
1092 name= "events_statements_summary_by_thread_by_event_name.row_count";
1093 size= thread_max * statement_class_max;
1094 break;
1095 case 109:
1096 name= "events_statements_summary_by_thread_by_event_name.memory";
1097 size= thread_max * statement_class_max * sizeof(PFS_statement_stat);
1098 total_memory+= size;
1099 break;
1100 case 110:
1101 name= "events_statements_summary_global_by_event_name.row_size";
1102 size= sizeof(PFS_statement_stat);
1103 break;
1104 case 111:
1105 name= "events_statements_summary_global_by_event_name.row_count";
1106 size= statement_class_max;
1107 break;
1108 case 112:
1109 name= "events_statements_summary_global_by_event_name.memory";
1110 size= statement_class_max * sizeof(PFS_statement_stat);
1111 total_memory+= size;
1112 break;
1113 case 113:
1114 name= "events_statements_summary_by_account_by_event_name.row_size";
1115 size= sizeof(PFS_statement_stat);
1116 break;
1117 case 114:
1118 name= "events_statements_summary_by_account_by_event_name.row_count";
1119 size= account_max * statement_class_max;
1120 break;
1121 case 115:
1122 name= "events_statements_summary_by_account_by_event_name.memory";
1123 size= account_max * statement_class_max * sizeof(PFS_statement_stat);
1124 total_memory+= size;
1125 break;
1126 case 116:
1127 name= "events_statements_summary_by_user_by_event_name.row_size";
1128 size= sizeof(PFS_statement_stat);
1129 break;
1130 case 117:
1131 name= "events_statements_summary_by_user_by_event_name.row_count";
1132 size= user_max * statement_class_max;
1133 break;
1134 case 118:
1135 name= "events_statements_summary_by_user_by_event_name.memory";
1136 size= user_max * statement_class_max * sizeof(PFS_statement_stat);
1137 total_memory+= size;
1138 break;
1139 case 119:
1140 name= "events_statements_summary_by_host_by_event_name.row_size";
1141 size= sizeof(PFS_statement_stat);
1142 break;
1143 case 120:
1144 name= "events_statements_summary_by_host_by_event_name.row_count";
1145 size= host_max * statement_class_max;
1146 break;
1147 case 121:
1148 name= "events_statements_summary_by_host_by_event_name.memory";
1149 size= host_max * statement_class_max * sizeof(PFS_statement_stat);
1150 total_memory+= size;
1151 break;
1152 case 122:
1153 name= "events_statements_current.row_size";
1154 size= sizeof(PFS_events_statements);
1155 break;
1156 case 123:
1157 name= "events_statements_current.row_count";
1158 size= thread_max * statement_stack_max;
1159 break;
1160 case 124:
1161 name= "events_statements_current.memory";
1162 size= thread_max * statement_stack_max * sizeof(PFS_events_statements);
1163 total_memory+= size;
1164 break;
1165 case 125:
1166 name= "(pfs_socket_class).row_size";
1167 size= sizeof(PFS_socket_class);
1168 break;
1169 case 126:
1170 name= "(pfs_socket_class).row_count";
1171 size= socket_class_max;
1172 break;
1173 case 127:
1174 name= "(pfs_socket_class).memory";
1175 size= socket_class_max * sizeof(PFS_socket_class);
1176 total_memory+= size;
1177 break;
1178 case 128:
1179 name= "socket_instances.row_size";
1180 size= sizeof(PFS_socket);
1181 break;
1182 case 129:
1183 name= "socket_instances.row_count";
1184 size= socket_max;
1185 break;
1186 case 130:
1187 name= "socket_instances.memory";
1188 size= socket_max * sizeof(PFS_socket);
1189 total_memory+= size;
1190 break;
1191 case 131:
1192 name= "events_statements_summary_by_digest.row_size";
1193 size= sizeof(PFS_statements_digest_stat);
1194 break;
1195 case 132:
1196 name= "events_statements_summary_by_digest.row_count";
1197 size= digest_max;
1198 break;
1199 case 133:
1200 name= "events_statements_summary_by_digest.memory";
1201 size= digest_max * sizeof(PFS_statements_digest_stat);
1202 total_memory+= size;
1203 break;
1204 case 134:
1205 name= "session_connect_attrs.row_size";
1206 size= thread_max;
1207 break;
1208 case 135:
1209 name= "session_connect_attrs.row_count";
1210 size= session_connect_attrs_size_per_thread;
1211 break;
1212 case 136:
1213 name= "session_connect_attrs.memory";
1214 size= thread_max * session_connect_attrs_size_per_thread;
1215 total_memory+= size;
1216 break;
1217
1218 case 137:
1219 name= "(account_hash).count";
1220 size= account_hash.count;
1221 break;
1222 case 138:
1223 name= "(account_hash).size";
1224 size= account_hash.size;
1225 break;
1226 case 139:
1227 name= "(digest_hash).count";
1228 size= digest_hash.count;
1229 break;
1230 case 140:
1231 name= "(digest_hash).size";
1232 size= digest_hash.size;
1233 break;
1234 case 141:
1235 name= "(filename_hash).count";
1236 size= filename_hash.count;
1237 break;
1238 case 142:
1239 name= "(filename_hash).size";
1240 size= filename_hash.size;
1241 break;
1242 case 143:
1243 name= "(host_hash).count";
1244 size= host_hash.count;
1245 break;
1246 case 144:
1247 name= "(host_hash).size";
1248 size= host_hash.size;
1249 break;
1250 case 145:
1251 name= "(setup_actor_hash).count";
1252 size= setup_actor_hash.count;
1253 break;
1254 case 146:
1255 name= "(setup_actor_hash).size";
1256 size= setup_actor_hash.size;
1257 break;
1258 case 147:
1259 name= "(setup_object_hash).count";
1260 size= setup_object_hash.count;
1261 break;
1262 case 148:
1263 name= "(setup_object_hash).size";
1264 size= setup_object_hash.size;
1265 break;
1266 case 149:
1267 name= "(table_share_hash).count";
1268 size= table_share_hash.count;
1269 break;
1270 case 150:
1271 name= "(table_share_hash).size";
1272 size= table_share_hash.size;
1273 break;
1274 case 151:
1275 name= "(user_hash).count";
1276 size= user_hash.count;
1277 break;
1278 case 152:
1279 name= "(user_hash).size";
1280 size= user_hash.size;
1281 break;
1282 case 153:
1283 /*
1284 This is not a performance_schema buffer,
1285 the data is maintained in the server,
1286 in hostname_cache.
1287 Print the size only, there are:
1288 - no host_cache.count
1289 - no host_cache.memory
1290 */
1291 name= "host_cache.size";
1292 size= sizeof(Host_entry);
1293 break;
1294 case 154:
1295 name= "(history_long_statements_digest_token_array).row_count";
1296 size= events_statements_history_long_size;
1297 break;
1298 case 155:
1299 name= "(history_long_statements_digest_token_array).row_size";
1300 size= pfs_max_digest_length;
1301 break;
1302 case 156:
1303 name= "(history_long_statements_digest_token_array).memory";
1304 size= events_statements_history_long_size * pfs_max_digest_length;
1305 total_memory+= size;
1306 break;
1307 case 157:
1308 name= "(history_statements_digest_token_array).row_count";
1309 size= thread_max * events_statements_history_per_thread;
1310 break;
1311 case 158:
1312 name= "(history_statements_digest_token_array).row_size";
1313 size= pfs_max_digest_length;
1314 break;
1315 case 159:
1316 name= "(history_statements_digest_token_array).memory";
1317 size= thread_max * events_statements_history_per_thread * pfs_max_digest_length;
1318 total_memory+= size;
1319 break;
1320 case 160:
1321 name= "(current_statements_digest_token_array).row_count";
1322 size= thread_max * statement_stack_max;
1323 break;
1324 case 161:
1325 name= "(current_statements_digest_token_array).row_size";
1326 size= pfs_max_digest_length;
1327 break;
1328 case 162:
1329 name= "(current_statements_digest_token_array).memory";
1330 size= thread_max * statement_stack_max * pfs_max_digest_length;
1331 total_memory+= size;
1332 break;
1333 case 163:
1334 name= "(statements_digest_token_array).row_count";
1335 size= digest_max;
1336 break;
1337 case 164:
1338 name= "(statements_digest_token_array).row_size";
1339 size= pfs_max_digest_length;
1340 break;
1341 case 165:
1342 name= "(statements_digest_token_array).memory";
1343 size= digest_max * pfs_max_digest_length;
1344 total_memory+= size;
1345 break;
1346
1347 /*
1348 This case must be last,
1349 for aggregation in total_memory.
1350 */
1351 case 166:
1352 name= "performance_schema.memory";
1353 size= total_memory;
1354 /* This will fail if something is not advertised here */
1355 DBUG_ASSERT(size == pfs_allocated_memory);
1356 break;
1357 default:
1358 goto end;
1359 break;
1360 }
1361
1362 buflen= (uint)(longlong10_to_str(size, buf, 10) - buf);
1363 if (print(thd,
1364 PERFORMANCE_SCHEMA_str.str, PERFORMANCE_SCHEMA_str.length,
1365 name, strlen(name),
1366 buf, buflen))
1367 DBUG_RETURN(true);
1368 }
1369
1370end:
1371 DBUG_RETURN(false);
1372}
1373
1374int pfs_discover_table_names(handlerton *hton __attribute__((unused)),
1375 LEX_CSTRING *db,
1376 MY_DIR *dir __attribute__((unused)),
1377 handlerton::discovered_list *result)
1378{
1379 if (compare_table_names(db->str, PERFORMANCE_SCHEMA_str.str))
1380 return 0;
1381 for (size_t i= 0; i < array_elements(all_shares) - 1; i++)
1382 result->add_table(all_shares[i]->m_name.str,
1383 all_shares[i]->m_name.length);
1384 return 0;
1385}
1386
1387/** @} */
1388
1389