diff --git a/mysql-test/suite/innodb/r/innodb_force_recovery_rollback.result b/mysql-test/suite/innodb/r/innodb_force_recovery_rollback.result new file mode 100644 index 0000000000000..dc037fd6c97d2 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_force_recovery_rollback.result @@ -0,0 +1,17 @@ +FLUSH TABLES; +# +# MDEV-21217 innodb_force_recovery=2 may wrongly abort the rollback +# of recovered transactions +# +connect con0,localhost,root; +CREATE TABLE t0 (a INT PRIMARY KEY) ENGINE=InnoDB; +BEGIN; +INSERT INTO t0 SELECT * FROM seq_1_to_1000; +connection default; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +disconnect con0; +connection default; +SELECT * FROM t0 LOCK IN SHARE MODE; +a +DROP TABLE t0,t1; diff --git a/mysql-test/suite/innodb/t/innodb_force_recovery_rollback.test b/mysql-test/suite/innodb/t/innodb_force_recovery_rollback.test new file mode 100644 index 0000000000000..ad234eba72ee7 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_force_recovery_rollback.test @@ -0,0 +1,34 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc + +# We will kill and restart the server. +--source include/not_embedded.inc +FLUSH TABLES; + +--echo # +--echo # MDEV-21217 innodb_force_recovery=2 may wrongly abort the rollback +--echo # of recovered transactions +--echo # + +connect (con0,localhost,root); +CREATE TABLE t0 (a INT PRIMARY KEY) ENGINE=InnoDB; +# Create enough undo log so that the rollback may take enough time. +BEGIN; +INSERT INTO t0 SELECT * FROM seq_1_to_1000; + +connection default; +# Persist the above incomplete transaction. +SET GLOBAL innodb_flush_log_at_trx_commit=1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; + +--let $restart_parameters= --innodb-force-recovery=2 +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc +--let $restart_parameters= +--let $shutdown_timeout= + +disconnect con0; +connection default; +# If the rollback was aborted, we would end up in a lock wait here. +SELECT * FROM t0 LOCK IN SHARE MODE; +DROP TABLE t0,t1; diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 9c63c68f84f40..127cfc9b07d74 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -750,7 +750,7 @@ trx_roll_must_shutdown() ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE - && !srv_is_being_started + && srv_shutdown_state != SRV_SHUTDOWN_NONE && !srv_undo_sources && srv_fast_shutdown) { return true; }