| Bug #112424 | Crash during background rollback if both prepare and active transaction exist | ||
|---|---|---|---|
| Submitted: | 22 Sep 2023 3:08 | Modified: | 25 Mar 2024 16:56 |
| Reporter: | genze wu (OCA) | Email Updates: | |
| Status: | Closed | Impact on me: | |
| 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 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 2024 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.

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.