1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00
Files
mariadb/mysql-test/suite/binlog/r/binlog_recover_async_rollback_trx.result
Libing Song 5bbda97111 MDEV-33853 Async rollback prepared transactions during binlog
crash recovery

Summary
=======
When doing server recovery, the active transactions will be rolled
back by InnoDB background rollback thread automatically. The
prepared transactions will be committed or rolled back accordingly
by binlog recovery. Binlog recovery is done in main thread before
the server can provide service to users. If there is a big
transaction to rollback, the server will not available for a long
time.

This patch provides a way to rollback the prepared transactions
asynchronously. Thus the rollback will not block server startup.

Design
======
- Handler::recover_rollback_by_xid()
  This patch provides a new handler interface to rollback transactions
  in recover phase. InnoDB just set the transaction's state to active.
  Then the transaction will be rolled back by the background rollback
  thread.

- Handler::signal_tc_log_recover_done()
  This function is called after tc log is opened(typically binlog opened)
  has done. When this function is called, all transactions will be rolled
  back have been reverted to ACTIVE state. Thus it starts rollback thread
  to rollback the transactions.

- Background rollback thread
  With this patch, background rollback thread is defered to run until binlog
  recovery is finished. It is started by innobase_tc_log_recovery_done().
2024-09-05 21:19:25 +03:00

53 lines
1.5 KiB
Plaintext

CREATE TABLE t1 (id int primary key, data int) ENGINE = InnoDB;
INSERT INTO t1 VALUES (0, 1);
#
# 1. Check DML in prepared state can rollback correctly.
#
connect con1, localhost, root,,;
SET debug_sync = "ha_commit_trans_after_prepare SIGNAL prepared1 WAIT_FOR continue";
INSERT INTO t1 VALUES(1, 1);;
connect con2, localhost, root,,;
SET debug_sync = "now WAIT_FOR prepared1";
SET debug_sync = "ha_commit_trans_after_prepare SIGNAL prepared2 WAIT_FOR continue";
UPDATE t1 SET data = data + 1 WHERE id = 0;
connection default;
SET debug_sync = "now WAIT_FOR prepared2";
# Kill the server
disconnect con1;
disconnect con2;
# restart
# Expect (0, 1)
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t1;
id data
0 1
INSERT INTO t1 VALUES(1, 1);
UPDATE t1 SET data = data + 1 WHERE id = 0;
# Expect (0, 2), (1, 1)
SELECT * FROM t1;
id data
0 2
1 1
#
# 2. Test that innodb shutdown as expected if any error happens before
# normal rollback task is started. In the situation, rollback task
# should be started at preshutdown accordingly to rollback or
# deregister all recovered active transactions.
#
INSERT INTO t1 SELECT seq + 2, 1 FROM seq_1_to_1024;
BEGIN;
UPDATE t1 SET data = 10;
SET GLOBAL innodb_log_checkpoint_now = 1;
# Kill the server
# restart: --innodb-read-only
SELECT count(*) FROM information_schema.innodb_trx;
count(*)
1
# Kill the server
# restart: --innodb-read-only
SELECT count(*) FROM information_schema.innodb_trx;
count(*)
1
# restart
DROP TABLE t1;