Drizzled Public API Documentation

sync0sync.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (C) 1995, 2011, 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_bh_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 trx_undo_mutex_key;
116 #endif /* UNIV_PFS_MUTEX */
117 
118 /******************************************************************/
120 UNIV_INTERN
121 void
122 sync_init(void);
123 /*===========*/
124 /******************************************************************/
126 UNIV_INTERN
127 void
128 sync_close(void);
129 /*===========*/
130 
131 #undef mutex_free /* Fix for MacOS X */
132 
133 #ifdef UNIV_PFS_MUTEX
134 /**********************************************************************
135 Following mutex APIs would be performance schema instrumented
136 if "UNIV_PFS_MUTEX" is defined:
137 
138 mutex_create
139 mutex_enter
140 mutex_exit
141 mutex_enter_nowait
142 mutex_free
143 
144 These mutex APIs will point to corresponding wrapper functions that contain
145 the performance schema instrumentation if "UNIV_PFS_MUTEX" is defined.
146 The instrumented wrapper functions have the prefix of "innodb_".
147 
148 NOTE! The following macro should be used in mutex operation, not the
149 corresponding function. */
150 
151 /******************************************************************/
156 # ifdef UNIV_DEBUG
157 # ifdef UNIV_SYNC_DEBUG
158 # define mutex_create(K, M, level) \
159  pfs_mutex_create_func((K), (M), #M, (level), __FILE__, __LINE__)
160 # else
161 # define mutex_create(K, M, level) \
162  pfs_mutex_create_func((K), (M), #M, __FILE__, __LINE__)
163 # endif/* UNIV_SYNC_DEBUG */
164 # else
165 # define mutex_create(K, M, level) \
166  pfs_mutex_create_func((K), (M), __FILE__, __LINE__)
167 # endif /* UNIV_DEBUG */
168 
169 # define mutex_enter(M) \
170  pfs_mutex_enter_func((M), __FILE__, __LINE__)
171 
172 # define mutex_enter_nowait(M) \
173  pfs_mutex_enter_nowait_func((M), __FILE__, __LINE__)
174 
175 # define mutex_exit(M) pfs_mutex_exit_func(M)
176 
177 # define mutex_free(M) pfs_mutex_free_func(M)
178 
179 #else /* UNIV_PFS_MUTEX */
180 
181 /* If "UNIV_PFS_MUTEX" is not defined, the mutex APIs point to
182 original non-instrumented functions */
183 # ifdef UNIV_DEBUG
184 # ifdef UNIV_SYNC_DEBUG
185 # define mutex_create(K, M, level) \
186  mutex_create_func((M), #M, (level), __FILE__, __LINE__)
187 # else /* UNIV_SYNC_DEBUG */
188 # define mutex_create(K, M, level) \
189  mutex_create_func((M), #M, __FILE__, __LINE__)
190 # endif /* UNIV_SYNC_DEBUG */
191 # else /* UNIV_DEBUG */
192 # define mutex_create(K, M, level) \
193  mutex_create_func((M), __FILE__, __LINE__)
194 # endif /* UNIV_DEBUG */
195 
196 # define mutex_enter(M) mutex_enter_func((M), __FILE__, __LINE__)
197 
198 # define mutex_enter_nowait(M) \
199  mutex_enter_nowait_func((M), __FILE__, __LINE__)
200 
201 # define mutex_exit(M) mutex_exit_func(M)
202 
203 # define mutex_free(M) mutex_free_func(M)
204 
205 #endif /* UNIV_PFS_MUTEX */
206 
207 /******************************************************************/
212 UNIV_INTERN
213 void
215 /*==============*/
216  mutex_t* mutex,
217 #ifdef UNIV_DEBUG
218  const char* cmutex_name,
219 # ifdef UNIV_SYNC_DEBUG
220  ulint level,
221 # endif /* UNIV_SYNC_DEBUG */
222 #endif /* UNIV_DEBUG */
223  const char* cfile_name,
224  ulint cline);
226 /******************************************************************/
231 UNIV_INTERN
232 void
234 /*============*/
235  mutex_t* mutex);
236 /**************************************************************/
240 /* NOTE! currently same as mutex_enter! */
241 
242 #define mutex_enter_fast(M) mutex_enter_func((M), __FILE__, __LINE__)
243 /******************************************************************/
248 UNIV_INLINE
249 void
251 /*=============*/
252  mutex_t* mutex,
253  const char* file_name,
254  ulint line);
255 /********************************************************************/
260 UNIV_INTERN
261 ulint
263 /*====================*/
264  mutex_t* mutex,
265  const char* file_name,
267  ulint line);
268 /******************************************************************/
271 UNIV_INLINE
272 void
274 /*============*/
275  mutex_t* mutex);
278 #ifdef UNIV_PFS_MUTEX
279 /******************************************************************/
285 UNIV_INLINE
286 void
287 pfs_mutex_create_func(
288 /*==================*/
289  PSI_mutex_key key,
290  mutex_t* mutex,
291 # ifdef UNIV_DEBUG
292  const char* cmutex_name,
293 # ifdef UNIV_SYNC_DEBUG
294  ulint level,
295 # endif /* UNIV_SYNC_DEBUG */
296 # endif /* UNIV_DEBUG */
297  const char* cfile_name,
298  ulint cline);
299 /******************************************************************/
304 UNIV_INLINE
305 void
306 pfs_mutex_enter_func(
307 /*=================*/
308  mutex_t* mutex,
309  const char* file_name,
310  ulint line);
311 /********************************************************************/
317 UNIV_INLINE
318 ulint
319 pfs_mutex_enter_nowait_func(
320 /*========================*/
321  mutex_t* mutex,
322  const char* file_name,
324  ulint line);
325 /******************************************************************/
330 UNIV_INLINE
331 void
332 pfs_mutex_exit_func(
333 /*================*/
334  mutex_t* mutex);
336 /******************************************************************/
341 UNIV_INLINE
342 void
343 pfs_mutex_free_func(
344 /*================*/
345  mutex_t* mutex);
347 #endif /* UNIV_PFS_MUTEX */
348 
349 #ifdef UNIV_SYNC_DEBUG
350 /******************************************************************/
354 UNIV_INTERN
355 ibool
356 sync_all_freed(void);
357 /*================*/
358 #endif /* UNIV_SYNC_DEBUG */
359 /*#####################################################################
360 FUNCTION PROTOTYPES FOR DEBUGGING */
361 /*******************************************************************/
363 UNIV_INTERN
364 void
366 /*=================*/
367  FILE* file);
368 /*******************************************************************/
370 UNIV_INTERN
371 void
372 sync_print(
373 /*=======*/
374  FILE* file);
375 #ifdef UNIV_DEBUG
376 /******************************************************************/
379 UNIV_INTERN
380 ibool
381 mutex_validate(
382 /*===========*/
383  const mutex_t* mutex);
384 /******************************************************************/
388 UNIV_INTERN
389 ibool
390 mutex_own(
391 /*======*/
392  const mutex_t* mutex)
393  __attribute__((warn_unused_result));
394 #endif /* UNIV_DEBUG */
395 #ifdef UNIV_SYNC_DEBUG
396 /******************************************************************/
400 UNIV_INTERN
401 void
402 sync_thread_add_level(
403 /*==================*/
404  void* latch,
405  ulint level);
407 /******************************************************************/
412 UNIV_INTERN
413 ibool
414 sync_thread_reset_level(
415 /*====================*/
416  void* latch);
417 /******************************************************************/
420 UNIV_INTERN
421 ibool
422 sync_thread_levels_empty(void);
423 /*==========================*/
424 /******************************************************************/
428 UNIV_INTERN
429 void*
430 sync_thread_levels_contains(
431 /*========================*/
432  ulint level);
434 /******************************************************************/
437 UNIV_INTERN
438 void*
439 sync_thread_levels_nonempty_gen(
440 /*============================*/
441  ibool dict_mutex_allowed);
445 #define sync_thread_levels_empty_gen(d) (!sync_thread_levels_nonempty_gen(d))
446 /******************************************************************/
448 UNIV_INTERN
449 void
450 mutex_get_debug_info(
451 /*=================*/
452  mutex_t* mutex,
453  const char** file_name,
454  ulint* line,
455  os_thread_id_t* thread_id);
457 /******************************************************************/
460 UNIV_INTERN
461 ulint
462 mutex_n_reserved(void);
463 /*==================*/
464 #endif /* UNIV_SYNC_DEBUG */
465 /******************************************************************/
468 UNIV_INLINE
469 lock_word_t
471 /*================*/
472  const mutex_t* mutex);
473 #ifdef UNIV_SYNC_DEBUG
474 /******************************************************************/
478 UNIV_INLINE
479 ulint
480 mutex_get_waiters(
481 /*==============*/
482  const mutex_t* mutex);
483 #endif /* UNIV_SYNC_DEBUG */
484 
485 /*
486  LATCHING ORDER WITHIN THE DATABASE
487  ==================================
488 
489 The mutex or latch in the central memory object, for instance, a rollback
490 segment object, must be acquired before acquiring the latch or latches to
491 the corresponding file data structure. In the latching order below, these
492 file page object latches are placed immediately below the corresponding
493 central memory object latch or mutex.
494 
495 Synchronization object Notes
496 ---------------------- -----
497 
498 Dictionary mutex If we have a pointer to a dictionary
499 | object, e.g., a table, it can be
500 | accessed without reserving the
501 | dictionary mutex. We must have a
502 | reservation, a memoryfix, to the
503 | appropriate table object in this case,
504 | and the table must be explicitly
505 | released later.
506 V
507 Dictionary header
508 |
509 V
510 Secondary index tree latch The tree latch protects also all
511 | the B-tree non-leaf pages. These
512 V can be read with the page only
513 Secondary index non-leaf bufferfixed to save CPU time,
514 | no s-latch is needed on the page.
515 | Modification of a page requires an
516 | x-latch on the page, however. If a
517 | thread owns an x-latch to the tree,
518 | it is allowed to latch non-leaf pages
519 | even after it has acquired the fsp
520 | latch.
521 V
522 Secondary index leaf The latch on the secondary index leaf
523 | can be kept while accessing the
524 | clustered index, to save CPU time.
525 V
526 Clustered index tree latch To increase concurrency, the tree
527 | latch is usually released when the
528 | leaf page latch has been acquired.
529 V
530 Clustered index non-leaf
531 |
532 V
533 Clustered index leaf
534 |
535 V
536 Transaction system header
537 |
538 V
539 Transaction undo mutex The undo log entry must be written
540 | before any index page is modified.
541 | Transaction undo mutex is for the undo
542 | logs the analogue of the tree latch
543 | for a B-tree. If a thread has the
544 | trx undo mutex reserved, it is allowed
545 | to latch the undo log pages in any
546 | order, and also after it has acquired
547 | the fsp latch.
548 V
549 Rollback segment mutex The rollback segment mutex must be
550 | reserved, if, e.g., a new page must
551 | be added to an undo log. The rollback
552 | segment and the undo logs in its
553 | history list can be seen as an
554 | analogue of a B-tree, and the latches
555 | reserved similarly, using a version of
556 | lock-coupling. If an undo log must be
557 | extended by a page when inserting an
558 | undo log record, this corresponds to
559 | a pessimistic insert in a B-tree.
560 V
561 Rollback segment header
562 |
563 V
564 Purge system latch
565 |
566 V
567 Undo log pages If a thread owns the trx undo mutex,
568 | or for a log in the history list, the
569 | rseg mutex, it is allowed to latch
570 | undo log pages in any order, and even
571 | after it has acquired the fsp latch.
572 | If a thread does not have the
573 | appropriate mutex, it is allowed to
574 | latch only a single undo log page in
575 | a mini-transaction.
576 V
577 File space management latch If a mini-transaction must allocate
578 | several file pages, it can do that,
579 | because it keeps the x-latch to the
580 | file space management in its memo.
581 V
582 File system pages
583 |
584 V
585 Kernel mutex If a kernel operation needs a file
586 | page allocation, it must reserve the
587 | fsp x-latch before acquiring the kernel
588 | mutex.
589 V
590 Search system mutex
591 |
592 V
593 Buffer pool mutex
594 |
595 V
596 Log mutex
597 |
598 Any other latch
599 |
600 V
601 Memory pool mutex */
602 
603 /* Latching order levels */
604 
605 /* User transaction locks are higher than any of the latch levels below:
606 no latches are allowed when a thread goes to wait for a normal table
607 or row lock! */
608 #define SYNC_USER_TRX_LOCK 9999
609 #define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress
610  latching order checking */
611 #define SYNC_LEVEL_VARYING 2000 /* Level is varying. Only used with
612  buffer pool page locks, which do not
613  have a fixed level, but instead have
614  their level set after the page is
615  locked; see e.g.
616  ibuf_bitmap_get_map_page(). */
617 #define SYNC_TRX_I_S_RWLOCK 1910 /* Used for
618  trx_i_s_cache_t::rw_lock */
619 #define SYNC_TRX_I_S_LAST_READ 1900 /* Used for
620  trx_i_s_cache_t::last_read_mutex */
621 #define SYNC_FILE_FORMAT_TAG 1200 /* Used to serialize access to the
622  file format tag */
623 #define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve
624  this in X-mode; implicit or backround
625  operations purge, rollback, foreign
626  key checks reserve this in S-mode */
627 #define SYNC_DICT 1000
628 #define SYNC_DICT_AUTOINC_MUTEX 999
629 #define SYNC_DICT_HEADER 995
630 #define SYNC_IBUF_HEADER 914
631 #define SYNC_IBUF_PESS_INSERT_MUTEX 912
632 #define SYNC_IBUF_MUTEX 910 /* ibuf mutex is really below
633  SYNC_FSP_PAGE: we assign a value this
634  high only to make the program to pass
635  the debug checks */
636 /*-------------------------------*/
637 #define SYNC_INDEX_TREE 900
638 #define SYNC_TREE_NODE_NEW 892
639 #define SYNC_TREE_NODE_FROM_HASH 891
640 #define SYNC_TREE_NODE 890
641 #define SYNC_PURGE_LATCH 800
642 #define SYNC_TRX_UNDO 700
643 #define SYNC_RSEG 600
644 #define SYNC_RSEG_HEADER_NEW 591
645 #define SYNC_RSEG_HEADER 590
646 #define SYNC_TRX_UNDO_PAGE 570
647 #define SYNC_EXTERN_STORAGE 500
648 #define SYNC_FSP 400
649 #define SYNC_FSP_PAGE 395
650 /*------------------------------------- Insert buffer headers */
651 /*------------------------------------- ibuf_mutex */
652 /*------------------------------------- Insert buffer tree */
653 #define SYNC_IBUF_BITMAP_MUTEX 351
654 #define SYNC_IBUF_BITMAP 350
655 /*------------------------------------- MySQL query cache mutex */
656 /*------------------------------------- MySQL binlog mutex */
657 /*-------------------------------*/
658 #define SYNC_KERNEL 300
659 #define SYNC_REC_LOCK 299
660 #define SYNC_TRX_LOCK_HEAP 298
661 #define SYNC_TRX_SYS_HEADER 290
662 #define SYNC_PURGE_QUEUE 200
663 #define SYNC_LOG 170
664 #define SYNC_LOG_FLUSH_ORDER 147
665 #define SYNC_RECV 168
666 #define SYNC_WORK_QUEUE 162
667 #define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */
668 #define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory
669  heap that can be extended to the
670  buffer pool, its logical level is
671  SYNC_SEARCH_SYS, as memory allocation
672  can call routines there! Otherwise
673  the level is SYNC_MEM_HASH. */
674 #define SYNC_COMMIT_ID_LOCK 159
675 #define SYNC_BUF_POOL 150 /* Buffer pool mutex */
676 #define SYNC_BUF_BLOCK 146 /* Block mutex */
677 #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
678 #define SYNC_DOUBLEWRITE 140
679 #define SYNC_ANY_LATCH 135
680 #define SYNC_THR_LOCAL 133
681 #define SYNC_MEM_HASH 131
682 #define SYNC_MEM_POOL 130
683 
684 /* Codes used to designate lock operations */
685 #define RW_LOCK_NOT_LOCKED 350
686 #define RW_LOCK_EX 351
687 #define RW_LOCK_EXCLUSIVE 351
688 #define RW_LOCK_SHARED 352
689 #define RW_LOCK_WAIT_EX 353
690 #define SYNC_MUTEX 354
691 
692 /* NOTE! The structure appears here only for the compiler to know its size.
693 Do not use its fields directly! The structure used in the spin lock
694 implementation of a mutual exclusion semaphore. */
695 
697 struct mutex_struct {
699  volatile lock_word_t lock_word;
703 #if !defined(HAVE_ATOMIC_BUILTINS)
707 #endif
708  ulint waiters;
712  UT_LIST_NODE_T(mutex_t) list;
714 #ifdef UNIV_SYNC_DEBUG
715  const char* file_name;
716  ulint line;
717  ulint level;
718 #endif /* UNIV_SYNC_DEBUG */
719  const char* cfile_name;
720  ulint cline;
721 #ifdef UNIV_DEBUG
722  os_thread_id_t thread_id;
724  ulint magic_n;
726 # define MUTEX_MAGIC_N (ulint)979585
727 #endif /* UNIV_DEBUG */
729 #ifdef UNIV_DEBUG
730  ulong count_using;
731  ulong count_spin_loop;
732  ulong count_spin_rounds;
733  ulong count_os_yield;
734  ulonglong lspent_time;
735  ulonglong lmax_spent_time;
736  const char* cmutex_name;
737  ulint mutex_type;
738 #endif /* UNIV_DEBUG */
739 #ifdef UNIV_PFS_MUTEX
740  struct PSI_mutex* pfs_psi;
742 #endif
743 };
744 
747 extern sync_array_t* sync_primary_wait_array;/* Appears here for
748  debugging purposes only! */
749 
754 #define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds
755 
757 extern ib_int64_t mutex_exit_count;
758 
759 #ifdef UNIV_SYNC_DEBUG
760 
761 extern ibool sync_order_checks_on;
762 #endif /* UNIV_SYNC_DEBUG */
763 
765 extern ibool sync_initialized;
766 
768 typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t;
770 extern ut_list_base_node_t mutex_list;
771 
773 extern mutex_t mutex_list_mutex;
774 
775 
776 #ifndef UNIV_NONINL
777 #include "sync0sync.ic"
778 #endif
779 
780 #endif