1 /* Copyright (c) 2015, 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
21   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22 
23 #ifndef PFS_VARIABLE_H
24 #define PFS_VARIABLE_H
25 
26 /**
27   @file storage/perfschema/pfs_variable.h
28   Performance schema system and status variables (declarations).
29 */
30 
31 /**
32   OVERVIEW
33   --------
34   Status and system variables are implemented differently in the server, but the
35   steps to process them in the Performance Schema are essentially the same:
36 
37   1. INITIALIZE - Build or acquire a sorted list of variables to use for input.
38      Use the SHOW_VAR struct as an intermediate format common to system, status
39      and user vars:
40 
41      SHOW_VAR
42        Name  - Text string
43        Value - Pointer to memory location, function, subarray structure
44        Type  - Scalar, function, or subarray
45        Scope - SESSION, GLOBAL, BOTH
46 
47      Steps:
48      - Register the server's internal buffer with the class. Acquire locks
49        if necessary, then scan the contents of the input buffer.
50      - For system variables, convert each element to SHOW_VAR format, store in
51        a temporary array.
52      - For status variables, copy existing global status array into a local
53        array that can be used without locks. Expand nested subarrays, indicated
54        by a type of SHOW_ARRAY.
55 
56   2. MATERIALIZE - Convert the list of SHOW_VAR variables to string format,
57      store in a local cache:
58      - Resolve each variable according to the type.
59      - Recursively process unexpanded nested arrays and callback functions.
60      - Aggregate values across threads for global status.
61      - Convert numeric values to a string.
62      - Prefix variable name with the plugin name.
63 
64   3. OUTPUT - Iterate the cache for the SHOW command or table query.
65 
66   CLASS OVERVIEW
67   --------------
68   1. System_variable - A materialized system variable
69   2. Status_variable - A materialized status variable
70   3. PFS_variable_cache - Base class that defines the interface for the operations above.
71      public
72        init_show_var_array() - Build SHOW_VAR list of variables for processing
73        materialize_global()  - Materialize global variables, aggregate across sessions
74        materialize_session() - Materialize variables for a given PFS_thread or THD
75        materialize_user()    - Materialize variables for a user, aggregate across related threads.
76        materialize_host()    - Materialize variables for a host, aggregate across related threads.
77        materialize_account() - Materialize variables for a account, aggregate across related threads.
78      private
79        m_show_var_array         - Prealloc_array of SHOW_VARs for input to Materialize
80        m_cache                  - Prealloc_array of materialized variables for output
81        do_materialize_global()  - Implementation of materialize_global()
82        do_materialize_session() - Implementation of materialize_session()
83        do_materialize_client()  - Implementation of materialize_user/host/account()
84 
85   4. PFS_system_variable_cache - System variable implementation of PFS_variable_cache
86   5. PFS_status_variable_cache - Status variable implementation of PFS_variable_cache
87   6. Find_THD_variable         - Used by the thread manager to find and lock a THD.
88 
89   GLOSSARY
90   --------
91   Status variable - Server or plugin status counter. Not dynamic.
92   System variable - Server or plugin configuration variable. Usually dynamic.
93   GLOBAL scope    - Associated with the server, no context at thread level.
94   SESSION scope   - Associated with a connection or thread, but no global context.
95   BOTH scope      - Globally defined but applies at the session level.
96   Initialize      - Build list of variables in SHOW_VAR format.
97   Materialize     - Convert variables in SHOW_VAR list to string, cache for output.
98   Manifest        - Substep of Materialize. Resolve variable values according to
99                     type. This includes SHOW_FUNC types which are resolved by
100                     executing a callback function (possibly recursively), and
101                     SHOW_ARRAY types that expand into nested subarrays.
102   LOCK PRIORITIES
103   ---------------
104   System Variables
105     LOCK_plugin_delete              (block plugin delete)
106      LOCK_system_variables_hash
107      LOCK_thd_data                  (block THD delete)
108      LOCK_thd_sysvar                (block system variable updates, alloc_and_copy_thd_dynamic_variables)
109        LOCK_global_system_variables (very briefly held)
110 
111   Status Variables
112     LOCK_status
113       LOCK_thd_data                 (block THD delete)
114 */
115 
116 /* Iteration on THD from the sql layer. */
117 #include "mysqld_thd_manager.h"
118 #define PFS_VAR
119 /* Class sys_var */
120 #include "set_var.h"
121 /* convert_value_to_string */
122 #include "sql_show.h"
123 /* PFS_thread */
124 #include "pfs_instr.h"
125 #include "pfs_user.h"
126 #include "pfs_host.h"
127 #include "pfs_account.h"
128 
129 /* Global array of all server and plugin-defined status variables. */
130 extern Status_var_array all_status_vars;
131 extern bool status_vars_inited;
132 static const uint SYSVAR_MEMROOT_BLOCK_SIZE = 4096;
133 
134 extern mysql_mutex_t LOCK_plugin_delete;
135 
136 class Find_THD_Impl;
137 class Find_THD_variable;
138 typedef PFS_connection_slice PFS_client;
139 
140 /**
141   CLASS System_variable - System variable derived from sys_var object.
142 */
143 class System_variable
144 {
145 public:
146   System_variable();
147   System_variable(THD *target_thd, const SHOW_VAR *show_var,
148                   enum_var_type query_scope, bool ignore);
~System_variable()149   ~System_variable() {}
150 
is_null()151   bool is_null() const { return !m_initialized; }
is_ignored()152   bool is_ignored() const { return m_ignore; }
153 
154 public:
155   const char *m_name;
156   size_t m_name_length;
157   char m_value_str[SHOW_VAR_FUNC_BUFF_SIZE+1];
158   size_t m_value_length;
159   enum_mysql_show_type m_type;
160   int m_scope;
161   bool m_ignore;
162   const CHARSET_INFO *m_charset;
163 
164 private:
165   bool m_initialized;
166   void init(THD *thd, const SHOW_VAR *show_var, enum_var_type query_scope);
167 };
168 
169 
170 /**
171   CLASS Status_variable - Status variable derived from SHOW_VAR.
172 */
173 class Status_variable
174 {
175 public:
Status_variable()176   Status_variable() : m_name(NULL), m_name_length(0), m_value_length(0),
177                       m_type(SHOW_UNDEF), m_scope(SHOW_SCOPE_UNDEF),
178                       m_charset(NULL), m_initialized(false) {}
179 
180   Status_variable(const SHOW_VAR *show_var, STATUS_VAR *status_array, enum_var_type query_scope);
181 
~Status_variable()182   ~Status_variable() {}
183 
is_null()184   bool is_null() const {return !m_initialized;};
185 
186 public:
187   const char *m_name;
188   size_t m_name_length;
189   char m_value_str[SHOW_VAR_FUNC_BUFF_SIZE+1];
190   size_t m_value_length;
191   SHOW_TYPE  m_type;
192   SHOW_SCOPE m_scope;
193   const CHARSET_INFO *m_charset;
194 private:
195   bool m_initialized;
196   void init(const SHOW_VAR *show_var, STATUS_VAR *status_array, enum_var_type query_scope);
197 };
198 
199 
200 /**
201   CLASS Find_THD_variable - Get and lock a validated THD from the thread manager.
202 */
203 class Find_THD_variable : public Find_THD_Impl
204 {
205 public:
Find_THD_variable()206   Find_THD_variable() : m_unsafe_thd(NULL) {}
Find_THD_variable(THD * unsafe_thd)207   Find_THD_variable(THD *unsafe_thd) : m_unsafe_thd(unsafe_thd) {}
208 
operator()209   virtual bool operator()(THD *thd)
210   {
211     //TODO: filter bg threads?
212     if (thd != m_unsafe_thd)
213       return false;
214 
215     /* Hold this lock to keep THD during materialization. */
216     mysql_mutex_lock(&thd->LOCK_thd_data);
217     return true;
218   }
set_unsafe_thd(THD * unsafe_thd)219   void set_unsafe_thd(THD *unsafe_thd) { m_unsafe_thd= unsafe_thd; }
220 private:
221   THD *m_unsafe_thd;
222 };
223 
224 /**
225   CLASS PFS_variable_cache - Base class for a system or status variable cache.
226 */
227 template <class Var_type>
228 class PFS_variable_cache
229 {
230 public:
231   typedef Prealloced_array<Var_type, SHOW_VAR_PREALLOC, false> Variable_array;
232 
PFS_variable_cache(bool external_init)233   PFS_variable_cache(bool external_init)
234     : m_safe_thd(NULL),
235       m_unsafe_thd(NULL),
236       m_current_thd(current_thd),
237       m_pfs_thread(NULL),
238       m_pfs_client(NULL),
239       m_thd_finder(),
240       m_cache(PSI_INSTRUMENT_ME),
241       m_initialized(false),
242       m_external_init(external_init),
243       m_materialized(false),
244       m_show_var_array(PSI_INSTRUMENT_ME),
245       m_version(0),
246       m_query_scope(OPT_DEFAULT),
247       m_use_mem_root(false),
248       m_aggregate(false)
249   { }
250 
251   virtual ~PFS_variable_cache()= 0;
252 
253   /**
254     Build array of SHOW_VARs from the external variable source.
255     Filter using session scope.
256   */
257   bool initialize_session(void);
258 
259   /**
260     Build array of SHOW_VARs suitable for aggregation by user, host or account.
261     Filter using session scope.
262   */
263   bool initialize_client_session(void);
264 
265   /**
266     Build cache of GLOBAL system or status variables.
267     Aggregate across threads if applicable.
268   */
269   int materialize_global();
270 
271   /**
272     Build cache of GLOBAL and SESSION variables for a non-instrumented thread.
273   */
274   int materialize_all(THD *thd);
275 
276   /**
277     Build cache of SESSION variables for a non-instrumented thread.
278   */
279   int materialize_session(THD *thd);
280 
281   /**
282     Build cache of SESSION variables for an instrumented thread.
283   */
284   int materialize_session(PFS_thread *pfs_thread, bool use_mem_root= false);
285 
286   /**
287     Cache a single SESSION variable for an instrumented thread.
288   */
289   int materialize_session(PFS_thread *pfs_thread, uint index);
290 
291   /**
292     Build cache of SESSION status variables for a user.
293   */
294   int materialize_user(PFS_user *pfs_user);
295 
296   /**
297     Build cache of SESSION status variables for a host.
298   */
299   int materialize_host(PFS_host *pfs_host);
300 
301   /**
302     Build cache of SESSION status variables for an account.
303   */
304   int materialize_account(PFS_account *pfs_account);
305 
306   /**
307     True if variables have been materialized.
308   */
is_materialized(void)309   bool is_materialized(void)
310   {
311     return m_materialized;
312   }
313 
314   /**
315     True if variables have been materialized for given THD.
316   */
is_materialized(THD * unsafe_thd)317   bool is_materialized(THD *unsafe_thd)
318   {
319     return (unsafe_thd == m_unsafe_thd && m_materialized);
320   }
321 
322   /**
323     True if variables have been materialized for given PFS_thread.
324   */
is_materialized(PFS_thread * pfs_thread)325   bool is_materialized(PFS_thread *pfs_thread)
326   {
327     return (pfs_thread == m_pfs_thread && m_materialized);
328   }
329 
330   /**
331     True if variables have been materialized for given PFS_user.
332   */
is_materialized(PFS_user * pfs_user)333   bool is_materialized(PFS_user *pfs_user)
334   {
335     return (static_cast<PFS_client *>(pfs_user) == m_pfs_client && m_materialized);
336   }
337 
338   /**
339     True if variables have been materialized for given PFS_host.
340   */
is_materialized(PFS_host * pfs_host)341   bool is_materialized(PFS_host *pfs_host)
342   {
343     return (static_cast<PFS_client *>(pfs_host) == m_pfs_client && m_materialized);
344   }
345 
346   /**
347     True if variables have been materialized for given PFS_account.
348   */
is_materialized(PFS_account * pfs_account)349   bool is_materialized(PFS_account *pfs_account)
350   {
351     return (static_cast<PFS_client *>(pfs_account) == m_pfs_client && m_materialized);
352   }
353 
354   /**
355     True if variables have been materialized for given PFS_user/host/account.
356   */
is_materialized(PFS_client * pfs_client)357   bool is_materialized(PFS_client *pfs_client)
358   {
359     return (static_cast<PFS_client *>(pfs_client) == m_pfs_client && m_materialized);
360   }
361 
362   /**
363     Get a validated THD from the thread manager. Execute callback function while
364     inside of the thread manager locks.
365   */
366   THD *get_THD(THD *thd);
367   THD *get_THD(PFS_thread *pfs_thread);
368 
369   /**
370     Get a single variable from the cache.
371     Get the first element in the cache by default.
372   */
373   const Var_type *get(uint index= 0) const
374   {
375     if (index >= m_cache.size())
376       return NULL;
377 
378     const Var_type *p= &m_cache.at(index);
379     return p;
380   }
381 
382   /**
383     Number of elements in the cache.
384   */
size()385   uint size()
386   {
387     return (uint)m_cache.size();
388   }
389 
390 private:
do_initialize_global(void)391   virtual bool do_initialize_global(void) { return true; }
do_initialize_session(void)392   virtual bool do_initialize_session(void) { return true; }
do_materialize_global(void)393   virtual int do_materialize_global(void) { return 1; }
do_materialize_all(THD * thd)394   virtual int do_materialize_all(THD *thd) { return 1; }
do_materialize_session(THD * thd)395   virtual int do_materialize_session(THD *thd) { return 1; }
do_materialize_session(PFS_thread *)396   virtual int do_materialize_session(PFS_thread *) { return 1; }
do_materialize_session(PFS_thread *,uint index)397   virtual int do_materialize_session(PFS_thread *, uint index) { return 1; }
398 
399 protected:
400   /* Validated THD */
401   THD *m_safe_thd;
402 
403   /* Unvalidated THD */
404   THD *m_unsafe_thd;
405 
406   /* Current THD */
407   THD *m_current_thd;
408 
409   /* Current PFS_thread. */
410   PFS_thread *m_pfs_thread;
411 
412   /* Current PFS_user, host or account. */
413   PFS_client *m_pfs_client;
414 
415   /* Callback for thread iterator. */
416   Find_THD_variable m_thd_finder;
417 
418   /* Cache of materialized variables. */
419   Variable_array m_cache;
420 
421   /* True when list of SHOW_VAR is complete. */
422   bool m_initialized;
423 
424   /*
425     True if the SHOW_VAR array must be initialized externally from the
426     materialization step, such as with aggregations and queries by thread.
427   */
428   bool m_external_init;
429 
430   /* True when cache is complete. */
431   bool m_materialized;
432 
433   /* Array of variables to be materialized. Last element must be null. */
434   Show_var_array m_show_var_array;
435 
436   /* Version of global hash/array. Changes when vars added/removed. */
437   ulonglong m_version;
438 
439   /* Query scope: GLOBAL or SESSION. */
440   enum_var_type m_query_scope;
441 
442   /* True if temporary mem_root should be used for materialization. */
443   bool m_use_mem_root;
444 
445   /* True if summarizing across users, hosts or accounts. */
446   bool m_aggregate;
447 
448 };
449 
450 /**
451   Required implementation for pure virtual destructor of a template class.
452 */
453 template <class Var_type>
~PFS_variable_cache()454 PFS_variable_cache<Var_type>::~PFS_variable_cache()
455 {
456 }
457 
458 /**
459   Get a validated THD from the thread manager. Execute callback function while
460   while inside the thread manager lock.
461 */
462 template <class Var_type>
get_THD(THD * unsafe_thd)463 THD *PFS_variable_cache<Var_type>::get_THD(THD *unsafe_thd)
464 {
465   if (unsafe_thd == NULL)
466   {
467     /*
468       May happen, precisely because the pointer is unsafe
469       (THD just disconnected for example).
470       No need to walk Global_THD_manager for that.
471     */
472     return NULL;
473   }
474 
475   m_thd_finder.set_unsafe_thd(unsafe_thd);
476   THD* safe_thd= Global_THD_manager::get_instance()->find_thd(&m_thd_finder);
477   return safe_thd;
478 }
479 
480 template <class Var_type>
get_THD(PFS_thread * pfs_thread)481 THD *PFS_variable_cache<Var_type>::get_THD(PFS_thread *pfs_thread)
482 {
483   assert(pfs_thread != NULL);
484   return get_THD(pfs_thread->m_thd);
485 }
486 
487 /**
488   Build array of SHOW_VARs from external source of system or status variables.
489   Filter using session scope.
490 */
491 template <class Var_type>
initialize_session(void)492 bool PFS_variable_cache<Var_type>::initialize_session(void)
493 {
494   if (m_initialized)
495     return 0;
496 
497   return do_initialize_session();
498 }
499 
500 /**
501   Build array of SHOW_VARs suitable for aggregation by user, host or account.
502   Filter using session scope.
503 */
504 template <class Var_type>
initialize_client_session(void)505 bool PFS_variable_cache<Var_type>::initialize_client_session(void)
506 {
507   if (m_initialized)
508     return 0;
509 
510   /* Requires aggregation by user, host or account. */
511   m_aggregate= true;
512 
513   return do_initialize_session();
514 }
515 
516 /**
517   Build cache of all GLOBAL variables.
518 */
519 template <class Var_type>
materialize_global()520 int PFS_variable_cache<Var_type>::materialize_global()
521 {
522   if (is_materialized())
523     return 0;
524 
525   return do_materialize_global();
526 }
527 
528 /**
529   Build cache of GLOBAL and SESSION variables for a non-instrumented thread.
530 */
531 template <class Var_type>
materialize_all(THD * unsafe_thd)532 int PFS_variable_cache<Var_type>::materialize_all(THD *unsafe_thd)
533 {
534   if (!unsafe_thd)
535     return 1;
536 
537   if (is_materialized(unsafe_thd))
538     return 0;
539 
540   return do_materialize_all(unsafe_thd);
541 }
542 
543 /**
544   Build cache of SESSION variables for a non-instrumented thread.
545 */
546 template <class Var_type>
materialize_session(THD * unsafe_thd)547 int PFS_variable_cache<Var_type>::materialize_session(THD *unsafe_thd)
548 {
549   if (!unsafe_thd)
550     return 1;
551 
552   if (is_materialized(unsafe_thd))
553     return 0;
554 
555   return do_materialize_session(unsafe_thd);
556 }
557 
558 /**
559   Build cache of SESSION variables for a thread.
560 */
561 template <class Var_type>
materialize_session(PFS_thread * pfs_thread,bool use_mem_root)562 int PFS_variable_cache<Var_type>::materialize_session(PFS_thread *pfs_thread, bool use_mem_root)
563 {
564   if (!pfs_thread)
565     return 1;
566 
567   if (is_materialized(pfs_thread))
568     return 0;
569 
570   if (!pfs_thread->m_lock.is_populated() || pfs_thread->m_thd == NULL)
571     return 1;
572 
573   m_use_mem_root= use_mem_root;
574 
575   return do_materialize_session(pfs_thread);
576 }
577 
578 /**
579   Materialize a single variable for a thread.
580 */
581 template <class Var_type>
materialize_session(PFS_thread * pfs_thread,uint index)582 int PFS_variable_cache<Var_type>::materialize_session(PFS_thread *pfs_thread, uint index)
583 {
584   /* No check for is_materialized(). */
585 
586   if (!pfs_thread)
587     return 1;
588 
589   if (!pfs_thread->m_lock.is_populated() || pfs_thread->m_thd == NULL)
590     return 1;
591 
592   return do_materialize_session(pfs_thread, index);
593 }
594 
595 /**
596   CLASS PFS_system_variable_cache - System variable cache.
597 */
598 class PFS_system_variable_cache : public PFS_variable_cache<System_variable>
599 {
600 public:
PFS_system_variable_cache(bool external_init)601   PFS_system_variable_cache(bool external_init) :
602                             PFS_variable_cache<System_variable>(external_init),
603                             m_mem_thd(NULL), m_mem_thd_save(NULL),
604                             m_mem_sysvar_ptr(NULL) { }
605   bool match_scope(int scope);
get_sysvar_hash_version(void)606   ulonglong get_sysvar_hash_version(void) { return m_version; }
~PFS_system_variable_cache()607   ~PFS_system_variable_cache() { free_mem_root(); }
608 
609 private:
610   /* Build SHOW_var array. */
611   bool init_show_var_array(enum_var_type scope, bool strict);
612   bool do_initialize_session(void);
613 
614   /* Global */
615   int do_materialize_global(void);
616   /* Global and Session - THD */
617   int do_materialize_all(THD* thd);
618   /* Session - THD */
619   int do_materialize_session(THD* thd);
620   /* Session -  PFS_thread */
621   int do_materialize_session(PFS_thread *thread);
622   /* Single variable -  PFS_thread */
623   int do_materialize_session(PFS_thread *pfs_thread, uint index);
624 
625   /* Temporary mem_root to use for materialization. */
626   MEM_ROOT m_mem_sysvar;
627   /* Pointer to THD::mem_root. */
628   MEM_ROOT **m_mem_thd;
629   /* Save THD::mem_root. */
630   MEM_ROOT *m_mem_thd_save;
631   /* Pointer to temporary mem_root. */
632   MEM_ROOT *m_mem_sysvar_ptr;
633   /* Allocate and/or assign temporary mem_root. */
634   void set_mem_root(void);
635   /* Mark all memory blocks as free in temporary mem_root. */
636   void clear_mem_root(void);
637   /* Free mem_root memory. */
638   void free_mem_root(void);
639 };
640 
641 
642 /**
643   CLASS PFS_status_variable_cache - Status variable cache
644 */
645 class PFS_status_variable_cache : public PFS_variable_cache<Status_variable>
646 {
647 public:
648   PFS_status_variable_cache(bool external_init);
649 
650   int materialize_user(PFS_user *pfs_user);
651   int materialize_host(PFS_host *pfs_host);
652   int materialize_account(PFS_account *pfs_account);
653 
get_status_array_version(void)654   ulonglong get_status_array_version(void) { return m_version; }
655 
656 protected:
657   /* Get PFS_user, account or host associated with a PFS_thread. Implemented by table class. */
get_pfs(PFS_thread * pfs_thread)658   virtual PFS_client *get_pfs(PFS_thread *pfs_thread) { return NULL; }
659 
660   /* True if query is a SHOW command. */
661   bool m_show_command;
662 
663 private:
664   bool do_initialize_session(void);
665 
666   int do_materialize_global(void);
667   /* Global and Session - THD */
668   int do_materialize_all(THD* thd);
669   int do_materialize_session(THD *thd);
670   int do_materialize_session(PFS_thread *thread);
do_materialize_session(PFS_thread * thread,uint index)671   int do_materialize_session(PFS_thread *thread, uint index) { return 0; }
672   int do_materialize_client(PFS_client *pfs_client);
673 
674   /* Callback to sum user, host or account status variables. */
675   void (*m_sum_client_status)(PFS_client *pfs_client, STATUS_VAR *status_totals);
676 
677   /* Build SHOW_VAR array from external source. */
678   bool init_show_var_array(enum_var_type scope, bool strict);
679 
680   /* Recursively expand nested SHOW_VAR arrays. */
681   void expand_show_var_array(const SHOW_VAR *show_var_array, const char *prefix, bool strict);
682 
683   /* Exclude unwanted variables from the query. */
684   bool filter_show_var(const SHOW_VAR *show_var, bool strict);
685 
686   /* Check the variable scope against the query scope. */
687   bool match_scope(SHOW_SCOPE variable_scope, bool strict);
688 
689   /* Exclude specific status variables by name or prefix. */
690   bool filter_by_name(const SHOW_VAR *show_var);
691 
692   /* Check if a variable has an aggregatable type. */
693   bool can_aggregate(enum_mysql_show_type variable_type);
694 
695   /* Build status variable name with prefix. Return in the buffer provided. */
696   char *make_show_var_name(const char* prefix, const char* name, char *name_buf, size_t buf_len);
697 
698   /* Build status variable name with prefix. Return copy of the string. */
699   char *make_show_var_name(const char* prefix, const char* name);
700 
701   /* For the current THD, use initial_status_vars taken from before the query start. */
702   STATUS_VAR *set_status_vars(void);
703 
704   /* Build the list of status variables from SHOW_VAR array. */
705   void manifest(THD *thd, const SHOW_VAR *show_var_array,
706                 STATUS_VAR *status_var_array, const char *prefix, bool nested_array, bool strict);
707 };
708 
709 /* Callback functions to sum status variables for a given user, host or account. */
710 void sum_user_status(PFS_client *pfs_user, STATUS_VAR *status_totals);
711 void sum_host_status(PFS_client *pfs_host, STATUS_VAR *status_totals);
712 void sum_account_status(PFS_client *pfs_account, STATUS_VAR *status_totals);
713 
714 
715 /** @} */
716 #endif
717 
718