1/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software Foundation,
14 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15
16#ifndef PFS_INSTR_CLASS_H
17#define PFS_INSTR_CLASS_H
18
19#include "my_global.h"
20#include "mysql_com.h" /* NAME_LEN */
21#include "lf.h"
22#include "pfs_global.h"
23
24/**
25 @file storage/perfschema/pfs_instr_class.h
26 Performance schema instruments meta data (declarations).
27*/
28
29/**
30 Maximum length of an instrument name.
31 For example, 'wait/sync/mutex/sql/LOCK_open' is an instrument name.
32*/
33#define PFS_MAX_INFO_NAME_LENGTH 128
34
35/**
36 Maximum length of the 'full' prefix of an instrument name.
37 For example, for the instrument name 'wait/sync/mutex/sql/LOCK_open',
38 the full prefix is 'wait/sync/mutex/sql/', which in turn derives from
39 a prefix 'wait/sync/mutex' for mutexes, and a category of 'sql' for mutexes
40 of the sql layer in the server.
41*/
42#define PFS_MAX_FULL_PREFIX_NAME_LENGTH 32
43
44#include <my_global.h>
45#include <my_sys.h>
46#include <mysql/psi/psi.h>
47#include "pfs_lock.h"
48#include "pfs_stat.h"
49#include "pfs_column_types.h"
50
51struct PFS_global_param;
52
53/**
54 @addtogroup Performance_schema_buffers
55 @{
56*/
57
58extern my_bool pfs_enabled;
59extern enum_timer_name *class_timers[];
60
61/** Key, naming a synch instrument (mutex, rwlock, cond). */
62typedef unsigned int PFS_sync_key;
63/** Key, naming a thread instrument. */
64typedef unsigned int PFS_thread_key;
65/** Key, naming a file instrument. */
66typedef unsigned int PFS_file_key;
67/** Key, naming a stage instrument. */
68typedef unsigned int PFS_stage_key;
69/** Key, naming a statement instrument. */
70typedef unsigned int PFS_statement_key;
71/** Key, naming a socket instrument. */
72typedef unsigned int PFS_socket_key;
73
74enum PFS_class_type
75{
76 PFS_CLASS_NONE= 0,
77 PFS_CLASS_MUTEX= 1,
78 PFS_CLASS_RWLOCK= 2,
79 PFS_CLASS_COND= 3,
80 PFS_CLASS_FILE= 4,
81 PFS_CLASS_TABLE= 5,
82 PFS_CLASS_STAGE= 6,
83 PFS_CLASS_STATEMENT= 7,
84 PFS_CLASS_SOCKET= 8,
85 PFS_CLASS_TABLE_IO= 9,
86 PFS_CLASS_TABLE_LOCK= 10,
87 PFS_CLASS_IDLE= 11,
88 PFS_CLASS_LAST= PFS_CLASS_IDLE,
89 PFS_CLASS_MAX= PFS_CLASS_LAST + 1
90};
91
92/** User-defined instrument configuration. */
93struct PFS_instr_config
94{
95 /* Instrument name. */
96 char *m_name;
97 /* Name length. */
98 uint m_name_length;
99 /** Enabled flag. */
100 bool m_enabled;
101 /** Timed flag. */
102 bool m_timed;
103};
104
105extern DYNAMIC_ARRAY pfs_instr_config_array;
106extern int pfs_instr_config_state;
107
108static const int PFS_INSTR_CONFIG_NOT_INITIALIZED= 0;
109static const int PFS_INSTR_CONFIG_ALLOCATED= 1;
110static const int PFS_INSTR_CONFIG_DEALLOCATED= 2;
111
112struct PFS_thread;
113
114extern uint mutex_class_start;
115extern uint rwlock_class_start;
116extern uint cond_class_start;
117extern uint file_class_start;
118extern uint socket_class_start;
119extern uint wait_class_max;
120
121/** Information for all instrumentation. */
122struct PFS_instr_class
123{
124 /** Class type */
125 PFS_class_type m_type;
126 /** True if this instrument is enabled. */
127 bool m_enabled;
128 /** True if this instrument is timed. */
129 bool m_timed;
130 /** Instrument flags. */
131 int m_flags;
132 /**
133 Instrument name index.
134 Self index in:
135 - EVENTS_WAITS_SUMMARY_*_BY_EVENT_NAME for waits
136 - EVENTS_STAGES_SUMMARY_*_BY_EVENT_NAME for stages
137 - EVENTS_STATEMENTS_SUMMARY_*_BY_EVENT_NAME for statements
138 */
139 uint m_event_name_index;
140 /** Instrument name. */
141 char m_name[PFS_MAX_INFO_NAME_LENGTH];
142 /** Length in bytes of @c m_name. */
143 uint m_name_length;
144 /** Timer associated with this class. */
145 enum_timer_name *m_timer;
146
147 bool is_singleton() const
148 {
149 return m_flags & PSI_FLAG_GLOBAL;
150 }
151
152 bool is_mutable() const
153 {
154 return m_flags & PSI_FLAG_MUTABLE;
155 }
156
157 static void set_enabled(PFS_instr_class *pfs, bool enabled);
158 static void set_timed(PFS_instr_class *pfs, bool timed);
159
160 bool is_deferred() const
161 {
162 switch(m_type)
163 {
164 case PFS_CLASS_SOCKET:
165 return true;
166 break;
167 default:
168 return false;
169 break;
170 };
171 }
172};
173
174struct PFS_mutex;
175
176/** Instrumentation metadata for a MUTEX. */
177struct PFS_ALIGNED PFS_mutex_class : public PFS_instr_class
178{
179 /** Mutex usage statistics. */
180 PFS_mutex_stat m_mutex_stat;
181 /** Singleton instance. */
182 PFS_mutex *m_singleton;
183};
184
185struct PFS_rwlock;
186
187/** Instrumentation metadata for a RWLOCK. */
188struct PFS_ALIGNED PFS_rwlock_class : public PFS_instr_class
189{
190 /** Rwlock usage statistics. */
191 PFS_rwlock_stat m_rwlock_stat;
192 /** Singleton instance. */
193 PFS_rwlock *m_singleton;
194};
195
196struct PFS_cond;
197
198/** Instrumentation metadata for a COND. */
199struct PFS_ALIGNED PFS_cond_class : public PFS_instr_class
200{
201 /**
202 Condition usage statistics.
203 This statistic is not exposed in user visible tables yet.
204 */
205 PFS_cond_stat m_cond_stat;
206 /** Singleton instance. */
207 PFS_cond *m_singleton;
208};
209
210/** Instrumentation metadata of a thread. */
211struct PFS_ALIGNED PFS_thread_class
212{
213 /** True if this thread instrument is enabled. */
214 bool m_enabled;
215 /** Singleton instance. */
216 PFS_thread *m_singleton;
217 /** Thread instrument name. */
218 char m_name[PFS_MAX_INFO_NAME_LENGTH];
219 /** Length in bytes of @c m_name. */
220 uint m_name_length;
221};
222
223#define PFS_TABLESHARE_HASHKEY_SIZE (NAME_LEN + 1 + NAME_LEN + 1)
224
225/** Key identifying a table share. */
226struct PFS_table_share_key
227{
228 /**
229 Hash search key.
230 This has to be a string for LF_HASH,
231 the format is "<enum_object_type><schema_name><0x00><object_name><0x00>"
232 @see create_table_def_key
233 */
234 char m_hash_key[PFS_TABLESHARE_HASHKEY_SIZE];
235 /** Length in bytes of @c m_hash_key. */
236 uint m_key_length;
237};
238
239/** Table index or 'key' */
240struct PFS_table_key
241{
242 /** Index name */
243 char m_name[NAME_LEN];
244 /** Length in bytes of @c m_name. */
245 uint m_name_length;
246};
247
248/** Instrumentation metadata for a table share. */
249struct PFS_ALIGNED PFS_table_share
250{
251public:
252 uint32 get_version()
253 { return m_lock.get_version(); }
254
255 enum_object_type get_object_type()
256 {
257 return (enum_object_type) m_key.m_hash_key[0];
258 }
259
260 void aggregate_io(void);
261 void aggregate_lock(void);
262
263 inline void aggregate(void)
264 {
265 aggregate_io();
266 aggregate_lock();
267 }
268
269 inline void init_refcount(void)
270 {
271 PFS_atomic::store_32(& m_refcount, 1);
272 }
273
274 inline int get_refcount(void)
275 {
276 return PFS_atomic::load_32(& m_refcount);
277 }
278
279 inline void inc_refcount(void)
280 {
281 PFS_atomic::add_32(& m_refcount, 1);
282 }
283
284 inline void dec_refcount(void)
285 {
286 PFS_atomic::add_32(& m_refcount, -1);
287 }
288
289 void refresh_setup_object_flags(PFS_thread *thread);
290
291 /** Internal lock. */
292 pfs_lock m_lock;
293 /**
294 True if table instrumentation is enabled.
295 This flag is computed from the content of table setup_objects.
296 */
297 bool m_enabled;
298 /**
299 True if table instrumentation is timed.
300 This flag is computed from the content of table setup_objects.
301 */
302 bool m_timed;
303 /** Search key. */
304 PFS_table_share_key m_key;
305 /** Schema name. */
306 const char *m_schema_name;
307 /** Length in bytes of @c m_schema_name. */
308 uint m_schema_name_length;
309 /** Table name. */
310 const char *m_table_name;
311 /** Length in bytes of @c m_table_name. */
312 uint m_table_name_length;
313 /** Number of indexes. */
314 uint m_key_count;
315 /** Table statistics. */
316 PFS_table_stat m_table_stat;
317 /** Index names. */
318 PFS_table_key m_keys[MAX_INDEXES];
319
320private:
321 /** Number of opened table handles. */
322 int m_refcount;
323};
324
325/** Statistics for the IDLE instrument. */
326extern PFS_single_stat global_idle_stat;
327/** Statistics for dropped table io. */
328extern PFS_table_io_stat global_table_io_stat;
329/** Statistics for dropped table lock. */
330extern PFS_table_lock_stat global_table_lock_stat;
331
332inline uint sanitize_index_count(uint count)
333{
334 if (likely(count <= MAX_INDEXES))
335 return count;
336 return 0;
337}
338
339#define GLOBAL_TABLE_IO_EVENT_INDEX 0
340#define GLOBAL_TABLE_LOCK_EVENT_INDEX 1
341#define GLOBAL_IDLE_EVENT_INDEX 2
342
343/**
344 Instrument controlling all table io.
345 This instrument is used with table SETUP_OBJECTS.
346*/
347extern PFS_instr_class global_table_io_class;
348
349/**
350 Instrument controlling all table lock.
351 This instrument is used with table SETUP_OBJECTS.
352*/
353extern PFS_instr_class global_table_lock_class;
354
355/**
356 Instrument controlling all idle waits.
357*/
358extern PFS_instr_class global_idle_class;
359
360struct PFS_file;
361
362/** Instrumentation metadata for a file. */
363struct PFS_ALIGNED PFS_file_class : public PFS_instr_class
364{
365 /** File usage statistics. */
366 PFS_file_stat m_file_stat;
367 /** Singleton instance. */
368 PFS_file *m_singleton;
369};
370
371/** Instrumentation metadata for a stage. */
372struct PFS_ALIGNED PFS_stage_class : public PFS_instr_class
373{
374 /**
375 Length of the 'stage/<component>/' prefix.
376 This is to extract 'foo' from 'stage/sql/foo'.
377 */
378 uint m_prefix_length;
379 /** Stage usage statistics. */
380 PFS_stage_stat m_stage_stat;
381};
382
383/** Instrumentation metadata for a statement. */
384struct PFS_ALIGNED PFS_statement_class : public PFS_instr_class
385{
386};
387
388struct PFS_socket;
389
390/** Instrumentation metadata for a socket. */
391struct PFS_ALIGNED PFS_socket_class : public PFS_instr_class
392{
393 /** Socket usage statistics. */
394 PFS_socket_stat m_socket_stat;
395 /** Singleton instance. */
396 PFS_socket *m_singleton;
397};
398
399void init_event_name_sizing(const PFS_global_param *param);
400
401void register_global_classes();
402
403int init_sync_class(uint mutex_class_sizing,
404 uint rwlock_class_sizing,
405 uint cond_class_sizing);
406
407void cleanup_sync_class();
408int init_thread_class(uint thread_class_sizing);
409void cleanup_thread_class();
410int init_table_share(uint table_share_sizing);
411void cleanup_table_share();
412int init_table_share_hash();
413void cleanup_table_share_hash();
414int init_file_class(uint file_class_sizing);
415void cleanup_file_class();
416int init_stage_class(uint stage_class_sizing);
417void cleanup_stage_class();
418int init_statement_class(uint statement_class_sizing);
419void cleanup_statement_class();
420int init_socket_class(uint socket_class_sizing);
421void cleanup_socket_class();
422
423PFS_sync_key register_mutex_class(const char *name, uint name_length,
424 int flags);
425
426PFS_sync_key register_rwlock_class(const char *name, uint name_length,
427 int flags);
428
429PFS_sync_key register_cond_class(const char *name, uint name_length,
430 int flags);
431
432PFS_thread_key register_thread_class(const char *name, uint name_length,
433 int flags);
434
435PFS_file_key register_file_class(const char *name, uint name_length,
436 int flags);
437
438PFS_stage_key register_stage_class(const char *name,
439 uint prefix_length,
440 uint name_length,
441 int flags);
442
443PFS_statement_key register_statement_class(const char *name, uint name_length,
444 int flags);
445
446PFS_socket_key register_socket_class(const char *name, uint name_length,
447 int flags);
448
449PFS_mutex_class *find_mutex_class(PSI_mutex_key key);
450PFS_mutex_class *sanitize_mutex_class(PFS_mutex_class *unsafe);
451PFS_rwlock_class *find_rwlock_class(PSI_rwlock_key key);
452PFS_rwlock_class *sanitize_rwlock_class(PFS_rwlock_class *unsafe);
453PFS_cond_class *find_cond_class(PSI_cond_key key);
454PFS_cond_class *sanitize_cond_class(PFS_cond_class *unsafe);
455PFS_thread_class *find_thread_class(PSI_thread_key key);
456PFS_thread_class *sanitize_thread_class(PFS_thread_class *unsafe);
457PFS_file_class *find_file_class(PSI_file_key key);
458PFS_file_class *sanitize_file_class(PFS_file_class *unsafe);
459PFS_stage_class *find_stage_class(PSI_stage_key key);
460PFS_stage_class *sanitize_stage_class(PFS_stage_class *unsafe);
461PFS_statement_class *find_statement_class(PSI_statement_key key);
462PFS_statement_class *sanitize_statement_class(PFS_statement_class *unsafe);
463PFS_instr_class *find_table_class(uint index);
464PFS_instr_class *sanitize_table_class(PFS_instr_class *unsafe);
465PFS_socket_class *find_socket_class(PSI_socket_key key);
466PFS_socket_class *sanitize_socket_class(PFS_socket_class *unsafe);
467PFS_instr_class *find_idle_class(uint index);
468PFS_instr_class *sanitize_idle_class(PFS_instr_class *unsafe);
469
470PFS_table_share *find_or_create_table_share(PFS_thread *thread,
471 bool temporary,
472 const TABLE_SHARE *share);
473void release_table_share(PFS_table_share *pfs);
474void drop_table_share(PFS_thread *thread,
475 bool temporary,
476 const char *schema_name, uint schema_name_length,
477 const char *table_name, uint table_name_length);
478
479PFS_table_share *sanitize_table_share(PFS_table_share *unsafe);
480
481extern ulong mutex_class_max;
482extern ulong mutex_class_lost;
483extern ulong rwlock_class_max;
484extern ulong rwlock_class_lost;
485extern ulong cond_class_max;
486extern ulong cond_class_lost;
487extern ulong thread_class_max;
488extern ulong thread_class_lost;
489extern ulong file_class_max;
490extern ulong file_class_lost;
491extern ulong stage_class_max;
492extern ulong stage_class_lost;
493extern ulong statement_class_max;
494extern ulong statement_class_lost;
495extern ulong socket_class_max;
496extern ulong socket_class_lost;
497extern ulong table_share_max;
498extern ulong table_share_lost;
499
500/* Exposing the data directly, for iterators. */
501
502extern PFS_mutex_class *mutex_class_array;
503extern PFS_rwlock_class *rwlock_class_array;
504extern PFS_cond_class *cond_class_array;
505extern PFS_file_class *file_class_array;
506extern PFS_table_share *table_share_array;
507
508void reset_events_waits_by_class();
509void reset_file_class_io();
510void reset_socket_class_io();
511
512/** Update derived flags for all table shares. */
513void update_table_share_derived_flags(PFS_thread *thread);
514
515extern LF_HASH table_share_hash;
516
517/** @} */
518#endif
519
520