Drizzled Public API Documentation

sync0sync.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
4 Copyright (C) 2008, Google Inc.
5 
6 Portions of this file contain modifications contributed and copyrighted by
7 Google, Inc. Those modifications are gratefully acknowledged and are described
8 briefly in the InnoDB documentation. The contributions by Google are
9 incorporated with their permission, and subject to the conditions contained in
10 the file COPYING.Google.
11 
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free Software
14 Foundation; version 2 of the License.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22 St, Fifth Floor, Boston, MA 02110-1301 USA
23 
24 *****************************************************************************/
25 
26 /**************************************************/
33 #pragma once
34 #ifndef sync0sync_h
35 #define sync0sync_h
36 
37 #include "univ.i"
38 #include "sync0types.h"
39 #include "ut0lst.h"
40 #include "ut0mem.h"
41 #include "os0thread.h"
42 #include "os0sync.h"
43 #include "sync0arr.h"
44 
45 #if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP)
46 extern my_bool timed_mutexes;
47 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
48 
49 #ifdef HAVE_WINDOWS_ATOMICS
50 typedef LONG lock_word_t;
52 #else
53 typedef byte lock_word_t;
54 #endif
55 
56 #if defined UNIV_PFS_MUTEX || defined UNIV_PFS_RWLOCK
57 /* There are mutexes/rwlocks that we want to exclude from
58 instrumentation even if their corresponding performance schema
59 define is set. And this PFS_NOT_INSTRUMENTED is used
60 as the key value to dentify those objects that would
61 be excluded from instrumentation. */
62 # define PFS_NOT_INSTRUMENTED ULINT32_UNDEFINED
63 
64 # define PFS_IS_INSTRUMENTED(key) ((key) != PFS_NOT_INSTRUMENTED)
65 
66 /* By default, buffer mutexes and rwlocks will be excluded from
67 instrumentation due to their large number of instances. */
68 # define PFS_SKIP_BUFFER_MUTEX_RWLOCK
69 
70 #endif /* UNIV_PFS_MUTEX || UNIV_PFS_RWLOCK */
71 
72 #ifdef UNIV_PFS_MUTEX
73 /* Key defines to register InnoDB mutexes with performance schema */
74 extern mysql_pfs_key_t autoinc_mutex_key;
75 extern mysql_pfs_key_t btr_search_enabled_mutex_key;
76 extern mysql_pfs_key_t buffer_block_mutex_key;
77 extern mysql_pfs_key_t buf_pool_mutex_key;
78 extern mysql_pfs_key_t buf_pool_zip_mutex_key;
79 extern mysql_pfs_key_t cache_last_read_mutex_key;
80 extern mysql_pfs_key_t dict_foreign_err_mutex_key;
81 extern mysql_pfs_key_t dict_sys_mutex_key;
82 extern mysql_pfs_key_t file_format_max_mutex_key;
83 extern mysql_pfs_key_t fil_system_mutex_key;
84 extern mysql_pfs_key_t flush_list_mutex_key;
85 extern mysql_pfs_key_t hash_table_mutex_key;
86 extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
87 extern mysql_pfs_key_t ibuf_mutex_key;
88 extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
89 extern mysql_pfs_key_t log_sys_mutex_key;
90 extern mysql_pfs_key_t log_flush_order_mutex_key;
91 extern mysql_pfs_key_t kernel_mutex_key;
92 extern mysql_pfs_key_t commit_id_mutex_key;
93 # ifdef UNIV_MEM_DEBUG
94 extern mysql_pfs_key_t mem_hash_mutex_key;
95 # endif /* UNIV_MEM_DEBUG */
96 extern mysql_pfs_key_t mem_pool_mutex_key;
97 extern mysql_pfs_key_t mutex_list_mutex_key;
98 extern mysql_pfs_key_t purge_sys_mutex_key;
99 extern mysql_pfs_key_t recv_sys_mutex_key;
100 extern mysql_pfs_key_t rseg_mutex_key;
101 # ifdef UNIV_SYNC_DEBUG
102 extern mysql_pfs_key_t rw_lock_debug_mutex_key;
103 # endif /* UNIV_SYNC_DEBUG */
104 extern mysql_pfs_key_t rw_lock_list_mutex_key;
105 extern mysql_pfs_key_t rw_lock_mutex_key;
106 extern mysql_pfs_key_t srv_dict_tmpfile_mutex_key;
107 extern mysql_pfs_key_t srv_innodb_monitor_mutex_key;
108 extern mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
109 extern mysql_pfs_key_t srv_monitor_file_mutex_key;
110 extern mysql_pfs_key_t syn_arr_mutex_key;
111 # ifdef UNIV_SYNC_DEBUG
112 extern mysql_pfs_key_t sync_thread_mutex_key;
113 # endif /* UNIV_SYNC_DEBUG */
114 extern mysql_pfs_key_t trx_doublewrite_mutex_key;
115 extern mysql_pfs_key_t thr_local_mutex_key;
116 extern mysql_pfs_key_t trx_undo_mutex_key;
117 #endif /* UNIV_PFS_MUTEX */
118 
119 /******************************************************************/
121 UNIV_INTERN
122 void
123 sync_init(void);
124 /*===========*/
125 /******************************************************************/
127 UNIV_INTERN
128 void
129 sync_close(void);
130 /*===========*/
131 
132 #undef mutex_free /* Fix for MacOS X */
133 
134 #ifdef UNIV_PFS_MUTEX
135 /**********************************************************************
136 Following mutex APIs would be performance schema instrumented
137 if "UNIV_PFS_MUTEX" is defined:
138 
139 mutex_create
140 mutex_enter
141 mutex_exit
142 mutex_enter_nowait
143 mutex_free
144 
145 These mutex APIs will point to corresponding wrapper functions that contain
146 the performance schema instrumentation if "UNIV_PFS_MUTEX" is defined.
147 The instrumented wrapper functions have the prefix of "innodb_".
148 
149 NOTE! The following macro should be used in mutex operation, not the
150 corresponding function. */
151 
152 /******************************************************************/
157 # ifdef UNIV_DEBUG
158 # ifdef UNIV_SYNC_DEBUG
159 # define mutex_create(K, M, level) \
160  pfs_mutex_create_func((K), (M), #M, (level), __FILE__, __LINE__)
161 # else
162 # define mutex_create(K, M, level) \
163  pfs_mutex_create_func((K), (M), #M, __FILE__, __LINE__)
164 # endif/* UNIV_SYNC_DEBUG */
165 # else
166 # define mutex_create(K, M, level) \
167  pfs_mutex_create_func((K), (M), __FILE__, __LINE__)
168 # endif /* UNIV_DEBUG */
169 
170 # define mutex_enter(M) \
171  pfs_mutex_enter_func((M), __FILE__, __LINE__)
172 
173 # define mutex_enter_nowait(M) \
174  pfs_mutex_enter_nowait_func((M), __FILE__, __LINE__)
175 
176 # define mutex_exit(M) pfs_mutex_exit_func(M)
177 
178 # define mutex_free(M) pfs_mutex_free_func(M)
179 
180 #else /* UNIV_PFS_MUTEX */
181 
182 /* If "UNIV_PFS_MUTEX" is not defined, the mutex APIs point to
183 original non-instrumented functions */
184 # ifdef UNIV_DEBUG
185 # ifdef UNIV_SYNC_DEBUG
186 # define mutex_create(K, M, level) \
187  mutex_create_func((M), #M, (level), __FILE__, __LINE__)
188 # else /* UNIV_SYNC_DEBUG */
189 # define mutex_create(K, M, level) \
190  mutex_create_func((M), #M, __FILE__, __LINE__)
191 # endif /* UNIV_SYNC_DEBUG */
192 # else /* UNIV_DEBUG */
193 # define mutex_create(K, M, level) \
194  mutex_create_func((M), __FILE__, __LINE__)
195 # endif /* UNIV_DEBUG */
196 
197 # define mutex_enter(M) mutex_enter_func((M), __FILE__, __LINE__)
198 
199 # define mutex_enter_nowait(M) \
200  mutex_enter_nowait_func((M), __FILE__, __LINE__)
201 
202 # define mutex_exit(M) mutex_exit_func(M)
203 
204 # define mutex_free(M) mutex_free_func(M)
205 
206 #endif /* UNIV_PFS_MUTEX */
207 
208 /******************************************************************/
213 UNIV_INTERN
214 void
216 /*==============*/
217  mutex_t* mutex,
218 #ifdef UNIV_DEBUG
219  const char* cmutex_name,
220 # ifdef UNIV_SYNC_DEBUG
221  ulint level,
222 # endif /* UNIV_SYNC_DEBUG */
223 #endif /* UNIV_DEBUG */
224  const char* cfile_name,
225  ulint cline);
227 /******************************************************************/
232 UNIV_INTERN
233 void
235 /*============*/
236  mutex_t* mutex);
237 /**************************************************************/
241 /* NOTE! currently same as mutex_enter! */
242 
243 #define mutex_enter_fast(M) mutex_enter_func((M), __FILE__, __LINE__)
244 /******************************************************************/
249 UNIV_INLINE
250 void
252 /*=============*/
253  mutex_t* mutex,
254  const char* file_name,
255  ulint line);
256 /********************************************************************/
261 UNIV_INTERN
262 ulint
264 /*====================*/
265  mutex_t* mutex,
266  const char* file_name,
268  ulint line);
269 /******************************************************************/
272 UNIV_INLINE
273 void
275 /*============*/
276  mutex_t* mutex);
279 #ifdef UNIV_PFS_MUTEX
280 /******************************************************************/
286 UNIV_INLINE
287 void
288 pfs_mutex_create_func(
289 /*==================*/
290  PSI_mutex_key key,
291  mutex_t* mutex,
292 # ifdef UNIV_DEBUG
293  const char* cmutex_name,
294 # ifdef UNIV_SYNC_DEBUG
295  ulint level,
296 # endif /* UNIV_SYNC_DEBUG */
297 # endif /* UNIV_DEBUG */
298  const char* cfile_name,
299  ulint cline);
300 /******************************************************************/
305 UNIV_INLINE
306 void
307 pfs_mutex_enter_func(
308 /*=================*/
309  mutex_t* mutex,
310  const char* file_name,
311  ulint line);
312 /********************************************************************/
318 UNIV_INLINE
319 ulint
320 pfs_mutex_enter_nowait_func(
321 /*========================*/
322  mutex_t* mutex,
323  const char* file_name,
325  ulint line);
326 /******************************************************************/
331 UNIV_INLINE
332 void
333 pfs_mutex_exit_func(
334 /*================*/
335  mutex_t* mutex);
337 /******************************************************************/
342 UNIV_INLINE
343 void
344 pfs_mutex_free_func(
345 /*================*/
346  mutex_t* mutex);
348 #endif /* UNIV_PFS_MUTEX */
349 
350 #ifdef UNIV_SYNC_DEBUG
351 /******************************************************************/
355 UNIV_INTERN
356 ibool
357 sync_all_freed(void);
358 /*================*/
359 #endif /* UNIV_SYNC_DEBUG */
360 /*#####################################################################
361 FUNCTION PROTOTYPES FOR DEBUGGING */
362 /*******************************************************************/
364 UNIV_INTERN
365 void
367 /*=================*/
368  FILE* file);
369 /*******************************************************************/
371 UNIV_INTERN
372 void
373 sync_print(
374 /*=======*/
375  FILE* file);
376 #ifdef UNIV_DEBUG
377 /******************************************************************/
380 UNIV_INTERN
381 ibool
382 mutex_validate(
383 /*===========*/
384  const mutex_t* mutex);
385 /******************************************************************/
389 UNIV_INTERN
390 ibool
391 mutex_own(
392 /*======*/
393  const mutex_t* mutex)
394  __attribute__((warn_unused_result));
395 #endif /* UNIV_DEBUG */
396 #ifdef UNIV_SYNC_DEBUG
397 /******************************************************************/
401 UNIV_INTERN
402 void
403 sync_thread_add_level(
404 /*==================*/
405  void* latch,
406  ulint level);
408 /******************************************************************/
413 UNIV_INTERN
414 ibool
415 sync_thread_reset_level(
416 /*====================*/
417  void* latch);
418 /******************************************************************/
421 UNIV_INTERN
422 ibool
423 sync_thread_levels_empty(void);
424 /*==========================*/
425 /******************************************************************/
429 UNIV_INTERN
430 void*
431 sync_thread_levels_contains(
432 /*========================*/
433  ulint level);
435 /******************************************************************/
438 UNIV_INTERN
439 void*
440 sync_thread_levels_nonempty_gen(
441 /*============================*/
442  ibool dict_mutex_allowed);
446 #define sync_thread_levels_empty_gen(d) (!sync_thread_levels_nonempty_gen(d))
447 /******************************************************************/
449 UNIV_INTERN
450 void
451 mutex_get_debug_info(
452 /*=================*/
453  mutex_t* mutex,
454  const char** file_name,
455  ulint* line,
456  os_thread_id_t* thread_id);
458 /******************************************************************/
461 UNIV_INTERN
462 ulint
463 mutex_n_reserved(void);
464 /*==================*/
465 #endif /* UNIV_SYNC_DEBUG */
466 /******************************************************************/
469 UNIV_INLINE
470 lock_word_t
472 /*================*/
473  const mutex_t* mutex);
474 #ifdef UNIV_SYNC_DEBUG
475 /******************************************************************/
479 UNIV_INLINE
480 ulint
481 mutex_get_waiters(
482 /*==============*/
483  const mutex_t* mutex);
484 #endif /* UNIV_SYNC_DEBUG */
485 
486 /*
487  LATCHING ORDER WITHIN THE DATABASE
488  ==================================
489 
490 The mutex or latch in the central memory object, for instance, a rollback
491 segment object, must be acquired before acquiring the latch or latches to
492 the corresponding file data structure. In the latching order below, these
493 file page object latches are placed immediately below the corresponding
494 central memory object latch or mutex.
495 
496 Synchronization object Notes
497 ---------------------- -----
498 
499 Dictionary mutex If we have a pointer to a dictionary
500 | object, e.g., a table, it can be
501 | accessed without reserving the
502 | dictionary mutex. We must have a
503 | reservation, a memoryfix, to the
504 | appropriate table object in this case,
505 | and the table must be explicitly
506 | released later.
507 V
508 Dictionary header
509 |
510 V
511 Secondary index tree latch The tree latch protects also all
512 | the B-tree non-leaf pages. These
513 V can be read with the page only
514 Secondary index non-leaf bufferfixed to save CPU time,
515 | no s-latch is needed on the page.
516 | Modification of a page requires an
517 | x-latch on the page, however. If a
518 | thread owns an x-latch to the tree,
519 | it is allowed to latch non-leaf pages
520 | even after it has acquired the fsp
521 | latch.
522 V
523 Secondary index leaf The latch on the secondary index leaf
524 | can be kept while accessing the
525 | clustered index, to save CPU time.
526 V
527 Clustered index tree latch To increase concurrency, the tree
528 | latch is usually released when the
529 | leaf page latch has been acquired.
530 V
531 Clustered index non-leaf
532 |
533 V
534 Clustered index leaf
535 |
536 V
537 Transaction system header
538 |
539 V
540 Transaction undo mutex The undo log entry must be written
541 | before any index page is modified.
542 | Transaction undo mutex is for the undo
543 | logs the analogue of the tree latch
544 | for a B-tree. If a thread has the
545 | trx undo mutex reserved, it is allowed
546 | to latch the undo log pages in any
547 | order, and also after it has acquired
548 | the fsp latch.
549 V
550 Rollback segment mutex The rollback segment mutex must be
551 | reserved, if, e.g., a new page must
552 | be added to an undo log. The rollback
553 | segment and the undo logs in its
554 | history list can be seen as an
555 | analogue of a B-tree, and the latches
556 | reserved similarly, using a version of
557 | lock-coupling. If an undo log must be
558 | extended by a page when inserting an
559 | undo log record, this corresponds to
560 | a pessimistic insert in a B-tree.
561 V
562 Rollback segment header
563 |
564 V
565 Purge system latch
566 |
567 V
568 Undo log pages If a thread owns the trx undo mutex,
569 | or for a log in the history list, the
570 | rseg mutex, it is allowed to latch
571 | undo log pages in any order, and even
572 | after it has acquired the fsp latch.
573 | If a thread does not have the
574 | appropriate mutex, it is allowed to
575 | latch only a single undo log page in
576 | a mini-transaction.
577 V
578 File space management latch If a mini-transaction must allocate
579 | several file pages, it can do that,
580 | because it keeps the x-latch to the
581 | file space management in its memo.
582 V
583 File system pages
584 |
585 V
586 Kernel mutex If a kernel operation needs a file
587 | page allocation, it must reserve the
588 | fsp x-latch before acquiring the kernel
589 | mutex.
590 V
591 Search system mutex
592 |
593 V
594 Buffer pool mutex
595 |
596 V
597 Log mutex
598 |
599 Any other latch
600 |
601 V
602 Memory pool mutex */
603 
604 /* Latching order levels */
605 
606 /* User transaction locks are higher than any of the latch levels below:
607 no latches are allowed when a thread goes to wait for a normal table
608 or row lock! */
609 #define SYNC_USER_TRX_LOCK 9999
610 #define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress
611  latching order checking */
612 #define SYNC_LEVEL_VARYING 2000 /* Level is varying. Only used with
613  buffer pool page locks, which do not
614  have a fixed level, but instead have
615  their level set after the page is
616  locked; see e.g.
617  ibuf_bitmap_get_map_page(). */
618 #define SYNC_TRX_I_S_RWLOCK 1910 /* Used for
619  trx_i_s_cache_t::rw_lock */
620 #define SYNC_TRX_I_S_LAST_READ 1900 /* Used for
621  trx_i_s_cache_t::last_read_mutex */
622 #define SYNC_FILE_FORMAT_TAG 1200 /* Used to serialize access to the
623  file format tag */
624 #define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve
625  this in X-mode; implicit or backround
626  operations purge, rollback, foreign
627  key checks reserve this in S-mode */
628 #define SYNC_DICT 1000
629 #define SYNC_DICT_AUTOINC_MUTEX 999
630 #define SYNC_DICT_HEADER 995
631 #define SYNC_IBUF_HEADER 914
632 #define SYNC_IBUF_PESS_INSERT_MUTEX 912
633 #define SYNC_IBUF_MUTEX 910 /* ibuf mutex is really below
634  SYNC_FSP_PAGE: we assign a value this
635  high only to make the program to pass
636  the debug checks */
637 /*-------------------------------*/
638 #define SYNC_INDEX_TREE 900
639 #define SYNC_TREE_NODE_NEW 892
640 #define SYNC_TREE_NODE_FROM_HASH 891
641 #define SYNC_TREE_NODE 890
642 #define SYNC_PURGE_SYS 810
643 #define SYNC_PURGE_LATCH 800
644 #define SYNC_TRX_UNDO 700
645 #define SYNC_RSEG 600
646 #define SYNC_RSEG_HEADER_NEW 591
647 #define SYNC_RSEG_HEADER 590
648 #define SYNC_TRX_UNDO_PAGE 570
649 #define SYNC_EXTERN_STORAGE 500
650 #define SYNC_FSP 400
651 #define SYNC_FSP_PAGE 395
652 /*------------------------------------- Insert buffer headers */
653 /*------------------------------------- ibuf_mutex */
654 /*------------------------------------- Insert buffer tree */
655 #define SYNC_IBUF_BITMAP_MUTEX 351
656 #define SYNC_IBUF_BITMAP 350
657 /*------------------------------------- MySQL query cache mutex */
658 /*------------------------------------- MySQL binlog mutex */
659 /*-------------------------------*/
660 #define SYNC_KERNEL 300
661 #define SYNC_REC_LOCK 299
662 #define SYNC_TRX_LOCK_HEAP 298
663 #define SYNC_TRX_SYS_HEADER 290
664 #define SYNC_LOG 170
665 #define SYNC_LOG_FLUSH_ORDER 147
666 #define SYNC_RECV 168
667 #define SYNC_WORK_QUEUE 162
668 #define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */
669 #define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory
670  heap that can be extended to the
671  buffer pool, its logical level is
672  SYNC_SEARCH_SYS, as memory allocation
673  can call routines there! Otherwise
674  the level is SYNC_MEM_HASH. */
675 #define SYNC_COMMIT_ID_LOCK 159
676 #define SYNC_BUF_POOL 150 /* Buffer pool mutex */
677 #define SYNC_BUF_BLOCK 146 /* Block mutex */
678 #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
679 #define SYNC_DOUBLEWRITE 140
680 #define SYNC_ANY_LATCH 135
681 #define SYNC_THR_LOCAL 133
682 #define SYNC_MEM_HASH 131
683 #define SYNC_MEM_POOL 130
684 
685 /* Codes used to designate lock operations */
686 #define RW_LOCK_NOT_LOCKED 350
687 #define RW_LOCK_EX 351
688 #define RW_LOCK_EXCLUSIVE 351
689 #define RW_LOCK_SHARED 352
690 #define RW_LOCK_WAIT_EX 353
691 #define SYNC_MUTEX 354
692 
693 /* NOTE! The structure appears here only for the compiler to know its size.
694 Do not use its fields directly! The structure used in the spin lock
695 implementation of a mutual exclusion semaphore. */
696 
698 struct mutex_struct {
699  os_event_t event;
700  volatile lock_word_t lock_word;
704 #if !defined(HAVE_ATOMIC_BUILTINS)
706  os_fast_mutex;
708 #endif
709  ulint waiters;
713  UT_LIST_NODE_T(mutex_t) list;
715 #ifdef UNIV_SYNC_DEBUG
716  const char* file_name;
717  ulint line;
718  ulint level;
719 #endif /* UNIV_SYNC_DEBUG */
720  const char* cfile_name;
721  ulint cline;
722 #ifdef UNIV_DEBUG
723  os_thread_id_t thread_id;
725  ulint magic_n;
727 # define MUTEX_MAGIC_N (ulint)979585
728 #endif /* UNIV_DEBUG */
729  ulong count_os_wait;
730 #ifdef UNIV_DEBUG
731  ulong count_using;
732  ulong count_spin_loop;
733  ulong count_spin_rounds;
734  ulong count_os_yield;
735  ulonglong lspent_time;
736  ulonglong lmax_spent_time;
737  const char* cmutex_name;
738  ulint mutex_type;
739 #endif /* UNIV_DEBUG */
740 #ifdef UNIV_PFS_MUTEX
741  struct PSI_mutex* pfs_psi;
743 #endif
744 };
745 
748 extern sync_array_t* sync_primary_wait_array;/* Appears here for
749  debugging purposes only! */
750 
755 #define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds
756 
758 extern ib_int64_t mutex_exit_count;
759 
760 #ifdef UNIV_SYNC_DEBUG
761 
762 extern ibool sync_order_checks_on;
763 #endif /* UNIV_SYNC_DEBUG */
764 
766 extern ibool sync_initialized;
767 
769 typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t;
771 extern ut_list_base_node_t mutex_list;
772 
774 extern mutex_t mutex_list_mutex;
775 
776 
777 #ifndef UNIV_NONINL
778 #include "sync0sync.ic"
779 #endif
780 
781 #endif