Skip to content

Commit

Permalink
Bug 21052754 ADD SHOW ENGINE INNODB MUTEX FUNCTIONALITY
Browse files Browse the repository at this point in the history
Add the functionality that was removed in WL#6044. However, this is a compelete
rewrite of SHOW ... MUTEX infrastructure inside InnoDB. The RW-Locks tracking
however was not changed in any substantial way. Except that some useless debug
counters were removed and the waits are now enabled/reset/disabled using the
Monitor infrastructure.

In the old SHOW ... MUTEX For each mutex pointer and rw-lock pointer we were
doing a search through all the buffer pool chunks to check if the pointer was
contained within to identify if it was a page mutex/rw-lock or not. For large
buffer pools this is unacceptable. To avoid these expensive scans, I've added
a LATCH_ID to identify each mutex and rw-lock. Removed the cfile_name and
cline from the mutex definition and moved them to a separate lookup table.
This information is only used when there is a problem and is very rare but
under normal operation they take up sizeof(void*) + sizeof(uint16_t) space,
the sizeof(uint16_t) actually occupies 8 bytes due to the alignment. The size
of the mutex was therefore 72 bytes. It has now been reduced to:

We don't track the create file and line number for the block mutexes. There
are just too many of them and they are all created in the same file(buf0buf.cc)
and on the same line number, you can grep the code to figure that out.

  gdb) p sizeof(ib_mutex_t)
      $1 = 48

For rw_lock_t, add a is_block_lock flag. This flag is set in buf0buf.cc where
the block lock is created.

Removed UNIV_SYNC_DEBUG. UNIV_DEBUG will by default do sync order checking.
Add read-only debug config variable: --innodb-sync-debug (default: true).
Potential use case is to run the latch ordering checks in the weekly tests
if the overhead is too much for daily tests.

Added dynamic enable/disable/reset of mutex/rw statistic gathering using
the existing monitor infrastructure

    SET GLOBAL innodb_monitor_enable="latch";
    SET GLOBAL innodb_monitor_reset="latch";
    SET GLOBAL innodb_monitor_disable="latch";

Added additonal information to the SHOW ... MUTEX OUTPUT

mysql> show engine innodb mutex;
+--------+-------------------------+------------------------------------------+
| Type   | Name                    | Status                                   |
+--------+-------------------------+------------------------------------------+
| InnoDB | TRX_SYS                 | spins=3371806,waits=44790,calls=800875   |
...
| InnoDB | rwlock: log0log.cc:784  | waits=3                                  |
+--------+-------------------------+------------------------------------------+

The "Name" columns will now display the mutex name and not the filename:line
format which was very build specific. For RW-LOCKS we will stick with the old
format.

Fixed several bugs in the SyncDebug checks that were introduced in WL#6044.

Moved the low level OS mutex to a separate class with a separate interface.
We can't track these because they are implemented outside of InnoDB.

Remove UNIV_DEBUG_FILE_ACCESSES, fold into UNIV_DEBUG

Approved by Jimmy Yang and Bin Su rb#9037
  • Loading branch information
Sunny Bains authored and Sunny Bains committed Jun 11, 2015
1 parent 1a0fb83 commit 139b0f3
Show file tree
Hide file tree
Showing 94 changed files with 4,360 additions and 2,658 deletions.
4 changes: 2 additions & 2 deletions BUILD/build_mccge.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

# Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
Expand Down Expand Up @@ -175,7 +175,7 @@ Usage: $0 [options]
--with-debug Build debug version
--extra-debug-flag flag Add -Dflag to compiler flags
InnoDB supports the following debug flags,
UNIV_DEBUG, UNIV_SYNC_DEBUG, UNIV_MEM_DEBUG,
UNIV_DEBUG, UNIV_MEM_DEBUG,
UNIV_DEBUG_THREAD_CREATION, UNIV_DEBUG_LOCK_VALIDATE,
UNIV_DEBUG_PRINT, UNIV_DEBUG_FILE_ACCESS,
UNIV_LIGHT_MEM_DEBUG, UNIV_LOG_DEBUG,
Expand Down
1 change: 1 addition & 0 deletions mysql-test/suite/perfschema/t/show_sanity.test
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ insert into test.sanity values
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_STATUS_OUTPUT_LOCKS"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_SYNC_ARRAY_SIZE"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_SYNC_SPIN_LOOPS"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_SYNC_DEBUG"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_TEMP_DATA_FILE_PATH"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_THREAD_CONCURRENCY"),
("JUNK: GLOBAL-ONLY", "I_S.SESSION_VARIABLES", "INNODB_THREAD_SLEEP_DELAY"),
Expand Down
19 changes: 18 additions & 1 deletion storage/innobase/Doxyfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

