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 #ifndef PFS_INSTR_H
24 #define PFS_INSTR_H
25 
26 /**
27   @file storage/perfschema/pfs_instr.h
28   Performance schema instruments (declarations).
29 */
30 
31 struct PFS_mutex_class;
32 struct PFS_rwlock_class;
33 struct PFS_cond_class;
34 struct PFS_file_class;
35 struct PFS_table_share;
36 struct PFS_thread_class;
37 struct PFS_socket_class;
38 class PFS_opaque_container_page;
39 
40 class THD;
41 
42 #include "my_global.h"
43 #include "my_thread_os_id.h"
44 #ifdef _WIN32
45 #include <winsock2.h>
46 #endif
47 #ifdef HAVE_ARPA_INET_H
48 #include <arpa/inet.h>
49 #endif
50 #include "my_compiler.h"
51 #include "pfs_lock.h"
52 #include "pfs_stat.h"
53 #include "pfs_instr_class.h"
54 #include "pfs_events_waits.h"
55 #include "pfs_events_stages.h"
56 #include "pfs_events_statements.h"
57 #include "pfs_events_transactions.h"
58 #include "pfs_server.h"
59 #include "lf.h"
60 #include "pfs_con_slice.h"
61 #include "pfs_column_types.h"
62 #include "mdl.h"
63 #include "violite.h" /* enum_vio_type */
64 
65 extern PFS_single_stat *thread_instr_class_waits_array_start;
66 extern PFS_single_stat *thread_instr_class_waits_array_end;
67 extern my_bool show_compatibility_56;
68 
69 /**
70   @addtogroup Performance_schema_buffers
71   @{
72 */
73 
74 struct PFS_thread;
75 struct PFS_host;
76 struct PFS_user;
77 struct PFS_account;
78 
79 /** Base structure for wait instruments. */
80 struct PFS_instr
81 {
82   /** Internal lock. */
83   pfs_lock m_lock;
84   /** Enabled flag. */
85   bool m_enabled;
86   /** Timed flag. */
87   bool m_timed;
88   /** Container page. */
89   PFS_opaque_container_page *m_page;
90 };
91 
92 /** Instrumented mutex implementation. @see PSI_mutex. */
93 struct PFS_ALIGNED PFS_mutex : public PFS_instr
94 {
95   /** Mutex identity, typically a pthread_mutex_t. */
96   const void *m_identity;
97   /** Mutex class. */
98   PFS_mutex_class *m_class;
99   /** Instrument statistics. */
100   PFS_mutex_stat m_mutex_stat;
101   /** Current owner. */
102   PFS_thread *m_owner;
103   /**
104     Timestamp of the last lock.
105     This statistic is not exposed in user visible tables yet.
106   */
107   ulonglong m_last_locked;
108 };
109 
110 /** Instrumented rwlock implementation. @see PSI_rwlock. */
111 struct PFS_ALIGNED PFS_rwlock : public PFS_instr
112 {
113   /** RWLock identity, typically a pthread_rwlock_t. */
114   const void *m_identity;
115   /** RWLock class. */
116   PFS_rwlock_class *m_class;
117   /** Instrument statistics. */
118   PFS_rwlock_stat m_rwlock_stat;
119   /** Current writer thread. */
120   PFS_thread *m_writer;
121   /** Current count of readers. */
122   uint m_readers;
123   /**
124     Timestamp of the last write.
125     This statistic is not exposed in user visible tables yet.
126   */
127   ulonglong m_last_written;
128   /**
129     Timestamp of the last read.
130     This statistic is not exposed in user visible tables yet.
131   */
132   ulonglong m_last_read;
133 };
134 
135 /** Instrumented cond implementation. @see PSI_cond. */
136 struct PFS_ALIGNED PFS_cond : public PFS_instr
137 {
138   /** Condition identity, typically a pthread_cond_t. */
139   const void *m_identity;
140   /** Condition class. */
141   PFS_cond_class *m_class;
142   /** Condition instance usage statistics. */
143   PFS_cond_stat m_cond_stat;
144 };
145 
146 /** Instrumented File and FILE implementation. @see PSI_file. */
147 struct PFS_ALIGNED PFS_file : public PFS_instr
148 {
get_versionPFS_file149   uint32 get_version()
150   { return m_lock.get_version(); }
151 
152   /** File identity */
153   const void *m_identity;
154   /** File name. */
155   char m_filename[FN_REFLEN];
156   /** File name length in bytes. */
157   uint m_filename_length;
158   /** File class. */
159   PFS_file_class *m_class;
160   /** File usage statistics. */
161   PFS_file_stat m_file_stat;
162   /** True if a temporary file. */
163   bool m_temporary;
164 };
165 
166 /** Instrumented table implementation. @see PSI_table. */
167 struct PFS_ALIGNED PFS_table
168 {
169   /**
170     True if table io instrumentation is enabled.
171     This flag is computed.
172   */
173   bool m_io_enabled;
174   /**
175     True if table lock instrumentation is enabled.
176     This flag is computed.
177   */
178   bool m_lock_enabled;
179   /**
180     True if table io instrumentation is timed.
181     This flag is computed.
182   */
183   bool m_io_timed;
184   /**
185     True if table lock instrumentation is timed.
186     This flag is computed.
187   */
188   bool m_lock_timed;
189 
190   /** True if table io statistics have been collected. */
191   bool m_has_io_stats;
192 
193   /** True if table lock statistics have been collected. */
194   bool m_has_lock_stats;
195 
196 public:
197   /**
198     Aggregate this table handle statistics to the parents.
199     Only use this method for handles owned by the calling code.
200     @sa sanitized_aggregate.
201   */
aggregatePFS_table202   void aggregate(const TABLE_SHARE *server_share)
203   {
204     if (m_has_io_stats)
205     {
206       safe_aggregate_io(server_share, & m_table_stat, m_share);
207       m_has_io_stats= false;
208     }
209     if (m_has_lock_stats)
210     {
211       safe_aggregate_lock(& m_table_stat, m_share);
212       m_has_lock_stats= false;
213     }
214   }
215 
216   /**
217     Aggregate this table handle statistics to the parents.
218     This method is safe to call on handles not owned by the calling code.
219     @sa aggregate
220     @sa sanitized_aggregate_io
221     @sa sanitized_aggregate_lock
222   */
223   void sanitized_aggregate(void);
224 
225   /**
226     Aggregate this table handle io statistics to the parents.
227     This method is safe to call on handles not owned by the calling code.
228   */
229   void sanitized_aggregate_io(void);
230 
231   /**
232     Aggregate this table handle lock statistics to the parents.
233     This method is safe to call on handles not owned by the calling code.
234   */
235   void sanitized_aggregate_lock(void);
236 
237   /** Internal lock. */
238   pfs_lock m_lock;
239   /** Thread Owner. */
240   PFS_thread *m_thread_owner;
241   /** Event Owner. */
242   ulonglong m_owner_event_id;
243   /** Table share. */
244   PFS_table_share *m_share;
245   /** Table identity, typically a handler. */
246   const void *m_identity;
247   /** Table statistics. */
248   PFS_table_stat m_table_stat;
249   /** Current internal lock. */
250   PFS_TL_LOCK_TYPE m_internal_lock;
251   /** Current external lock. */
252   PFS_TL_LOCK_TYPE m_external_lock;
253   /** Container page. */
254   PFS_opaque_container_page *m_page;
255 
256 private:
257   static void safe_aggregate_io(const TABLE_SHARE *optional_server_share,
258                                 PFS_table_stat *stat,
259                                 PFS_table_share *safe_share);
260   static void safe_aggregate_lock(PFS_table_stat *stat,
261                                   PFS_table_share *safe_share);
262 };
263 
264 /** Instrumented socket implementation. @see PSI_socket. */
265 struct PFS_ALIGNED PFS_socket : public PFS_instr
266 {
get_versionPFS_socket267   uint32 get_version()
268   { return m_lock.get_version(); }
269 
270   /** Socket identity, typically int */
271   const void *m_identity;
272   /** Owning thread, if applicable */
273   PFS_thread *m_thread_owner;
274   /** Socket file descriptor */
275   uint m_fd;
276   /** Raw socket address */
277   struct sockaddr_storage  m_sock_addr;
278   /** Length of address */
279   socklen_t m_addr_len;
280   /** Idle flag. */
281   bool m_idle;
282   /** Socket class. */
283   PFS_socket_class *m_class;
284   /** Socket usage statistics. */
285   PFS_socket_stat m_socket_stat;
286 };
287 
288 /** Instrumented metadata lock implementation. @see PSI_metadata_lock. */
289 struct PFS_ALIGNED PFS_metadata_lock : public PFS_instr
290 {
get_versionPFS_metadata_lock291   uint32 get_version()
292   { return m_lock.get_version(); }
293 
294   /** Lock identity. */
295   const void *m_identity;
296   MDL_key m_mdl_key;
297   opaque_mdl_type m_mdl_type;
298   opaque_mdl_duration m_mdl_duration;
299   opaque_mdl_status m_mdl_status;
300   const char *m_src_file;
301   uint m_src_line;
302   ulonglong m_owner_thread_id;
303   ulonglong m_owner_event_id;
304 };
305 
306 /**
307   @def WAIT_STACK_LOGICAL_SIZE
308   Maximum number of nested waits.
309   Some waits, such as:
310   - "wait/io/table/sql/handler"
311   - "wait/lock/table/sql/handler"
312   are implemented by calling code in a storage engine,
313   that can cause nested waits (file io, mutex, ...)
314   Because of partitioned tables, a table io event (on the whole table)
315   can contain a nested table io event (on a partition).
316   Because of additional debug instrumentation,
317   waiting on what looks like a "mutex" (safe_mutex, innodb sync0sync, ...)
318   can cause nested waits to be recorded.
319   For example, a wait on innodb mutexes can lead to:
320   - wait/sync/mutex/innobase/some_mutex
321     - wait/sync/mutex/innobase/sync0sync
322       - wait/sync/mutex/innobase/os0sync
323   The max depth of the event stack must be sufficient
324   for these low level details to be visible.
325 */
326 #define WAIT_STACK_LOGICAL_SIZE 5
327 /**
328   @def WAIT_STACK_BOTTOM
329   Maximum number dummy waits records.
330   One dummy record is reserved for the parent stage / statement / transaction,
331   at the bottom of the wait stack.
332 */
333 #define WAIT_STACK_BOTTOM 1
334 /**
335   @def WAIT_STACK_SIZE
336   Physical size of the waits stack
337 */
338 #define WAIT_STACK_SIZE (WAIT_STACK_BOTTOM + WAIT_STACK_LOGICAL_SIZE)
339 
340 /** Max size of the statements stack. */
341 extern uint statement_stack_max;
342 /** Max size of the digests token array. */
343 extern size_t pfs_max_digest_length;
344 /** Max size of SQL TEXT. */
345 extern size_t pfs_max_sqltext;
346 
347 /** Instrumented thread implementation. @see PSI_thread. */
348 struct PFS_ALIGNED PFS_thread : PFS_connection_slice
349 {
350   static PFS_thread* get_current_thread(void);
351 
352   /** Thread instrumentation flag. */
353   bool m_enabled;
354   bool m_disable_instrumentation;
355   /** Thread history instrumentation flag. */
356   bool m_history;
357 
358   /**
359     Derived flag flag_events_waits_history, per thread.
360     Cached computation of
361       TABLE SETUP_CONSUMERS[EVENTS_WAITS_HISTORY].ENABLED == 'YES'
362     AND
363       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
364   */
365   bool m_flag_events_waits_history;
366   /**
367     Derived flag flag_events_waits_history_long, per thread.
368     Cached computation of
369       TABLE SETUP_CONSUMERS[EVENTS_WAITS_HISTORY_LONG].ENABLED == 'YES'
370     AND
371       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
372   */
373   bool m_flag_events_waits_history_long;
374   /**
375     Derived flag flag_events_stages_history, per thread.
376     Cached computation of
377       TABLE SETUP_CONSUMERS[EVENTS_STAGES_HISTORY].ENABLED == 'YES'
378     AND
379       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
380   */
381   bool m_flag_events_stages_history;
382   /**
383     Derived flag flag_events_stages_history_long, per thread.
384     Cached computation of
385       TABLE SETUP_CONSUMERS[EVENTS_STAGES_HISTORY_LONG].ENABLED == 'YES'
386     AND
387       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
388   */
389   bool m_flag_events_stages_history_long;
390   /**
391     Derived flag flag_events_statements_history, per thread.
392     Cached computation of
393       TABLE SETUP_CONSUMERS[EVENTS_STATEMENTS_HISTORY].ENABLED == 'YES'
394     AND
395       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
396   */
397   bool m_flag_events_statements_history;
398   /**
399     Derived flag flag_events_statements_history_long, per thread.
400     Cached computation of
401       TABLE SETUP_CONSUMERS[EVENTS_STATEMENTS_HISTORY_LONG].ENABLED == 'YES'
402     AND
403       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
404   */
405   bool m_flag_events_statements_history_long;
406   /**
407     Derived flag flag_events_transactions_history, per thread.
408     Cached computation of
409       TABLE SETUP_CONSUMERS[EVENTS_TRANSACTIONS_HISTORY].ENABLED == 'YES'
410     AND
411       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
412   */
413   bool m_flag_events_transactions_history;
414   /**
415     Derived flag flag_events_transactions_history_long, per thread.
416     Cached computation of
417       TABLE SETUP_CONSUMERS[EVENTS_TRANSACTIONS_HISTORY_LONG].ENABLED == 'YES'
418     AND
419       TABLE THREADS[THREAD_ID].HISTORY == 'YES'
420   */
421   bool m_flag_events_transactions_history_long;
422 
423   /** Current wait event in the event stack. */
424   PFS_events_waits *m_events_waits_current;
425   /** Event ID counter */
426   ulonglong m_event_id;
427   /**
428     Internal lock.
429     This lock is exclusively used to protect against races
430     when creating and destroying PFS_thread.
431     Do not use this lock to protect thread attributes,
432     use one of @c m_stmt_lock or @c m_session_lock instead.
433   */
434   pfs_lock m_lock;
435   /** Pins for filename_hash. */
436   LF_PINS *m_filename_hash_pins;
437   /** Pins for table_share_hash. */
438   LF_PINS *m_table_share_hash_pins;
439   /** Pins for setup_actor_hash. */
440   LF_PINS *m_setup_actor_hash_pins;
441   /** Pins for setup_object_hash. */
442   LF_PINS *m_setup_object_hash_pins;
443   /** Pins for host_hash. */
444   LF_PINS *m_host_hash_pins;
445   /** Pins for user_hash. */
446   LF_PINS *m_user_hash_pins;
447   /** Pins for account_hash. */
448   LF_PINS *m_account_hash_pins;
449   /** Pins for digest_hash. */
450   LF_PINS *m_digest_hash_pins;
451   /** Pins for routine_hash. */
452   LF_PINS *m_program_hash_pins;
453   /** Internal thread identifier, unique. */
454   ulonglong m_thread_internal_id;
455   /** Parent internal thread identifier. */
456   ulonglong m_parent_thread_internal_id;
457   /** External (SHOW PROCESSLIST) thread identifier, not unique. */
458   ulong m_processlist_id;
459   /** External (Operating system) thread identifier, if any. */
460   my_thread_os_id_t m_thread_os_id;
461   /** Thread class. */
462   PFS_thread_class *m_class;
463   /**
464     Stack of events waits.
465     This member holds the data for the table PERFORMANCE_SCHEMA.EVENTS_WAITS_CURRENT.
466     Note that stack[0] is a dummy record that represents the parent stage/statement/transaction.
467     For example, assuming the following tree:
468     - STAGE ID 100
469       - WAIT ID 101, parent STAGE 100
470         - WAIT ID 102, parent wait 101
471     the data in the stack will be:
472     stack[0].m_event_id= 100, set by the stage instrumentation
473     stack[0].m_event_type= STAGE, set by the stage instrumentation
474     stack[0].m_nesting_event_id= unused
475     stack[0].m_nesting_event_type= unused
476     stack[1].m_event_id= 101
477     stack[1].m_event_type= WAIT
478     stack[1].m_nesting_event_id= stack[0].m_event_id= 100
479     stack[1].m_nesting_event_type= stack[0].m_event_type= STAGE
480     stack[2].m_event_id= 102
481     stack[2].m_event_type= WAIT
482     stack[2].m_nesting_event_id= stack[1].m_event_id= 101
483     stack[2].m_nesting_event_type= stack[1].m_event_type= WAIT
484 
485     The whole point of the stack[0] record is to allow this optimization
486     in the code, in the instrumentation for wait events:
487       wait->m_nesting_event_id= (wait-1)->m_event_id;
488       wait->m_nesting_event_type= (wait-1)->m_event_type;
489     This code works for both the top level wait, and nested waits,
490     and works without if conditions, which helps performances.
491   */
492   PFS_events_waits m_events_waits_stack[WAIT_STACK_SIZE];
493   /** True if the circular buffer @c m_waits_history is full. */
494   bool m_waits_history_full;
495   /** Current index in the circular buffer @c m_waits_history. */
496   uint m_waits_history_index;
497   /**
498     Waits history circular buffer.
499     This member holds the data for the table
500     PERFORMANCE_SCHEMA.EVENTS_WAITS_HISTORY.
501   */
502   PFS_events_waits *m_waits_history;
503 
504   /** True if the circular buffer @c m_stages_history is full. */
505   bool m_stages_history_full;
506   /** Current index in the circular buffer @c m_stages_history. */
507   uint m_stages_history_index;
508   /**
509     Stages history circular buffer.
510     This member holds the data for the table
511     PERFORMANCE_SCHEMA.EVENTS_STAGES_HISTORY.
512   */
513   PFS_events_stages *m_stages_history;
514 
515   /** True if the circular buffer @c m_statements_history is full. */
516   bool m_statements_history_full;
517   /** Current index in the circular buffer @c m_statements_history. */
518   uint m_statements_history_index;
519   /**
520     Statements history circular buffer.
521     This member holds the data for the table
522     PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_HISTORY.
523   */
524   PFS_events_statements *m_statements_history;
525 
526   /** True if the circular buffer @c m_transactions_history is full. */
527   bool m_transactions_history_full;
528   /** Current index in the circular buffer @c m_transactions_history. */
529   uint m_transactions_history_index;
530   /**
531     Statements history circular buffer.
532     This member holds the data for the table
533     PERFORMANCE_SCHEMA.EVENTS_TRANSACTIONS_HISTORY.
534   */
535   PFS_events_transactions *m_transactions_history;
536 
537   /**
538     Internal lock, for session attributes.
539     Statement attributes are expected to be updated in frequently,
540     typically per session execution.
541   */
542   pfs_lock m_session_lock;
543 
544   /**
545     User name.
546     Protected by @c m_session_lock.
547   */
548   char m_username[USERNAME_LENGTH];
549   /**
550     Length of @c m_username.
551     Protected by @c m_session_lock.
552   */
553   uint m_username_length;
554   /**
555     Host name.
556     Protected by @c m_session_lock.
557   */
558   char m_hostname[HOSTNAME_LENGTH];
559   /**
560     Length of @c m_hostname.
561     Protected by @c m_session_lock.
562   */
563   uint m_hostname_length;
564   /**
565     Database name.
566     Protected by @c m_stmt_lock.
567   */
568   char m_dbname[NAME_LEN];
569   /**
570     Length of @c m_dbname.
571     Protected by @c m_stmt_lock.
572   */
573   uint m_dbname_length;
574   /** Current command. */
575   int m_command;
576   /** Connection type. */
577   enum_vio_type m_connection_type;
578   /** Start time. */
579   time_t m_start_time;
580   /**
581     Internal lock, for statement attributes.
582     Statement attributes are expected to be updated frequently,
583     typically per statement execution.
584   */
585   pfs_lock m_stmt_lock;
586   /** Processlist state (derived from stage). */
587   PFS_stage_key m_stage;
588   /** Current stage progress. */
589   PSI_stage_progress* m_stage_progress;
590   /**
591     Processlist info.
592     Protected by @c m_stmt_lock.
593   */
594   char m_processlist_info[COL_INFO_SIZE];
595   /**
596     Length of @c m_processlist_info_length.
597     Protected by @c m_stmt_lock.
598   */
599   uint m_processlist_info_length;
600 
601   PFS_events_stages m_stage_current;
602 
603   /** Size of @c m_events_statements_stack. */
604   uint m_events_statements_count;
605   PFS_events_statements *m_statement_stack;
606 
607   PFS_events_transactions m_transaction_current;
608 
609   THD *m_thd;
610   PFS_host *m_host;
611   PFS_user *m_user;
612   PFS_account *m_account;
613 
614   /** Reset session connect attributes */
615   void reset_session_connect_attrs();
616 
617   /**
618     Buffer for the connection attributes.
619     Protected by @c m_session_lock.
620   */
621   char *m_session_connect_attrs;
622   /**
623     Length used by @c m_connect_attrs.
624     Protected by @c m_session_lock.
625   */
626   uint m_session_connect_attrs_length;
627   /**
628     Character set in which @c m_connect_attrs are encoded.
629     Protected by @c m_session_lock.
630   */
631   uint m_session_connect_attrs_cs_number;
632 
633   void carry_memory_stat_delta(PFS_memory_stat_delta *delta, uint index);
634 
set_enabledPFS_thread635   void set_enabled(bool enabled)
636   {
637     m_enabled= enabled;
638   }
639 
set_historyPFS_thread640   void set_history(bool history)
641   {
642     m_history= history;
643     set_history_derived_flags();
644   }
645 
646   void set_history_derived_flags();
647 };
648 
649 void carry_global_memory_stat_delta(PFS_memory_stat_delta *delta, uint index);
650 
651 extern PFS_stage_stat *global_instr_class_stages_array;
652 extern PFS_statement_stat *global_instr_class_statements_array;
653 extern PFS_memory_stat *global_instr_class_memory_array;
654 
655 PFS_mutex *sanitize_mutex(PFS_mutex *unsafe);
656 PFS_rwlock *sanitize_rwlock(PFS_rwlock *unsafe);
657 PFS_cond *sanitize_cond(PFS_cond *unsafe);
658 PFS_thread *sanitize_thread(PFS_thread *unsafe);
659 PFS_file *sanitize_file(PFS_file *unsafe);
660 PFS_socket *sanitize_socket(PFS_socket *unsafe);
661 PFS_metadata_lock *sanitize_metadata_lock(PFS_metadata_lock *unsafe);
662 
663 int init_instruments(const PFS_global_param *param);
664 void cleanup_instruments();
665 int init_file_hash(const PFS_global_param *param);
666 void cleanup_file_hash();
667 PFS_mutex* create_mutex(PFS_mutex_class *mutex_class, const void *identity);
668 void destroy_mutex(PFS_mutex *pfs);
669 PFS_rwlock* create_rwlock(PFS_rwlock_class *klass, const void *identity);
670 void destroy_rwlock(PFS_rwlock *pfs);
671 PFS_cond* create_cond(PFS_cond_class *klass, const void *identity);
672 void destroy_cond(PFS_cond *pfs);
673 
674 PFS_thread* create_thread(PFS_thread_class *klass, const void *identity,
675                           ulonglong processlist_id);
676 
677 void destroy_thread(PFS_thread *pfs);
678 
679 PFS_file* find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
680                               const char *filename, uint len, bool create);
681 void find_and_rename_file(PFS_thread *thread, const char *old_filename,
682                           uint old_len, const char *new_filename,
683                           uint new_len);
684 
685 void release_file(PFS_file *pfs);
686 void destroy_file(PFS_thread *thread, PFS_file *pfs);
687 PFS_table* create_table(PFS_table_share *share, PFS_thread *opening_thread,
688                         const void *identity);
689 void destroy_table(PFS_table *pfs);
690 
691 PFS_socket* create_socket(PFS_socket_class *socket_class,
692                           const my_socket *fd,
693                           const struct sockaddr *addr,
694                           socklen_t addr_len);
695 void destroy_socket(PFS_socket *pfs);
696 
697 PFS_metadata_lock* create_metadata_lock(void *identity,
698                                         const MDL_key *mdl_key,
699                                         opaque_mdl_type mdl_type,
700                                         opaque_mdl_duration mdl_duration,
701                                         opaque_mdl_status mdl_status,
702                                         const char *src_file,
703                                         uint src_line);
704 void destroy_metadata_lock(PFS_metadata_lock *pfs);
705 
706 /* For iterators and show status. */
707 
708 extern long file_handle_max;
709 extern ulong file_handle_lost;
710 extern ulong events_waits_history_per_thread;
711 extern ulong events_stages_history_per_thread;
712 extern ulong events_statements_history_per_thread;
713 extern ulong events_transactions_history_per_thread;
714 extern ulong locker_lost;
715 extern ulong statement_lost;
716 extern ulong session_connect_attrs_lost;
717 extern ulong session_connect_attrs_size_per_thread;
718 
719 /* Exposing the data directly, for iterators. */
720 
721 extern PFS_file **file_handle_array;
722 
723 void reset_events_waits_by_instance();
724 void reset_file_instance_io();
725 void reset_socket_instance_io();
726 
727 void aggregate_all_event_names(PFS_single_stat *from_array,
728                                PFS_single_stat *to_array);
729 void aggregate_all_event_names(PFS_single_stat *from_array,
730                                PFS_single_stat *to_array_1,
731                                PFS_single_stat *to_array_2);
732 
733 void aggregate_all_stages(PFS_stage_stat *from_array,
734                           PFS_stage_stat *to_array);
735 void aggregate_all_stages(PFS_stage_stat *from_array,
736                           PFS_stage_stat *to_array_1,
737                           PFS_stage_stat *to_array_2);
738 
739 void aggregate_all_statements(PFS_statement_stat *from_array,
740                               PFS_statement_stat *to_array);
741 void aggregate_all_statements(PFS_statement_stat *from_array,
742                               PFS_statement_stat *to_array_1,
743                               PFS_statement_stat *to_array_2);
744 
745 void aggregate_all_transactions(PFS_transaction_stat *from_array,
746                                 PFS_transaction_stat *to_array);
747 void aggregate_all_transactions(PFS_transaction_stat *from_array,
748                                 PFS_transaction_stat *to_array_1,
749                                 PFS_transaction_stat *to_array_2);
750 
751 void aggregate_all_memory(bool alive,
752                           PFS_memory_stat *from_array,
753                           PFS_memory_stat *to_array);
754 void aggregate_all_memory(bool alive,
755                           PFS_memory_stat *from_array,
756                           PFS_memory_stat *to_array_1,
757                           PFS_memory_stat *to_array_2);
758 
759 void aggregate_thread(PFS_thread *thread,
760                       PFS_account *safe_account,
761                       PFS_user *safe_user,
762                       PFS_host *safe_host);
763 void aggregate_thread_waits(PFS_thread *thread,
764                             PFS_account *safe_account,
765                             PFS_user *safe_user,
766                             PFS_host *safe_host);
767 void aggregate_thread_stages(PFS_thread *thread,
768                              PFS_account *safe_account,
769                              PFS_user *safe_user,
770                              PFS_host *safe_host);
771 void aggregate_thread_statements(PFS_thread *thread,
772                                  PFS_account *safe_account,
773                                  PFS_user *safe_user,
774                                  PFS_host *safe_host);
775 void aggregate_thread_transactions(PFS_thread *thread,
776                                    PFS_account *safe_account,
777                                    PFS_user *safe_user,
778                                    PFS_host *safe_host);
779 
780 void aggregate_thread_memory(bool alive, PFS_thread *thread,
781                              PFS_account *safe_account,
782                              PFS_user *safe_user,
783                              PFS_host *safe_host);
784 
785 void aggregate_thread_status(PFS_thread *thread,
786                              PFS_account *safe_account,
787                              PFS_user *safe_user,
788                              PFS_host *safe_host);
789 
790 void clear_thread_account(PFS_thread *thread);
791 void set_thread_account(PFS_thread *thread);
792 
793 /** Update derived flags for all mutex instances. */
794 void update_mutex_derived_flags();
795 /** Update derived flags for all rwlock instances. */
796 void update_rwlock_derived_flags();
797 /** Update derived flags for all condition instances. */
798 void update_cond_derived_flags();
799 /** Update derived flags for all file handles. */
800 void update_file_derived_flags();
801 /** Update derived flags for all table handles. */
802 void update_table_derived_flags();
803 /** Update derived flags for all socket instances. */
804 void update_socket_derived_flags();
805 /** Update derived flags for all metadata instances. */
806 void update_metadata_derived_flags();
807 /** Update derived flags for all thread instances. */
808 void update_thread_derived_flags();
809 /** Update derived flags for all instruments. */
810 void update_instruments_derived_flags();
811 
812 extern LF_HASH filename_hash;
813 
814 /** @} */
815 #endif
816 
817