diff --git a/mysql-test/suite/innodb/r/undo_truncate.result b/mysql-test/suite/innodb/r/undo_truncate.result
index 25fd07cf930..4b185a58d2c 100644
--- a/mysql-test/suite/innodb/r/undo_truncate.result
+++ b/mysql-test/suite/innodb/r/undo_truncate.result
@@ -2,11 +2,7 @@ SET @save_undo_logs = @@GLOBAL.innodb_undo_logs;
 SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
 SET @save_truncate = @@GLOBAL.innodb_undo_log_truncate;
 SET GLOBAL innodb_undo_log_truncate = 0;
-SET GLOBAL innodb_undo_logs = 4;
 SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
-SET @trunc_start=
-(SELECT variable_value FROM information_schema.global_status
-WHERE variable_name = 'innodb_undo_truncations');
 create table t1(keyc int primary key, c char(100)) engine = innodb;
 create table t2(keyc int primary key, c char(100)) engine = innodb;
 connect  con1,localhost,root,,;
@@ -35,8 +31,5 @@ connection con2;
 commit;
 disconnect con2;
 connection default;
+set global innodb_fast_shutdown=0;
 drop table t1, t2;
-InnoDB		0 transactions not purged
-SET GLOBAL innodb_undo_logs = @save_undo_logs;
-SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
-SET GLOBAL innodb_undo_log_truncate = @save_truncate;
diff --git a/mysql-test/suite/innodb/t/undo_truncate.test b/mysql-test/suite/innodb/t/undo_truncate.test
index bc2e6a3a119..32697e59c91 100644
--- a/mysql-test/suite/innodb/t/undo_truncate.test
+++ b/mysql-test/suite/innodb/t/undo_truncate.test
@@ -1,23 +1,15 @@
 --source include/have_innodb.inc
-# With 32k, truncation could happen on shutdown after the test,
-# and the mtr.add_suppression() would not filter out the warning.
-# With 64k, no truncation seems to happen.
-# --source include/innodb_page_size.inc
---source include/innodb_page_size_small.inc
+--source include/innodb_page_size.inc
 --source include/have_undo_tablespaces.inc
+--source include/not_embedded.inc
 --source include/have_sequence.inc
 
 SET @save_undo_logs = @@GLOBAL.innodb_undo_logs;
 SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
 SET @save_truncate = @@GLOBAL.innodb_undo_log_truncate;
 SET GLOBAL innodb_undo_log_truncate = 0;
-SET GLOBAL innodb_undo_logs = 4;
 SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
 
-SET @trunc_start=
-(SELECT variable_value FROM information_schema.global_status
-WHERE variable_name = 'innodb_undo_truncations');
-
 #-----------------------------------------------------------------------------
 #
 # Perform DML action using multiple clients and multiple undo tablespace.
@@ -48,21 +40,20 @@ commit; disconnect con1;
 connection con2; commit; disconnect con2;
 
 connection default;
+
+--replace_regex /.*Trx id counter ([0-9]+).*/\1/
+let $trx_before= `SHOW ENGINE INNODB STATUS`;
+let $trx_before= `select substr('$trx_before',9)+2`;
+
+set global innodb_fast_shutdown=0;
+--source include/restart_mysqld.inc
+--replace_regex /.*Trx id counter ([0-9]+).*/\1/
+let $trx_after= `SHOW ENGINE INNODB STATUS`;
+let $trx_after= `select substr('$trx_after',9)`;
+
 drop table t1, t2;
 
---source include/wait_all_purged.inc
-
-# Truncation will normally not occur with innodb_page_size=64k,
-# and occasionally not with innodb_page_size=32k,
-# because the undo log will not grow enough.
-if (`select @@innodb_page_size IN (4096,8192,16384)`)
+if ($trx_before != $trx_after)
 {
-  let $wait_condition = (SELECT variable_value!=@trunc_start
-                         FROM information_schema.global_status
-                         WHERE variable_name = 'innodb_undo_truncations');
-  source include/wait_condition.inc;
+  echo Transaction sequence mismatch: $trx_before != $trx_after;
 }