# This is the Doxygen configuration file for InnoDB

# Doxyfile 1.5.6

# Usage: SVNVERSION=-r$(svnversion) doxygen
Expand Down Expand Up @@ -1160,7 +1177,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.

PREDEFINED = DOXYGEN UNIV_DEBUG UNIV_SYNC_DEBUG __attribute__()=
PREDEFINED = DOXYGEN UNIV_DEBUG __attribute__()=

# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
Expand Down
4 changes: 0 additions & 4 deletions storage/innobase/btr/btr0btr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,7 @@ btr_height_get(
/* Release the S latch on the root page. */
mtr->memo_release(root_block, MTR_MEMO_PAGE_S_FIX);

#ifdef UNIV_SYNC_DEBUG
ut_d(sync_check_unlock(&root_block->lock));
#endif /* UNIV_SYNC_DEBUG */

return(height);
}
Expand Down Expand Up @@ -2567,11 +2565,9 @@ btr_page_split_and_insert(
ut_ad(!dict_index_is_online_ddl(cursor->index)
|| (flags & BTR_CREATE_FLAG)
|| dict_index_is_clust(cursor->index));
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own_flagged(dict_index_get_lock(cursor->index),
RW_LOCK_FLAG_X | RW_LOCK_FLAG_SX)
|| dict_table_is_intrinsic(cursor->index->table));
#endif /* UNIV_SYNC_DEBUG */

