From f1627045701b0dc0ff10ec09cca18dc5da351768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 30 Jan 2017 17:00:51 +0200 Subject: [PATCH] Rewrite the innodb.log_file_size test with DBUG_EXECUTE_IF. Remove the debug parameter innodb_force_recovery_crash that was introduced into MySQL 5.6 by me in WL#6494 which allowed InnoDB to resize the redo log on startup. Let innodb.log_file_size actually start up the server, but ensure that the InnoDB storage engine refuses to start up in each of the scenarios. --- .../suite/innodb/r/log_file_size.result | 60 ++++++- mysql-test/suite/innodb/t/log_file_size.test | 162 +++++++++++------- .../innodb_force_recovery_crash_basic.result | 33 ---- .../t/innodb_force_recovery_crash_basic.test | 28 --- storage/innobase/handler/ha_innodb.cc | 12 +- storage/innobase/include/srv0srv.h | 3 - storage/innobase/srv/srv0srv.cc | 5 - storage/innobase/srv/srv0start.cc | 103 ++++++----- storage/xtradb/handler/ha_innodb.cc | 10 -- storage/xtradb/include/srv0srv.h | 3 - storage/xtradb/srv/srv0srv.cc | 5 - storage/xtradb/srv/srv0start.cc | 101 ++++++----- 12 files changed, 267 insertions(+), 258 deletions(-) delete mode 100644 mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result delete mode 100644 mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test diff --git a/mysql-test/suite/innodb/r/log_file_size.result b/mysql-test/suite/innodb/r/log_file_size.result index d83af09997989..d0b389379e771 100644 --- a/mysql-test/suite/innodb/r/log_file_size.result +++ b/mysql-test/suite/innodb/r/log_file_size.result @@ -15,15 +15,57 @@ INSERT INTO t1 VALUES (123); BEGIN; DELETE FROM t1; # Kill the server ---innodb-force-recovery-crash=1 ---innodb-force-recovery-crash=3 ---innodb-force-recovery-crash=4 ---innodb-force-recovery-crash=5 ---innodb-force-recovery-crash=6 ---innodb-force-recovery-crash=7 ---innodb-force-recovery-crash=8 ---innodb-force-recovery-crash=9 ---innodb-force-recovery-crash=10 +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /syntax error in innodb_log_group_home_dir/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: innodb_read_only prevents crash recovery/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err +FOUND /InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err +FOUND /InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: innodb_read_only prevents crash recovery/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Starting an apply batch of log records/ in mysqld.1.err +FOUND /InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Cannot create log files in read-only mode/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Setting log file .*ib_logfile[0-9]+ size to/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Setting log file .*ib_logfile[0-9]+ size to/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Only one log file found/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Log file .*ib_logfile0 size 7 is not a multiple of innodb_page_size/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Log file .*ib_logfile1 is of different size 1048576 bytes than other log files/ in mysqld.1.err +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +FOUND /InnoDB: Setting log file .*ib_logfile[0-9]+ size to/ in mysqld.1.err +FOUND /InnoDB: Renaming log file .*ib_logfile101 to .*ib_logfile0/ in mysqld.1.err SELECT * FROM t1; a 42 diff --git a/mysql-test/suite/innodb/t/log_file_size.test b/mysql-test/suite/innodb/t/log_file_size.test index e1a312df59a07..ae63ee6e13319 100644 --- a/mysql-test/suite/innodb/t/log_file_size.test +++ b/mysql-test/suite/innodb/t/log_file_size.test @@ -6,7 +6,7 @@ --source include/not_embedded.inc # Avoid CrashReporter popup on Mac --source include/not_crashrep.inc -# innodb-force-recovery-crash needs debug +# DBUG_EXECUTE_IF is needed --source include/have_debug.inc if (`SELECT @@innodb_log_file_size = 1048576`) { @@ -17,7 +17,22 @@ if (`SELECT @@innodb_log_file_size = 1048576`) { call mtr.add_suppression("InnoDB: Resizing redo log"); call mtr.add_suppression("InnoDB: Starting to delete and rewrite log files"); call mtr.add_suppression("InnoDB: New log files created"); +# This message is output by 10.0 and 10.1, not by 10.2 +call mtr.add_suppression("InnoDB: The log sequence number in the ibdata files is higher than the log sequence number in the ib_logfiles"); call mtr.add_suppression("InnoDB: The log sequence numbers [0-9]+ and [0-9]+ in ibdata files do not match the log sequence number [0-9]+ in the ib_logfiles"); +call mtr.add_suppression("syntax error in innodb_log_group_home_dir"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("InnoDB: innodb_read_only prevents crash recovery"); +call mtr.add_suppression("InnoDB: Are you sure you are using the right ib_logfiles"); +call mtr.add_suppression("InnoDB: Cannot create log files in read-only mode"); +call mtr.add_suppression("InnoDB: Only one log file found"); +call mtr.add_suppression("InnoDB: Log file .*ib_logfile[01].* size"); +call mtr.add_suppression("InnoDB: Unable to open .*ib_logfile0. to check native AIO read support"); +# InnoDB shutdown after refused startup is not clean in 10.0 or 10.1! +call mtr.add_suppression("mysqld got signal 11"); +call mtr.add_suppression("Attempting backtrace"); FLUSH TABLES; --enable_query_log @@ -42,106 +57,122 @@ SELECT * FROM t1; INSERT INTO t1 VALUES (123); let MYSQLD_DATADIR= `select @@datadir`; -let SEARCH_ABORT = NOT FOUND; -let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err; -let $args=--innodb --unknown-option --loose-console --core-file > $SEARCH_FILE 2>&1; -let $crash=--innodb --unknown-option --loose-console > $SEARCH_FILE 2>&1 --innodb-force-recovery-crash; +let SEARCH_RANGE= -50000; +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; BEGIN; DELETE FROM t1; --source include/kill_mysqld.inc ---error 2 ---exec $MYSQLD_CMD $args --innodb-log-group-home-dir=foo\;bar +--let $restart_parameters= --innodb-log-group-home-dir=foo\;bar +--source include/start_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= syntax error in innodb_log_group_home_dir; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=1 ---error 3 ---exec $MYSQLD_CMD $crash=1 +--let $restart_parameters= --debug=d,innodb_log_abort_1 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=3 ---error 3 ---exec $MYSQLD_CMD $crash=3 + +--let $restart_parameters= --debug=d,innodb_log_abort_3 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---error 2 ---exec $MYSQLD_CMD $args --innodb-read-only +--let $restart_parameters= --innodb-read-only +--source include/restart_mysqld.inc + +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= InnoDB: innodb_read_only prevents crash recovery; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=4 ---error 3 ---exec $MYSQLD_CMD $crash=4 +--let $restart_parameters= --debug=d,innodb_log_abort_4 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; --source include/search_pattern_in_file.inc let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=5 ---error 3 ---exec $MYSQLD_CMD $crash=5 + +--let $restart_parameters= --debug=d,innodb_log_abort_5 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; --source include/search_pattern_in_file.inc let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---error 2 ---exec $MYSQLD_CMD $args --innodb-read-only +--let $restart_parameters= --innodb-read-only +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= InnoDB: innodb_read_only prevents crash recovery; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=6 ---error 3 ---exec $MYSQLD_CMD $crash=6 +--let $restart_parameters= --debug=d,innodb_log_abort_6 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + let SEARCH_PATTERN= InnoDB: Starting an apply batch of log records; --source include/search_pattern_in_file.inc let SEARCH_PATTERN= InnoDB: Resizing redo log from 3\*[0-9]+ to 2\*[0-9]+ pages; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=7 ---error 3 ---exec $MYSQLD_CMD $crash=7 -# this crashes right after deleting all log files ---remove_file $SEARCH_FILE ---error 2 ---exec $MYSQLD_CMD $args --innodb-read-only +--let $restart_parameters= --debug=d,innodb_log_abort_7 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + +# this aborts right after deleting all log files + +--let $restart_parameters= --innodb-read-only +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + let SEARCH_PATTERN= InnoDB: Cannot create log files in read-only mode; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=8 ---error 3 ---exec $MYSQLD_CMD $crash=8 +--let $restart_parameters= --debug=d,innodb_log_abort_8 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE ---echo --innodb-force-recovery-crash=9 ---error 3 ---exec $MYSQLD_CMD $crash=9 + +--let $restart_parameters= --debug=d,innodb_log_abort_9 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE +--source include/shutdown_mysqld.inc # We should have perfectly synced files here. # Rename the log files, and trigger an error in recovery. --move_file $MYSQLD_DATADIR/ib_logfile101 $MYSQLD_DATADIR/ib_logfile0 --move_file $MYSQLD_DATADIR/ib_logfile1 $MYSQLD_DATADIR/ib_logfile1_hidden ---error 2 ---exec $MYSQLD_CMD $args + +--let $restart_parameters= +--source include/start_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + let SEARCH_PATTERN= InnoDB: Only one log file found; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE --move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile101 perl; @@ -149,11 +180,12 @@ die unless open(FILE, ">$ENV{MYSQLD_DATADIR}/ib_logfile0"); print FILE "garbage"; close(FILE); EOF ---error 2 ---exec $MYSQLD_CMD $args + +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; let SEARCH_PATTERN= InnoDB: Log file .*ib_logfile0 size 7 is not a multiple of innodb_page_size; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE --remove_file $MYSQLD_DATADIR/ib_logfile0 --move_file $MYSQLD_DATADIR/ib_logfile101 $MYSQLD_DATADIR/ib_logfile0 @@ -163,26 +195,28 @@ print FILE "junkfill" x 131072; close(FILE); EOF ---error 2 ---exec $MYSQLD_CMD $args +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + let SEARCH_PATTERN= InnoDB: Log file .*ib_logfile1 is of different size 1048576 bytes than other log files; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE --remove_file $MYSQLD_DATADIR/ib_logfile1 --move_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile101 --move_file $MYSQLD_DATADIR/ib_logfile1_hidden $MYSQLD_DATADIR/ib_logfile1 ---echo --innodb-force-recovery-crash=10 ---error 3 ---exec $MYSQLD_CMD $crash=10 +--let $restart_parameters= --debug=d,innodb_log_abort_10 +--source include/restart_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; + let SEARCH_PATTERN= InnoDB: Setting log file .*ib_logfile[0-9]+ size to; --source include/search_pattern_in_file.inc let SEARCH_PATTERN= InnoDB: Renaming log file .*ib_logfile101 to .*ib_logfile0; --source include/search_pattern_in_file.inc ---remove_file $SEARCH_FILE --let $restart_parameters= ---source include/start_mysqld.inc +--source include/restart_mysqld.inc SELECT * FROM t1; DROP TABLE t1; diff --git a/mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result b/mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result deleted file mode 100644 index 5af00f21c74e2..0000000000000 --- a/mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result +++ /dev/null @@ -1,33 +0,0 @@ -select @@global.innodb_force_recovery_crash in (0, 1); -@@global.innodb_force_recovery_crash in (0, 1) -1 -select @@global.innodb_force_recovery_crash; -@@global.innodb_force_recovery_crash -0 -select @@session.innodb_force_recovery_crash; -ERROR HY000: Variable 'innodb_force_recovery_crash' is a GLOBAL variable -show global variables like 'innodb_force_recovery_crash'; -Variable_name Value -innodb_force_recovery_crash 0 -show session variables like 'innodb_force_recovery_crash'; -Variable_name Value -innodb_force_recovery_crash 0 -select * from information_schema.global_variables where variable_name='innodb_force_recovery_crash'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_FORCE_RECOVERY_CRASH 0 -select * from information_schema.session_variables where variable_name='innodb_force_recovery_crash'; -VARIABLE_NAME VARIABLE_VALUE -INNODB_FORCE_RECOVERY_CRASH 0 -set global innodb_force_recovery_crash=1; -ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable -set global innodb_force_recovery_crash=0; -ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable -select @@global.innodb_force_recovery_crash; -@@global.innodb_force_recovery_crash -0 -set session innodb_force_recovery_crash='some'; -ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable -set @@session.innodb_force_recovery_crash='some'; -ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable -set global innodb_force_recovery_crash='some'; -ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable diff --git a/mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test b/mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test deleted file mode 100644 index 5eefe1b9219b1..0000000000000 --- a/mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test +++ /dev/null @@ -1,28 +0,0 @@ ---source include/have_innodb.inc ---source include/have_debug.inc - -# -# exists as global only -# -select @@global.innodb_force_recovery_crash in (0, 1); -select @@global.innodb_force_recovery_crash; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.innodb_force_recovery_crash; -show global variables like 'innodb_force_recovery_crash'; -show session variables like 'innodb_force_recovery_crash'; -select * from information_schema.global_variables where variable_name='innodb_force_recovery_crash'; -select * from information_schema.session_variables where variable_name='innodb_force_recovery_crash'; - -# show that it's read-only -# ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -set global innodb_force_recovery_crash=1; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -set global innodb_force_recovery_crash=0; -select @@global.innodb_force_recovery_crash; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -set session innodb_force_recovery_crash='some'; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -set @@session.innodb_force_recovery_crash='some'; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -set global innodb_force_recovery_crash='some'; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2c84530e6ac9e..91a507ef1b9c0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4,7 +4,7 @@ Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2016, MariaDB Corporation. +Copyright (c) 2013, 2017, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -16968,13 +16968,6 @@ static MYSQL_SYSVAR_ULONG(force_recovery, srv_force_recovery, "Helps to save your data in case the disk image of the database becomes corrupt.", NULL, NULL, 0, 0, 6, 0); -#ifndef DBUG_OFF -static MYSQL_SYSVAR_ULONG(force_recovery_crash, srv_force_recovery_crash, - PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Kills the server during crash recovery.", - NULL, NULL, 0, 0, 10, 0); -#endif /* !DBUG_OFF */ - static MYSQL_SYSVAR_ULONG(page_size, srv_page_size, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Page size to use for all InnoDB tablespaces.", @@ -17343,9 +17336,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(flush_log_at_trx_commit), MYSQL_SYSVAR(flush_method), MYSQL_SYSVAR(force_recovery), -#ifndef DBUG_OFF - MYSQL_SYSVAR(force_recovery_crash), -#endif /* !DBUG_OFF */ MYSQL_SYSVAR(ft_cache_size), MYSQL_SYSVAR(ft_total_cache_size), MYSQL_SYSVAR(ft_result_cache_limit), diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 9e016b90bf393..c4c3f5f834475 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -345,9 +345,6 @@ extern double srv_adaptive_flushing_lwm; extern ulong srv_flushing_avg_loops; extern ulong srv_force_recovery; -#ifndef DBUG_OFF -extern ulong srv_force_recovery_crash; -#endif /* !DBUG_OFF */ extern ulint srv_fast_shutdown; /*!< If this is 1, do not do a purge and index buffer merge. diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index eb82d7bcb2f2f..cc69065ff249f 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -313,11 +313,6 @@ starting from SRV_FORCE_IGNORE_CORRUPT, so that data can be recovered by SELECT or mysqldump. When this is nonzero, we do not allow any user modifications to the data. */ UNIV_INTERN ulong srv_force_recovery; -#ifndef DBUG_OFF -/** Inject a crash at different steps of the recovery process. -This is for testing and debugging only. */ -UNIV_INTERN ulong srv_force_recovery_crash; -#endif /* !DBUG_OFF */ /** Print all user-level transactions deadlocks to mysqld stderr */ diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 0e7d4b6c51197..5fd3adb3191ab 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -579,19 +579,6 @@ create_log_file( /** Initial number of the first redo log file */ #define INIT_LOG_FILE0 (SRV_N_LOG_FILES_MAX + 1) -#ifdef DBUG_OFF -# define RECOVERY_CRASH(x) do {} while(0) -#else -# define RECOVERY_CRASH(x) do { \ - if (srv_force_recovery_crash == x) { \ - fprintf(stderr, "innodb_force_recovery_crash=%lu\n", \ - srv_force_recovery_crash); \ - fflush(stderr); \ - exit(3); \ - } \ -} while (0) -#endif - /*********************************************************************//** Creates all log files. @return DB_SUCCESS or error code */ @@ -632,13 +619,14 @@ create_log_files( file should be recoverable. The buffer pool was clean, and we can simply create all log files from the scratch. */ - RECOVERY_CRASH(6); + DBUG_EXECUTE_IF("innodb_log_abort_6", + return(DB_ERROR);); } } ut_ad(!buf_pool_check_no_pending_io()); - RECOVERY_CRASH(7); + DBUG_EXECUTE_IF("innodb_log_abort_7", return(DB_ERROR);); for (unsigned i = 0; i < srv_n_log_files; i++) { sprintf(logfilename + dirnamelen, @@ -651,7 +639,7 @@ create_log_files( } } - RECOVERY_CRASH(8); + DBUG_EXECUTE_IF("innodb_log_abort_8", return(DB_ERROR);); /* We did not create the first log file initially as ib_logfile0, so that crash recovery cannot find it until it @@ -696,10 +684,16 @@ create_log_files( return(DB_SUCCESS); } -/*********************************************************************//** -Renames the first log file. */ +/** Rename the first redo log file. +@param[in,out] logfilename buffer for the log file name +@param[in] dirnamelen length of the directory path +@param[in] lsn FIL_PAGE_FILE_FLUSH_LSN value +@param[in,out] logfile0 name of the first log file +@return error code +@retval DB_SUCCESS on successful operation */ +MY_ATTRIBUTE((warn_unused_result, nonnull)) static -void +dberr_t create_log_files_rename( /*====================*/ char* logfilename, /*!< in/out: buffer for log file name */ @@ -710,6 +704,9 @@ create_log_files_rename( /* If innodb_flush_method=O_DSYNC, we need to explicitly flush the log buffers. */ fil_flush(SRV_LOG_SPACE_FIRST_ID); + + DBUG_EXECUTE_IF("innodb_log_abort_9", return(DB_ERROR);); + /* Close the log files, so that we can rename the first one. */ fil_close_log_files(false); @@ -718,26 +715,28 @@ create_log_files_rename( checkpoint has been created. */ sprintf(logfilename + dirnamelen, "ib_logfile%u", 0); - RECOVERY_CRASH(9); - ib_logf(IB_LOG_LEVEL_INFO, "Renaming log file %s to %s", logfile0, logfilename); mutex_enter(&log_sys->mutex); ut_ad(strlen(logfile0) == 2 + strlen(logfilename)); - ibool success = os_file_rename( - innodb_file_log_key, logfile0, logfilename); - ut_a(success); - - RECOVERY_CRASH(10); + dberr_t err = os_file_rename( + innodb_file_log_key, logfile0, logfilename) + ? DB_SUCCESS : DB_ERROR; /* Replace the first file with ib_logfile0. */ strcpy(logfile0, logfilename); mutex_exit(&log_sys->mutex); - fil_open_log_and_system_tablespace_files(); + DBUG_EXECUTE_IF("innodb_log_abort_10", err = DB_ERROR;); + + if (err == DB_SUCCESS) { + fil_open_log_and_system_tablespace_files(); + ib_logf(IB_LOG_LEVEL_WARN, + "New log files created, LSN=" LSN_PF, lsn); + } - ib_logf(IB_LOG_LEVEL_WARN, "New log files created, LSN=" LSN_PF, lsn); + return(err); } /*********************************************************************//** @@ -2196,14 +2195,18 @@ innobase_start_or_create_for_mysql(void) dirnamelen, max_flushed_lsn, logfile0); + if (err == DB_SUCCESS) { + err = create_log_files_rename( + logfilename, + dirnamelen, + max_flushed_lsn, + logfile0); + } + if (err != DB_SUCCESS) { return(err); } - create_log_files_rename( - logfilename, dirnamelen, - max_flushed_lsn, logfile0); - /* Suppress the message about crash recovery. */ max_flushed_lsn = min_flushed_lsn @@ -2371,8 +2374,12 @@ innobase_start_or_create_for_mysql(void) fil_flush_file_spaces(FIL_TABLESPACE); - create_log_files_rename(logfilename, dirnamelen, - max_flushed_lsn, logfile0); + err = create_log_files_rename(logfilename, dirnamelen, + max_flushed_lsn, logfile0); + + if (err != DB_SUCCESS) { + return(err); + } #ifdef UNIV_LOG_ARCHIVE } else if (srv_archive_recovery) { @@ -2593,7 +2600,8 @@ innobase_start_or_create_for_mysql(void) ULINT_MAX, LSN_MAX, NULL); ut_a(success); - RECOVERY_CRASH(1); + DBUG_EXECUTE_IF("innodb_log_abort_1", + return(DB_ERROR);); min_flushed_lsn = max_flushed_lsn = log_get_lsn(); @@ -2608,8 +2616,6 @@ innobase_start_or_create_for_mysql(void) buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); - RECOVERY_CRASH(2); - /* Flush the old log files. */ log_buffer_flush_to_disk(); /* If innodb_flush_method=O_DSYNC, @@ -2624,21 +2630,27 @@ innobase_start_or_create_for_mysql(void) ut_d(recv_no_log_write = TRUE); ut_ad(!buf_pool_check_no_pending_io()); - RECOVERY_CRASH(3); + DBUG_EXECUTE_IF("innodb_log_abort_3", + return(DB_ERROR);); /* Stamp the LSN to the data files. */ fil_write_flushed_lsn_to_data_files( max_flushed_lsn, 0); - fil_flush_file_spaces(FIL_TABLESPACE); + DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;); - RECOVERY_CRASH(4); + if (err != DB_SUCCESS) { + return(err); + } + + fil_flush_file_spaces(FIL_TABLESPACE); /* Close and free the redo log files, so that we can replace them. */ fil_close_log_files(true); - RECOVERY_CRASH(5); + DBUG_EXECUTE_IF("innodb_log_abort_5", + return(DB_ERROR);); /* Free the old log file space. */ log_group_close_all(); @@ -2652,12 +2664,15 @@ innobase_start_or_create_for_mysql(void) dirnamelen, max_flushed_lsn, logfile0); + if (err == DB_SUCCESS) { + err = create_log_files_rename( + logfilename, dirnamelen, + max_flushed_lsn, logfile0); + } + if (err != DB_SUCCESS) { return(err); } - - create_log_files_rename(logfilename, dirnamelen, - max_flushed_lsn, logfile0); } srv_startup_is_before_trx_rollback_phase = FALSE; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 1709d4e59a9b9..a35fa459c7fad 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -18508,13 +18508,6 @@ static MYSQL_SYSVAR_ULONG(force_recovery, srv_force_recovery, "Helps to save your data in case the disk image of the database becomes corrupt.", NULL, NULL, 0, 0, 6, 0); -#ifndef DBUG_OFF -static MYSQL_SYSVAR_ULONG(force_recovery_crash, srv_force_recovery_crash, - PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, - "Kills the server during crash recovery.", - NULL, NULL, 0, 0, 10, 0); -#endif /* !DBUG_OFF */ - static MYSQL_SYSVAR_ULONG(page_size, srv_page_size, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Page size to use for all InnoDB tablespaces.", @@ -18946,9 +18939,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(use_global_flush_log_at_trx_commit), MYSQL_SYSVAR(flush_method), MYSQL_SYSVAR(force_recovery), -#ifndef DBUG_OFF - MYSQL_SYSVAR(force_recovery_crash), -#endif /* !DBUG_OFF */ MYSQL_SYSVAR(ft_cache_size), MYSQL_SYSVAR(ft_total_cache_size), MYSQL_SYSVAR(ft_result_cache_limit), diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 8f5ea21712c98..9d4b6cd9557c0 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -419,9 +419,6 @@ extern double srv_adaptive_flushing_lwm; extern ulong srv_flushing_avg_loops; extern ulong srv_force_recovery; -#ifndef DBUG_OFF -extern ulong srv_force_recovery_crash; -#endif /* !DBUG_OFF */ extern ulint srv_fast_shutdown; /*!< If this is 1, do not do a purge and index buffer merge. diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index e5b2062b2174b..a6dc9a0140792 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -426,11 +426,6 @@ starting from SRV_FORCE_IGNORE_CORRUPT, so that data can be recovered by SELECT or mysqldump. When this is nonzero, we do not allow any user modifications to the data. */ UNIV_INTERN ulong srv_force_recovery; -#ifndef DBUG_OFF -/** Inject a crash at different steps of the recovery process. -This is for testing and debugging only. */ -UNIV_INTERN ulong srv_force_recovery_crash; -#endif /* !DBUG_OFF */ /** Print all user-level transactions deadlocks to mysqld stderr */ diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index a19f120a7d880..a9d6fc91f0270 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -609,19 +609,6 @@ create_log_file( /** Initial number of the first redo log file */ #define INIT_LOG_FILE0 (SRV_N_LOG_FILES_MAX + 1) -#ifdef DBUG_OFF -# define RECOVERY_CRASH(x) do {} while(0) -#else -# define RECOVERY_CRASH(x) do { \ - if (srv_force_recovery_crash == x) { \ - fprintf(stderr, "innodb_force_recovery_crash=%lu\n", \ - srv_force_recovery_crash); \ - fflush(stderr); \ - exit(3); \ - } \ -} while (0) -#endif - /*********************************************************************//** Creates all log files. @return DB_SUCCESS or error code */ @@ -662,13 +649,14 @@ create_log_files( file should be recoverable. The buffer pool was clean, and we can simply create all log files from the scratch. */ - RECOVERY_CRASH(6); + DBUG_EXECUTE_IF("innodb_log_abort_6", + return(DB_ERROR);); } } ut_ad(!buf_pool_check_no_pending_io()); - RECOVERY_CRASH(7); + DBUG_EXECUTE_IF("innodb_log_abort_7", return(DB_ERROR);); for (unsigned i = 0; i < srv_n_log_files; i++) { sprintf(logfilename + dirnamelen, @@ -681,7 +669,7 @@ create_log_files( } } - RECOVERY_CRASH(8); + DBUG_EXECUTE_IF("innodb_log_abort_8", return(DB_ERROR);); /* We did not create the first log file initially as ib_logfile0, so that crash recovery cannot find it until it @@ -736,10 +724,16 @@ create_log_files( return(DB_SUCCESS); } -/*********************************************************************//** -Renames the first log file. */ +/** Rename the first redo log file. +@param[in,out] logfilename buffer for the log file name +@param[in] dirnamelen length of the directory path +@param[in] lsn FIL_PAGE_FILE_FLUSH_LSN value +@param[in,out] logfile0 name of the first log file +@return error code +@retval DB_SUCCESS on successful operation */ +MY_ATTRIBUTE((warn_unused_result, nonnull)) static -void +dberr_t create_log_files_rename( /*====================*/ char* logfilename, /*!< in/out: buffer for log file name */ @@ -750,6 +744,9 @@ create_log_files_rename( /* If innodb_flush_method=O_DSYNC, we need to explicitly flush the log buffers. */ fil_flush(SRV_LOG_SPACE_FIRST_ID); + + DBUG_EXECUTE_IF("innodb_log_abort_9", return(DB_ERROR);); + /* Close the log files, so that we can rename the first one. */ fil_close_log_files(false); @@ -758,26 +755,28 @@ create_log_files_rename( checkpoint has been created. */ sprintf(logfilename + dirnamelen, "ib_logfile%u", 0); - RECOVERY_CRASH(9); - ib_logf(IB_LOG_LEVEL_INFO, "Renaming log file %s to %s", logfile0, logfilename); mutex_enter(&log_sys->mutex); ut_ad(strlen(logfile0) == 2 + strlen(logfilename)); - ibool success = os_file_rename( - innodb_file_log_key, logfile0, logfilename); - ut_a(success); - - RECOVERY_CRASH(10); + dberr_t err = os_file_rename( + innodb_file_log_key, logfile0, logfilename) + ? DB_SUCCESS : DB_ERROR; /* Replace the first file with ib_logfile0. */ strcpy(logfile0, logfilename); mutex_exit(&log_sys->mutex); - fil_open_log_and_system_tablespace_files(); + DBUG_EXECUTE_IF("innodb_log_abort_10", err = DB_ERROR;); + + if (err == DB_SUCCESS) { + fil_open_log_and_system_tablespace_files(); + ib_logf(IB_LOG_LEVEL_WARN, + "New log files created, LSN=" LSN_PF, lsn); + } - ib_logf(IB_LOG_LEVEL_WARN, "New log files created, LSN=" LSN_PF, lsn); + return(err); } /*********************************************************************//** @@ -2274,14 +2273,18 @@ innobase_start_or_create_for_mysql(void) dirnamelen, max_flushed_lsn, logfile0); + if (err == DB_SUCCESS) { + err = create_log_files_rename( + logfilename, + dirnamelen, + max_flushed_lsn, + logfile0); + } + if (err != DB_SUCCESS) { return(err); } - create_log_files_rename( - logfilename, dirnamelen, - max_flushed_lsn, logfile0); - /* Suppress the message about crash recovery. */ max_flushed_lsn = min_flushed_lsn @@ -2450,8 +2453,12 @@ innobase_start_or_create_for_mysql(void) fil_flush_file_spaces(FIL_TABLESPACE); - create_log_files_rename(logfilename, dirnamelen, - max_flushed_lsn, logfile0); + err = create_log_files_rename(logfilename, dirnamelen, + max_flushed_lsn, logfile0); + + if (err != DB_SUCCESS) { + return(err); + } } else { /* Check if we support the max format that is stamped @@ -2642,7 +2649,8 @@ innobase_start_or_create_for_mysql(void) ULINT_MAX, LSN_MAX, NULL); ut_a(success); - RECOVERY_CRASH(1); + DBUG_EXECUTE_IF("innodb_log_abort_1", + return(DB_ERROR);); min_flushed_lsn = max_flushed_lsn = log_get_lsn(); @@ -2657,8 +2665,6 @@ innobase_start_or_create_for_mysql(void) buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); - RECOVERY_CRASH(2); - /* Flush the old log files. */ log_buffer_flush_to_disk(); /* If innodb_flush_method=O_DSYNC, @@ -2673,21 +2679,27 @@ innobase_start_or_create_for_mysql(void) ut_d(recv_no_log_write = TRUE); ut_ad(!buf_pool_check_no_pending_io()); - RECOVERY_CRASH(3); + DBUG_EXECUTE_IF("innodb_log_abort_3", + return(DB_ERROR);); /* Stamp the LSN to the data files. */ fil_write_flushed_lsn_to_data_files( max_flushed_lsn, 0); - fil_flush_file_spaces(FIL_TABLESPACE); + DBUG_EXECUTE_IF("innodb_log_abort_4", err = DB_ERROR;); - RECOVERY_CRASH(4); + if (err != DB_SUCCESS) { + return(err); + } + + fil_flush_file_spaces(FIL_TABLESPACE); /* Close and free the redo log files, so that we can replace them. */ fil_close_log_files(true); - RECOVERY_CRASH(5); + DBUG_EXECUTE_IF("innodb_log_abort_5", + return(DB_ERROR);); /* Free the old log file space. */ log_group_close_all(); @@ -2711,8 +2723,11 @@ innobase_start_or_create_for_mysql(void) fil_write_flushed_lsn_to_data_files(min_flushed_lsn, 0); fil_flush_file_spaces(FIL_TABLESPACE); - create_log_files_rename(logfilename, dirnamelen, - log_get_lsn(), logfile0); + err = create_log_files_rename(logfilename, dirnamelen, + log_get_lsn(), logfile0); + if (err != DB_SUCCESS) { + return(err); + } } srv_startup_is_before_trx_rollback_phase = FALSE;