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