[MDEV-12030] innodb_fast_shutdown should not wait for rollback to finish Created: 2017-02-09  Updated: 2017-03-14  Resolved: 2017-03-14

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.0, 10.1, 10.2
Fix Version/s: 10.1.23, 10.2.5, 10.0.31

Type: Bug Priority: Major
Reporter: Marko Mäkelä Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: innodb, recovery, shutdown

Issue Links:
Duplicate
duplicates MDEV-12091 Shutdown fails to wait for rollback o... Closed

 Description   

InnoDB shutdown is effectively waiting for the rollback of recovered transactions to finish, even though the intention seems to be to only do this when a slow shutdown (innodb_fast_shutdown=0) has been requested:

	ib_logf(IB_LOG_LEVEL_INFO, "Starting shutdown...");
 
	while (srv_fast_shutdown == 0 && trx_rollback_or_clean_is_active) {
		/* we should wait until rollback after recovery end
		for slow shutdown */
		os_thread_sleep(100000);
	}

Below is the output from XtraDB shutdown with innodb_fast_shutdown=2. It shows that we are indirectly waiting for the rollback somewhere later in logs_empty_and_mark_files_at_shutdown().

170209 10:58:21 [Note] InnoDB: Starting shutdown...
 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100170209 10:58:31 [Note] InnoDB: Rollback of trx with id 1286 completed
2017-02-09 10:58:31 7fb4fed13700  InnoDB: Rollback of non-prepared transactions completed
170209 10:58:32 [Note] InnoDB: Waiting for page_cleaner to finish flushing of buffer pool
170209 10:58:32 [Note] InnoDB: MySQL has requested a very fast shutdown without flushing the InnoDB buffer pool to data files. At the next mysqld startup InnoDB will do a crash recovery!

The above is also showing a message about page_cleaner that conflicts with the last message.
The output was obtained by running the following test:

--source include/have_innodb.inc
# Embedded server tests do not support restarting
--source include/not_embedded.inc
 
CREATE TABLE t1(
  a INT PRIMARY KEY,
  b CHAR(255) NOT NULL DEFAULT '',
  c CHAR(255) NOT NULL DEFAULT ''
) ENGINE=InnoDB STATS_PERSISTENT=1;
 
BEGIN;
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8);
INSERT INTO t1 (a) SELECT a+8 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+16 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+32 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+64 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+128 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+256 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+512 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+1024 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+2048 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+4096 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+8192 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+16384 FROM t1 WHERE a>0;
INSERT INTO t1 (a) SELECT a+32768 FROM t1 WHERE a>0;
 
--echo # Persist the state of the above incomplete transaction by
--echo # causing a redo log write for another transaction.
--connect(con1, localhost, root)
SET GLOBAL innodb_flush_log_at_trx_commit=1;
ANALYZE TABLE t1;
--disconnect con1
--connection default
 
--let $restart_parameters= --innodb-fast-shutdown=2
--source include/kill_and_restart_mysqld.inc
 
-- echo # Request very fast shutdown (should be without rollback).
-- echo # Disable the rollback of recovered transactions on startup.
--let $restart_parameters= --innodb-force-recovery=3
--source include/restart_mysqld.inc
 
--echo # There table should not be empty.
--echo # Currently it may be, because the shutdown waited for the rollback!
--echo # (It can be nonempty if the rollback was not persisted.)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT COUNT(*)>0 `Expected 1` FROM t1;
 
--let $restart_parameters=
--source include/restart_mysqld.inc
SELECT * FROM t1;
DROP TABLE t1;

I repeated the problem on the latest development versions of 10.0.30, 10.1.22, 10.2.4.



 Comments   
Comment by Marko Mäkelä [ 2017-03-14 ]

This was fixed as part of MDEV-12091. A normal shutdown will complete the rollback of the current being-rolled-back-transaction. If there are multiple recovered transactions, we would no longer advance to the next transaction to be rolled back if shutdown was initiated.
The crash-like shutdown (innodb_fast_shutdown=2) will not wait for a current background rollback to finish, but the normal and slow shutdown will wait for the completion.

Generated at Thu Feb 08 07:54:34 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.