mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts
Due to how gap locks work, two transactions could group commit together on the master, but get lock conflicts and then deadlock due to different thread scheduling order on slave. For now, remove these deadlocks by running the parallel slave in READ COMMITTED mode. And let InnoDB/XtraDB allow statement-based binlogging for the parallel slave in READ COMMITTED. We are also investigating a different solution long-term, which is based on relaxing the gap locks only between the transactions running in parallel for one slave, but not against possibly external transactions.
This commit is contained in:
@@ -1172,6 +1172,84 @@ START SLAVE SQL_THREAD;
|
||||
SELECT * FROM t3 WHERE a >= 110 ORDER BY a;
|
||||
|
||||
|
||||
--echo ***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts ***
|
||||
--connection server_2
|
||||
--source include/stop_slave.inc
|
||||
|
||||
--connection server_1
|
||||
CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB;
|
||||
INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6);
|
||||
|
||||
# Create a group commit with UPDATE and DELETE, in that order.
|
||||
# The bug was that while the UPDATE's row lock does not block the DELETE, the
|
||||
# DELETE's gap lock _does_ block the UPDATE. This could cause a deadlock
|
||||
# on the slave.
|
||||
--connection con1
|
||||
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1';
|
||||
send UPDATE t4 SET b=NULL WHERE a=6;
|
||||
--connection server_1
|
||||
SET debug_sync='now WAIT_FOR master_queued1';
|
||||
|
||||
--connection con2
|
||||
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2';
|
||||
send DELETE FROM t4 WHERE b <= 3;
|
||||
|
||||
--connection server_1
|
||||
SET debug_sync='now WAIT_FOR master_queued2';
|
||||
SET debug_sync='now SIGNAL master_cont1';
|
||||
|
||||
--connection con1
|
||||
REAP;
|
||||
--connection con2
|
||||
REAP;
|
||||
SET debug_sync='RESET';
|
||||
--save_master_pos
|
||||
|
||||
--connection server_2
|
||||
--source include/start_slave.inc
|
||||
--sync_with_master
|
||||
--source include/stop_slave.inc
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
|
||||
|
||||
# Another example, this one with INSERT vs. DELETE
|
||||
--connection server_1
|
||||
DELETE FROM t4;
|
||||
INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6);
|
||||
|
||||
# Create a group commit with INSERT and DELETE, in that order.
|
||||
# The bug was that while the INSERT's insert intention lock does not block
|
||||
# the DELETE, the DELETE's gap lock _does_ block the INSERT. This could cause
|
||||
# a deadlock on the slave.
|
||||
--connection con1
|
||||
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1';
|
||||
send INSERT INTO t4 VALUES (7, NULL);
|
||||
--connection server_1
|
||||
SET debug_sync='now WAIT_FOR master_queued1';
|
||||
|
||||
--connection con2
|
||||
SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2';
|
||||
send DELETE FROM t4 WHERE b <= 3;
|
||||
|
||||
--connection server_1
|
||||
SET debug_sync='now WAIT_FOR master_queued2';
|
||||
SET debug_sync='now SIGNAL master_cont1';
|
||||
|
||||
--connection con1
|
||||
REAP;
|
||||
--connection con2
|
||||
REAP;
|
||||
SET debug_sync='RESET';
|
||||
--save_master_pos
|
||||
|
||||
--connection server_2
|
||||
--source include/start_slave.inc
|
||||
--sync_with_master
|
||||
|
||||
SELECT * FROM t4 ORDER BY a;
|
||||
|
||||
|
||||
--connection server_2
|
||||
--source include/stop_slave.inc
|
||||
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
|
||||
@@ -1180,7 +1258,7 @@ SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
--connection server_1
|
||||
DROP function foo;
|
||||
DROP TABLE t1,t2,t3;
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
--source include/rpl_end.inc
|
||||
|
||||
Reference in New Issue
Block a user