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