From 28098420317bc2efe082df799c917babde879242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= <marko.makela@mariadb.com> Date: Sat, 19 Oct 2019 15:16:47 +0300 Subject: [PATCH] MDEV-20864 Introduce debug option innodb_change_buffer_dump To diagnose a hang in slow shutdown (innodb_fast_shutdown=0), let us introduce a Boolean startup option in debug builds that will cause the contents of the InnoDB change buffer to be dumped to the server error log at startup. --- mysql-test/suite/innodb/t/ibuf_not_empty.test | 2 +- .../suite/sys_vars/r/sysvars_innodb.result | 12 +++++++++++ storage/innobase/handler/ha_innodb.cc | 6 ++++++ storage/innobase/ibuf/ibuf0ibuf.cc | 21 +++++++++++++++++++ storage/innobase/include/dict0types.h | 4 +++- 5 files changed, 43 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/t/ibuf_not_empty.test b/mysql-test/suite/innodb/t/ibuf_not_empty.test index a1a2da1f903..9ee0b180f44 100644 --- a/mysql-test/suite/innodb/t/ibuf_not_empty.test +++ b/mysql-test/suite/innodb/t/ibuf_not_empty.test @@ -41,7 +41,7 @@ INSERT INTO t1 SELECT 0,b,c FROM t1; INSERT INTO t1 SELECT 0,b,c FROM t1; INSERT INTO t1 SELECT 0,b,c FROM t1; ---let $restart_parameters= --innodb-force-recovery=6 +--let $restart_parameters= --innodb-force-recovery=6 --innodb-change-buffer-dump --source include/restart_mysqld.inc --replace_regex /contains \d+ entries/contains #### entries/ diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index 1808cfb6ea3..65d47347a15 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -354,6 +354,18 @@ NUMERIC_BLOCK_SIZE 0 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME INNODB_CHANGE_BUFFER_DUMP +SESSION_VALUE NULL +DEFAULT_VALUE OFF +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BOOLEAN +VARIABLE_COMMENT Dump the change buffer at startup. +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST OFF,ON +READ_ONLY YES +COMMAND_LINE_ARGUMENT NONE VARIABLE_NAME INNODB_CHANGE_BUFFER_MAX_SIZE SESSION_VALUE NULL DEFAULT_VALUE 25 diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a556b5875df..3ad12c455bf 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -20642,6 +20642,11 @@ static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method, NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib); #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +static MYSQL_SYSVAR_BOOL(change_buffer_dump, ibuf_dump, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "Dump the change buffer at startup.", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, PLUGIN_VAR_RQCMDARG, "Debug flags for InnoDB change buffering (0=none, 1=try to buffer)", @@ -21158,6 +21163,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(change_buffering), MYSQL_SYSVAR(change_buffer_max_size), #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + MYSQL_SYSVAR(change_buffer_dump), MYSQL_SYSVAR(change_buffering_debug), MYSQL_SYSVAR(disable_background_merge), #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index d3fdd46c29b..e701271379e 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -188,6 +188,8 @@ access order rules. */ ibuf_use_t ibuf_use = IBUF_USE_ALL; #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Dump the change buffer at startup */ +my_bool ibuf_dump; /** Flag to control insert buffer debugging. */ uint ibuf_debug; #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ @@ -506,6 +508,25 @@ ibuf_init_at_db_start(void) #endif /* BTR_CUR_ADAPT */ ibuf->index->page = FSP_IBUF_TREE_ROOT_PAGE_NO; ut_d(ibuf->index->cached = TRUE); + +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG + if (!ibuf_dump) { + return error; + } + ib::info() << "Dumping the change buffer"; + ibuf_mtr_start(&mtr); + btr_pcur_t pcur; + if (DB_SUCCESS == btr_pcur_open_at_index_side( + true, ibuf->index, BTR_SEARCH_LEAF, &pcur, + true, 0, &mtr)) { + while (btr_pcur_move_to_next_user_rec(&pcur, &mtr)) { + rec_print_old(stderr, btr_pcur_get_rec(&pcur)); + } + } + ibuf_mtr_commit(&mtr); + ib::info() << "Dumped the change buffer"; +#endif + return (error); } diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index 93c2f570e54..bea08f398de 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. 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 @@ -96,6 +96,8 @@ typedef ib_mutex_t DictSysMutex; #define TEMP_TABLE_PATH_PREFIX "/" TEMP_TABLE_PREFIX #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG +/** Dump the change buffer at startup */ +extern my_bool ibuf_dump; /** Flag to control insert buffer debugging. */ extern uint ibuf_debug; #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ -- 2.30.9