From 1a5c7552ea3a0233e7abff56a167c3a532c7da0a Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 14 Feb 2023 14:36:17 +0530 Subject: MDEV-30552 InnoDB recovery crashes when error handling scenario - InnoDB fails to reset the after_apply variable before applying the redo log in last batch during multi-batch recovery. --- mysql-test/suite/innodb/r/recovery_memory.result | 20 ++++++++++++++++++++ mysql-test/suite/innodb/t/recovery_memory.test | 21 +++++++++++++++++++++ storage/innobase/ibuf/ibuf0ibuf.cc | 4 ++++ storage/innobase/log/log0recv.cc | 5 +++++ 4 files changed, 50 insertions(+) diff --git a/mysql-test/suite/innodb/r/recovery_memory.result b/mysql-test/suite/innodb/r/recovery_memory.result index 4fa31009130..6faea097616 100644 --- a/mysql-test/suite/innodb/r/recovery_memory.result +++ b/mysql-test/suite/innodb/r/recovery_memory.result @@ -1,3 +1,7 @@ +call mtr.add_suppression("InnoDB: The change buffer is corrupted"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted at srv0start.cc"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); CREATE TABLE t1(c TEXT, KEY(c(3072)))ENGINE=InnoDB; CREATE PROCEDURE dorepeat() LOOP @@ -10,3 +14,19 @@ CALL dorepeat(); connection default; # restart: --innodb_buffer_pool_size=5242880 DROP TABLE t1; +DROP PROCEDURE dorepeat; +# +# MDEV-30552 InnoDB recovery crashes when error +# handling scenario +# +SET DEBUG_DBUG="+d,ib_log_checkpoint_avoid_hard"; +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +INSERT INTO t1 SELECT * FROM seq_1_to_65536; +# restart: --innodb_buffer_pool_size=5242880 --debug_dbug=+d,ibuf_init_corrupt +# restart +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/recovery_memory.test b/mysql-test/suite/innodb/t/recovery_memory.test index d9afd52c499..e723ba25d36 100644 --- a/mysql-test/suite/innodb/t/recovery_memory.test +++ b/mysql-test/suite/innodb/t/recovery_memory.test @@ -1,5 +1,10 @@ --source include/have_innodb.inc --source include/big_test.inc +--source include/have_sequence.inc +call mtr.add_suppression("InnoDB: The change buffer is corrupted"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted at srv0start.cc"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); CREATE TABLE t1(c TEXT, KEY(c(3072)))ENGINE=InnoDB; DELIMITER |; @@ -19,3 +24,19 @@ let $shutdown_timeout=0; let $restart_parameters=--innodb_buffer_pool_size=5242880; --source include/restart_mysqld.inc DROP TABLE t1; +DROP PROCEDURE dorepeat; + +--echo # +--echo # MDEV-30552 InnoDB recovery crashes when error +--echo # handling scenario +--echo # +SET DEBUG_DBUG="+d,ib_log_checkpoint_avoid_hard"; +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +INSERT INTO t1 SELECT * FROM seq_1_to_65536; +let $shutdown_timeout=0; +let $restart_parameters=--innodb_buffer_pool_size=5242880 --debug_dbug="+d,ibuf_init_corrupt"; +--source include/restart_mysqld.inc +let $restart_parameters=; +--source include/restart_mysqld.inc +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index d88c2b0027e..dff0ad57057 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -450,6 +450,10 @@ err_exit: root = buf_block_get_frame(block); } + DBUG_EXECUTE_IF("ibuf_init_corrupt", + err = DB_CORRUPTION; + goto err_exit;); + if (page_is_comp(root) || fil_page_get_type(root) != FIL_PAGE_INDEX || btr_page_get_index_id(root) != DICT_IBUF_ID_MIN) { err = DB_CORRUPTION; diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index eb2931adf0e..9b4ceb4f03e 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -3642,6 +3642,11 @@ completed: mysql_mutex_unlock(&log_sys.mutex); return(DB_ERROR); } + + /* In case of multi-batch recovery, + redo log for the last batch is not + applied yet. */ + ut_d(recv_sys.after_apply = false); } } else { ut_ad(!rescan || recv_sys.pages.empty()); -- cgit v1.2.1