Skip to content

Commit

Permalink
MDEV-30423 Deadlock on Replica during BACKUP STAGE BLOCK_COMMIT on XA…
Browse files Browse the repository at this point in the history
… transactions

The user XA commit execution branch was caught not have been covered
with MDEV-21953 fixes.

The XA involved deadlock is resolved now to apply the former fixes
pattern.
Along the fixes the following changes have been implemented.
- MDL lock attribute correction
- dissociation of the externally completed XA from the current
  thread's xid_state in the error branches
- cleanup_context() preseves the prepared XA
- wait_for_prior_commit() is relocated to satisfy both
  the binlog ON (log-slave-updates and skip-log-bin)
  and OFF slave execution branches.
  • Loading branch information
andrelkin committed Jan 23, 2023
1 parent 647a723 commit dc646c2
Show file tree
Hide file tree
Showing 17 changed files with 784 additions and 35 deletions.
2 changes: 1 addition & 1 deletion extra/wolfssl/wolfssl
Submodule wolfssl updated 522 files
2 changes: 1 addition & 1 deletion libmariadb
1 change: 1 addition & 0 deletions mysql-test/include/master-slave.inc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# [--let $rpl_skip_start_slave= 1]
# [--let $rpl_debug= 1]
# [--let $slave_timeout= NUMBER]
# [--let $rpl_server_skip_log_bin= 1]
# --source include/master-slave.inc
#
# Parameters:
Expand Down
16 changes: 15 additions & 1 deletion mysql-test/include/rpl_init.inc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
# before CHANGE MASTER and START SLAVE. RESET MASTER and RESET
# SLAVE are suppressed if $rpl_skip_reset_master_and_slave is
# set.
# Also see $rpl_server_skip_log_bin.
#
# $rpl_skip_change_master
# By default, this script issues CHANGE MASTER so that all slaves
Expand All @@ -94,6 +95,10 @@
# Timeout used when waiting for the slave threads to start.
# See include/wait_for_slave_param.inc
#
# $rpl_server_skip_log_bin
# When $rpl_skip_reset_master_and_slave is not set
# RESET MASTER does not report ER_FLUSH_MASTER_BINLOG_CLOSED
# on any server.
#
# ==== Side effects ====
#
Expand Down Expand Up @@ -161,7 +166,16 @@ while ($_rpl_server)
USE test;
if (!$rpl_skip_reset_master_and_slave)
{
RESET MASTER;
if (!$rpl_server_skip_log_bin)
{
--error 0
RESET MASTER;
}
if ($rpl_server_skip_log_bin)
{
--error 0,ER_FLUSH_MASTER_BINLOG_CLOSED
RESET MASTER;
}
SET GLOBAL gtid_slave_pos= "";
RESET SLAVE;
}
Expand Down
163 changes: 163 additions & 0 deletions mysql-test/suite/rpl/r/parallel_backup.result
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ include/master-slave.inc
connection master;
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE = innodb;
connection slave;
call mtr.add_suppression("Deadlock found when trying to get lock");
call mtr.add_suppression("Commit failed due to failure of an earlier commit");
include/stop_slave.inc
SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads;
SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode;
Expand All @@ -30,6 +32,167 @@ connection backup_slave;
BACKUP STAGE END;
connection slave;
include/diff_tables.inc [master:t1,slave:t1]
# MDEV-30423: dealock XA COMMIT vs BACKUP
#
# Normal XA COMMIT
connection slave;
include/stop_slave.inc
connection master;
connection aux_slave;
BEGIN;
INSERT INTO t1 VALUES (4);
connection master;
XA START '1';
INSERT INTO t1 VALUES (3);
XA END '1';
XA PREPARE '1';
connection master1;
INSERT INTO t1 VALUES (4);
connection master;
XA COMMIT '1';
include/save_master_gtid.inc
connection slave;
include/start_slave.inc
connection aux_slave;
# Xid '1' must be in the output:
XA RECOVER;
formatID gtrid_length bqual_length data
1 1 0 1
connection backup_slave;
BACKUP STAGE START;
BACKUP STAGE BLOCK_COMMIT;
connection aux_slave;
ROLLBACK;
connection backup_slave;
BACKUP STAGE END;
connection slave;
include/sync_with_master_gtid.inc
include/stop_slave.inc
#
# Normal XA ROLLBACK
connection slave;
include/stop_slave.inc
Warnings:
Note 1255 Slave already has been stopped
connection master;
connection aux_slave;
BEGIN;
INSERT INTO t1 VALUES (6);
connection master;
XA START '1';
INSERT INTO t1 VALUES (5);
XA END '1';
XA PREPARE '1';
connection master1;
INSERT INTO t1 VALUES (6);
connection master;
XA ROLLBACK '1';
include/save_master_gtid.inc
connection slave;
include/start_slave.inc
connection aux_slave;
# Xid '1' must be in the output:
XA RECOVER;
formatID gtrid_length bqual_length data
1 1 0 1
connection backup_slave;
BACKUP STAGE START;
BACKUP STAGE BLOCK_COMMIT;
connection aux_slave;
ROLLBACK;
connection backup_slave;
BACKUP STAGE END;
connection slave;
include/sync_with_master_gtid.inc
include/stop_slave.inc
#
# Errored out XA COMMIT
connection slave;
include/stop_slave.inc
Warnings:
Note 1255 Slave already has been stopped
connection master;
connection aux_slave;
BEGIN;
INSERT INTO t1 VALUES (8);
connection master;
XA START '1';
INSERT INTO t1 VALUES (7);
XA END '1';
XA PREPARE '1';
connection master1;
INSERT INTO t1 VALUES (8);
connection master;
XA COMMIT '1';
include/save_master_gtid.inc
connection slave;
SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout;
SET @sav_slave_transaction_retries = @@global.slave_transaction_retries;
SET @@global.innodb_lock_wait_timeout =1;
SET @@global.slave_transaction_retries=0;
include/start_slave.inc
connection aux_slave;
# Xid '1' must be in the output:
XA RECOVER;
formatID gtrid_length bqual_length data
1 1 0 1
connection backup_slave;
BACKUP STAGE START;
BACKUP STAGE BLOCK_COMMIT;
connection aux_slave;
ROLLBACK;
connection backup_slave;
BACKUP STAGE END;
connection slave;
include/stop_slave.inc
SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout;
SET @@global.slave_transaction_retries= @sav_slave_transaction_retries;
connection slave;
include/start_slave.inc
include/sync_with_master_gtid.inc
#
# Errored out XA ROLLBACK
connection slave;
include/stop_slave.inc
connection master;
connection aux_slave;
BEGIN;
INSERT INTO t1 VALUES (10);
connection master;
XA START '1';
INSERT INTO t1 VALUES (9);
XA END '1';
XA PREPARE '1';
connection master1;
INSERT INTO t1 VALUES (10);
connection master;
XA ROLLBACK '1';
include/save_master_gtid.inc
connection slave;
SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout;
SET @sav_slave_transaction_retries = @@global.slave_transaction_retries;
SET @@global.innodb_lock_wait_timeout =1;
SET @@global.slave_transaction_retries=0;
include/start_slave.inc
connection aux_slave;
# Xid '1' must be in the output:
XA RECOVER;
formatID gtrid_length bqual_length data
1 1 0 1
connection backup_slave;
BACKUP STAGE START;
BACKUP STAGE BLOCK_COMMIT;
connection aux_slave;
ROLLBACK;
connection backup_slave;
BACKUP STAGE END;
connection slave;
include/stop_slave.inc
SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout;
SET @@global.slave_transaction_retries= @sav_slave_transaction_retries;
connection slave;
include/start_slave.inc
include/sync_with_master_gtid.inc
connection slave;
include/stop_slave.inc
SET @@global.slave_parallel_threads= @old_parallel_threads;
Expand Down
Loading

0 comments on commit dc646c2

Please sign in to comment.