mirror of
https://github.com/MariaDB/server.git
synced 2025-02-16 02:15:33 +01:00
182 lines
4.9 KiB
Text
182 lines
4.9 KiB
Text
--source include/have_innodb.inc
|
|
--source include/have_log_bin.inc
|
|
--let $rpl_topology=1->2,1->3
|
|
--source include/rpl_init.inc
|
|
--connect (server_2b,127.0.0.1,root,,,$SERVER_MYPORT_2)
|
|
|
|
--connection server_2
|
|
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
|
|
SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode;
|
|
SET @old_timeout= @@GLOBAL.lock_wait_timeout;
|
|
SET @old_innodb_timeout= @@GLOBAL.innodb_lock_wait_timeout;
|
|
--source include/stop_slave.inc
|
|
SET GLOBAL slave_parallel_threads=5;
|
|
set global slave_parallel_mode= aggressive;
|
|
# High timeout so we get replication sync error and test failure if the
|
|
# conflict handling is insufficient and lock wait timeout occurs.
|
|
SET GLOBAL lock_wait_timeout= 86400;
|
|
SET GLOBAL innodb_lock_wait_timeout= 86400;
|
|
SET STATEMENT sql_log_bin=0 FOR ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
|
--source include/start_slave.inc
|
|
|
|
--connection server_1
|
|
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
|
|
INSERT INTO t1 VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0);
|
|
--save_master_pos
|
|
|
|
--connection server_2
|
|
--sync_with_master
|
|
--source include/stop_slave.inc
|
|
|
|
# Test the following scenario:
|
|
#
|
|
# Transactions T1, T2 in domain 1, U1, U2 in domain 2.
|
|
# Wait cycle T1->U2->U1->T2->T1 as follows:
|
|
# T1 row lock wait on U2
|
|
# U2 wait_for_prior_commit on U1
|
|
# U1 row lock wait on T2
|
|
# T2 wait_for_prior_commit on T1
|
|
#
|
|
# Test that the wait cycle is broken correctly with deadlock kill.
|
|
|
|
--connection server_2b
|
|
# Temporarily block T1 and U1.
|
|
BEGIN;
|
|
SELECT * FROM t1 WHERE a=1 FOR UPDATE;
|
|
SELECT * FROM t1 WHERE a=5 FOR UPDATE;
|
|
|
|
--connection server_1
|
|
|
|
SET SESSION gtid_domain_id= 1;
|
|
# T1 in domain 1
|
|
BEGIN;
|
|
UPDATE t1 SET b=1 WHERE a=1;
|
|
UPDATE t1 SET b=1 WHERE a=7;
|
|
COMMIT;
|
|
# T2 in domain 1
|
|
UPDATE t1 SET b=2 WHERE a=3;
|
|
|
|
SET SESSION gtid_domain_id=2;
|
|
# U1 in domain 2
|
|
BEGIN;
|
|
UPDATE t1 SET b=3 WHERE a=5;
|
|
UPDATE t1 SET b=3 WHERE a=3;
|
|
COMMIT;
|
|
# U2 in domain 2
|
|
UPDATE t1 SET b=4 WHERE a=7;
|
|
SET SESSION gtid_domain_id= 0;
|
|
--source include/save_master_gtid.inc
|
|
|
|
--connection server_2
|
|
--source include/start_slave.inc
|
|
# Wait until T2, U2 are holding the row locks.
|
|
--let $wait_condition= SELECT COUNT(*)=2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state LIKE '%Waiting for prior transaction to commit%'
|
|
--source include/wait_condition.inc
|
|
|
|
# Then let T1, U1 continue to conflict on the row locks, and check that
|
|
# replication correctly handles the conflict.
|
|
--connection server_2b
|
|
ROLLBACK;
|
|
|
|
--connection server_2
|
|
--source include/sync_with_master_gtid.inc
|
|
|
|
# Allow either domain to "win" on the conflicting updates.
|
|
SELECT a, (
|
|
(a=1 AND b=1) OR
|
|
(a=3 AND (b=2 OR b=3)) OR
|
|
(a=5 AND b=3) OR
|
|
(a=7 AND (b=1 OR b=4)) OR
|
|
((a MOD 2)=0 AND b=0)) AS `ok`
|
|
FROM t1
|
|
ORDER BY a;
|
|
|
|
# Now try the same thing with multi-source replication.
|
|
|
|
# Make server_3 a second master
|
|
--connection server_3
|
|
--source include/sync_with_master_gtid.inc
|
|
--source include/stop_slave.inc
|
|
|
|
--connection server_2
|
|
--source include/stop_slave.inc
|
|
--replace_result $SERVER_MYPORT_3 MYPORT_3
|
|
eval CHANGE MASTER 'm2' to master_port=$SERVER_MYPORT_3 , master_host='127.0.0.1', master_user='root', master_use_gtid=slave_pos, master_ssl_verify_server_cert=0;
|
|
|
|
--connection server_1
|
|
|
|
SET SESSION gtid_domain_id= 1;
|
|
# T1 in domain 1
|
|
BEGIN;
|
|
UPDATE t1 SET b=11 WHERE a=1;
|
|
UPDATE t1 SET b=11 WHERE a=7;
|
|
COMMIT;
|
|
# T2 in domain 1
|
|
UPDATE t1 SET b=12 WHERE a=3;
|
|
SET SESSION gtid_domain_id= 1;
|
|
|
|
--connection server_3
|
|
SET SESSION gtid_domain_id=3;
|
|
# U1 in domain 3
|
|
BEGIN;
|
|
UPDATE t1 SET b=13 WHERE a=5;
|
|
UPDATE t1 SET b=13 WHERE a=3;
|
|
COMMIT;
|
|
# U2 in domain 3
|
|
UPDATE t1 SET b=14 WHERE a=7;
|
|
--source include/save_master_gtid.inc
|
|
|
|
--connection server_2b
|
|
# Temporarily block T1 and U1.
|
|
BEGIN;
|
|
SELECT * FROM t1 WHERE a=1 FOR UPDATE;
|
|
SELECT * FROM t1 WHERE a=5 FOR UPDATE;
|
|
|
|
START ALL SLAVES;
|
|
# Wait until T2, U2 are holding the row locks.
|
|
--let $wait_condition= SELECT COUNT(*)=2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE state LIKE '%Waiting for prior transaction to commit%'
|
|
--source include/wait_condition.inc
|
|
|
|
--connection server_2b
|
|
ROLLBACK;
|
|
|
|
--connection server_1
|
|
--source include/save_master_gtid.inc
|
|
--connection server_2
|
|
--source include/sync_with_master_gtid.inc
|
|
--connection server_3
|
|
--source include/save_master_gtid.inc
|
|
--connection server_2
|
|
--source include/sync_with_master_gtid.inc
|
|
|
|
SELECT a, (
|
|
(a=1 AND b=11) OR
|
|
(a=3 AND (b=12 OR b=13)) OR
|
|
(a=5 AND b=13) OR
|
|
(a=7 AND (b=11 OR b=14)) OR
|
|
((a MOD 2)=0 AND b=0)) AS `ok`
|
|
FROM t1
|
|
ORDER BY a;
|
|
|
|
SET default_master_connection = 'm2';
|
|
--source include/stop_slave.inc
|
|
RESET SLAVE 'm2' ALL;
|
|
SET default_master_connection = '';
|
|
|
|
--connection server_3
|
|
--source include/start_slave.inc
|
|
|
|
# Cleanup
|
|
|
|
--disconnect server_2b
|
|
--connection server_1
|
|
DROP TABLE t1;
|
|
--connection server_2
|
|
--source include/stop_slave.inc
|
|
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
|
|
set global slave_parallel_mode= @old_parallel_mode;
|
|
SET GLOBAL lock_wait_timeout= @old_timeout;
|
|
SET GLOBAL innodb_lock_wait_timeout= @old_innodb_timeout;
|
|
--source include/start_slave.inc
|
|
|
|
--source include/rpl_end.inc
|