block = btr_cur_get_block(cursor);
page = buf_block_get_frame(block);
Expand Down
16 changes: 7 additions & 9 deletions storage/innobase/btr/btr0cur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ btr_cur_search_to_nth_level(

#ifdef BTR_CUR_ADAPT
btr_search_t* info;
#endif
#endif /* BTR_CUR_ADAPT */
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
Expand All @@ -818,7 +818,7 @@ btr_cur_search_to_nth_level(
#ifdef UNIV_DEBUG
cursor->up_match = ULINT_UNDEFINED;
cursor->low_match = ULINT_UNDEFINED;
#endif
#endif /* UNIV_DEBUG */

ibool s_latch_by_caller;

Expand Down Expand Up @@ -994,10 +994,8 @@ btr_cur_search_to_nth_level(
default:
if (!srv_read_only_mode) {
if (s_latch_by_caller) {
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(dict_index_get_lock(index),
RW_LOCK_S));
#endif /* UNIV_SYNC_DEBUG */
} else if (!modify_external) {
/* BTR_SEARCH_TREE is intended to be used with
BTR_ALREADY_S_LATCHED */
Expand Down Expand Up @@ -5190,7 +5188,7 @@ btr_cur_pessimistic_delete(
ulint* offsets;
#ifdef UNIV_DEBUG
bool parent_latched = false;
#endif
#endif /* UNIV_DEBUG */

block = btr_cur_get_block(cursor);
page = buf_block_get_frame(block);
Expand Down Expand Up @@ -7306,9 +7304,9 @@ btr_free_externally_stored_field(
}

for (;;) {
#ifdef UNIV_SYNC_DEBUG
#ifdef UNIV_DEBUG
buf_block_t* rec_block;
#endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
buf_block_t* ext_block;

mtr_start(&mtr);
Expand All @@ -7323,9 +7321,9 @@ btr_free_externally_stored_field(
const page_id_t page_id(page_get_space_id(p),
page_get_page_no(p));

#ifdef UNIV_SYNC_DEBUG
#ifdef UNIV_DEBUG
rec_block =
#endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
buf_page_get(page_id, rec_page_size, RW_X_LATCH, &mtr);

buf_block_dbg_add_level(rec_block, SYNC_NO_ORDER_CHECK);
Expand Down
45 changes: 6 additions & 39 deletions storage/innobase/btr/btr0sea.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,8 @@ btr_search_check_free_space_in_heap(dict_index_t* index)
hash_table_t* table;
mem_heap_t* heap;

#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

table = btr_get_search_table(index);

Expand Down Expand Up @@ -182,7 +180,7 @@ btr_search_sys_create(ulint hash_size)

btr_search_sys->hash_tables[i] =
ib_create((hash_size / btr_ahi_parts),
"hash_table_mutex",
LATCH_ID_HASH_TABLE_MUTEX,
0, MEM_HEAP_FOR_BTR_SEARCH);

#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
Expand Down Expand Up @@ -217,7 +215,7 @@ btr_search_sys_resize(ulint hash_size)

btr_search_sys->hash_tables[i] =
ib_create((hash_size / btr_ahi_parts),
"hash_table_mutex",
LATCH_ID_HASH_TABLE_MUTEX,
0, MEM_HEAP_FOR_BTR_SEARCH);

#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
Expand Down Expand Up @@ -269,12 +267,11 @@ btr_search_disable_ref_count(

ut_ad(mutex_own(&dict_sys->mutex));

for (index = dict_table_get_first_index(table); index;
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {

#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));

index->search_info->ref_count = 0;
}
Expand Down Expand Up @@ -352,9 +349,7 @@ btr_search_info_create(mem_heap_t* heap)

info = (btr_search_t*) mem_heap_alloc(heap, sizeof(btr_search_t));

#ifdef UNIV_DEBUG
info->magic_n = BTR_SEARCH_MAGIC_N;
#endif /* UNIV_DEBUG */
ut_d(info->magic_n = BTR_SEARCH_MAGIC_N);

info->ref_count = 0;
info->root_guess = NULL;
Expand Down Expand Up @@ -393,10 +388,8 @@ btr_search_info_get_ref_count(

ut_ad(info);

#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

rw_lock_s_lock(btr_get_search_latch(index));
ret = info->ref_count;
Expand All @@ -419,10 +412,8 @@ btr_search_info_update_hash(
dict_index_t* index = cursor->index;
ulint n_unique;

#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_S));
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

if (dict_index_is_ibuf(index)) {
/* So many deletes are performed on an insert buffer tree
Expand Down Expand Up @@ -516,14 +507,10 @@ btr_search_update_block_hash_info(
buf_block_t* block,
const btr_cur_t* cursor)
{
ut_ad(cursor);

#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_S));
ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
ut_ad(rw_lock_own(&block->lock, RW_LOCK_S)
|| rw_lock_own(&block->lock, RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

info->last_hash_succ = FALSE;

Expand Down Expand Up @@ -599,11 +586,9 @@ btr_search_update_hash_ref(
const rec_t* rec;

ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
|| rw_lock_own(&(block->lock), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(page_align(btr_cur_get_rec(cursor))
== buf_block_get_frame(block));

Expand Down Expand Up @@ -639,9 +624,7 @@ btr_search_update_hash_ref(
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

ha_insert_for_fold(btr_get_search_table(index), fold,
block, rec);
Expand All @@ -661,10 +644,8 @@ btr_search_info_update_slow(
buf_block_t* block;
ibool build_index;

#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_S));
ut_ad(!rw_lock_own(btr_get_search_latch(cursor->index), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

block = btr_cur_get_block(cursor);

Expand Down Expand Up @@ -1119,10 +1100,8 @@ btr_search_drop_page_hash_index(buf_block_t* block)
return;
}

#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(btr_get_search_latch(block->index), RW_LOCK_S));
ut_ad(!rw_lock_own(btr_get_search_latch(block->index), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

retry:
index = block->index;
Expand Down Expand Up @@ -1160,12 +1139,10 @@ btr_search_drop_page_hash_index(buf_block_t* block)

table = btr_get_search_table(index);

#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
|| rw_lock_own(&(block->lock), RW_LOCK_X)
|| block->page.buf_fix_count == 0
|| buf_block_get_state(block) == BUF_BLOCK_REMOVE_HASH);
#endif /* UNIV_SYNC_DEBUG */

n_fields = block->curr_n_fields;

Expand Down Expand Up @@ -1356,11 +1333,9 @@ btr_search_build_page_hash_index(
ut_ad(block->page.id.space() == index->space);
ut_a(!dict_index_is_ibuf(index));

#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(btr_get_search_latch(index), RW_LOCK_X));
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_S)
|| rw_lock_own(&(block->lock), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

rw_lock_s_lock(btr_get_search_latch(index));

Expand Down Expand Up @@ -1535,10 +1510,8 @@ btr_search_move_or_delete_hash_entries(

ut_ad(!dict_table_is_intrinsic(index->table));

#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X));
ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

rw_lock_s_lock(btr_get_search_latch(index));

Expand Down Expand Up @@ -1598,9 +1571,7 @@ btr_search_update_hash_on_delete(btr_cur_t* cursor)

block = btr_cur_get_block(cursor);

#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

index = block->index;

Expand Down Expand Up @@ -1661,9 +1632,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor)

block = btr_cur_get_block(cursor);

#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

index = block->index;

Expand Down Expand Up @@ -1736,9 +1705,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor)

block = btr_cur_get_block(cursor);

#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_X));
#endif /* UNIV_SYNC_DEBUG */

index = block->index;

Expand Down
Loading

0 comments on commit 139b0f3

Please sign in to comment.