-
-SET GLOBAL innodb_undo_logs = @save_undo_logs;
-SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
-SET GLOBAL innodb_undo_log_truncate = @save_truncate;
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index 687c6fa0e97..27548e96b0a 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -71,6 +71,7 @@ trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf);
 /** Create a rollback segment header.
 @param[in,out]	space		system, undo, or temporary tablespace
 @param[in]	rseg_id		rollback segment identifier
+@param[in]	max_trx_id	new value of TRX_RSEG_MAX_TRX_ID
 @param[in,out]	sys_header	the TRX_SYS page (NULL for temporary rseg)
 @param[in,out]	mtr		mini-transaction
 @return the created rollback segment
@@ -79,6 +80,7 @@ buf_block_t*
 trx_rseg_header_create(
 	fil_space_t*	space,
 	ulint		rseg_id,
+	trx_id_t	max_trx_id,
 	buf_block_t*	sys_header,
 	mtr_t*		mtr);
 
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 9d19a14cb66..e283c594456 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2640,6 +2640,8 @@ static ulint srv_do_purge(ulint* n_total_purged
 		n_pages_purged = trx_purge(
 			n_use_threads,
 			(++count % rseg_truncate_frequency) == 0
+			|| (srv_shutdown_state != SRV_SHUTDOWN_NONE
+			    && srv_fast_shutdown == 0)
 #ifdef UNIV_DEBUG
 			, slot
 #endif
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 7d5679e889e..8b72a6c0aaf 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1029,6 +1029,8 @@ srv_undo_tablespaces_init(bool create_new_db)
 			return DB_CORRUPTION;
 		}
 
+		const trx_id_t max_trx_id = trx_sys.get_max_trx_id();
+
 		for (undo::undo_spaces_t::const_iterator it
 			     = undo::Truncate::s_fix_up_spaces.begin();
 		     it != undo::Truncate::s_fix_up_spaces.end();
@@ -1046,7 +1048,8 @@ srv_undo_tablespaces_init(bool create_new_db)
 				if (trx_sysf_rseg_get_space(sys_header, i)
 				    == *it) {
 					trx_rseg_header_create(
-						space, i, sys_header, &mtr);
+						space, i, max_trx_id,
+						sys_header, &mtr);
 				}
 			}
 
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index d300e3b54e3..208f400c8a3 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -977,7 +977,8 @@ not_found:
 	for (ulint i = 0; i < undo_trunc->rsegs_size(); ++i) {
 		trx_rseg_t*	rseg = undo_trunc->get_ith_rseg(i);
 		buf_block_t* rblock = trx_rseg_header_create(
-			space, rseg->id, sys_header, &mtr);
+			space, rseg->id, trx_sys.get_max_trx_id(),
+			sys_header, &mtr);
 		ut_ad(rblock);
 		rseg->page_no = rblock ? rblock->page.id.page_no() : FIL_NULL;
 
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index c5ab4d37aae..0ae11390f0b 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -286,6 +286,7 @@ void trx_rseg_format_upgrade(trx_rsegf_t* rseg_header, mtr_t* mtr)
 /** Create a rollback segment header.
 @param[in,out]	space		system, undo, or temporary tablespace
 @param[in]	rseg_id		rollback segment identifier
+@param[in]	max_trx_id	new value of TRX_RSEG_MAX_TRX_ID
 @param[in,out]	sys_header	the TRX_SYS page (NULL for temporary rseg)
 @param[in,out]	mtr		mini-transaction
 @return the created rollback segment
@@ -294,6 +295,7 @@ buf_block_t*
 trx_rseg_header_create(
 	fil_space_t*	space,
 	ulint		rseg_id,
+	trx_id_t	max_trx_id,
 	buf_block_t*	sys_header,
 	mtr_t*		mtr)
 {
@@ -319,6 +321,12 @@ trx_rseg_header_create(
 
 	mlog_write_ulint(TRX_RSEG + TRX_RSEG_HISTORY_SIZE + block->frame, 0,
 			 MLOG_4BYTES, mtr);
+
+	if (max_trx_id) {
+		mlog_write_ull(TRX_RSEG + TRX_RSEG_MAX_TRX_ID + block->frame,
+			       max_trx_id, mtr);
+	}
+
 	flst_init(TRX_RSEG + TRX_RSEG_HISTORY + block->frame, mtr);
 	trx_rsegf_t* rsegf = TRX_RSEG + block->frame;
 
@@ -684,7 +692,7 @@ trx_rseg_create(ulint space_id)
 		ulint	rseg_id = trx_sys_rseg_find_free(sys_header);
 		if (buf_block_t* rblock = rseg_id == ULINT_UNDEFINED
 		    ? NULL
-		    : trx_rseg_header_create(space, rseg_id, sys_header,
+		    : trx_rseg_header_create(space, rseg_id, 0, sys_header,
 					     &mtr)) {
 			ut_ad(trx_sysf_rseg_get_space(sys_header, rseg_id)
 			      == space_id);
@@ -714,7 +722,7 @@ trx_temp_rseg_create()
 		mtr_x_lock_space(fil_system.temp_space, &mtr);
 
 		buf_block_t* rblock = trx_rseg_header_create(
-			fil_system.temp_space, i, NULL, &mtr);
+			fil_system.temp_space, i, 0, NULL, &mtr);
 		trx_rseg_t* rseg = trx_rseg_mem_create(
 			i, fil_system.temp_space, rblock->page.id.page_no());
 		ut_ad(!rseg->is_persistent());
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 87814fa6c69..0b1f72412f6 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -197,7 +197,7 @@ trx_sysf_create(
 	/* Create the first rollback segment in the SYSTEM tablespace */
 	slot_no = trx_sys_rseg_find_free(block);
 	buf_block_t* rblock = trx_rseg_header_create(fil_system.sys_space,
-						     slot_no, block, mtr);
+						     slot_no, 0, block, mtr);
 
 	ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
 	ut_a(rblock->page.id.page_no() == FSP_FIRST_RSEG_PAGE_NO);