1 /* Copyright (c) 2008, 2021, Oracle and/or its affiliates.
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_thread.h"
30 #include "hostname.h" /* For Host_entry */
31 #include "pfs_engine_table.h"
32 #include "pfs_buffer_container.h"
33
34 #include "table_events_waits.h"
35 #include "table_setup_actors.h"
36 #include "table_setup_consumers.h"
37 #include "table_setup_instruments.h"
38 #include "table_setup_objects.h"
39 #include "table_setup_timers.h"
40 #include "table_performance_timers.h"
41 #include "table_events_waits_summary.h"
42 #include "table_ews_by_thread_by_event_name.h"
43 #include "table_ews_global_by_event_name.h"
44 #include "table_host_cache.h"
45 #include "table_os_global_by_type.h"
46 #include "table_sync_instances.h"
47 #include "table_file_instances.h"
48 #include "table_file_summary_by_instance.h"
49 #include "table_file_summary_by_event_name.h"
50 #include "table_threads.h"
51
52 #include "table_ews_by_host_by_event_name.h"
53 #include "table_ews_by_user_by_event_name.h"
54 #include "table_ews_by_account_by_event_name.h"
55 #include "table_tiws_by_index_usage.h"
56 #include "table_tiws_by_table.h"
57 #include "table_tlws_by_table.h"
58
59 #include "table_events_stages.h"
60 #include "table_esgs_by_thread_by_event_name.h"
61 #include "table_esgs_by_host_by_event_name.h"
62 #include "table_esgs_by_user_by_event_name.h"
63 #include "table_esgs_by_account_by_event_name.h"
64 #include "table_esgs_global_by_event_name.h"
65
66 #include "table_events_statements.h"
67 #include "table_esms_by_thread_by_event_name.h"
68 #include "table_esms_by_host_by_event_name.h"
69 #include "table_esms_by_user_by_event_name.h"
70 #include "table_esms_by_account_by_event_name.h"
71 #include "table_esms_global_by_event_name.h"
72 #include "table_esms_by_digest.h"
73 #include "table_esms_by_program.h"
74
75 #include "table_events_transactions.h"
76 #include "table_ets_by_thread_by_event_name.h"
77 #include "table_ets_by_host_by_event_name.h"
78 #include "table_ets_by_user_by_event_name.h"
79 #include "table_ets_by_account_by_event_name.h"
80 #include "table_ets_global_by_event_name.h"
81
82 #include "table_users.h"
83 #include "table_accounts.h"
84 #include "table_hosts.h"
85
86 #include "table_socket_instances.h"
87 #include "table_socket_summary_by_instance.h"
88 #include "table_socket_summary_by_event_name.h"
89 #include "table_session_connect_attrs.h"
90 #include "table_session_account_connect_attrs.h"
91 #include "table_mems_global_by_event_name.h"
92 #include "table_mems_by_account_by_event_name.h"
93 #include "table_mems_by_host_by_event_name.h"
94 #include "table_mems_by_thread_by_event_name.h"
95 #include "table_mems_by_user_by_event_name.h"
96
97 /* For replication related perfschema tables. */
98 #include "table_replication_connection_configuration.h"
99 #include "table_replication_group_members.h"
100 #include "table_replication_connection_status.h"
101 #include "table_replication_applier_configuration.h"
102 #include "table_replication_applier_status.h"
103 #include "table_replication_applier_status_by_coordinator.h"
104 #include "table_replication_applier_status_by_worker.h"
105 #include "table_replication_group_member_stats.h"
106
107 #include "table_prepared_stmt_instances.h"
108
109 #include "table_md_locks.h"
110 #include "table_table_handles.h"
111
112 #include "table_uvar_by_thread.h"
113
114 #include "table_status_by_account.h"
115 #include "table_status_by_host.h"
116 #include "table_status_by_thread.h"
117 #include "table_status_by_user.h"
118 #include "table_global_status.h"
119 #include "table_session_status.h"
120
121 #include "table_variables_by_thread.h"
122 #include "table_global_variables.h"
123 #include "table_session_variables.h"
124
125 /* For show status */
126 #include "pfs_column_values.h"
127 #include "pfs_instr_class.h"
128 #include "pfs_instr.h"
129 #include "pfs_setup_actor.h"
130 #include "pfs_setup_object.h"
131 #include "pfs_global.h"
132 #include "pfs_digest.h"
133
134 #include "sql_base.h" // close_thread_tables
135 #include "lock.h" // MYSQL_LOCK_IGNORE_TIMEOUT
136 #include "log.h"
137
138 /**
139 @addtogroup Performance_schema_engine
140 @{
141 */
142
initialize(void)143 bool PFS_table_context::initialize(void)
144 {
145 if (m_restore)
146 {
147 /* Restore context from TLS. */
148 PFS_table_context *context= static_cast<PFS_table_context *>(my_get_thread_local(m_thr_key));
149 assert(context != NULL);
150
151 if(context)
152 {
153 m_last_version= context->m_current_version;
154 m_map= context->m_map;
155 assert(m_map_size == context->m_map_size);
156 m_map_size= context->m_map_size;
157 m_word_size= context->m_word_size;
158 }
159 }
160 else
161 {
162 /* Check that TLS is not in use. */
163 PFS_table_context *context= static_cast<PFS_table_context *>(my_get_thread_local(m_thr_key));
164 //assert(context == NULL);
165
166 context= this;
167
168 /* Initialize a new context, store in TLS. */
169 m_last_version= m_current_version;
170 m_map= NULL;
171 m_word_size= sizeof(ulong) * 8;
172
173 /* Allocate a bitmap to record which threads are materialized. */
174 if (m_map_size > 0)
175 {
176 THD *thd= current_thd;
177 ulong words= m_map_size / m_word_size + (m_map_size % m_word_size > 0);
178 m_map= (ulong *)thd->mem_calloc(words * m_word_size);
179 }
180
181 /* Write to TLS. */
182 my_set_thread_local(m_thr_key, static_cast<void *>(context));
183 }
184
185 m_initialized= (m_map_size > 0) ? (m_map != NULL) : true;
186
187 return m_initialized;
188 }
189
190 /* Constructor for global or single thread tables, map size = 0. */
PFS_table_context(ulonglong current_version,bool restore,thread_local_key_t key)191 PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, thread_local_key_t key) :
192 m_thr_key(key), m_current_version(current_version), m_last_version(0),
193 m_map(NULL), m_map_size(0), m_word_size(sizeof(ulong)),
194 m_restore(restore), m_initialized(false), m_last_item(0)
195 {
196 initialize();
197 }
198
199 /* Constructor for by-thread or aggregate tables, map size = max thread/user/host/account. */
PFS_table_context(ulonglong current_version,ulong map_size,bool restore,thread_local_key_t key)200 PFS_table_context::PFS_table_context(ulonglong current_version, ulong map_size, bool restore, thread_local_key_t key) :
201 m_thr_key(key), m_current_version(current_version), m_last_version(0),
202 m_map(NULL), m_map_size(map_size), m_word_size(sizeof(ulong)),
203 m_restore(restore), m_initialized(false), m_last_item(0)
204 {
205 initialize();
206 }
207
~PFS_table_context(void)208 PFS_table_context::~PFS_table_context(void)
209 {
210 /* Clear TLS after final use. */ // TODO: How is that determined?
211 // if (m_restore)
212 // {
213 // my_set_thread_local(m_thr_key, NULL);
214 // }
215 }
216
set_item(ulong n)217 void PFS_table_context::set_item(ulong n)
218 {
219 if (n == m_last_item)
220 return;
221 ulong word= n / m_word_size;
222 ulong bit= n % m_word_size;
223 m_map[word] |= (1 << bit);
224 m_last_item= n;
225 }
226
is_item_set(ulong n)227 bool PFS_table_context::is_item_set(ulong n)
228 {
229 ulong word= n / m_word_size;
230 ulong bit= n % m_word_size;
231 return (m_map[word] & (1 << bit));
232 }
233
234
235 static PFS_engine_table_share *all_shares[]=
236 {
237 &table_cond_instances::m_share,
238 &table_events_waits_current::m_share,
239 &table_events_waits_history::m_share,
240 &table_events_waits_history_long::m_share,
241 &table_ews_by_host_by_event_name::m_share,
242 &table_events_waits_summary_by_instance::m_share,
243 &table_ews_by_thread_by_event_name::m_share,
244 &table_ews_by_user_by_event_name::m_share,
245 &table_ews_by_account_by_event_name::m_share,
246 &table_ews_global_by_event_name::m_share,
247 &table_file_instances::m_share,
248 &table_file_summary_by_event_name::m_share,
249 &table_file_summary_by_instance::m_share,
250 &table_host_cache::m_share,
251 &table_mutex_instances::m_share,
252 &table_os_global_by_type::m_share,
253 &table_performance_timers::m_share,
254 &table_rwlock_instances::m_share,
255 &table_setup_actors::m_share,
256 &table_setup_consumers::m_share,
257 &table_setup_instruments::m_share,
258 &table_setup_objects::m_share,
259 &table_setup_timers::m_share,
260 &table_tiws_by_index_usage::m_share,
261 &table_tiws_by_table::m_share,
262 &table_tlws_by_table::m_share,
263 &table_threads::m_share,
264
265 &table_events_stages_current::m_share,
266 &table_events_stages_history::m_share,
267 &table_events_stages_history_long::m_share,
268 &table_esgs_by_thread_by_event_name::m_share,
269 &table_esgs_by_account_by_event_name::m_share,
270 &table_esgs_by_user_by_event_name::m_share,
271 &table_esgs_by_host_by_event_name::m_share,
272 &table_esgs_global_by_event_name::m_share,
273
274 &table_events_statements_current::m_share,
275 &table_events_statements_history::m_share,
276 &table_events_statements_history_long::m_share,
277 &table_esms_by_thread_by_event_name::m_share,
278 &table_esms_by_account_by_event_name::m_share,
279 &table_esms_by_user_by_event_name::m_share,
280 &table_esms_by_host_by_event_name::m_share,
281 &table_esms_global_by_event_name::m_share,
282 &table_esms_by_digest::m_share,
283 &table_esms_by_program::m_share,
284
285 &table_events_transactions_current::m_share,
286 &table_events_transactions_history::m_share,
287 &table_events_transactions_history_long::m_share,
288 &table_ets_by_thread_by_event_name::m_share,
289 &table_ets_by_account_by_event_name::m_share,
290 &table_ets_by_user_by_event_name::m_share,
291 &table_ets_by_host_by_event_name::m_share,
292 &table_ets_global_by_event_name::m_share,
293
294 &table_users::m_share,
295 &table_accounts::m_share,
296 &table_hosts::m_share,
297
298 &table_socket_instances::m_share,
299 &table_socket_summary_by_instance::m_share,
300 &table_socket_summary_by_event_name::m_share,
301
302 &table_session_connect_attrs::m_share,
303 &table_session_account_connect_attrs::m_share,
304
305 &table_mems_global_by_event_name::m_share,
306 &table_mems_by_account_by_event_name::m_share,
307 &table_mems_by_host_by_event_name::m_share,
308 &table_mems_by_thread_by_event_name::m_share,
309 &table_mems_by_user_by_event_name::m_share,
310 &table_table_handles::m_share,
311 &table_metadata_locks::m_share,
312
313 &table_replication_connection_configuration::m_share,
314 &table_replication_group_members::m_share,
315 &table_replication_connection_status::m_share,
316 &table_replication_applier_configuration::m_share,
317 &table_replication_applier_status::m_share,
318 &table_replication_applier_status_by_coordinator::m_share,
319 &table_replication_applier_status_by_worker::m_share,
320 &table_replication_group_member_stats::m_share,
321
322 &table_prepared_stmt_instances::m_share,
323
324 &table_uvar_by_thread::m_share,
325 &table_status_by_account::m_share,
326 &table_status_by_host::m_share,
327 &table_status_by_thread::m_share,
328 &table_status_by_user::m_share,
329 &table_global_status::m_share,
330 &table_session_status::m_share,
331
332 &table_variables_by_thread::m_share,
333 &table_global_variables::m_share,
334 &table_session_variables::m_share,
335
336 NULL
337 };
338
339 /**
340 Check all the tables structure.
341 @param thd current thread
342 */
check_all_tables(THD * thd)343 void PFS_engine_table_share::check_all_tables(THD *thd)
344 {
345 PFS_engine_table_share **current;
346
347 DBUG_EXECUTE_IF("tampered_perfschema_table1",
348 {
349 /* Hack SETUP_INSTRUMENT, incompatible change. */
350 all_shares[20]->m_field_def->count++;
351 });
352
353 for (current= &all_shares[0]; (*current) != NULL; current++)
354 (*current)->check_one_table(thd);
355 }
356
357 /** Error reporting for schema integrity checks. */
358 class PFS_check_intact : public Table_check_intact
359 {
360 protected:
361 virtual void report_error(uint code, const char *fmt, ...);
362
363 public:
PFS_check_intact()364 PFS_check_intact()
365 {}
366
~PFS_check_intact()367 ~PFS_check_intact()
368 {}
369 };
370
report_error(uint code,const char * fmt,...)371 void PFS_check_intact::report_error(uint code, const char *fmt, ...)
372 {
373 va_list args;
374 char buff[MYSQL_ERRMSG_SIZE];
375
376 va_start(args, fmt);
377 my_vsnprintf(buff, sizeof(buff), fmt, args);
378 va_end(args);
379
380 /*
381 This is an install/upgrade issue:
382 - do not report it in the user connection, there is none in main(),
383 - report it in the server error log.
384 */
385 sql_print_error("%s", buff);
386 }
387
388 /**
389 Check integrity of the actual table schema.
390 The actual table schema (.frm) is compared to the expected schema.
391 @param thd current thread
392 */
check_one_table(THD * thd)393 void PFS_engine_table_share::check_one_table(THD *thd)
394 {
395 TABLE_LIST tables;
396
397 tables.init_one_table(PERFORMANCE_SCHEMA_str.str,
398 PERFORMANCE_SCHEMA_str.length,
399 m_name.str, m_name.length,
400 m_name.str, TL_READ);
401
402 /* Work around until Bug#32115 is backported. */
403 LEX dummy_lex;
404 LEX *old_lex= thd->lex;
405 thd->lex= &dummy_lex;
406 lex_start(thd);
407
408 if (! open_and_lock_tables(thd, &tables, MYSQL_LOCK_IGNORE_TIMEOUT))
409 {
410 PFS_check_intact checker;
411
412 if (!checker.check(tables.table, m_field_def))
413 m_checked= true;
414 close_thread_tables(thd);
415 }
416 else
417 sql_print_error(ER(ER_WRONG_NATIVE_TABLE_STRUCTURE),
418 PERFORMANCE_SCHEMA_str.str, m_name.str);
419
420 lex_end(&dummy_lex);
421 thd->lex= old_lex;
422 }
423
424 /** Initialize all the table share locks. */
init_all_locks(void)425 void PFS_engine_table_share::init_all_locks(void)
426 {
427 PFS_engine_table_share **current;
428
429 for (current= &all_shares[0]; (*current) != NULL; current++)
430 thr_lock_init((*current)->m_thr_lock_ptr);
431 }
432
433 /** Delete all the table share locks. */
delete_all_locks(void)434 void PFS_engine_table_share::delete_all_locks(void)
435 {
436 PFS_engine_table_share **current;
437
438 for (current= &all_shares[0]; (*current) != NULL; current++)
439 thr_lock_delete((*current)->m_thr_lock_ptr);
440 }
441
get_row_count(void) const442 ha_rows PFS_engine_table_share::get_row_count(void) const
443 {
444 return m_get_row_count();
445 }
446
write_row(TABLE * table,unsigned char * buf,Field ** fields) const447 int PFS_engine_table_share::write_row(TABLE *table, unsigned char *buf,
448 Field **fields) const
449 {
450 my_bitmap_map *org_bitmap;
451
452 /*
453 Make sure the table structure is as expected before mapping
454 hard wired columns in m_write_row.
455 */
456 if (! m_checked)
457 {
458 return HA_ERR_TABLE_NEEDS_UPGRADE;
459 }
460
461 if (m_write_row == NULL)
462 {
463 return HA_ERR_WRONG_COMMAND;
464 }
465
466 /* We internally read from Fields to support the write interface */
467 org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
468 int result= m_write_row(table, buf, fields);
469 dbug_tmp_restore_column_map(table->read_set, org_bitmap);
470
471 return result;
472 }
473
compare_table_names(const char * name1,const char * name2)474 static int compare_table_names(const char *name1, const char *name2)
475 {
476 /*
477 The performance schema is implemented as a storage engine, in memory.
478 The current storage engine interface exposed by the server,
479 and in particular handlerton::discover, uses 'FRM' files to describe a
480 table structure, which are later stored on disk, by the server,
481 in ha_create_table_from_engine().
482 Because the table metadata is stored on disk, the table naming rules
483 used by the performance schema then have to comply with the constraints
484 imposed by the disk storage, and in particular with lower_case_table_names.
485 Once the server is changed to be able to discover a table in a storage engine
486 and then open the table without storing a FRM file on disk, this constraint
487 on the performance schema will be lifted, and the naming logic can be relaxed
488 to be simply my_strcasecmp(system_charset_info, name1, name2).
489 */
490 if (lower_case_table_names)
491 return native_strcasecmp(name1, name2);
492 return strcmp(name1, name2);
493 }
494
495 /**
496 Find a table share by name.
497 @param name The table name
498 @return table share
499 */
500 const PFS_engine_table_share*
find_engine_table_share(const char * name)501 PFS_engine_table::find_engine_table_share(const char *name)
502 {
503 DBUG_ENTER("PFS_engine_table::find_table_share");
504
505 PFS_engine_table_share **current;
506
507 for (current= &all_shares[0]; (*current) != NULL; current++)
508 {
509 if (compare_table_names(name, (*current)->m_name.str) == 0)
510 DBUG_RETURN(*current);
511 }
512
513 DBUG_RETURN(NULL);
514 }
515
516 /**
517 Read a table row.
518 @param table Table handle
519 @param buf Row buffer
520 @param fields Table fields
521 @return 0 on success
522 */
read_row(TABLE * table,unsigned char * buf,Field ** fields)523 int PFS_engine_table::read_row(TABLE *table,
524 unsigned char *buf,
525 Field **fields)
526 {
527 my_bitmap_map *org_bitmap;
528 Field *f;
529 Field **fields_reset;
530
531 /*
532 Make sure the table structure is as expected before mapping
533 hard wired columns in read_row_values.
534 */
535 if (! m_share_ptr->m_checked)
536 {
537 return HA_ERR_TABLE_NEEDS_UPGRADE;
538 }
539
540 /* We must read all columns in case a table is opened for update */
541 bool read_all= !bitmap_is_clear_all(table->write_set);
542
543 /* We internally write to Fields to support the read interface */
544 org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
545
546 /*
547 Some callers of the storage engine interface do not honor the
548 f->is_null() flag, and will attempt to read the data itself.
549 A known offender is mysql_checksum_table().
550 For robustness, reset every field.
551 */
552 for (fields_reset= fields; (f= *fields_reset) ; fields_reset++)
553 f->reset();
554
555 int result= read_row_values(table, buf, fields, read_all);
556 dbug_tmp_restore_column_map(table->write_set, org_bitmap);
557
558 return result;
559 }
560
561 /**
562 Update a table row.
563 @param table Table handle
564 @param old_buf old row buffer
565 @param new_buf new row buffer
566 @param fields Table fields
567 @return 0 on success
568 */
update_row(TABLE * table,const unsigned char * old_buf,unsigned char * new_buf,Field ** fields)569 int PFS_engine_table::update_row(TABLE *table,
570 const unsigned char *old_buf,
571 unsigned char *new_buf,
572 Field **fields)
573 {
574 my_bitmap_map *org_bitmap;
575
576 /*
577 Make sure the table structure is as expected before mapping
578 hard wired columns in update_row_values.
579 */
580 if (! m_share_ptr->m_checked)
581 {
582 return HA_ERR_TABLE_NEEDS_UPGRADE;
583 }
584
585 /* We internally read from Fields to support the write interface */
586 org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
587 int result= update_row_values(table, old_buf, new_buf, fields);
588 dbug_tmp_restore_column_map(table->read_set, org_bitmap);
589
590 return result;
591 }
592
delete_row(TABLE * table,const unsigned char * buf,Field ** fields)593 int PFS_engine_table::delete_row(TABLE *table,
594 const unsigned char *buf,
595 Field **fields)
596 {
597 my_bitmap_map *org_bitmap;
598
599 /*
600 Make sure the table structure is as expected before mapping
601 hard wired columns in delete_row_values.
602 */
603 if (! m_share_ptr->m_checked)
604 {
605 return HA_ERR_TABLE_NEEDS_UPGRADE;
606 }
607
608 /* We internally read from Fields to support the delete interface */
609 org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
610 int result= delete_row_values(table, buf, fields);
611 dbug_tmp_restore_column_map(table->read_set, org_bitmap);
612
613 return result;
614 }
615
delete_row_values(TABLE *,const unsigned char *,Field **)616 int PFS_engine_table::delete_row_values(TABLE *,
617 const unsigned char *,
618 Field **)
619 {
620 return HA_ERR_WRONG_COMMAND;
621 }
622
623 /**
624 Get the position of the current row.
625 @param [out] ref position
626 */
get_position(void * ref)627 void PFS_engine_table::get_position(void *ref)
628 {
629 memcpy(ref, m_pos_ptr, m_share_ptr->m_ref_length);
630 }
631
632 /**
633 Set the table cursor at a given position.
634 @param [in] ref position
635 */
set_position(const void * ref)636 void PFS_engine_table::set_position(const void *ref)
637 {
638 memcpy(m_pos_ptr, ref, m_share_ptr->m_ref_length);
639 }
640
641 /**
642 Get the timer normalizer and class type for the current row.
643 @param [in] instr_class class
644 */
get_normalizer(PFS_instr_class * instr_class)645 void PFS_engine_table::get_normalizer(PFS_instr_class *instr_class)
646 {
647 if (instr_class->m_type != m_class_type)
648 {
649 m_normalizer= time_normalizer::get(*instr_class->m_timer);
650 m_class_type= instr_class->m_type;
651 }
652 }
653
set_field_long(Field * f,long value)654 void PFS_engine_table::set_field_long(Field *f, long value)
655 {
656 assert(f->real_type() == MYSQL_TYPE_LONG);
657 Field_long *f2= (Field_long*) f;
658 f2->store(value, false);
659 }
660
set_field_ulong(Field * f,ulong value)661 void PFS_engine_table::set_field_ulong(Field *f, ulong value)
662 {
663 assert(f->real_type() == MYSQL_TYPE_LONG);
664 Field_long *f2= (Field_long*) f;
665 f2->store(value, true);
666 }
667
set_field_longlong(Field * f,longlong value)668 void PFS_engine_table::set_field_longlong(Field *f, longlong value)
669 {
670 assert(f->real_type() == MYSQL_TYPE_LONGLONG);
671 Field_longlong *f2= (Field_longlong*) f;
672 f2->store(value, false);
673 }
674
set_field_ulonglong(Field * f,ulonglong value)675 void PFS_engine_table::set_field_ulonglong(Field *f, ulonglong value)
676 {
677 assert(f->real_type() == MYSQL_TYPE_LONGLONG);
678 Field_longlong *f2= (Field_longlong*) f;
679 f2->store(value, true);
680 }
681
set_field_char_utf8(Field * f,const char * str,uint len)682 void PFS_engine_table::set_field_char_utf8(Field *f, const char* str,
683 uint len)
684 {
685 assert(f->real_type() == MYSQL_TYPE_STRING);
686 Field_string *f2= (Field_string*) f;
687 f2->store(str, len, &my_charset_utf8_bin);
688 }
689
set_field_varchar(Field * f,const CHARSET_INFO * cs,const char * str,uint len)690 void PFS_engine_table::set_field_varchar(Field *f,
691 const CHARSET_INFO *cs,
692 const char* str,
693 uint len)
694 {
695 assert(f->real_type() == MYSQL_TYPE_VARCHAR);
696 Field_varstring *f2= (Field_varstring*) f;
697 f2->store(str, len, cs);
698 }
699
set_field_varchar_utf8(Field * f,const char * str,uint len)700 void PFS_engine_table::set_field_varchar_utf8(Field *f, const char* str,
701 uint len)
702 {
703 assert(f->real_type() == MYSQL_TYPE_VARCHAR);
704 Field_varstring *f2= (Field_varstring*) f;
705 f2->store(str, len, &my_charset_utf8_bin);
706 }
707
set_field_longtext_utf8(Field * f,const char * str,uint len)708 void PFS_engine_table::set_field_longtext_utf8(Field *f, const char* str,
709 uint len)
710 {
711 assert(f->real_type() == MYSQL_TYPE_BLOB);
712 Field_blob *f2= (Field_blob*) f;
713 f2->store(str, len, &my_charset_utf8_bin);
714 }
715
set_field_blob(Field * f,const char * val,uint len)716 void PFS_engine_table::set_field_blob(Field *f, const char* val,
717 uint len)
718 {
719 assert(f->real_type() == MYSQL_TYPE_BLOB);
720 Field_blob *f2= (Field_blob*) f;
721 f2->store(val, len, &my_charset_utf8_bin);
722 }
723
set_field_enum(Field * f,ulonglong value)724 void PFS_engine_table::set_field_enum(Field *f, ulonglong value)
725 {
726 assert(f->real_type() == MYSQL_TYPE_ENUM);
727 Field_enum *f2= (Field_enum*) f;
728 f2->store_type(value);
729 }
730
set_field_timestamp(Field * f,ulonglong value)731 void PFS_engine_table::set_field_timestamp(Field *f, ulonglong value)
732 {
733 struct timeval tm;
734 tm.tv_sec= (long)(value / 1000000);
735 tm.tv_usec= (long)(value % 1000000);
736 assert(f->real_type() == MYSQL_TYPE_TIMESTAMP2);
737 Field_timestampf *f2= (Field_timestampf*) f;
738 f2->store_timestamp(& tm);
739 }
740
set_field_double(Field * f,double value)741 void PFS_engine_table::set_field_double(Field *f, double value)
742 {
743 assert(f->real_type() == MYSQL_TYPE_DOUBLE);
744 Field_double *f2= (Field_double*) f;
745 f2->store(value);
746 }
747
get_field_enum(Field * f)748 ulonglong PFS_engine_table::get_field_enum(Field *f)
749 {
750 assert(f->real_type() == MYSQL_TYPE_ENUM);
751 Field_enum *f2= (Field_enum*) f;
752 return f2->val_int();
753 }
754
755 String*
get_field_char_utf8(Field * f,String * val)756 PFS_engine_table::get_field_char_utf8(Field *f, String *val)
757 {
758 assert(f->real_type() == MYSQL_TYPE_STRING);
759 Field_string *f2= (Field_string*) f;
760 val= f2->val_str(NULL, val);
761 return val;
762 }
763
764 String*
get_field_varchar_utf8(Field * f,String * val)765 PFS_engine_table::get_field_varchar_utf8(Field *f, String *val)
766 {
767 assert(f->real_type() == MYSQL_TYPE_VARCHAR);
768 Field_varstring *f2= (Field_varstring*) f;
769 val= f2->val_str(NULL, val);
770 return val;
771 }
772
update_row_values(TABLE *,const unsigned char *,unsigned char *,Field **)773 int PFS_engine_table::update_row_values(TABLE *,
774 const unsigned char *,
775 unsigned char *,
776 Field **)
777 {
778 return HA_ERR_WRONG_COMMAND;
779 }
780
781 /** Implementation of internal ACL checks, for the performance schema. */
782 class PFS_internal_schema_access : public ACL_internal_schema_access
783 {
784 public:
PFS_internal_schema_access()785 PFS_internal_schema_access()
786 {}
787
~PFS_internal_schema_access()788 ~PFS_internal_schema_access()
789 {}
790
791 ACL_internal_access_result check(ulong want_access,
792 ulong *save_priv) const;
793
794 const ACL_internal_table_access *lookup(const char *name) const;
795 };
796
797 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const798 PFS_internal_schema_access::check(ulong want_access,
799 ulong *save_priv) const
800 {
801 const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
802 | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | EXECUTE_ACL
803 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL
804 | EVENT_ACL | TRIGGER_ACL ;
805
806 if (unlikely(want_access & always_forbidden))
807 return ACL_INTERNAL_ACCESS_DENIED;
808
809 /*
810 Proceed with regular grant tables,
811 to give administrative control to the DBA.
812 */
813 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
814 }
815
816 const ACL_internal_table_access *
lookup(const char * name) const817 PFS_internal_schema_access::lookup(const char *name) const
818 {
819 const PFS_engine_table_share* share;
820 share= PFS_engine_table::find_engine_table_share(name);
821 if (share)
822 return share->m_acl;
823 /*
824 Do not return NULL, it would mean we are not interested
825 in privilege checks for unknown tables.
826 Instead, return an object that denies every actions,
827 to prevent users for creating their own tables in the
828 performance_schema database schema.
829 */
830 return &pfs_unknown_acl;
831 }
832
833 PFS_internal_schema_access pfs_internal_access;
834
initialize_performance_schema_acl(bool bootstrap)835 void initialize_performance_schema_acl(bool bootstrap)
836 {
837 /*
838 ACL is always enforced, even if the performance schema
839 is not enabled (the tables are still visible).
840 */
841 if (! bootstrap)
842 {
843 ACL_internal_schema_registry::register_schema(PERFORMANCE_SCHEMA_str,
844 &pfs_internal_access);
845 }
846 }
847
allow_drop_table_privilege()848 static bool allow_drop_table_privilege() {
849 /*
850 The same DROP_ACL privilege is used for different statements,
851 in particular:
852 - TRUNCATE TABLE
853 - DROP TABLE
854 - ALTER TABLE
855 Here, we want to prevent DROP / ALTER while allowing TRUNCATE.
856 Note that we must also allow GRANT to transfer the truncate privilege.
857 */
858 THD *thd= current_thd;
859 if (thd == NULL) {
860 return false;
861 }
862
863 assert(thd->lex != NULL);
864 if ((thd->lex->sql_command != SQLCOM_TRUNCATE) &&
865 (thd->lex->sql_command != SQLCOM_GRANT)) {
866 return false;
867 }
868
869 return true;
870 }
871
872
873 PFS_readonly_acl pfs_readonly_acl;
874
875 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const876 PFS_readonly_acl::check(ulong want_access, ulong *save_priv) const
877 {
878 const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
879 | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
880 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
881
882 if (unlikely(want_access & always_forbidden))
883 return ACL_INTERNAL_ACCESS_DENIED;
884
885 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
886 }
887
888
889 PFS_readonly_world_acl pfs_readonly_world_acl;
890
891 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const892 PFS_readonly_world_acl::check(ulong want_access, ulong *save_priv) const
893 {
894 ACL_internal_access_result res= PFS_readonly_acl::check(want_access, save_priv);
895 if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT)
896 {
897 if (want_access == SELECT_ACL)
898 res= ACL_INTERNAL_ACCESS_GRANTED;
899 }
900 return res;
901 }
902
903
904 PFS_truncatable_acl pfs_truncatable_acl;
905
906 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const907 PFS_truncatable_acl::check(ulong want_access, ulong *save_priv) const
908 {
909 const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
910 | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
911 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
912
913 if (unlikely(want_access & always_forbidden))
914 return ACL_INTERNAL_ACCESS_DENIED;
915
916 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
917 }
918
919
920 PFS_truncatable_world_acl pfs_truncatable_world_acl;
921
922 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const923 PFS_truncatable_world_acl::check(ulong want_access, ulong *save_priv) const
924 {
925 ACL_internal_access_result res= PFS_truncatable_acl::check(want_access, save_priv);
926 if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT)
927 {
928 if (want_access == DROP_ACL)
929 {
930 if (allow_drop_table_privilege())
931 res= ACL_INTERNAL_ACCESS_GRANTED;
932 }
933 else if (want_access == SELECT_ACL)
934 res= ACL_INTERNAL_ACCESS_GRANTED;
935 }
936 return res;
937 }
938
939
940 PFS_updatable_acl pfs_updatable_acl;
941
942 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const943 PFS_updatable_acl::check(ulong want_access, ulong *save_priv) const
944 {
945 const ulong always_forbidden= INSERT_ACL | DELETE_ACL
946 | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
947 | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
948
949 if (unlikely(want_access & always_forbidden))
950 return ACL_INTERNAL_ACCESS_DENIED;
951
952 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
953 }
954
955 PFS_editable_acl pfs_editable_acl;
956
957 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const958 PFS_editable_acl::check(ulong want_access, ulong *save_priv) const
959 {
960 const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
961 | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
962
963 if (unlikely(want_access & always_forbidden))
964 return ACL_INTERNAL_ACCESS_DENIED;
965
966 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
967 }
968
969 PFS_unknown_acl pfs_unknown_acl;
970
971 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const972 PFS_unknown_acl::check(ulong want_access, ulong *save_priv) const
973 {
974 const ulong always_forbidden= CREATE_ACL
975 | REFERENCES_ACL | INDEX_ACL | ALTER_ACL
976 | CREATE_VIEW_ACL | TRIGGER_ACL;
977
978 if (unlikely(want_access & always_forbidden))
979 return ACL_INTERNAL_ACCESS_DENIED;
980
981 /*
982 There is no point in hiding (by enforcing ACCESS_DENIED for SELECT_ACL
983 on performance_schema.*) tables that do not exist anyway.
984 When SELECT_ACL is granted on performance_schema.* or *.*,
985 SELECT * from performance_schema.wrong_table
986 will fail with a more understandable ER_NO_SUCH_TABLE error,
987 instead of ER_TABLEACCESS_DENIED_ERROR.
988 The same goes for other DML (INSERT_ACL | UPDATE_ACL | DELETE_ACL),
989 for ease of use: error messages will be less surprising.
990 */
991 return ACL_INTERNAL_ACCESS_CHECK_GRANT;
992 }
993
994 /**
995 SHOW ENGINE PERFORMANCE_SCHEMA STATUS.
996 @param hton Storage engine handler
997 @param thd Current thread
998 @param print Print function
999 @param stat status to show
1000 */
pfs_show_status(handlerton * hton,THD * thd,stat_print_fn * print,enum ha_stat_type stat)1001 bool pfs_show_status(handlerton *hton, THD *thd,
1002 stat_print_fn *print, enum ha_stat_type stat)
1003 {
1004 char buf[1024];
1005 uint buflen;
1006 const char *name;
1007 int i;
1008 size_t size;
1009
1010 DBUG_ENTER("pfs_show_status");
1011
1012 /*
1013 Note about naming conventions:
1014 - Internal buffers exposed as a table in the performance schema are named
1015 after the table, as in 'events_waits_current'
1016 - Internal buffers not exposed by a table are named with parenthesis,
1017 as in '(pfs_mutex_class)'.
1018 */
1019 if (stat != HA_ENGINE_STATUS)
1020 DBUG_RETURN(false);
1021
1022 size_t total_memory= 0;
1023
1024 for (i=0; /* empty */; i++)
1025 {
1026 switch (i){
1027 case 0:
1028 name= "events_waits_current.size";
1029 size= sizeof(PFS_events_waits);
1030 break;
1031 case 1:
1032 name= "events_waits_current.count";
1033 size= WAIT_STACK_SIZE * global_thread_container.get_row_count();
1034 break;
1035 case 2:
1036 name= "events_waits_history.size";
1037 size= sizeof(PFS_events_waits);
1038 break;
1039 case 3:
1040 name= "events_waits_history.count";
1041 size= events_waits_history_per_thread * global_thread_container.get_row_count();
1042 break;
1043 case 4:
1044 name= "events_waits_history.memory";
1045 size= events_waits_history_per_thread * global_thread_container.get_row_count()
1046 * sizeof(PFS_events_waits);
1047 total_memory+= size;
1048 break;
1049 case 5:
1050 name= "events_waits_history_long.size";
1051 size= sizeof(PFS_events_waits);
1052 break;
1053 case 6:
1054 name= "events_waits_history_long.count";
1055 size= events_waits_history_long_size;
1056 break;
1057 case 7:
1058 name= "events_waits_history_long.memory";
1059 size= events_waits_history_long_size * sizeof(PFS_events_waits);
1060 total_memory+= size;
1061 break;
1062 case 8:
1063 name= "(pfs_mutex_class).size";
1064 size= sizeof(PFS_mutex_class);
1065 break;
1066 case 9:
1067 name= "(pfs_mutex_class).count";
1068 size= mutex_class_max;
1069 break;
1070 case 10:
1071 name= "(pfs_mutex_class).memory";
1072 size= mutex_class_max * sizeof(PFS_mutex_class);
1073 total_memory+= size;
1074 break;
1075 case 11:
1076 name= "(pfs_rwlock_class).size";
1077 size= sizeof(PFS_rwlock_class);
1078 break;
1079 case 12:
1080 name= "(pfs_rwlock_class).count";
1081 size= rwlock_class_max;
1082 break;
1083 case 13:
1084 name= "(pfs_rwlock_class).memory";
1085 size= rwlock_class_max * sizeof(PFS_rwlock_class);
1086 total_memory+= size;
1087 break;
1088 case 14:
1089 name= "(pfs_cond_class).size";
1090 size= sizeof(PFS_cond_class);
1091 break;
1092 case 15:
1093 name= "(pfs_cond_class).count";
1094 size= cond_class_max;
1095 break;
1096 case 16:
1097 name= "(pfs_cond_class).memory";
1098 size= cond_class_max * sizeof(PFS_cond_class);
1099 total_memory+= size;
1100 break;
1101 case 17:
1102 name= "(pfs_thread_class).size";
1103 size= sizeof(PFS_thread_class);
1104 break;
1105 case 18:
1106 name= "(pfs_thread_class).count";
1107 size= thread_class_max;
1108 break;
1109 case 19:
1110 name= "(pfs_thread_class).memory";
1111 size= thread_class_max * sizeof(PFS_thread_class);
1112 total_memory+= size;
1113 break;
1114 case 20:
1115 name= "(pfs_file_class).size";
1116 size= sizeof(PFS_file_class);
1117 break;
1118 case 21:
1119 name= "(pfs_file_class).count";
1120 size= file_class_max;
1121 break;
1122 case 22:
1123 name= "(pfs_file_class).memory";
1124 size= file_class_max * sizeof(PFS_file_class);
1125 total_memory+= size;
1126 break;
1127 case 23:
1128 name= "mutex_instances.size";
1129 size= global_mutex_container.get_row_size();
1130 break;
1131 case 24:
1132 name= "mutex_instances.count";
1133 size= global_mutex_container.get_row_count();
1134 break;
1135 case 25:
1136 name= "mutex_instances.memory";
1137 size= global_mutex_container.get_memory();
1138 total_memory+= size;
1139 break;
1140 case 26:
1141 name= "rwlock_instances.size";
1142 size= global_rwlock_container.get_row_size();
1143 break;
1144 case 27:
1145 name= "rwlock_instances.count";
1146 size= global_rwlock_container.get_row_count();
1147 break;
1148 case 28:
1149 name= "rwlock_instances.memory";
1150 size= global_rwlock_container.get_memory();
1151 total_memory+= size;
1152 break;
1153 case 29:
1154 name= "cond_instances.size";
1155 size= global_cond_container.get_row_size();
1156 break;
1157 case 30:
1158 name= "cond_instances.count";
1159 size= global_cond_container.get_row_count();
1160 break;
1161 case 31:
1162 name= "cond_instances.memory";
1163 size= global_cond_container.get_memory();
1164 total_memory+= size;
1165 break;
1166 case 32:
1167 name= "threads.size";
1168 size= global_thread_container.get_row_size();
1169 break;
1170 case 33:
1171 name= "threads.count";
1172 size= global_thread_container.get_row_count();
1173 break;
1174 case 34:
1175 name= "threads.memory";
1176 size= global_thread_container.get_memory();
1177 total_memory+= size;
1178 break;
1179 case 35:
1180 name= "file_instances.size";
1181 size= global_file_container.get_row_size();
1182 break;
1183 case 36:
1184 name= "file_instances.count";
1185 size= global_file_container.get_row_count();
1186 break;
1187 case 37:
1188 name= "file_instances.memory";
1189 size= global_file_container.get_memory();
1190 total_memory+= size;
1191 break;
1192 case 38:
1193 name= "(pfs_file_handle).size";
1194 size= sizeof(PFS_file*);
1195 break;
1196 case 39:
1197 name= "(pfs_file_handle).count";
1198 size= file_handle_max;
1199 break;
1200 case 40:
1201 name= "(pfs_file_handle).memory";
1202 size= file_handle_max * sizeof(PFS_file*);
1203 total_memory+= size;
1204 break;
1205 case 41:
1206 name= "events_waits_summary_by_thread_by_event_name.size";
1207 size= sizeof(PFS_single_stat);
1208 break;
1209 case 42:
1210 name= "events_waits_summary_by_thread_by_event_name.count";
1211 size= global_thread_container.get_row_count() * wait_class_max;
1212 break;
1213 case 43:
1214 name= "events_waits_summary_by_thread_by_event_name.memory";
1215 size= global_thread_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1216 total_memory+= size;
1217 break;
1218 case 44:
1219 name= "(pfs_table_share).size";
1220 size= global_table_share_container.get_row_size();
1221 break;
1222 case 45:
1223 name= "(pfs_table_share).count";
1224 size= global_table_share_container.get_row_count();
1225 break;
1226 case 46:
1227 name= "(pfs_table_share).memory";
1228 size= global_table_share_container.get_memory();
1229 total_memory+= size;
1230 break;
1231 case 47:
1232 name= "(pfs_table).size";
1233 size= global_table_container.get_row_size();
1234 break;
1235 case 48:
1236 name= "(pfs_table).count";
1237 size= global_table_container.get_row_count();
1238 break;
1239 case 49:
1240 name= "(pfs_table).memory";
1241 size= global_table_container.get_memory();
1242 total_memory+= size;
1243 break;
1244 case 50:
1245 name= "setup_actors.size";
1246 size= global_setup_actor_container.get_row_size();
1247 break;
1248 case 51:
1249 name= "setup_actors.count";
1250 size= global_setup_actor_container.get_row_count();
1251 break;
1252 case 52:
1253 name= "setup_actors.memory";
1254 size= global_setup_actor_container.get_memory();
1255 total_memory+= size;
1256 break;
1257 case 53:
1258 name= "setup_objects.size";
1259 size= global_setup_object_container.get_row_size();
1260 break;
1261 case 54:
1262 name= "setup_objects.count";
1263 size= global_setup_object_container.get_row_count();
1264 break;
1265 case 55:
1266 name= "setup_objects.memory";
1267 size= global_setup_object_container.get_memory();
1268 total_memory+= size;
1269 break;
1270 case 56:
1271 name= "(pfs_account).size";
1272 size= global_account_container.get_row_size();
1273 break;
1274 case 57:
1275 name= "(pfs_account).count";
1276 size= global_account_container.get_row_count();
1277 break;
1278 case 58:
1279 name= "(pfs_account).memory";
1280 size= global_account_container.get_memory();
1281 total_memory+= size;
1282 break;
1283 case 59:
1284 name= "events_waits_summary_by_account_by_event_name.size";
1285 size= sizeof(PFS_single_stat);
1286 break;
1287 case 60:
1288 name= "events_waits_summary_by_account_by_event_name.count";
1289 size= global_account_container.get_row_count() * wait_class_max;
1290 break;
1291 case 61:
1292 name= "events_waits_summary_by_account_by_event_name.memory";
1293 size= global_account_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1294 total_memory+= size;
1295 break;
1296 case 62:
1297 name= "events_waits_summary_by_user_by_event_name.size";
1298 size= sizeof(PFS_single_stat);
1299 break;
1300 case 63:
1301 name= "events_waits_summary_by_user_by_event_name.count";
1302 size= global_user_container.get_row_count() * wait_class_max;
1303 break;
1304 case 64:
1305 name= "events_waits_summary_by_user_by_event_name.memory";
1306 size= global_user_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1307 total_memory+= size;
1308 break;
1309 case 65:
1310 name= "events_waits_summary_by_host_by_event_name.size";
1311 size= sizeof(PFS_single_stat);
1312 break;
1313 case 66:
1314 name= "events_waits_summary_by_host_by_event_name.count";
1315 size= global_host_container.get_row_count() * wait_class_max;
1316 break;
1317 case 67:
1318 name= "events_waits_summary_by_host_by_event_name.memory";
1319 size= global_host_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1320 total_memory+= size;
1321 break;
1322 case 68:
1323 name= "(pfs_user).size";
1324 size= global_user_container.get_row_size();
1325 break;
1326 case 69:
1327 name= "(pfs_user).count";
1328 size= global_user_container.get_row_count();
1329 break;
1330 case 70:
1331 name= "(pfs_user).memory";
1332 size= global_user_container.get_memory();
1333 total_memory+= size;
1334 break;
1335 case 71:
1336 name= "(pfs_host).size";
1337 size= global_host_container.get_row_size();
1338 break;
1339 case 72:
1340 name= "(pfs_host).count";
1341 size= global_host_container.get_row_count();
1342 break;
1343 case 73:
1344 name= "(pfs_host).memory";
1345 size= global_host_container.get_memory();
1346 total_memory+= size;
1347 break;
1348 case 74:
1349 name= "(pfs_stage_class).size";
1350 size= sizeof(PFS_stage_class);
1351 break;
1352 case 75:
1353 name= "(pfs_stage_class).count";
1354 size= stage_class_max;
1355 break;
1356 case 76:
1357 name= "(pfs_stage_class).memory";
1358 size= stage_class_max * sizeof(PFS_stage_class);
1359 total_memory+= size;
1360 break;
1361 case 77:
1362 name= "events_stages_history.size";
1363 size= sizeof(PFS_events_stages);
1364 break;
1365 case 78:
1366 name= "events_stages_history.count";
1367 size= events_stages_history_per_thread * global_thread_container.get_row_count();
1368 break;
1369 case 79:
1370 name= "events_stages_history.memory";
1371 size= events_stages_history_per_thread * global_thread_container.get_row_count()
1372 * sizeof(PFS_events_stages);
1373 total_memory+= size;
1374 break;
1375 case 80:
1376 name= "events_stages_history_long.size";
1377 size= sizeof(PFS_events_stages);
1378 break;
1379 case 81:
1380 name= "events_stages_history_long.count";
1381 size= events_stages_history_long_size;
1382 break;
1383 case 82:
1384 name= "events_stages_history_long.memory";
1385 size= events_stages_history_long_size * sizeof(PFS_events_stages);
1386 total_memory+= size;
1387 break;
1388 case 83:
1389 name= "events_stages_summary_by_thread_by_event_name.size";
1390 size= sizeof(PFS_stage_stat);
1391 break;
1392 case 84:
1393 name= "events_stages_summary_by_thread_by_event_name.count";
1394 size= global_thread_container.get_row_count() * stage_class_max;
1395 break;
1396 case 85:
1397 name= "events_stages_summary_by_thread_by_event_name.memory";
1398 size= global_thread_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1399 total_memory+= size;
1400 break;
1401 case 86:
1402 name= "events_stages_summary_global_by_event_name.size";
1403 size= sizeof(PFS_stage_stat);
1404 break;
1405 case 87:
1406 name= "events_stages_summary_global_by_event_name.count";
1407 size= stage_class_max;
1408 break;
1409 case 88:
1410 name= "events_stages_summary_global_by_event_name.memory";
1411 size= stage_class_max * sizeof(PFS_stage_stat);
1412 total_memory+= size;
1413 break;
1414 case 89:
1415 name= "events_stages_summary_by_account_by_event_name.size";
1416 size= sizeof(PFS_stage_stat);
1417 break;
1418 case 90:
1419 name= "events_stages_summary_by_account_by_event_name.count";
1420 size= global_account_container.get_row_count() * stage_class_max;
1421 break;
1422 case 91:
1423 name= "events_stages_summary_by_account_by_event_name.memory";
1424 size= global_account_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1425 total_memory+= size;
1426 break;
1427 case 92:
1428 name= "events_stages_summary_by_user_by_event_name.size";
1429 size= sizeof(PFS_stage_stat);
1430 break;
1431 case 93:
1432 name= "events_stages_summary_by_user_by_event_name.count";
1433 size= global_user_container.get_row_count() * stage_class_max;
1434 break;
1435 case 94:
1436 name= "events_stages_summary_by_user_by_event_name.memory";
1437 size= global_user_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1438 total_memory+= size;
1439 break;
1440 case 95:
1441 name= "events_stages_summary_by_host_by_event_name.size";
1442 size= sizeof(PFS_stage_stat);
1443 break;
1444 case 96:
1445 name= "events_stages_summary_by_host_by_event_name.count";
1446 size= global_host_container.get_row_count() * stage_class_max;
1447 break;
1448 case 97:
1449 name= "events_stages_summary_by_host_by_event_name.memory";
1450 size= global_host_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1451 total_memory+= size;
1452 break;
1453 case 98:
1454 name= "(pfs_statement_class).size";
1455 size= sizeof(PFS_statement_class);
1456 break;
1457 case 99:
1458 name= "(pfs_statement_class).count";
1459 size= statement_class_max;
1460 break;
1461 case 100:
1462 name= "(pfs_statement_class).memory";
1463 size= statement_class_max * sizeof(PFS_statement_class);
1464 total_memory+= size;
1465 break;
1466 case 101:
1467 name= "events_statements_history.size";
1468 size= sizeof(PFS_events_statements);
1469 break;
1470 case 102:
1471 name= "events_statements_history.count";
1472 size= events_statements_history_per_thread * global_thread_container.get_row_count();
1473 break;
1474 case 103:
1475 name= "events_statements_history.memory";
1476 size= events_statements_history_per_thread * global_thread_container.get_row_count()
1477 * sizeof(PFS_events_statements);
1478 total_memory+= size;
1479 break;
1480 case 104:
1481 name= "events_statements_history_long.size";
1482 size= sizeof(PFS_events_statements);
1483 break;
1484 case 105:
1485 name= "events_statements_history_long.count";
1486 size= events_statements_history_long_size;
1487 break;
1488 case 106:
1489 name= "events_statements_history_long.memory";
1490 size= events_statements_history_long_size * (sizeof(PFS_events_statements));
1491 total_memory+= size;
1492 break;
1493 case 107:
1494 name= "events_statements_summary_by_thread_by_event_name.size";
1495 size= sizeof(PFS_statement_stat);
1496 break;
1497 case 108:
1498 name= "events_statements_summary_by_thread_by_event_name.count";
1499 size= global_thread_container.get_row_count() * statement_class_max;
1500 break;
1501 case 109:
1502 name= "events_statements_summary_by_thread_by_event_name.memory";
1503 size= global_thread_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1504 total_memory+= size;
1505 break;
1506 case 110:
1507 name= "events_statements_summary_global_by_event_name.size";
1508 size= sizeof(PFS_statement_stat);
1509 break;
1510 case 111:
1511 name= "events_statements_summary_global_by_event_name.count";
1512 size= statement_class_max;
1513 break;
1514 case 112:
1515 name= "events_statements_summary_global_by_event_name.memory";
1516 size= statement_class_max * sizeof(PFS_statement_stat);
1517 total_memory+= size;
1518 break;
1519 case 113:
1520 name= "events_statements_summary_by_account_by_event_name.size";
1521 size= sizeof(PFS_statement_stat);
1522 break;
1523 case 114:
1524 name= "events_statements_summary_by_account_by_event_name.count";
1525 size= global_account_container.get_row_count() * statement_class_max;
1526 break;
1527 case 115:
1528 name= "events_statements_summary_by_account_by_event_name.memory";
1529 size= global_account_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1530 total_memory+= size;
1531 break;
1532 case 116:
1533 name= "events_statements_summary_by_user_by_event_name.size";
1534 size= sizeof(PFS_statement_stat);
1535 break;
1536 case 117:
1537 name= "events_statements_summary_by_user_by_event_name.count";
1538 size= global_user_container.get_row_count() * statement_class_max;
1539 break;
1540 case 118:
1541 name= "events_statements_summary_by_user_by_event_name.memory";
1542 size= global_user_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1543 total_memory+= size;
1544 break;
1545 case 119:
1546 name= "events_statements_summary_by_host_by_event_name.size";
1547 size= sizeof(PFS_statement_stat);
1548 break;
1549 case 120:
1550 name= "events_statements_summary_by_host_by_event_name.count";
1551 size= global_host_container.get_row_count() * statement_class_max;
1552 break;
1553 case 121:
1554 name= "events_statements_summary_by_host_by_event_name.memory";
1555 size= global_host_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1556 total_memory+= size;
1557 break;
1558 case 122:
1559 name= "events_statements_current.size";
1560 size= sizeof(PFS_events_statements);
1561 break;
1562 case 123:
1563 name= "events_statements_current.count";
1564 size= global_thread_container.get_row_count() * statement_stack_max;
1565 break;
1566 case 124:
1567 name= "events_statements_current.memory";
1568 size= global_thread_container.get_row_count() * statement_stack_max * sizeof(PFS_events_statements);
1569 total_memory+= size;
1570 break;
1571 case 125:
1572 name= "(pfs_socket_class).size";
1573 size= sizeof(PFS_socket_class);
1574 break;
1575 case 126:
1576 name= "(pfs_socket_class).count";
1577 size= socket_class_max;
1578 break;
1579 case 127:
1580 name= "(pfs_socket_class).memory";
1581 size= socket_class_max * sizeof(PFS_socket_class);
1582 total_memory+= size;
1583 break;
1584 case 128:
1585 name= "socket_instances.size";
1586 size= global_socket_container.get_row_size();
1587 break;
1588 case 129:
1589 name= "socket_instances.count";
1590 size= global_socket_container.get_row_count();
1591 break;
1592 case 130:
1593 name= "socket_instances.memory";
1594 size= global_socket_container.get_memory();
1595 total_memory+= size;
1596 break;
1597 case 131:
1598 name= "events_statements_summary_by_digest.size";
1599 size= sizeof(PFS_statements_digest_stat);
1600 break;
1601 case 132:
1602 name= "events_statements_summary_by_digest.count";
1603 size= digest_max;
1604 break;
1605 case 133:
1606 name= "events_statements_summary_by_digest.memory";
1607 size= digest_max * (sizeof(PFS_statements_digest_stat));
1608 total_memory+= size;
1609 break;
1610 case 134:
1611 name= "events_statements_summary_by_program.size";
1612 size= global_program_container.get_row_size();
1613 break;
1614 case 135:
1615 name= "events_statements_summary_by_program.count";
1616 size= global_program_container.get_row_count();
1617 break;
1618 case 136:
1619 name= "events_statements_summary_by_program.memory";
1620 size= global_program_container.get_memory();
1621 total_memory+= size;
1622 break;
1623 case 137:
1624 name= "session_connect_attrs.size";
1625 size= global_thread_container.get_row_count();
1626 break;
1627 case 138:
1628 name= "session_connect_attrs.count";
1629 size= session_connect_attrs_size_per_thread;
1630 break;
1631 case 139:
1632 name= "session_connect_attrs.memory";
1633 size= global_thread_container.get_row_count() * session_connect_attrs_size_per_thread;
1634 total_memory+= size;
1635 break;
1636 case 140:
1637 name= "prepared_statements_instances.size";
1638 size= global_prepared_stmt_container.get_row_size();
1639 break;
1640 case 141:
1641 name= "prepared_statements_instances.count";
1642 size= global_prepared_stmt_container.get_row_count();
1643 break;
1644 case 142:
1645 name= "prepared_statements_instances.memory";
1646 size= global_prepared_stmt_container.get_memory();
1647 total_memory+= size;
1648 break;
1649
1650 case 143:
1651 name= "(account_hash).count";
1652 size= account_hash.count;
1653 break;
1654 case 144:
1655 name= "(account_hash).size";
1656 size= account_hash.size;
1657 break;
1658 case 145:
1659 name= "(digest_hash).count";
1660 size= digest_hash.count;
1661 break;
1662 case 146:
1663 name= "(digest_hash).size";
1664 size= digest_hash.size;
1665 break;
1666 case 147:
1667 name= "(filename_hash).count";
1668 size= filename_hash.count;
1669 break;
1670 case 148:
1671 name= "(filename_hash).size";
1672 size= filename_hash.size;
1673 break;
1674 case 149:
1675 name= "(host_hash).count";
1676 size= host_hash.count;
1677 break;
1678 case 150:
1679 name= "(host_hash).size";
1680 size= host_hash.size;
1681 break;
1682 case 151:
1683 name= "(setup_actor_hash).count";
1684 size= setup_actor_hash.count;
1685 break;
1686 case 152:
1687 name= "(setup_actor_hash).size";
1688 size= setup_actor_hash.size;
1689 break;
1690 case 153:
1691 name= "(setup_object_hash).count";
1692 size= setup_object_hash.count;
1693 break;
1694 case 154:
1695 name= "(setup_object_hash).size";
1696 size= setup_object_hash.size;
1697 break;
1698 case 155:
1699 name= "(table_share_hash).count";
1700 size= table_share_hash.count;
1701 break;
1702 case 156:
1703 name= "(table_share_hash).size";
1704 size= table_share_hash.size;
1705 break;
1706 case 157:
1707 name= "(user_hash).count";
1708 size= user_hash.count;
1709 break;
1710 case 158:
1711 name= "(user_hash).size";
1712 size= user_hash.size;
1713 break;
1714 case 159:
1715 name= "(program_hash).count";
1716 size= program_hash.count;
1717 break;
1718 case 160:
1719 name= "(program_hash).size";
1720 size= program_hash.size;
1721 break;
1722 case 161:
1723 /*
1724 This is not a performance_schema buffer,
1725 the data is maintained in the server,
1726 in hostname_cache.
1727 Print the size only, there are:
1728 - no host_cache.count
1729 - no host_cache.memory
1730 */
1731 name= "host_cache.size";
1732 size= sizeof(Host_entry);
1733 break;
1734
1735 case 162:
1736 name= "(pfs_memory_class).row_size";
1737 size= sizeof(PFS_memory_class);
1738 break;
1739 case 163:
1740 name= "(pfs_memory_class).row_count";
1741 size= memory_class_max;
1742 break;
1743 case 164:
1744 name= "(pfs_memory_class).memory";
1745 size= memory_class_max * sizeof(PFS_memory_class);
1746 total_memory+= size;
1747 break;
1748
1749 case 165:
1750 name= "memory_summary_by_thread_by_event_name.row_size";
1751 size= sizeof(PFS_memory_stat);
1752 break;
1753 case 166:
1754 name= "memory_summary_by_thread_by_event_name.row_count";
1755 size= global_thread_container.get_row_count() * memory_class_max;
1756 break;
1757 case 167:
1758 name= "memory_summary_by_thread_by_event_name.memory";
1759 size= global_thread_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1760 total_memory+= size;
1761 break;
1762 case 168:
1763 name= "memory_summary_global_by_event_name.row_size";
1764 size= sizeof(PFS_memory_stat);
1765 break;
1766 case 169:
1767 name= "memory_summary_global_by_event_name.row_count";
1768 size= memory_class_max;
1769 break;
1770 case 170:
1771 name= "memory_summary_global_by_event_name.memory";
1772 size= memory_class_max * sizeof(PFS_memory_stat);
1773 total_memory+= size;
1774 break;
1775 case 171:
1776 name= "memory_summary_by_account_by_event_name.row_size";
1777 size= sizeof(PFS_memory_stat);
1778 break;
1779 case 172:
1780 name= "memory_summary_by_account_by_event_name.row_count";
1781 size= global_account_container.get_row_count() * memory_class_max;
1782 break;
1783 case 173:
1784 name= "memory_summary_by_account_by_event_name.memory";
1785 size= global_account_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1786 total_memory+= size;
1787 break;
1788 case 174:
1789 name= "memory_summary_by_user_by_event_name.row_size";
1790 size= sizeof(PFS_memory_stat);
1791 break;
1792 case 175:
1793 name= "memory_summary_by_user_by_event_name.row_count";
1794 size= global_user_container.get_row_count() * memory_class_max;
1795 break;
1796 case 176:
1797 name= "memory_summary_by_user_by_event_name.memory";
1798 size= global_user_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1799 total_memory+= size;
1800 break;
1801 case 177:
1802 name= "memory_summary_by_host_by_event_name.row_size";
1803 size= sizeof(PFS_memory_stat);
1804 break;
1805 case 178:
1806 name= "memory_summary_by_host_by_event_name.row_count";
1807 size= global_host_container.get_row_count() * memory_class_max;
1808 break;
1809 case 179:
1810 name= "memory_summary_by_host_by_event_name.memory";
1811 size= global_host_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1812 total_memory+= size;
1813 break;
1814 case 180:
1815 name= "metadata_locks.row_size";
1816 size= global_mdl_container.get_row_size();
1817 break;
1818 case 181:
1819 name= "metadata_locks.row_count";
1820 size= global_mdl_container.get_row_count();
1821 break;
1822 case 182:
1823 name= "metadata_locks.memory";
1824 size= global_mdl_container.get_memory();
1825 total_memory+= size;
1826 break;
1827 case 183:
1828 name= "events_transactions_history.size";
1829 size= sizeof(PFS_events_transactions);
1830 break;
1831 case 184:
1832 name= "events_transactions_history.count";
1833 size= events_transactions_history_per_thread * global_thread_container.get_row_count();
1834 break;
1835 case 185:
1836 name= "events_transactions_history.memory";
1837 size= events_transactions_history_per_thread * global_thread_container.get_row_count()
1838 * sizeof(PFS_events_transactions);
1839 total_memory+= size;
1840 break;
1841 case 186:
1842 name= "events_transactions_history_long.size";
1843 size= sizeof(PFS_events_transactions);
1844 break;
1845 case 187:
1846 name= "events_transactions_history_long.count";
1847 size= events_transactions_history_long_size;
1848 break;
1849 case 188:
1850 name= "events_transactions_history_long.memory";
1851 size= events_transactions_history_long_size * sizeof(PFS_events_transactions);
1852 total_memory+= size;
1853 break;
1854 case 189:
1855 name= "events_transactions_summary_by_thread_by_event_name.size";
1856 size= sizeof(PFS_transaction_stat);
1857 break;
1858 case 190:
1859 name= "events_transactions_summary_by_thread_by_event_name.count";
1860 size= global_thread_container.get_row_count() * transaction_class_max;
1861 break;
1862 case 191:
1863 name= "events_transactions_summary_by_thread_by_event_name.memory";
1864 size= global_thread_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1865 total_memory+= size;
1866 break;
1867 case 192:
1868 name= "events_transactions_summary_by_account_by_event_name.size";
1869 size= sizeof(PFS_transaction_stat);
1870 break;
1871 case 193:
1872 name= "events_transactions_summary_by_account_by_event_name.count";
1873 size= global_account_container.get_row_count() * transaction_class_max;
1874 break;
1875 case 194:
1876 name= "events_transactions_summary_by_account_by_event_name.memory";
1877 size= global_account_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1878 total_memory+= size;
1879 break;
1880 case 195:
1881 name= "events_transactions_summary_by_user_by_event_name.size";
1882 size= sizeof(PFS_transaction_stat);
1883 break;
1884 case 196:
1885 name= "events_transactions_summary_by_user_by_event_name.count";
1886 size= global_user_container.get_row_count() * transaction_class_max;
1887 break;
1888 case 197:
1889 name= "events_transactions_summary_by_user_by_event_name.memory";
1890 size= global_user_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1891 total_memory+= size;
1892 break;
1893 case 198:
1894 name= "events_transactions_summary_by_host_by_event_name.size";
1895 size= sizeof(PFS_transaction_stat);
1896 break;
1897 case 199:
1898 name= "events_transactions_summary_by_host_by_event_name.count";
1899 size= global_host_container.get_row_count() * transaction_class_max;
1900 break;
1901 case 200:
1902 name= "events_transactions_summary_by_host_by_event_name.memory";
1903 size= global_host_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1904 total_memory+= size;
1905 break;
1906 case 201:
1907 name= "table_lock_waits_summary_by_table.size";
1908 size= global_table_share_lock_container.get_row_size();
1909 break;
1910 case 202:
1911 name= "table_lock_waits_summary_by_table.count";
1912 size= global_table_share_lock_container.get_row_count();
1913 break;
1914 case 203:
1915 name= "table_lock_waits_summary_by_table.memory";
1916 size= global_table_share_lock_container.get_memory();
1917 total_memory+= size;
1918 break;
1919 case 204:
1920 name= "table_io_waits_summary_by_index_usage.size";
1921 size= global_table_share_index_container.get_row_size();
1922 break;
1923 case 205:
1924 name= "table_io_waits_summary_by_index_usage.count";
1925 size= global_table_share_index_container.get_row_count();
1926 break;
1927 case 206:
1928 name= "table_io_waits_summary_by_index_usage.memory";
1929 size= global_table_share_index_container.get_memory();
1930 total_memory+= size;
1931 break;
1932 case 207:
1933 name= "(history_long_statements_digest_token_array).count";
1934 size= events_statements_history_long_size;
1935 break;
1936 case 208:
1937 name= "(history_long_statements_digest_token_array).size";
1938 size= pfs_max_digest_length;
1939 break;
1940 case 209:
1941 name= "(history_long_statements_digest_token_array).memory";
1942 size= events_statements_history_long_size * pfs_max_digest_length;
1943 total_memory+= size;
1944 break;
1945 case 210:
1946 name= "(history_statements_digest_token_array).count";
1947 size= global_thread_container.get_row_count() * events_statements_history_per_thread;
1948 break;
1949 case 211:
1950 name= "(history_statements_digest_token_array).size";
1951 size= pfs_max_digest_length;
1952 break;
1953 case 212:
1954 name= "(history_statements_digest_token_array).memory";
1955 size= global_thread_container.get_row_count() * events_statements_history_per_thread * pfs_max_digest_length;
1956 total_memory+= size;
1957 break;
1958 case 213:
1959 name= "(current_statements_digest_token_array).count";
1960 size= global_thread_container.get_row_count() * statement_stack_max;
1961 break;
1962 case 214:
1963 name= "(current_statements_digest_token_array).size";
1964 size= pfs_max_digest_length;
1965 break;
1966 case 215:
1967 name= "(current_statements_digest_token_array).memory";
1968 size= global_thread_container.get_row_count() * statement_stack_max * pfs_max_digest_length;
1969 total_memory+= size;
1970 break;
1971 case 216:
1972 name= "(history_long_statements_text_array).count";
1973 size= events_statements_history_long_size;
1974 break;
1975 case 217:
1976 name= "(history_long_statements_text_array).size";
1977 size= pfs_max_sqltext;
1978 break;
1979 case 218:
1980 name= "(history_long_statements_text_array).memory";
1981 size= events_statements_history_long_size * pfs_max_sqltext;
1982 total_memory+= size;
1983 break;
1984 case 219:
1985 name= "(history_statements_text_array).count";
1986 size= global_thread_container.get_row_count() * events_statements_history_per_thread;
1987 break;
1988 case 220:
1989 name= "(history_statements_text_array).size";
1990 size= pfs_max_sqltext;
1991 break;
1992 case 221:
1993 name= "(history_statements_text_array).memory";
1994 size= global_thread_container.get_row_count() * events_statements_history_per_thread * pfs_max_sqltext;
1995 total_memory+= size;
1996 break;
1997 case 222:
1998 name= "(current_statements_text_array).count";
1999 size= global_thread_container.get_row_count() * statement_stack_max;
2000 break;
2001 case 223:
2002 name= "(current_statements_text_array).size";
2003 size= pfs_max_sqltext;
2004 break;
2005 case 224:
2006 name= "(current_statements_text_array).memory";
2007 size= global_thread_container.get_row_count() * statement_stack_max * pfs_max_sqltext;
2008 total_memory+= size;
2009 break;
2010 case 225:
2011 name= "(statements_digest_token_array).count";
2012 size= digest_max;
2013 break;
2014 case 226:
2015 name= "(statements_digest_token_array).size";
2016 size= pfs_max_digest_length;
2017 break;
2018 case 227:
2019 name= "(statements_digest_token_array).memory";
2020 size= digest_max * pfs_max_digest_length;
2021 total_memory+= size;
2022 break;
2023 /*
2024 This case must be last,
2025 for aggregation in total_memory.
2026 */
2027 case 228:
2028 name= "performance_schema.memory";
2029 size= total_memory;
2030 break;
2031 default:
2032 goto end;
2033 break;
2034 }
2035
2036 buflen= (uint)(longlong10_to_str(size, buf, 10) - buf);
2037 if (print(thd,
2038 PERFORMANCE_SCHEMA_str.str, PERFORMANCE_SCHEMA_str.length,
2039 name, strlen(name),
2040 buf, buflen))
2041 DBUG_RETURN(true);
2042 }
2043
2044 end:
2045 DBUG_RETURN(false);
2046 }
2047
2048 /** @} */
2049
2050