Skip to content

Commit fb21744

Browse files
committed
MDEV-13626: Import and adapt innodb.xa_recovery_debug
Adapt the test that was added in mysql/mysql-server@6b65d90 but omitted in commit 2e814d4. Instead of triggering a log checkpoint, we will only trigger a redo log flush before killing the server. Note: the mtr.commit() call in trx_rollback_for_mysql() will not actually make the undo log header page state change durable. A call to log_write_up_to(mtr.commit_lsn(), true) would do that. It is unclear what the originally reported bug scenario was. As long as innobase_rollback_by_xid() will not return without ensuring that the redo log has been durably written, we should be safe.
1 parent 2d16452 commit fb21744

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#
2+
# Bug#20872655 XA ROLLBACK IS NOT CRASH-SAFE
3+
#
4+
CREATE TABLE t(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=INNODB;
5+
INSERT INTO t SET a=0;
6+
connect con1,localhost,root;
7+
XA START 'zombie';
8+
INSERT INTO t SET a=1;
9+
UPDATE t SET b=1 WHERE a=1;
10+
SELECT COUNT(*) FROM t;
11+
COUNT(*)
12+
2
13+
XA END 'zombie';
14+
XA PREPARE 'zombie';
15+
SET DEBUG_SYNC='trx_xa_rollback SIGNAL s1 WAIT_FOR s2';
16+
XA ROLLBACK 'zombie';
17+
connection default;
18+
SET DEBUG_SYNC='now WAIT_FOR s1';
19+
SET GLOBAL innodb_flush_log_at_trx_commit=1;
20+
DELETE FROM t LIMIT 1;
21+
disconnect con1;
22+
XA COMMIT 'zombie';
23+
ERROR XAE04: XAER_NOTA: Unknown XID
24+
SELECT COUNT(*) FROM t;
25+
COUNT(*)
26+
0
27+
DROP TABLE t;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--source include/have_innodb.inc
2+
--source include/have_debug.inc
3+
--source include/have_debug_sync.inc
4+
# Embedded server does not support restarting
5+
--source include/not_embedded.inc
6+
7+
--echo #
8+
--echo # Bug#20872655 XA ROLLBACK IS NOT CRASH-SAFE
9+
--echo #
10+
11+
CREATE TABLE t(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=INNODB;
12+
INSERT INTO t SET a=0;
13+
connect (con1,localhost,root);
14+
XA START 'zombie';
15+
INSERT INTO t SET a=1;
16+
UPDATE t SET b=1 WHERE a=1;
17+
SELECT COUNT(*) FROM t;
18+
XA END 'zombie';
19+
XA PREPARE 'zombie';
20+
SET DEBUG_SYNC='trx_xa_rollback SIGNAL s1 WAIT_FOR s2';
21+
--send XA ROLLBACK 'zombie'
22+
connection default;
23+
SET DEBUG_SYNC='now WAIT_FOR s1';
24+
# Ensure that the state change from XA PREPARE to ACTIVE gets flushed
25+
# to the redo log. Without this, it could be that we will recover to
26+
# a state that precedes the start of the XA ROLLBACK.
27+
SET GLOBAL innodb_flush_log_at_trx_commit=1;
28+
DELETE FROM t LIMIT 1;
29+
let $shutdown_timeout=0;
30+
--source include/restart_mysqld.inc
31+
disconnect con1;
32+
--error ER_XAER_NOTA
33+
XA COMMIT 'zombie';
34+
SELECT COUNT(*) FROM t;
35+
DROP TABLE t;

0 commit comments

Comments
 (0)