Bug #112424 Crash during background rollback if both prepare and active transaction exist
Submitted: 22 Sep 2023 3:08 Modified: 25 Mar 16:56
Reporter: genze wu (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S6 (Debug Builds)
Version:8.0.34 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[22 Sep 2023 3:08] genze wu
Description:
In debug mode, If a server rollback both prepared and active transaction during crash recovery, server will crash with assert at storage/innobase/trx/trx0roll.cc:805.

Prepared transaction will be rollback during binlog_recovery, it can happen before background thread begin to take MDL lock, which will make assert failed.

How to repeat:
@@ -784,6 +784,9 @@ void trx_recovery_rollback(THD *thd) {
   std::vector<MDL_ticket *> shared_mdl_list;
   ut_ad(!srv_read_only_mode);

+  DBUG_EXECUTE_IF("sleep_before_trx_recovery_rollback",
+                  {std::this_thread::sleep_for(std::chrono::seconds(5));});
+
   // Take MDL locks
   /* During this stage the server is not open for external connections, and
    * there will not be any concurrent threads requesting MDL, hence we don't

+++ b/mysql-test/t/test_rollback_crash.test
@@ -0,0 +1,18 @@
+create table t1(n int);
+
+connect (con_4, localhost, root,,);
+#SET debug_sync = "bgc_before_flush_stage SIGNAL bgc_4 WAIT_FOR go";
+begin;
+insert into t1 values(1);
+
+connection default;
+#SET DEBUG_SYNC= 'now WAIT_FOR bgc_4';
+
+--source include/expect_crash.inc
+SET debug = "+d,crash_after_flush_engine_log";
+--error 2013
+CREATE TABLE t2(n int);
+
+# Restart the server.
+--let $restart_parameters = restart: --debug=d,sleep_before_trx_recovery_rollback
+--source include/start_mysqld.inc

Add DBUG_EXECUTE_IF and run testcasae provided above in debug mode, server will crash.

Suggested fix:
Remove the assert in storage/innobase/trx/trx0roll.cc:805.
[22 Sep 2023 9:20] MySQL Verification Team
Hello genze wu,

Thank you for the report and feedback.

regards,
Umesh
[19 Oct 2023 9:07] genze wu
git_diff.txt is the git diff of fix patch for this bug.

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: git_diff.txt (text/plain), 2.50 KiB.

[25 Mar 16:56] Philip Olson
Posted by developer:
 
Fixed as of the upcoming MySQL Server 8.0.37 and 8.4.1 releases, and here's the proposed changelog entry from the documentation team:

In debug builds, there was an assertion failure in InnoDB's background
when a transaction it wanted to acquire an MDL lock on was no longer
active.

This fix is based on a patch from Genze Wu with
Alibaba, thank you for the contribution.

Thank you for the bug report.