diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index 514c28b0e00..e984c4dc497 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -66,7 +66,7 @@ if ($tmp) --echo Gtid_IO_Pos # --echo Replicate_Do_Domain_Ids --echo Replicate_Ignore_Domain_Ids - --echo Parallel_Mode conservative + --echo Parallel_Mode optimistic --echo SQL_Delay 0 --echo SQL_Remaining_Delay NULL --echo Slave_SQL_Running_State diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel.result b/mysql-test/suite/binlog_encryption/rpl_parallel.result deleted file mode 100644 index 5f78a378829..00000000000 --- a/mysql-test/suite/binlog_encryption/rpl_parallel.result +++ /dev/null @@ -1,1691 +0,0 @@ -include/master-slave.inc -[connection master] -connection server_2; -SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; -SET GLOBAL slave_parallel_threads=10; -ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=10; -SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) -OK -CHANGE MASTER TO master_use_gtid=slave_pos; -include/start_slave.inc -SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) -OK -include/stop_slave.inc -SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) -OK -include/start_slave.inc -SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) -OK -*** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** -connection server_1; -ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; -CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; -CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); -INSERT INTO t2 VALUES (1); -connection server_2; -connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; -LOCK TABLE t1 WRITE; -connection server_1; -SET gtid_domain_id=1; -INSERT INTO t1 VALUES (2); -SET gtid_domain_id=0; -INSERT INTO t2 VALUES (2); -INSERT INTO t2 VALUES (3); -BEGIN; -INSERT INTO t2 VALUES (4); -INSERT INTO t2 VALUES (5); -COMMIT; -INSERT INTO t2 VALUES (6); -connection server_2; -SELECT * FROM t2 ORDER by a; -a -1 -2 -3 -4 -5 -6 -connection con_temp1; -SELECT * FROM t1; -a -1 -UNLOCK TABLES; -connection server_2; -SELECT * FROM t1 ORDER BY a; -a -1 -2 -*** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** -connection server_2; -include/stop_slave.inc -connection server_1; -SET sql_log_bin=0; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format='statement'; -SET gtid_domain_id=1; -INSERT INTO t2 VALUES (foo(10, -'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); -connection server_2; -FLUSH LOGS; -SET sql_log_bin=0; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -SET @old_format=@@GLOBAL.binlog_format; -SET GLOBAL binlog_format=statement; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -SET debug_sync='now WAIT_FOR ready1'; -connection server_1; -SET gtid_domain_id=2; -INSERT INTO t2 VALUES (foo(11, -'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); -SET gtid_domain_id=0; -SELECT * FROM t2 WHERE a >= 10 ORDER BY a; -a -10 -11 -connection server_2; -SET debug_sync='now WAIT_FOR ready3'; -SET debug_sync='now SIGNAL cont3'; -SET debug_sync='now WAIT_FOR ready4'; -SET debug_sync='now SIGNAL cont1'; -SET debug_sync='now WAIT_FOR ready2'; -SET debug_sync='now SIGNAL cont4'; -SELECT * FROM t2 WHERE a >= 10 ORDER BY a; -a -10 -11 -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 -slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(11, -'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')) -slave-bin.000002 # Xid # # COMMIT /* XID */ -slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(10, -'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')) -slave-bin.000002 # Xid # # COMMIT /* XID */ -FLUSH LOGS; -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET debug_sync='RESET'; -include/start_slave.inc -*** Test that group-committed transactions on the master can replicate in parallel on the slave. *** -connection server_1; -SET debug_sync='RESET'; -FLUSH LOGS; -CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; -INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); -connection server_2; -connection con_temp1; -BEGIN; -INSERT INTO t3 VALUES (2,102); -connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; -BEGIN; -INSERT INTO t3 VALUES (4,104); -connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (2, foo(12, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (4, foo(14, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (6, foo(16, -'group_commit_waiting_for_prior SIGNAL slave_queued3', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -SET debug_sync='RESET'; -connection server_1; -SELECT * FROM t3 ORDER BY a; -a b -1 1 -2 12 -3 3 -4 14 -5 5 -6 16 -7 7 -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 # Binlog_checkpoint # # master-bin.000001 -master-bin.000002 # Binlog_checkpoint # # master-bin.000002 -master-bin.000002 # Gtid # # GTID #-#-# -master-bin.000002 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB -master-bin.000002 # Gtid # # BEGIN GTID #-#-# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) -master-bin.000002 # Xid # # COMMIT /* XID */ -master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', -'')) -master-bin.000002 # Xid # # COMMIT /* XID */ -master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', -'')) -master-bin.000002 # Xid # # COMMIT /* XID */ -master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, -'group_commit_waiting_for_prior SIGNAL slave_queued3', -'')) -master-bin.000002 # Xid # # COMMIT /* XID */ -connection server_2; -SET debug_sync='now WAIT_FOR slave_queued3'; -connection con_temp1; -ROLLBACK; -connection server_2; -SET debug_sync='now WAIT_FOR slave_queued1'; -connection con_temp2; -ROLLBACK; -connection server_2; -SET debug_sync='now WAIT_FOR slave_queued2'; -SET debug_sync='now SIGNAL slave_cont1'; -SELECT * FROM t3 ORDER BY a; -a b -1 1 -2 12 -3 3 -4 14 -5 5 -6 16 -7 7 -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000003 # Binlog_checkpoint # # slave-bin.000003 -slave-bin.000003 # Gtid # # GTID #-#-# -slave-bin.000003 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) -slave-bin.000003 # Xid # # COMMIT /* XID */ -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', -'')) -slave-bin.000003 # Xid # # COMMIT /* XID */ -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', -'')) -slave-bin.000003 # Xid # # COMMIT /* XID */ -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, -'group_commit_waiting_for_prior SIGNAL slave_queued3', -'')) -slave-bin.000003 # Xid # # COMMIT /* XID */ -*** Test STOP SLAVE in parallel mode *** -connection server_2; -include/stop_slave.inc -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -connection server_1; -SET binlog_direct_non_transactional_updates=0; -SET sql_log_bin=0; -CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); -SET sql_log_bin=1; -BEGIN; -INSERT INTO t2 VALUES (20); -INSERT INTO t1 VALUES (20); -INSERT INTO t2 VALUES (21); -INSERT INTO t3 VALUES (20, 20); -COMMIT; -INSERT INTO t3 VALUES(21, 21); -INSERT INTO t3 VALUES(22, 22); -SET binlog_format=@old_format; -connection con_temp1; -BEGIN; -INSERT INTO t2 VALUES (21); -connection server_2; -START SLAVE; -connection con_temp2; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; -STOP SLAVE; -connection con_temp1; -SET debug_sync='now WAIT_FOR wait_for_done_waiting'; -ROLLBACK; -connection con_temp2; -SET GLOBAL debug_dbug=@old_dbug; -SET debug_sync='RESET'; -connection server_2; -include/wait_for_slave_to_stop.inc -SELECT * FROM t1 WHERE a >= 20 ORDER BY a; -a -20 -SELECT * FROM t2 WHERE a >= 20 ORDER BY a; -a -20 -21 -SELECT * FROM t3 WHERE a >= 20 ORDER BY a; -a b -20 20 -include/start_slave.inc -SELECT * FROM t1 WHERE a >= 20 ORDER BY a; -a -20 -SELECT * FROM t2 WHERE a >= 20 ORDER BY a; -a -20 -21 -SELECT * FROM t3 WHERE a >= 20 ORDER BY a; -a b -20 20 -21 21 -22 22 -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** Test killing slave threads at various wait points *** -*** 1. Test killing transaction waiting in commit for previous transaction to commit *** -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (31, foo(31, -'commit_before_prepare_ordered WAIT_FOR t2_waiting', -'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -INSERT INTO t3 VALUES (32, foo(32, -'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', -'')); -INSERT INTO t3 VALUES (33, foo(33, -'group_commit_waiting_for_prior SIGNAL t2_waiting', -'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -COMMIT; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (34, foo(34, -'', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -a b -31 31 -32 32 -33 33 -34 34 -SET debug_sync='RESET'; -connection server_2; -SET sql_log_bin=0; -CALL mtr.add_suppression("Query execution was interrupted"); -CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); -CALL mtr.add_suppression("Slave: Connection was killed"); -SET sql_log_bin=1; -SET debug_sync='now WAIT_FOR t2_query'; -SET debug_sync='now SIGNAL t2_cont'; -SET debug_sync='now WAIT_FOR t1_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t2_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -STOP SLAVE IO_THREAD; -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -a b -31 31 -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -INSERT INTO t3 VALUES (39,0); -connection server_2; -include/start_slave.inc -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -a b -31 31 -32 32 -33 33 -34 34 -39 0 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (41, foo(41, -'commit_before_prepare_ordered WAIT_FOR t2_waiting', -'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -INSERT INTO t3 VALUES (42, foo(42, -'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', -'')); -INSERT INTO t3 VALUES (43, foo(43, -'group_commit_waiting_for_prior SIGNAL t2_waiting', -'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -COMMIT; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (44, foo(44, -'', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 40 ORDER BY a; -a b -41 41 -42 42 -43 43 -44 44 -SET debug_sync='RESET'; -connection server_2; -SET debug_sync='now WAIT_FOR t2_query'; -SET debug_sync='now SIGNAL t2_cont'; -SET debug_sync='now WAIT_FOR t1_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t2_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -INSERT INTO t3 VALUES (49,0); -connection server_2; -START SLAVE SQL_THREAD; -SELECT * FROM t3 WHERE a >= 40 ORDER BY a; -a b -41 41 -42 42 -43 43 -44 44 -49 0 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** 3. Same as (2), but not using gtid mode *** -connection server_2; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; -include/start_slave.inc -connection server_1; -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (51, foo(51, -'commit_before_prepare_ordered WAIT_FOR t2_waiting', -'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -INSERT INTO t3 VALUES (52, foo(52, -'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', -'')); -INSERT INTO t3 VALUES (53, foo(53, -'group_commit_waiting_for_prior SIGNAL t2_waiting', -'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -COMMIT; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (54, foo(54, -'', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -a b -51 51 -52 52 -53 53 -54 54 -SET debug_sync='RESET'; -connection server_2; -SET debug_sync='now WAIT_FOR t2_query'; -SET debug_sync='now SIGNAL t2_cont'; -SET debug_sync='now WAIT_FOR t1_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t2_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -a b -51 51 -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -INSERT INTO t3 VALUES (59,0); -connection server_2; -START SLAVE SQL_THREAD; -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -a b -51 51 -52 52 -53 53 -54 54 -59 0 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=slave_pos; -include/start_slave.inc -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=4; -include/start_slave.inc -*** 4. Test killing thread that is waiting to start transaction until previous transaction commits *** -connection server_1; -SET binlog_format=statement; -SET gtid_domain_id=2; -BEGIN; -INSERT INTO t3 VALUES (70, foo(70, -'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); -INSERT INTO t3 VALUES (60, foo(60, -'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', -'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); -COMMIT; -SET gtid_domain_id=0; -connection server_2; -SET debug_sync='now WAIT_FOR d2_query'; -connection server_1; -SET gtid_domain_id=1; -BEGIN; -INSERT INTO t3 VALUES (61, foo(61, -'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', -'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); -INSERT INTO t3 VALUES (62, foo(62, -'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', -'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); -COMMIT; -SET gtid_domain_id=0; -connection server_2; -SET debug_sync='now WAIT_FOR d1_query'; -connection server_1; -SET gtid_domain_id=0; -INSERT INTO t3 VALUES (63, foo(63, -'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', -'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); -connection server_2; -SET debug_sync='now WAIT_FOR d0_query'; -connection server_1; -SET gtid_domain_id=3; -BEGIN; -INSERT INTO t3 VALUES (68, foo(68, -'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); -INSERT INTO t3 VALUES (69, foo(69, -'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', -'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); -COMMIT; -SET gtid_domain_id=0; -connection server_2; -SET debug_sync='now WAIT_FOR d3_query'; -SET debug_sync='now SIGNAL d2_cont2'; -SET debug_sync='now WAIT_FOR d2_done'; -SET debug_sync='now SIGNAL d1_cont2'; -SET debug_sync='now WAIT_FOR d1_done'; -SET debug_sync='now SIGNAL d0_cont2'; -SET debug_sync='now WAIT_FOR d0_done'; -SET debug_sync='now SIGNAL d3_cont2'; -SET debug_sync='now WAIT_FOR d3_done'; -connection con_temp3; -SET binlog_format=statement; -INSERT INTO t3 VALUES (64, foo(64, -'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; -INSERT INTO t3 VALUES (65, foo(65, '', '')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -INSERT INTO t3 VALUES (66, foo(66, '', '')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; -INSERT INTO t3 VALUES (67, foo(67, '', '')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued4'; -SET debug_sync='now SIGNAL master_cont2'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 60 ORDER BY a; -a b -60 60 -61 61 -62 62 -63 63 -64 64 -65 65 -66 66 -67 67 -68 68 -69 69 -70 70 -SET debug_sync='RESET'; -connection server_2; -SET debug_sync='now SIGNAL d0_cont'; -SET debug_sync='now WAIT_FOR t1_waiting'; -SET debug_sync='now SIGNAL d3_cont'; -SET debug_sync='now WAIT_FOR t2_waiting'; -SET debug_sync='now SIGNAL d1_cont'; -SET debug_sync='now WAIT_FOR t3_waiting'; -SET debug_sync='now SIGNAL d2_cont'; -SET debug_sync='now WAIT_FOR t4_waiting'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t3_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -STOP SLAVE IO_THREAD; -SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; -a b -60 60 -61 61 -62 62 -63 63 -64 64 -68 68 -69 69 -70 70 -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -UPDATE t3 SET b=b+1 WHERE a=60; -connection server_2; -include/start_slave.inc -SELECT * FROM t3 WHERE a >= 60 ORDER BY a; -a b -60 61 -61 61 -62 62 -63 63 -64 64 -65 65 -66 66 -67 67 -68 68 -69 69 -70 70 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** 5. Test killing thread that is waiting for queue of max length to shorten *** -SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; -SET GLOBAL slave_parallel_max_queued=9000; -connection server_1; -SET binlog_format=statement; -INSERT INTO t3 VALUES (80, foo(0, -'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); -connection server_2; -SET debug_sync='now WAIT_FOR query_waiting'; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; -connection server_1; -SELECT * FROM t3 WHERE a >= 80 ORDER BY a; -a b -80 0 -81 10000 -connection server_2; -SET debug_sync='now WAIT_FOR wait_queue_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR wait_queue_killed'; -SET debug_sync='now SIGNAL query_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -STOP SLAVE IO_THREAD; -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_max_queued= @old_max_queued; -connection server_1; -INSERT INTO t3 VALUES (82,0); -SET binlog_format=@old_format; -connection server_2; -SET debug_sync='RESET'; -include/start_slave.inc -SELECT * FROM t3 WHERE a >= 80 ORDER BY a; -a b -80 0 -81 10000 -82 0 -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL replicate_ignore_table="test.t3"; -SET GLOBAL slave_parallel_threads=2; -include/start_slave.inc -connection server_1; -INSERT INTO t3 VALUES (100, rand()); -INSERT INTO t3 VALUES (101, rand()); -connection server_2; -connection server_1; -INSERT INTO t3 VALUES (102, rand()); -INSERT INTO t3 VALUES (103, rand()); -INSERT INTO t3 VALUES (104, rand()); -INSERT INTO t3 VALUES (105, rand()); -connection server_2; -include/stop_slave.inc -SET GLOBAL replicate_ignore_table=""; -include/start_slave.inc -connection server_1; -INSERT INTO t3 VALUES (106, rand()); -INSERT INTO t3 VALUES (107, rand()); -connection server_2; -SELECT * FROM t3 WHERE a >= 100 ORDER BY a; -a b -106 # -107 # -*** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -connection server_1; -INSERT INTO t3 VALUES (110, 1); -connection server_2; -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -a b -110 1 -SET sql_log_bin=0; -INSERT INTO t3 VALUES (111, 666); -SET sql_log_bin=1; -connection server_1; -connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -INSERT INTO t3 VALUES (111, 2); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -INSERT INTO t3 VALUES (112, 3); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -SET debug_sync='now SIGNAL master_cont1'; -connection con1; -connection con2; -SET debug_sync='RESET'; -connection server_2; -include/wait_for_slave_sql_error.inc [errno=1062] -include/wait_for_slave_sql_to_stop.inc -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -a b -110 1 -111 666 -SET sql_log_bin=0; -DELETE FROM t3 WHERE a=111 AND b=666; -SET sql_log_bin=1; -START SLAVE SQL_THREAD; -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -a b -110 1 -111 2 -112 3 -***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts *** -connection server_2; -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); -connection con1; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -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'; -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; -connection con2; -SET debug_sync='RESET'; -connection server_2; -include/start_slave.inc -include/stop_slave.inc -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 NULL -connection server_1; -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); -connection con1; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -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'; -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; -connection con2; -SET debug_sync='RESET'; -connection server_2; -include/start_slave.inc -include/stop_slave.inc -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 6 -7 NULL -connection server_1; -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); -connection con1; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -UPDATE t4 SET b=NULL WHERE a=6; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con2; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format='statement'; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -DELETE FROM t4 WHERE b <= 1; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -SET debug_sync='now SIGNAL master_cont1'; -connection con1; -connection con2; -SET @old_format=@@GLOBAL.binlog_format; -SET debug_sync='RESET'; -connection server_2; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; -include/start_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -2 2 -3 NULL -4 4 -5 NULL -6 NULL -SET @last_gtid= 'GTID'; -SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", -CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) -AS result; -result -GTID found ok -SELECT "ROW FOUND" AS `Is the row found?` - FROM mysql.gtid_slave_pos -WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; -Is the row found? -ROW FOUND -*** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=1; -SET DEBUG_SYNC= 'RESET'; -include/start_slave.inc -connection server_1; -CREATE TABLE t5 (a INT PRIMARY KEY, b INT); -INSERT INTO t5 VALUES (1,1); -INSERT INTO t5 VALUES (2,2), (3,8); -INSERT INTO t5 VALUES (4,16); -connection server_2; -test_check -OK -test_check -OK -connection server_1; -FLUSH LOGS; -connection server_2; -test_check -OK -test_check -OK -*** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** -connection server_1; -CREATE TABLE t6 (a INT) ENGINE=MyISAM; -CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; -connection con1; -SET @old_format= @@binlog_format; -SET binlog_format= statement; -SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; -INSERT INTO t6 VALUES (1), (2), (3); -connection server_1; -SET debug_sync='now WAIT_FOR ready'; -KILL QUERY CONID; -SET debug_sync='now SIGNAL cont'; -connection con1; -ERROR 70100: Query execution was interrupted -SET binlog_format= @old_format; -SET debug_sync='RESET'; -connection server_1; -SET debug_sync='RESET'; -connection server_2; -include/wait_for_slave_sql_error.inc [errno=1317] -STOP SLAVE IO_THREAD; -SET GLOBAL gtid_slave_pos= 'AFTER_ERROR_GTID_POS'; -include/start_slave.inc -connection server_1; -INSERT INTO t6 VALUES (4); -SELECT * FROM t6 ORDER BY a; -a -1 -4 -connection server_2; -SELECT * FROM t6 ORDER BY a; -a -4 -*** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** -connection server_1; -INSERT INTO t2 VALUES (31); -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -include/stop_slave.inc -SET GLOBAL slave_parallel_threads= 0; -include/start_slave.inc -SET sql_log_bin= 0; -INSERT INTO t2 VALUES (32); -SET sql_log_bin= 1; -connection server_1; -INSERT INTO t2 VALUES (32); -FLUSH LOGS; -INSERT INTO t2 VALUES (33); -INSERT INTO t2 VALUES (34); -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; -a -31 -32 -33 -34 -include/save_master_gtid.inc -connection server_2; -include/wait_for_slave_sql_error.inc [errno=1062] -connection server_2; -include/stop_slave_io.inc -SET GLOBAL slave_parallel_threads=10; -START SLAVE; -include/wait_for_slave_sql_error.inc [errno=1062] -START SLAVE SQL_THREAD; -include/wait_for_slave_sql_error.inc [errno=1062] -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; -a -31 -32 -SET sql_slave_skip_counter= 1; -ERROR HY000: When using parallel replication and GTID with multiple replication domains, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position -include/stop_slave_io.inc -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; -a -31 -32 -33 -34 -*** MDEV-6775: Wrong binlog order in parallel replication *** -connection server_1; -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; -SET @old_format=@@GLOBAL.binlog_format; -SET GLOBAL binlog_format=ROW; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -connection con1; -SET @old_format= @@binlog_format; -SET binlog_format= statement; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -UPDATE t4 SET b=NULL WHERE a=6; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con2; -SET @old_format= @@binlog_format; -SET binlog_format= statement; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -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; -SET binlog_format= @old_format; -connection con2; -SET binlog_format= @old_format; -SET debug_sync='RESET'; -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 NULL -connection server_2; -include/start_slave.inc -SET debug_sync= 'now WAIT_FOR waiting'; -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 NULL -SET debug_sync= 'now SIGNAL cont'; -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL binlog_format= @old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** -connection server_1; -INSERT INTO t2 VALUES (40); -connection server_2; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -connection server_1; -INSERT INTO t2 VALUES (41); -INSERT INTO t2 VALUES (42); -SET @old_format= @@binlog_format; -SET binlog_format= statement; -DELETE FROM t2 WHERE a=40; -SET binlog_format= @old_format; -INSERT INTO t2 VALUES (43); -INSERT INTO t2 VALUES (44); -FLUSH LOGS; -INSERT INTO t2 VALUES (45); -SET gtid_seq_no=100; -INSERT INTO t2 VALUES (46); -connection con_temp2; -BEGIN; -SELECT * FROM t2 WHERE a=40 FOR UPDATE; -a -40 -connection server_2; -include/start_slave.inc -SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; -STOP SLAVE; -connection con_temp2; -SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; -ROLLBACK; -connection server_2; -include/wait_for_slave_sql_to_stop.inc -SELECT * FROM t2 WHERE a >= 40 ORDER BY a; -a -41 -42 -include/start_slave.inc -SELECT * FROM t2 WHERE a >= 40 ORDER BY a; -a -41 -42 -43 -44 -45 -46 -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET DEBUG_SYNC= 'RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -CHANGE MASTER TO master_use_gtid=slave_pos; -include/start_slave.inc -*** MDEV-7326 Server deadlock in connection with parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=3; -SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; -include/start_slave.inc -connection server_1; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format= STATEMENT; -INSERT INTO t1 VALUES (foo(50, -"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", -"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; -connection server_1; -INSERT INTO t2 VALUES (foo(50, -"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", -"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; -connection server_1; -INSERT INTO t1 VALUES (foo(51, -"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", -"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; -SET DEBUG_SYNC= "now SIGNAL t1_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; -connection server_1; -INSERT INTO t1 VALUES (52); -SET BINLOG_FORMAT= @old_format; -SELECT * FROM t2 WHERE a>=50 ORDER BY a; -a -50 -SELECT * FROM t1 WHERE a>=50 ORDER BY a; -a -50 -51 -52 -connection server_2; -SET DEBUG_SYNC= "now SIGNAL prep_cont"; -SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; -SET DEBUG_SYNC= "now SIGNAL t2_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; -SET DEBUG_SYNC= "now SIGNAL t1_cont2"; -connection server_1; -connection server_2; -SELECT * FROM t2 WHERE a>=50 ORDER BY a; -a -50 -SELECT * FROM t1 WHERE a>=50 ORDER BY a; -a -50 -51 -52 -SET DEBUG_SYNC="reset"; -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-7326 Server deadlock in connection with parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=3; -SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; -include/start_slave.inc -connection server_1; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format= STATEMENT; -INSERT INTO t1 VALUES (foo(60, -"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", -"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; -connection server_1; -INSERT INTO t2 VALUES (foo(60, -"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", -"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t1 VALUES (foo(61, -"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", -"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -INSERT INTO t6 VALUES (62); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection server_1; -SET debug_sync='RESET'; -SET BINLOG_FORMAT= @old_format; -SELECT * FROM t2 WHERE a>=60 ORDER BY a; -a -60 -SELECT * FROM t1 WHERE a>=60 ORDER BY a; -a -60 -61 -SELECT * FROM t6 WHERE a>=60 ORDER BY a; -a -62 -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; -SET DEBUG_SYNC= "now SIGNAL t1_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; -connection server_2; -SET DEBUG_SYNC= "now SIGNAL prep_cont"; -SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; -SET DEBUG_SYNC= "now SIGNAL t2_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; -SET DEBUG_SYNC= "now SIGNAL t1_cont2"; -connection server_1; -connection server_2; -SELECT * FROM t2 WHERE a>=60 ORDER BY a; -a -60 -SELECT * FROM t1 WHERE a>=60 ORDER BY a; -a -60 -61 -SELECT * FROM t6 WHERE a>=60 ORDER BY a; -a -62 -SET DEBUG_SYNC="reset"; -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=1; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; -connection server_1; -INSERT INTO t2 VALUES (101); -INSERT INTO t2 VALUES (102); -INSERT INTO t2 VALUES (103); -INSERT INTO t2 VALUES (104); -INSERT INTO t2 VALUES (105); -SET gtid_seq_no=1000; -INSERT INTO t2 VALUES (106); -INSERT INTO t2 VALUES (107); -INSERT INTO t2 VALUES (108); -INSERT INTO t2 VALUES (109); -INSERT INTO t2 VALUES (110); -INSERT INTO t2 VALUES (111); -INSERT INTO t2 VALUES (112); -INSERT INTO t2 VALUES (113); -INSERT INTO t2 VALUES (114); -INSERT INTO t2 VALUES (115); -INSERT INTO t2 VALUES (116); -INSERT INTO t2 VALUES (117); -INSERT INTO t2 VALUES (118); -INSERT INTO t2 VALUES (119); -INSERT INTO t2 VALUES (120); -INSERT INTO t2 VALUES (121); -INSERT INTO t2 VALUES (122); -INSERT INTO t2 VALUES (123); -INSERT INTO t2 VALUES (124); -INSERT INTO t2 VALUES (125); -INSERT INTO t2 VALUES (126); -INSERT INTO t2 VALUES (127); -INSERT INTO t2 VALUES (128); -INSERT INTO t2 VALUES (129); -INSERT INTO t2 VALUES (130); -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 100 ORDER BY a; -a -101 -102 -103 -104 -105 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-6676 - test syntax of @@slave_parallel_mode *** -connection server_2; -Parallel_Mode = 'conservative' -include/stop_slave.inc -SET GLOBAL slave_parallel_mode='aggressive'; -Parallel_Mode = 'aggressive' -SET GLOBAL slave_parallel_mode='conservative'; -Parallel_Mode = 'conservative' -*** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** -connection server_1; -INSERT INTO t2 VALUES (1040); -include/save_master_gtid.inc -connection server_2; -SET GLOBAL slave_parallel_mode='none'; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; -a -1040 -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -*** MDEV-6676 - test disabling domain-based parallel replication *** -connection server_1; -SET gtid_domain_id = 1; -INSERT INTO t2 VALUES (1041); -INSERT INTO t2 VALUES (1042); -INSERT INTO t2 VALUES (1043); -INSERT INTO t2 VALUES (1044); -INSERT INTO t2 VALUES (1045); -INSERT INTO t2 VALUES (1046); -DELETE FROM t2 WHERE a >= 1041; -SET gtid_domain_id = 2; -INSERT INTO t2 VALUES (1041); -INSERT INTO t2 VALUES (1042); -INSERT INTO t2 VALUES (1043); -INSERT INTO t2 VALUES (1044); -INSERT INTO t2 VALUES (1045); -INSERT INTO t2 VALUES (1046); -SET gtid_domain_id = 0; -include/save_master_gtid.inc -connection server_2; -SET GLOBAL slave_parallel_mode=minimal; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; -a -1040 -1041 -1042 -1043 -1044 -1045 -1046 -*** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_mode='conservative'; -SET GLOBAL slave_parallel_threads=10; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @commit_id= 10000; -ANALYZE TABLE t2; -Table Op Msg_type Msg_text -test.t2 analyze status Engine-independent statistics collected -test.t2 analyze status OK -INSERT INTO t3 VALUES (120, 0); -SET @commit_id= 10001; -INSERT INTO t3 VALUES (121, 0); -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a >= 120 ORDER BY a; -a b -120 0 -121 0 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a >= 120 ORDER BY a; -a b -120 0 -121 0 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; -include/start_slave.inc -*** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** -connection server_2; -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @old_server_id= @@SESSION.server_id; -SET SESSION server_id= 100; -SET @commit_id= 10010; -ALTER TABLE t1 COMMENT "Hulubulu!"; -SET SESSION server_id= @old_server_id; -INSERT INTO t3 VALUES (130, 0); -SET @commit_id= 10011; -INSERT INTO t3 VALUES (131, 0); -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a >= 130 ORDER BY a; -a b -130 0 -131 0 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a >= 130 ORDER BY a; -a b -130 0 -131 0 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; -include/start_slave.inc -*** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** -connection server_1; -INSERT INTO t3 VALUES (201,0), (202,0); -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_mdev8031'; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @commit_id= 10200; -INSERT INTO t3 VALUES (203, 1); -INSERT INTO t3 VALUES (204, 1); -INSERT INTO t3 VALUES (205, 1); -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=205; -UPDATE t3 SET b=b+1 WHERE a=205; -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 3 -202 4 -203 4 -204 4 -205 3 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 3 -202 4 -203 4 -204 4 -205 3 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; -include/start_slave.inc -*** Check getting deadlock killed inside open_binlog() during retry. *** -connection server_2; -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; -SET @old_max= @@GLOBAL.max_relay_log_size; -SET GLOBAL max_relay_log_size= 4096; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @commit_id= 10210; -Omit long queries that cause relaylog rotations and transaction retries... -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 6 -202 8 -203 7 -204 7 -205 5 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 6 -202 8 -203 7 -204 7 -205 5 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_debg; -SET GLOBAL max_relay_log_size= @old_max; -include/start_slave.inc -*** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** -connection server_1; -BEGIN; -INSERT INTO t2 VALUES (2000); -INSERT INTO t1 VALUES (2000); -INSERT INTO t2 VALUES (2001); -ROLLBACK; -SELECT * FROM t1 WHERE a>=2000 ORDER BY a; -a -2000 -SELECT * FROM t2 WHERE a>=2000 ORDER BY a; -a -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -SELECT * FROM t1 WHERE a>=2000 ORDER BY a; -a -2000 -SELECT * FROM t2 WHERE a>=2000 ORDER BY a; -a -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=@old_parallel_threads; -include/start_slave.inc -SET DEBUG_SYNC= 'RESET'; -connection server_1; -DROP function foo; -DROP TABLE t1,t2,t3,t4,t5,t6; -SET DEBUG_SYNC= 'RESET'; -include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel.test b/mysql-test/suite/binlog_encryption/rpl_parallel.test deleted file mode 100644 index dba54e4fd7a..00000000000 --- a/mysql-test/suite/binlog_encryption/rpl_parallel.test +++ /dev/null @@ -1 +0,0 @@ ---source suite/rpl/include/rpl_parallel.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_analyze_table_hang.result b/mysql-test/suite/binlog_encryption/rpl_parallel_analyze_table_hang.result new file mode 100644 index 00000000000..3c3cd2601e8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_analyze_table_hang.result @@ -0,0 +1,51 @@ +*** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10000; +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +INSERT INTO t3 VALUES (120, 0); +SET @commit_id= 10001; +INSERT INTO t3 VALUES (121, 0); +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +a b +120 0 +121 0 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +a b +120 0 +121 0 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t2,t3; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_analyze_table_hang.test b/mysql-test/suite/binlog_encryption/rpl_parallel_analyze_table_hang.test new file mode 100644 index 00000000000..69e76692ce1 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_analyze_table_hang.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_analyze_table_hang.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_deadlock_corrupt_binlog.result b/mysql-test/suite/binlog_encryption/rpl_parallel_deadlock_corrupt_binlog.result new file mode 100644 index 00000000000..74d1d53b67c --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_deadlock_corrupt_binlog.result @@ -0,0 +1,93 @@ +*** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=1; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; +connection server_1; +INSERT INTO t2 VALUES (101); +INSERT INTO t2 VALUES (102); +INSERT INTO t2 VALUES (103); +INSERT INTO t2 VALUES (104); +INSERT INTO t2 VALUES (105); +SET gtid_seq_no=1000; +INSERT INTO t2 VALUES (106); +INSERT INTO t2 VALUES (107); +INSERT INTO t2 VALUES (108); +INSERT INTO t2 VALUES (109); +INSERT INTO t2 VALUES (110); +INSERT INTO t2 VALUES (111); +INSERT INTO t2 VALUES (112); +INSERT INTO t2 VALUES (113); +INSERT INTO t2 VALUES (114); +INSERT INTO t2 VALUES (115); +INSERT INTO t2 VALUES (116); +INSERT INTO t2 VALUES (117); +INSERT INTO t2 VALUES (118); +INSERT INTO t2 VALUES (119); +INSERT INTO t2 VALUES (120); +INSERT INTO t2 VALUES (121); +INSERT INTO t2 VALUES (122); +INSERT INTO t2 VALUES (123); +INSERT INTO t2 VALUES (124); +INSERT INTO t2 VALUES (125); +INSERT INTO t2 VALUES (126); +INSERT INTO t2 VALUES (127); +INSERT INTO t2 VALUES (128); +INSERT INTO t2 VALUES (129); +INSERT INTO t2 VALUES (130); +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 100 ORDER BY a; +a +101 +102 +103 +104 +105 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t2; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_deadlock_corrupt_binlog.test b/mysql-test/suite/binlog_encryption/rpl_parallel_deadlock_corrupt_binlog.test new file mode 100644 index 00000000000..71c589dcd88 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_deadlock_corrupt_binlog.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_deadlock_corrupt_binlog.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_domain.result b/mysql-test/suite/binlog_encryption/rpl_parallel_domain.result new file mode 100644 index 00000000000..69b9678d149 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_domain.result @@ -0,0 +1,71 @@ +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) +OK +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) +OK +include/stop_slave.inc +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) +OK +include/start_slave.inc +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) +OK +*** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +connection server_2; +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +LOCK TABLE t1 WRITE; +connection server_1; +SET gtid_domain_id=1; +INSERT INTO t1 VALUES (2); +SET gtid_domain_id=0; +INSERT INTO t2 VALUES (2); +INSERT INTO t2 VALUES (3); +BEGIN; +INSERT INTO t2 VALUES (4); +INSERT INTO t2 VALUES (5); +COMMIT; +INSERT INTO t2 VALUES (6); +connection server_2; +SELECT * FROM t2 ORDER by a; +a +1 +2 +3 +4 +5 +6 +connection con_temp1; +SELECT * FROM t1; +a +1 +UNLOCK TABLES; +connection server_2; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t1,t2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_domain.test b/mysql-test/suite/binlog_encryption/rpl_parallel_domain.test new file mode 100644 index 00000000000..b498b8616c8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_domain.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_domain.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_domain_slave_single_grp.result b/mysql-test/suite/binlog_encryption/rpl_parallel_domain_slave_single_grp.result new file mode 100644 index 00000000000..613aac64487 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_domain_slave_single_grp.result @@ -0,0 +1,101 @@ +*** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +connection server_2; +include/stop_slave.inc +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (foo(10, +'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); +connection server_2; +FLUSH LOGS; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=statement; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +SET debug_sync='now WAIT_FOR ready1'; +connection server_1; +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (foo(11, +'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); +SET gtid_domain_id=0; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +a +10 +11 +connection server_2; +SET debug_sync='now WAIT_FOR ready3'; +SET debug_sync='now SIGNAL cont3'; +SET debug_sync='now WAIT_FOR ready4'; +SET debug_sync='now SIGNAL cont1'; +SET debug_sync='now WAIT_FOR ready2'; +SET debug_sync='now SIGNAL cont4'; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +a +10 +11 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 +slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(11, +'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')) +slave-bin.000002 # Xid # # COMMIT /* XID */ +slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(10, +'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')) +slave-bin.000002 # Xid # # COMMIT /* XID */ +FLUSH LOGS; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL binlog_format=@old_format; +connection server_1; +DROP function foo; +DROP TABLE t1,t2; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL binlog_format=@old_format; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_domain_slave_single_grp.test b/mysql-test/suite/binlog_encryption/rpl_parallel_domain_slave_single_grp.test new file mode 100644 index 00000000000..ce9239f189e --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_domain_slave_single_grp.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_domain_slave_single_grp.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_free_deferred_event.result b/mysql-test/suite/binlog_encryption/rpl_parallel_free_deferred_event.result new file mode 100644 index 00000000000..6718561a321 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_free_deferred_event.result @@ -0,0 +1,44 @@ +*** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL replicate_ignore_table="test.t3"; +SET GLOBAL slave_parallel_threads=2; +include/start_slave.inc +connection server_1; +INSERT INTO t3 VALUES (100, rand()); +INSERT INTO t3 VALUES (101, rand()); +connection server_2; +connection server_1; +INSERT INTO t3 VALUES (102, rand()); +INSERT INTO t3 VALUES (103, rand()); +INSERT INTO t3 VALUES (104, rand()); +INSERT INTO t3 VALUES (105, rand()); +connection server_2; +include/stop_slave.inc +SET GLOBAL replicate_ignore_table=""; +include/start_slave.inc +connection server_1; +INSERT INTO t3 VALUES (106, rand()); +INSERT INTO t3 VALUES (107, rand()); +connection server_2; +SELECT * FROM t3 WHERE a >= 100 ORDER BY a; +a b +106 # +107 # +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t3; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_free_deferred_event.test b/mysql-test/suite/binlog_encryption/rpl_parallel_free_deferred_event.test new file mode 100644 index 00000000000..d0b6c970210 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_free_deferred_event.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_free_deferred_event.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_gco_wait_kill.result b/mysql-test/suite/binlog_encryption/rpl_parallel_gco_wait_kill.result new file mode 100644 index 00000000000..4472550c4f2 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_gco_wait_kill.result @@ -0,0 +1,257 @@ +*** Test killing thread that is waiting to start transaction until previous transaction commits *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Slave: Connection was killed"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET sql_log_bin=1; +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode= 'conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=4; +include/start_slave.inc +connection server_1; +SET gtid_domain_id=2; +BEGIN; +INSERT INTO t3 VALUES (70, foo(70, +'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); +INSERT INTO t3 VALUES (60, foo(60, +'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', +'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d2_query'; +connection server_1; +SET gtid_domain_id=1; +BEGIN; +INSERT INTO t3 VALUES (61, foo(61, +'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', +'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); +INSERT INTO t3 VALUES (62, foo(62, +'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', +'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d1_query'; +connection server_1; +SET gtid_domain_id=0; +INSERT INTO t3 VALUES (63, foo(63, +'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', +'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); +connection server_2; +SET debug_sync='now WAIT_FOR d0_query'; +connection server_1; +SET gtid_domain_id=3; +BEGIN; +INSERT INTO t3 VALUES (68, foo(68, +'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); +INSERT INTO t3 VALUES (69, foo(69, +'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', +'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d3_query'; +SET debug_sync='now SIGNAL d2_cont2'; +SET debug_sync='now WAIT_FOR d2_done'; +SET debug_sync='now SIGNAL d1_cont2'; +SET debug_sync='now WAIT_FOR d1_done'; +SET debug_sync='now SIGNAL d0_cont2'; +SET debug_sync='now WAIT_FOR d0_done'; +SET debug_sync='now SIGNAL d3_cont2'; +SET debug_sync='now WAIT_FOR d3_done'; +connection con_temp3; +INSERT INTO t3 VALUES (64, foo(64, +'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; +INSERT INTO t3 VALUES (65, foo(65, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (66, foo(66, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; +INSERT INTO t3 VALUES (67, foo(67, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued4'; +SET debug_sync='now SIGNAL master_cont2'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +a b +60 60 +61 61 +62 62 +63 63 +64 64 +65 65 +66 66 +67 67 +68 68 +69 69 +70 70 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now SIGNAL d0_cont'; +SET debug_sync='now WAIT_FOR t1_waiting'; +SET debug_sync='now SIGNAL d3_cont'; +SET debug_sync='now WAIT_FOR t2_waiting'; +SET debug_sync='now SIGNAL d1_cont'; +SET debug_sync='now WAIT_FOR t3_waiting'; +SET debug_sync='now SIGNAL d2_cont'; +SET debug_sync='now WAIT_FOR t4_waiting'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t3_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; +a b +60 60 +61 61 +62 62 +63 63 +64 64 +68 68 +69 69 +70 70 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +UPDATE t3 SET b=b+1 WHERE a=60; +connection server_2; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +a b +60 61 +61 61 +62 62 +63 63 +64 64 +65 65 +66 66 +67 67 +68 68 +69 69 +70 70 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 5. Test killing thread that is waiting for queue of max length to shorten *** +SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; +SET GLOBAL slave_parallel_max_queued=9000; +connection server_1; +INSERT INTO t3 VALUES (80, foo(0, +'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); +connection server_2; +SET debug_sync='now WAIT_FOR query_waiting'; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; +connection server_1; +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; +a b +80 0 +81 10000 +connection server_2; +SET debug_sync='now WAIT_FOR wait_queue_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR wait_queue_killed'; +SET debug_sync='now SIGNAL query_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_max_queued= @old_max_queued; +connection server_1; +INSERT INTO t3 VALUES (82,0); +connection server_2; +SET debug_sync='RESET'; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; +a b +80 0 +81 10000 +82 0 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP function foo; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_gco_wait_kill.test b/mysql-test/suite/binlog_encryption/rpl_parallel_gco_wait_kill.test new file mode 100644 index 00000000000..853465f1760 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_gco_wait_kill.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_gco_wait_kill.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_gtid_slave_pos_update_fail.result b/mysql-test/suite/binlog_encryption/rpl_parallel_gtid_slave_pos_update_fail.result new file mode 100644 index 00000000000..2e7e7f547af --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_gtid_slave_pos_update_fail.result @@ -0,0 +1,65 @@ +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +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); +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection server_2; +include/stop_slave.inc +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +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'; +DELETE FROM t4 WHERE b <= 1; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET debug_sync='RESET'; +connection server_2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; +include/start_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +2 2 +3 NULL +4 4 +5 NULL +6 NULL +SET @last_gtid= 'GTID'; +SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", +CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) +AS result; +result +GTID found ok +SELECT "ROW FOUND" AS `Is the row found?` + FROM mysql.gtid_slave_pos +WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; +Is the row found? +ROW FOUND +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +disconnect con1; +disconnect con2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_gtid_slave_pos_update_fail.test b/mysql-test/suite/binlog_encryption/rpl_parallel_gtid_slave_pos_update_fail.test new file mode 100644 index 00000000000..67105ccafee --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_gtid_slave_pos_update_fail.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_gtid_slave_pos_update_fail.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_ignore_error_on_rotate.result b/mysql-test/suite/binlog_encryption/rpl_parallel_ignore_error_on_rotate.result new file mode 100644 index 00000000000..d00740dba3d --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_ignore_error_on_rotate.result @@ -0,0 +1,74 @@ +*** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (1); +SET gtid_domain_id=0; +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (2); +SET gtid_domain_id=0; +INSERT INTO t2 VALUES (31); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET GLOBAL slave_parallel_threads= 0; +include/start_slave.inc +SET sql_log_bin= 0; +INSERT INTO t2 VALUES (32); +SET sql_log_bin= 1; +connection server_1; +INSERT INTO t2 VALUES (32); +FLUSH LOGS; +INSERT INTO t2 VALUES (33); +INSERT INTO t2 VALUES (34); +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +include/save_master_gtid.inc +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1062] +connection server_2; +include/stop_slave_io.inc +SET GLOBAL slave_parallel_threads=10; +START SLAVE; +include/wait_for_slave_sql_error.inc [errno=1062] +START SLAVE SQL_THREAD; +include/wait_for_slave_sql_error.inc [errno=1062] +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +SET sql_slave_skip_counter= 1; +ERROR HY000: When using parallel replication and GTID with multiple replication domains, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position +include/stop_slave_io.inc +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_ignore_error_on_rotate.test b/mysql-test/suite/binlog_encryption/rpl_parallel_ignore_error_on_rotate.test new file mode 100644 index 00000000000..ce57184d812 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_ignore_error_on_rotate.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_ignore_error_on_rotate.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_incorrect_relay_pos.result b/mysql-test/suite/binlog_encryption/rpl_parallel_incorrect_relay_pos.result new file mode 100644 index 00000000000..6ca7f2b68e8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_incorrect_relay_pos.result @@ -0,0 +1,75 @@ +*** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (40); +connection server_2; +connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +connection server_1; +INSERT INTO t2 VALUES (41); +INSERT INTO t2 VALUES (42); +SET @old_format= @@binlog_format; +SET binlog_format= statement; +DELETE FROM t2 WHERE a=40; +SET binlog_format= @old_format; +INSERT INTO t2 VALUES (43); +INSERT INTO t2 VALUES (44); +FLUSH LOGS; +INSERT INTO t2 VALUES (45); +SET gtid_seq_no=100; +INSERT INTO t2 VALUES (46); +connection con_temp2; +BEGIN; +SELECT * FROM t2 WHERE a=40 FOR UPDATE; +a +40 +connection server_2; +include/start_slave.inc +SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; +STOP SLAVE; +connection con_temp2; +SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; +connection server_2; +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a +41 +42 +include/start_slave.inc +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a +41 +42 +43 +44 +45 +46 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_incorrect_relay_pos.test b/mysql-test/suite/binlog_encryption/rpl_parallel_incorrect_relay_pos.test new file mode 100644 index 00000000000..ddec96e8792 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_incorrect_relay_pos.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_innodb_lock_conflict.result b/mysql-test/suite/binlog_encryption/rpl_parallel_innodb_lock_conflict.result new file mode 100644 index 00000000000..1411db16af6 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_innodb_lock_conflict.result @@ -0,0 +1,79 @@ +***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts *** +include/master-slave.inc +[connection master] +connection server_2; +SET sql_log_bin=0; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET sql_log_bin=1; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +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); +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +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'; +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; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/start_slave.inc +include/stop_slave.inc +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +connection server_1; +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +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'; +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; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/start_slave.inc +include/stop_slave.inc +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 6 +7 NULL +connection server_2; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +disconnect con1; +disconnect con2; +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_innodb_lock_conflict.test b/mysql-test/suite/binlog_encryption/rpl_parallel_innodb_lock_conflict.test new file mode 100644 index 00000000000..624667d5408 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_innodb_lock_conflict.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_innodb_lock_conflict.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.result b/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.result new file mode 100644 index 00000000000..e9d04c02d7a --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.result @@ -0,0 +1,65 @@ +*** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +connection server_1; +INSERT INTO t3 VALUES (110, 1); +connection server_2; +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +SET sql_log_bin=0; +INSERT INTO t3 VALUES (111, 666); +SET sql_log_bin=1; +connection server_1; +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (111, 2); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +INSERT INTO t3 VALUES (112, 3); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1062] +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +111 666 +SET sql_log_bin=0; +DELETE FROM t3 WHERE a=111 AND b=666; +SET sql_log_bin=1; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +111 2 +112 3 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +disconnect con1; +disconnect con2; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.test b/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.test new file mode 100644 index 00000000000..c6d09f2196b --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_missed_error_handling.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_missed_error_handling.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_mode.result b/mysql-test/suite/binlog_encryption/rpl_parallel_mode.result new file mode 100644 index 00000000000..313290b1fd2 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_mode.result @@ -0,0 +1,75 @@ +*** MDEV-6676 - test syntax of @@slave_parallel_mode *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +connection server_2; +Parallel_Mode = 'optimistic' +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='aggressive'; +Parallel_Mode = 'aggressive' +SET GLOBAL slave_parallel_mode='conservative'; +Parallel_Mode = 'conservative' +*** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** +connection server_1; +INSERT INTO t2 VALUES (1040); +include/save_master_gtid.inc +connection server_2; +SET GLOBAL slave_parallel_mode='none'; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +a +1040 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +*** MDEV-6676 - test disabling domain-based parallel replication *** +connection server_1; +SET gtid_domain_id = 1; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +DELETE FROM t2 WHERE a >= 1041; +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +SET gtid_domain_id = 0; +include/save_master_gtid.inc +connection server_2; +SET GLOBAL slave_parallel_mode=minimal; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +a +1040 +1041 +1042 +1043 +1044 +1045 +1046 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_mode.test b/mysql-test/suite/binlog_encryption/rpl_parallel_mode.test new file mode 100644 index 00000000000..93170f61c95 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_mode.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_mode.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_partial_binlog_trans.result b/mysql-test/suite/binlog_encryption/rpl_parallel_partial_binlog_trans.result new file mode 100644 index 00000000000..ab1cac692a0 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_partial_binlog_trans.result @@ -0,0 +1,51 @@ +*** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection con1; +SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; +INSERT INTO t6 VALUES (1), (2), (3); +connection server_1; +SET debug_sync='now WAIT_FOR ready'; +KILL QUERY CONID; +SET debug_sync='now SIGNAL cont'; +connection con1; +ERROR 70100: Query execution was interrupted +SET debug_sync='RESET'; +connection server_1; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1317] +STOP SLAVE IO_THREAD; +SET GLOBAL gtid_slave_pos= 'AFTER_ERROR_GTID_POS'; +include/start_slave.inc +connection server_1; +INSERT INTO t6 VALUES (4); +SELECT * FROM t6 ORDER BY a; +a +1 +4 +connection server_2; +SELECT * FROM t6 ORDER BY a; +a +4 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t6; +SET DEBUG_SYNC= 'RESET'; +disconnect con1; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_partial_binlog_trans.test b/mysql-test/suite/binlog_encryption/rpl_parallel_partial_binlog_trans.test new file mode 100644 index 00000000000..4f90cf4808e --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_partial_binlog_trans.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_partial_binlog_trans.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_record_gtid_wakeup.result b/mysql-test/suite/binlog_encryption/rpl_parallel_record_gtid_wakeup.result new file mode 100644 index 00000000000..cbe53e4f623 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_record_gtid_wakeup.result @@ -0,0 +1,48 @@ +*** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @old_server_id= @@SESSION.server_id; +SET SESSION server_id= 100; +SET @commit_id= 10010; +ALTER TABLE t1 COMMENT "Hulubulu!"; +SET SESSION server_id= @old_server_id; +INSERT INTO t3 VALUES (130, 0); +SET @commit_id= 10011; +INSERT INTO t3 VALUES (131, 0); +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +a b +130 0 +131 0 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +a b +130 0 +131 0 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t1,t3; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_record_gtid_wakeup.test b/mysql-test/suite/binlog_encryption/rpl_parallel_record_gtid_wakeup.test new file mode 100644 index 00000000000..cb3b0dfa119 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_record_gtid_wakeup.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_record_gtid_wakeup.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_retry_deadlock.result b/mysql-test/suite/binlog_encryption/rpl_parallel_retry_deadlock.result new file mode 100644 index 00000000000..1f5a23db848 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_retry_deadlock.result @@ -0,0 +1,192 @@ +*** MDEV-7326 Server deadlock in connection with parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +connection server_2; +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +include/start_slave.inc +connection server_1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +INSERT INTO t1 VALUES (foo(50, +"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", +"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; +connection server_1; +INSERT INTO t2 VALUES (foo(50, +"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", +"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +connection server_1; +INSERT INTO t1 VALUES (foo(51, +"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", +"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +connection server_1; +INSERT INTO t1 VALUES (52); +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +a +50 +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +a +50 +51 +52 +connection server_2; +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +connection server_1; +connection server_2; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +a +50 +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +a +50 +51 +52 +SET DEBUG_SYNC="reset"; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-7326 Server deadlock in connection with parallel replication *** +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection server_2; +include/stop_slave.inc +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +include/start_slave.inc +connection server_1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +INSERT INTO t1 VALUES (foo(60, +"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", +"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; +connection server_1; +INSERT INTO t2 VALUES (foo(60, +"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", +"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t1 VALUES (foo(61, +"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", +"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +INSERT INTO t6 VALUES (62); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection server_1; +SET debug_sync='RESET'; +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +a +60 +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +a +60 +61 +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +a +62 +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +connection server_2; +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +connection server_1; +connection server_2; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +a +60 +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +a +60 +61 +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +a +62 +SET DEBUG_SYNC="reset"; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP function foo; +DROP TABLE t1,t2,t6; +disconnect con_temp3; +disconnect con_temp4; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_retry_deadlock.test b/mysql-test/suite/binlog_encryption/rpl_parallel_retry_deadlock.test new file mode 100644 index 00000000000..61c2cb22a75 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_retry_deadlock.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_retry_deadlock.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_rollback_assert.result b/mysql-test/suite/binlog_encryption/rpl_parallel_rollback_assert.result new file mode 100644 index 00000000000..af9c5f14687 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_rollback_assert.result @@ -0,0 +1,45 @@ +*** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +connection server_2; +connection server_1; +BEGIN; +INSERT INTO t2 VALUES (2000); +INSERT INTO t1 VALUES (2000); +INSERT INTO t2 VALUES (2001); +ROLLBACK; +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +a +2000 +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +a +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +connection server_1; +INSERT INTO t2 VALUES (2020); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +a +2020 +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +a +2000 +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t1,t2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_rollback_assert.test b/mysql-test/suite/binlog_encryption/rpl_parallel_rollback_assert.test new file mode 100644 index 00000000000..181305219be --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_rollback_assert.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_rollback_assert.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_single_grpcmt.result b/mysql-test/suite/binlog_encryption/rpl_parallel_single_grpcmt.result new file mode 100644 index 00000000000..25fc9a189ac --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_single_grpcmt.result @@ -0,0 +1,161 @@ +*** Test that group-committed transactions on the master can replicate in parallel on the slave. *** +include/master-slave.inc +[connection master] +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); +connection server_2; +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +BEGIN; +INSERT INTO t3 VALUES (2,102); +connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +BEGIN; +INSERT INTO t3 VALUES (4,104); +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +SET debug_sync='RESET'; +connection server_1; +SELECT * FROM t3 ORDER BY a; +a b +1 1 +2 12 +3 3 +4 14 +5 5 +6 16 +7 7 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Binlog_checkpoint # # master-bin.000001 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')) +master-bin.000001 # Xid # # COMMIT /* XID */ +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued3'; +connection con_temp1; +ROLLBACK; +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued1'; +connection con_temp2; +ROLLBACK; +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued2'; +SET debug_sync='now SIGNAL slave_cont1'; +SELECT * FROM t3 ORDER BY a; +a b +1 1 +2 12 +3 3 +4 14 +5 5 +6 16 +7 7 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')) +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')) +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')) +slave-bin.000001 # Xid # # COMMIT /* XID */ +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP function foo; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_single_grpcmt.test b/mysql-test/suite/binlog_encryption/rpl_parallel_single_grpcmt.test new file mode 100644 index 00000000000..6a13735c29c --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_single_grpcmt.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_single_grpcmt.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.result b/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.result new file mode 100644 index 00000000000..320bf0e49f8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.result @@ -0,0 +1,323 @@ +*** Test killing slave threads at various wait points *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +*** 1. Test killing transaction waiting in commit for previous transaction to commit *** +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (31, foo(31, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +INSERT INTO t3 VALUES (32, foo(32, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (33, foo(33, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (34, foo(34, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +32 32 +33 33 +34 34 +SET debug_sync='RESET'; +connection server_2; +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +CALL mtr.add_suppression("Slave: Connection was killed"); +SET sql_log_bin=1; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (39,0); +connection server_2; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +32 32 +33 33 +34 34 +39 0 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (41, foo(41, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +INSERT INTO t3 VALUES (42, foo(42, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (43, foo(43, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (44, foo(44, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +a b +41 41 +42 42 +43 43 +44 44 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (49,0); +connection server_2; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +a b +41 41 +42 42 +43 43 +44 44 +49 0 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 3. Same as (2), but not using gtid mode *** +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +include/start_slave.inc +connection server_1; +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (51, foo(51, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +INSERT INTO t3 VALUES (52, foo(52, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (53, foo(53, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (54, foo(54, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +52 52 +53 53 +54 54 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (59,0); +connection server_2; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +52 52 +53 53 +54 54 +59 0 +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP function foo; +DROP TABLE t1,t2,t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.test b/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.test new file mode 100644 index 00000000000..72597f32685 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_slave_bgc_kill.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_slave_bgc_kill.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_stop_on_con_kill.result b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_on_con_kill.result new file mode 100644 index 00000000000..bf0ed9e4374 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_on_con_kill.result @@ -0,0 +1,102 @@ +*** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (201,0), (202,0); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_mdev8031'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10200; +INSERT INTO t3 VALUES (203, 1); +INSERT INTO t3 VALUES (204, 1); +INSERT INTO t3 VALUES (205, 1); +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=205; +UPDATE t3 SET b=b+1 WHERE a=205; +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 3 +202 4 +203 4 +204 4 +205 3 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 3 +202 4 +203 4 +204 4 +205 3 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +include/start_slave.inc +*** Check getting deadlock killed inside open_binlog() during retry. *** +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; +SET @old_max= @@GLOBAL.max_relay_log_size; +SET GLOBAL max_relay_log_size= 4096; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10210; +Omit long queries that cause relaylog rotations and transaction retries... +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 6 +202 8 +203 7 +204 7 +205 5 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 6 +202 8 +203 7 +204 7 +205 5 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_debg; +SET GLOBAL max_relay_log_size= @old_max; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t3; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_stop_on_con_kill.test b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_on_con_kill.test new file mode 100644 index 00000000000..adec2dc631c --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_on_con_kill.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_stop_on_con_kill.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.result b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.result new file mode 100644 index 00000000000..6c9fd168e73 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.result @@ -0,0 +1,85 @@ +*** Test STOP SLAVE in parallel mode *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +connection server_1; +SET binlog_direct_non_transactional_updates=0; +SET sql_log_bin=0; +CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); +SET sql_log_bin=1; +BEGIN; +INSERT INTO t2 VALUES (20); +INSERT INTO t1 VALUES (20); +INSERT INTO t2 VALUES (21); +INSERT INTO t3 VALUES (20, 20); +COMMIT; +INSERT INTO t3 VALUES(21, 21); +INSERT INTO t3 VALUES(22, 22); +connection con_temp1; +BEGIN; +INSERT INTO t2 VALUES (21); +connection server_2; +START SLAVE; +connection con_temp2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +STOP SLAVE; +connection con_temp1; +SET debug_sync='now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; +connection con_temp2; +SET GLOBAL debug_dbug=@old_dbug; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_to_stop.inc +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +a +20 +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +a +20 +21 +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; +a b +20 20 +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +a +20 +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +a +20 +21 +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; +a b +20 20 +21 21 +22 22 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +disconnect con_temp1; +disconnect con_temp2; +connection server_1; +DROP TABLE t1,t2,t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.test b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.test new file mode 100644 index 00000000000..c59b2805569 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_stop_slave.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_stop_slave.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_binlog_order.result b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_binlog_order.result new file mode 100644 index 00000000000..f6781f64d30 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_binlog_order.result @@ -0,0 +1,75 @@ +*** MDEV-6775: Wrong binlog order in parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB; +INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=ROW; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +connection con1; +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +UPDATE t4 SET b=NULL WHERE a=6; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con2; +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +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; +SET binlog_format= @old_format; +connection con2; +SET binlog_format= @old_format; +SET debug_sync='RESET'; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +connection server_2; +include/start_slave.inc +SET debug_sync= 'now WAIT_FOR waiting'; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +SET debug_sync= 'now SIGNAL cont'; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL binlog_format= @old_format; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +disconnect con1; +disconnect con2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_binlog_order.test b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_binlog_order.test new file mode 100644 index 00000000000..4141dfce6d6 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_binlog_order.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_wrong_binlog_order.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_exec_master_pos.result b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_exec_master_pos.result new file mode 100644 index 00000000000..47cfa5e08e2 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_exec_master_pos.result @@ -0,0 +1,34 @@ +*** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t5 (a INT PRIMARY KEY, b INT); +INSERT INTO t5 VALUES (1,1); +INSERT INTO t5 VALUES (2,2), (3,8); +INSERT INTO t5 VALUES (4,16); +connection server_2; +test_check +OK +test_check +OK +connection server_1; +FLUSH LOGS; +connection server_2; +test_check +OK +test_check +OK +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t5; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_exec_master_pos.test b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_exec_master_pos.test new file mode 100644 index 00000000000..34268eb6622 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_wrong_exec_master_pos.test @@ -0,0 +1 @@ +--source suite/rpl/include/rpl_parallel_wrong_exec_master_pos.inc diff --git a/mysql-test/suite/multi_source/info_logs.result b/mysql-test/suite/multi_source/info_logs.result index 531a6178cdb..f8519a99964 100644 --- a/mysql-test/suite/multi_source/info_logs.result +++ b/mysql-test/suite/multi_source/info_logs.result @@ -90,16 +90,16 @@ MASTER 2.2 # show all slaves status; Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos - Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 1 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 -MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 + Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 +MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 include/wait_for_slave_to_start.inc set default_master_connection = 'MASTER 2.2'; include/wait_for_slave_to_start.inc set default_master_connection = ''; show all slaves status; Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos - Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000004 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 1 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 6 0 60.000 -MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000004 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 6 0 60.000 + Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 relay.000004 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 6 0 60.000 +MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 relay-master@00202@002e2.000004 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 6 0 60.000 # # List of files matching '*info*' pattern # after slave server restart diff --git a/mysql-test/suite/multi_source/reset_slave.result b/mysql-test/suite/multi_source/reset_slave.result index c1d74ab9f3f..c048784e28d 100644 --- a/mysql-test/suite/multi_source/reset_slave.result +++ b/mysql-test/suite/multi_source/reset_slave.result @@ -14,14 +14,14 @@ connection slave; stop slave 'master1'; show slave 'master1' status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups - 127.0.0.1 root MYPORT_1 60 master-bin.000001 mysqld-relay-bin-master1.000002 master-bin.000001 No No 0 0 None 0 No NULL No 0 0 1 No conservative 0 NULL 2 1 0 + 127.0.0.1 root MYPORT_1 60 master-bin.000001 mysqld-relay-bin-master1.000002 master-bin.000001 No No 0 0 None 0 No NULL No 0 0 1 No optimistic 0 NULL 2 1 0 mysqld-relay-bin-master1.000001 mysqld-relay-bin-master1.000002 mysqld-relay-bin-master1.index reset slave 'master1'; show slave 'master1' status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups - 127.0.0.1 root MYPORT_1 60 4 No No 0 0 0 None 0 No NULL No 0 0 1 No conservative 0 NULL 2 1 0 + 127.0.0.1 root MYPORT_1 60 4 No No 0 0 0 None 0 No NULL No 0 0 1 No optimistic 0 NULL 2 1 0 reset slave 'master1' all; show slave 'master1' status; ERROR HY000: There is no master connection 'master1' diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index 93ea1c023bc..922c7555875 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -19,8 +19,8 @@ connection master2; connection slave; show all slaves status; Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos -slave1 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 mysqld-relay-bin-slave1.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 1 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 -slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 +slave1 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 mysqld-relay-bin-slave1.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 1 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 +slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 start all slaves; stop slave 'slave1'; show slave 'slave1' status; @@ -70,7 +70,7 @@ Using_Gtid No Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids -Parallel_Mode conservative +Parallel_Mode optimistic SQL_Delay 0 SQL_Remaining_Delay NULL Slave_SQL_Running_State @@ -80,18 +80,18 @@ Slave_Transactional_Groups 0 reset slave 'slave1'; show all slaves status; Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos -slave1 127.0.0.1 root MYPORT_1 60 4 No No 0 0 0 None 0 No NULL No 0 0 1 No conservative 0 NULL 0 0 0 0 1073741824 7 0 60.000 -slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 +slave1 127.0.0.1 root MYPORT_1 60 4 No No 0 0 0 None 0 No NULL No 0 0 1 No optimistic 0 NULL 0 0 0 0 1073741824 7 0 60.000 +slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 reset slave 'slave1' all; show all slaves status; Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos -slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No conservative 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 +slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 Yes Yes 0 0 None 0 No 0 No 0 0 2 No optimistic 0 NULL Slave has read all relay log; waiting for the slave I/O thread to update it 0 0 0 0 1073741824 7 0 60.000 stop all slaves; Warnings: Note 1938 SLAVE 'slave2' stopped show all slaves status; Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Master_SSL_Crl Master_SSL_Crlpath Using_Gtid Gtid_IO_Pos Replicate_Do_Domain_Ids Replicate_Ignore_Domain_Ids Parallel_Mode SQL_Delay SQL_Remaining_Delay Slave_SQL_Running_State Slave_DDL_Groups Slave_Non_Transactional_Groups Slave_Transactional_Groups Retried_transactions Max_relay_log_size Executed_log_entries Slave_received_heartbeats Slave_heartbeat_period Gtid_Slave_Pos -slave2 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 No No 0 0 None 0 No NULL No 0 0 2 No conservative 0 NULL 0 0 0 0 1073741824 7 0 60.000 +slave2 127.0.0.1 root MYPORT_2 60 master-bin.000001 mysqld-relay-bin-slave2.000002 master-bin.000001 No No 0 0 None 0 No NULL No 0 0 2 No optimistic 0 NULL 0 0 0 0 1073741824 7 0 60.000 stop all slaves; include/reset_master_slave.inc disconnect slave; diff --git a/mysql-test/suite/rpl/include/rpl_parallel.inc b/mysql-test/suite/rpl/include/rpl_parallel.inc deleted file mode 100644 index 42354343084..00000000000 --- a/mysql-test/suite/rpl/include/rpl_parallel.inc +++ /dev/null @@ -1,2219 +0,0 @@ -# -# This include file is used by more than one test suite -# (currently rpl and binlog_encryption). -# Please check all dependent tests after modifying it -# - ---source include/have_innodb.inc ---source include/have_debug.inc ---source include/have_debug_sync.inc ---source include/master-slave.inc - -# Test various aspects of parallel replication. - ---connection server_2 -SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; ---error ER_SLAVE_MUST_STOP -SET GLOBAL slave_parallel_threads=10; ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=10; - -# Check that we do not spawn any worker threads when no slave is running. -SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; - -CHANGE MASTER TO master_use_gtid=slave_pos; ---source include/start_slave.inc - -# Check that worker threads get spawned when slave starts. -SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -# ... and that worker threads get removed when slave stops. ---source include/stop_slave.inc -SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; ---source include/start_slave.inc -SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; - ---echo *** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** - ---connection server_1 -ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; -CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; -CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); -INSERT INTO t2 VALUES (1); ---save_master_pos - ---connection server_2 ---sync_with_master - -# Block the table t1 to simulate a replicated query taking a long time. ---connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) -LOCK TABLE t1 WRITE; - ---connection server_1 -SET gtid_domain_id=1; -# This query will be blocked on the slave until UNLOCK TABLES. -INSERT INTO t1 VALUES (2); -SET gtid_domain_id=0; -# These t2 queries can be replicated in parallel with the prior t1 query, as -# they are in a separate replication domain. -INSERT INTO t2 VALUES (2); -INSERT INTO t2 VALUES (3); -BEGIN; -INSERT INTO t2 VALUES (4); -INSERT INTO t2 VALUES (5); -COMMIT; -INSERT INTO t2 VALUES (6); - ---connection server_2 ---let $wait_condition= SELECT COUNT(*) = 6 FROM t2 ---source include/wait_condition.inc - -SELECT * FROM t2 ORDER by a; - ---connection con_temp1 -SELECT * FROM t1; -UNLOCK TABLES; - ---connection server_2 ---let $wait_condition= SELECT COUNT(*) = 2 FROM t1 ---source include/wait_condition.inc - -SELECT * FROM t1 ORDER BY a; - - ---echo *** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** ---connection server_2 ---source include/stop_slave.inc - ---connection server_1 -# Use a stored function to inject a debug_sync into the appropriate THD. -# The function does nothing on the master, and on the slave it injects the -# desired debug_sync action(s). -SET sql_log_bin=0; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - -SET @old_format= @@SESSION.binlog_format; -SET binlog_format='statement'; -SET gtid_domain_id=1; -INSERT INTO t2 VALUES (foo(10, - 'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', - 'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); - ---connection server_2 -FLUSH LOGS; ---source include/wait_for_binlog_checkpoint.inc -SET sql_log_bin=0; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - IF d1 != '' THEN - SET debug_sync = d1; - END IF; - IF d2 != '' THEN - SET debug_sync = d2; - END IF; - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; -SET @old_format=@@GLOBAL.binlog_format; -SET GLOBAL binlog_format=statement; -# We need to restart all parallel threads for the new global setting to -# be copied to the session-level values. -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - -# First make sure the first insert is ready to commit, but not queued yet. -SET debug_sync='now WAIT_FOR ready1'; - ---connection server_1 -SET gtid_domain_id=2; -INSERT INTO t2 VALUES (foo(11, - 'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', - 'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); -SET gtid_domain_id=0; -SELECT * FROM t2 WHERE a >= 10 ORDER BY a; - ---connection server_2 -# Now wait for the second insert to queue itself as the leader, and then -# wait for more commits to queue up. -SET debug_sync='now WAIT_FOR ready3'; -SET debug_sync='now SIGNAL cont3'; -SET debug_sync='now WAIT_FOR ready4'; -# Now allow the first insert to queue up to participate in group commit. -SET debug_sync='now SIGNAL cont1'; -SET debug_sync='now WAIT_FOR ready2'; -# Finally allow the second insert to proceed and do the group commit. -SET debug_sync='now SIGNAL cont4'; - ---let $wait_condition= SELECT COUNT(*) = 2 FROM t2 WHERE a >= 10 ---source include/wait_condition.inc -SELECT * FROM t2 WHERE a >= 10 ORDER BY a; -# The two INSERT transactions should have been committed in opposite order, -# but in the same group commit (seen by precense of cid=# in the SHOW -# BINLOG output). ---let $binlog_file= slave-bin.000002 ---source include/show_binlog_events.inc -FLUSH LOGS; ---source include/wait_for_binlog_checkpoint.inc - -# Restart all the slave parallel worker threads, to clear all debug_sync actions. ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET debug_sync='RESET'; ---source include/start_slave.inc - - ---echo *** Test that group-committed transactions on the master can replicate in parallel on the slave. *** ---connection server_1 -SET debug_sync='RESET'; -FLUSH LOGS; ---source include/wait_for_binlog_checkpoint.inc -CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; -# Create some sentinel rows so that the rows inserted in parallel fall into -# separate gaps and do not cause gap lock conflicts. -INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); ---save_master_pos ---connection server_2 ---sync_with_master - -# We want to test that the transactions can execute out-of-order on -# the slave, but still end up committing in-order, and in a single -# group commit. -# -# The idea is to group-commit three transactions together on the master: -# A, B, and C. On the slave, C will execute the insert first, then A, -# and then B. But B manages to complete before A has time to commit, so -# all three end up committing together. -# -# So we start by setting up some row locks that will block transactions -# A and B from executing, allowing C to run first. - ---connection con_temp1 -BEGIN; -INSERT INTO t3 VALUES (2,102); ---connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) -BEGIN; -INSERT INTO t3 VALUES (4,104); - -# On the master, queue three INSERT transactions as a single group commit. ---connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (2, foo(12, - 'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', - '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued1'; - ---connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (4, foo(14, - 'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', - '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued2'; - ---connect (con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (6, foo(16, - 'group_commit_waiting_for_prior SIGNAL slave_queued3', - '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; - ---connection con_temp3 -REAP; ---connection con_temp4 -REAP; ---connection con_temp5 -REAP; -SET debug_sync='RESET'; - ---connection server_1 -SELECT * FROM t3 ORDER BY a; ---let $binlog_file= master-bin.000002 ---source include/show_binlog_events.inc - -# First, wait until insert 3 is ready to queue up for group commit, but is -# waiting for insert 2 to commit before it can do so itself. ---connection server_2 -SET debug_sync='now WAIT_FOR slave_queued3'; - -# Next, let insert 1 proceed, and allow it to queue up as the group commit -# leader, but let it wait for insert 2 to also queue up before proceeding. ---connection con_temp1 -ROLLBACK; ---connection server_2 -SET debug_sync='now WAIT_FOR slave_queued1'; - -# Now let insert 2 proceed and queue up. ---connection con_temp2 -ROLLBACK; ---connection server_2 -SET debug_sync='now WAIT_FOR slave_queued2'; -# And finally, we can let insert 1 proceed and do the group commit with all -# three insert transactions together. -SET debug_sync='now SIGNAL slave_cont1'; - -# Wait for the commit to complete and check that all three transactions -# group-committed together (will be seen in the binlog as all three having -# cid=# on their GTID event). ---let $wait_condition= SELECT COUNT(*) = 3 FROM t3 WHERE a IN (2,4,6) ---source include/wait_condition.inc -SELECT * FROM t3 ORDER BY a; ---let $binlog_file= slave-bin.000003 ---source include/show_binlog_events.inc - - ---echo *** Test STOP SLAVE in parallel mode *** ---connection server_2 ---source include/stop_slave.inc -# Respawn all worker threads to clear any left-over debug_sync or other stuff. -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; - ---connection server_1 -# Set up a couple of transactions. The first will be blocked halfway -# through on a lock, and while it is blocked we initiate STOP SLAVE. -# We then test that the halfway-initiated transaction is allowed to -# complete, but no subsequent ones. -# We have to use statement-based mode and set -# binlog_direct_non_transactional_updates=0; otherwise the binlog will -# be split into two event groups, one for the MyISAM part and one for the -# InnoDB part. -SET binlog_direct_non_transactional_updates=0; -SET sql_log_bin=0; -CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); -SET sql_log_bin=1; -BEGIN; -INSERT INTO t2 VALUES (20); ---disable_warnings -INSERT INTO t1 VALUES (20); ---enable_warnings -INSERT INTO t2 VALUES (21); -INSERT INTO t3 VALUES (20, 20); -COMMIT; -INSERT INTO t3 VALUES(21, 21); -INSERT INTO t3 VALUES(22, 22); -SET binlog_format=@old_format; ---save_master_pos - -# Start a connection that will block the replicated transaction halfway. ---connection con_temp1 -BEGIN; -INSERT INTO t2 VALUES (21); - ---connection server_2 -START SLAVE; -# Wait for the MyISAM change to be visible, after which replication will wait -# for con_temp1 to roll back. ---let $wait_condition= SELECT COUNT(*) = 1 FROM t1 WHERE a=20 ---source include/wait_condition.inc - ---connection con_temp2 -# Initiate slave stop. It will have to wait for the current event group -# to complete. -# The dbug injection causes debug_sync to signal 'wait_for_done_waiting' -# when the SQL driver thread is ready. -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; -send STOP SLAVE; - ---connection con_temp1 -SET debug_sync='now WAIT_FOR wait_for_done_waiting'; -ROLLBACK; - ---connection con_temp2 -reap; -SET GLOBAL debug_dbug=@old_dbug; -SET debug_sync='RESET'; - ---connection server_2 ---source include/wait_for_slave_to_stop.inc -# We should see the first transaction applied, but not the two others. -SELECT * FROM t1 WHERE a >= 20 ORDER BY a; -SELECT * FROM t2 WHERE a >= 20 ORDER BY a; -SELECT * FROM t3 WHERE a >= 20 ORDER BY a; - ---source include/start_slave.inc ---sync_with_master -SELECT * FROM t1 WHERE a >= 20 ORDER BY a; -SELECT * FROM t2 WHERE a >= 20 ORDER BY a; -SELECT * FROM t3 WHERE a >= 20 ORDER BY a; - - ---connection server_2 -# Respawn all worker threads to clear any left-over debug_sync or other stuff. ---source include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - - ---echo *** Test killing slave threads at various wait points *** ---echo *** 1. Test killing transaction waiting in commit for previous transaction to commit *** - -# Set up three transactions on the master that will be group-committed -# together so they can be replicated in parallel on the slave. ---connection con_temp3 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (31, foo(31, - 'commit_before_prepare_ordered WAIT_FOR t2_waiting', - 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued1'; - ---connection con_temp4 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -# This insert is just so we can get T2 to wait while a query is running that we -# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. -INSERT INTO t3 VALUES (32, foo(32, - 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', - '')); -# This insert sets up debug_sync points so that T2 will tell when it is at its -# wait point where we want to kill it - and when it has been killed. -INSERT INTO t3 VALUES (33, foo(33, - 'group_commit_waiting_for_prior SIGNAL t2_waiting', - 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -send COMMIT; - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued2'; - ---connection con_temp5 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (34, foo(34, - '', - '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; - ---connection con_temp3 -REAP; ---connection con_temp4 -REAP; ---connection con_temp5 -REAP; - ---connection server_1 -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -SET debug_sync='RESET'; - ---connection server_2 -SET sql_log_bin=0; -CALL mtr.add_suppression("Query execution was interrupted"); -CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); -CALL mtr.add_suppression("Slave: Connection was killed"); -SET sql_log_bin=1; -# Wait until T2 is inside executing its insert of 32, then find it in SHOW -# PROCESSLIST to know its thread id for KILL later. -SET debug_sync='now WAIT_FOR t2_query'; ---let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(32%' AND INFO NOT LIKE '%LIKE%'` -SET debug_sync='now SIGNAL t2_cont'; - -# Wait until T2 has entered its wait for T1 to commit, and T1 has -# progressed into its commit phase. -SET debug_sync='now WAIT_FOR t1_ready'; - -# Now kill the transaction T2. ---replace_result $thd_id THD_ID -eval KILL $thd_id; - -# Wait until T2 has reacted on the kill. -SET debug_sync='now WAIT_FOR t2_killed'; - -# Now we can allow T1 to proceed. -SET debug_sync='now SIGNAL t1_cont'; - ---let $slave_sql_errno= 1317,1927,1964 ---source include/wait_for_slave_sql_error.inc -STOP SLAVE IO_THREAD; -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; - -# Now we have to disable the debug_sync statements, so they do not trigger -# when the events are retried. -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - ---connection server_1 -INSERT INTO t3 VALUES (39,0); ---save_master_pos - ---connection server_2 ---source include/start_slave.inc ---sync_with_master -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -# Restore the foo() function. -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - IF d1 != '' THEN - SET debug_sync = d1; - END IF; - IF d2 != '' THEN - SET debug_sync = d2; - END IF; - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - - ---connection server_2 -# Respawn all worker threads to clear any left-over debug_sync or other stuff. ---source include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - - ---echo *** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** - -# Set up three transactions on the master that will be group-committed -# together so they can be replicated in parallel on the slave. ---connection con_temp3 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (41, foo(41, - 'commit_before_prepare_ordered WAIT_FOR t2_waiting', - 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued1'; - ---connection con_temp4 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -# This insert is just so we can get T2 to wait while a query is running that we -# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. -INSERT INTO t3 VALUES (42, foo(42, - 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', - '')); -# This insert sets up debug_sync points so that T2 will tell when it is at its -# wait point where we want to kill it - and when it has been killed. -INSERT INTO t3 VALUES (43, foo(43, - 'group_commit_waiting_for_prior SIGNAL t2_waiting', - 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -send COMMIT; - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued2'; - ---connection con_temp5 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (44, foo(44, - '', - '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; - ---connection con_temp3 -REAP; ---connection con_temp4 -REAP; ---connection con_temp5 -REAP; - ---connection server_1 -SELECT * FROM t3 WHERE a >= 40 ORDER BY a; -SET debug_sync='RESET'; - ---connection server_2 -# Wait until T2 is inside executing its insert of 42, then find it in SHOW -# PROCESSLIST to know its thread id for KILL later. -SET debug_sync='now WAIT_FOR t2_query'; ---let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(42%' AND INFO NOT LIKE '%LIKE%'` -SET debug_sync='now SIGNAL t2_cont'; - -# Wait until T2 has entered its wait for T1 to commit, and T1 has -# progressed into its commit phase. -SET debug_sync='now WAIT_FOR t1_ready'; - -# Now kill the transaction T2. ---replace_result $thd_id THD_ID -eval KILL $thd_id; - -# Wait until T2 has reacted on the kill. -SET debug_sync='now WAIT_FOR t2_killed'; - -# Now we can allow T1 to proceed. -SET debug_sync='now SIGNAL t1_cont'; - ---let $slave_sql_errno= 1317,1927,1964 ---source include/wait_for_slave_sql_error.inc - -# Now we have to disable the debug_sync statements, so they do not trigger -# when the events are retried. -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - ---connection server_1 -INSERT INTO t3 VALUES (49,0); ---save_master_pos - ---connection server_2 -START SLAVE SQL_THREAD; ---sync_with_master -SELECT * FROM t3 WHERE a >= 40 ORDER BY a; -# Restore the foo() function. -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - IF d1 != '' THEN - SET debug_sync = d1; - END IF; - IF d2 != '' THEN - SET debug_sync = d2; - END IF; - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - - ---connection server_2 -# Respawn all worker threads to clear any left-over debug_sync or other stuff. ---source include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - - ---echo *** 3. Same as (2), but not using gtid mode *** - ---connection server_2 ---source include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; ---source include/start_slave.inc - ---connection server_1 -# Set up three transactions on the master that will be group-committed -# together so they can be replicated in parallel on the slave. ---connection con_temp3 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (51, foo(51, - 'commit_before_prepare_ordered WAIT_FOR t2_waiting', - 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued1'; - ---connection con_temp4 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -# This insert is just so we can get T2 to wait while a query is running that we -# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. -INSERT INTO t3 VALUES (52, foo(52, - 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', - '')); -# This insert sets up debug_sync points so that T2 will tell when it is at its -# wait point where we want to kill it - and when it has been killed. -INSERT INTO t3 VALUES (53, foo(53, - 'group_commit_waiting_for_prior SIGNAL t2_waiting', - 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -send COMMIT; - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued2'; - ---connection con_temp5 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -send INSERT INTO t3 VALUES (54, foo(54, - '', - '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; - ---connection con_temp3 -REAP; ---connection con_temp4 -REAP; ---connection con_temp5 -REAP; - ---connection server_1 -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -SET debug_sync='RESET'; - ---connection server_2 -# Wait until T2 is inside executing its insert of 52, then find it in SHOW -# PROCESSLIST to know its thread id for KILL later. -SET debug_sync='now WAIT_FOR t2_query'; ---let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(52%' AND INFO NOT LIKE '%LIKE%'` -SET debug_sync='now SIGNAL t2_cont'; - -# Wait until T2 has entered its wait for T1 to commit, and T1 has -# progressed into its commit phase. -SET debug_sync='now WAIT_FOR t1_ready'; - -# Now kill the transaction T2. ---replace_result $thd_id THD_ID -eval KILL $thd_id; - -# Wait until T2 has reacted on the kill. -SET debug_sync='now WAIT_FOR t2_killed'; - -# Now we can allow T1 to proceed. -SET debug_sync='now SIGNAL t1_cont'; - ---let $slave_sql_errno= 1317,1927,1964 ---source include/wait_for_slave_sql_error.inc -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; - -# Now we have to disable the debug_sync statements, so they do not trigger -# when the events are retried. -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - ---connection server_1 -INSERT INTO t3 VALUES (59,0); ---save_master_pos - ---connection server_2 -START SLAVE SQL_THREAD; ---sync_with_master -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -# Restore the foo() function. -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - IF d1 != '' THEN - SET debug_sync = d1; - END IF; - IF d2 != '' THEN - SET debug_sync = d2; - END IF; - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - - ---source include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=slave_pos; ---source include/start_slave.inc - ---connection server_2 -# Respawn all worker threads to clear any left-over debug_sync or other stuff. ---source include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=4; ---source include/start_slave.inc - - ---echo *** 4. Test killing thread that is waiting to start transaction until previous transaction commits *** - -# We set up four transactions T1, T2, T3, and T4 on the master. T2, T3, and T4 -# can run in parallel with each other (same group commit and commit id), -# but not in parallel with T1. -# -# We use four worker threads, each Ti will be queued on each their own -# worker thread. We will delay T1 commit, T3 will wait for T1 to begin -# commit before it can start. We will kill T3 during this wait, and -# check that everything works correctly. -# -# It is rather tricky to get the correct thread id of the worker to kill. -# We start by injecting four dummy transactions in a debug_sync-controlled -# manner to be able to get known thread ids for the workers in a pool with -# just 4 worker threads. Then we let in each of the real test transactions -# T1-T4 one at a time in a way which allows us to know which transaction -# ends up with which thread id. - ---connection server_1 -SET binlog_format=statement; -SET gtid_domain_id=2; -BEGIN; -# This debug_sync will linger on and be used to control T4 later. -INSERT INTO t3 VALUES (70, foo(70, - 'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); -INSERT INTO t3 VALUES (60, foo(60, - 'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', - 'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); -COMMIT; -SET gtid_domain_id=0; - ---connection server_2 -SET debug_sync='now WAIT_FOR d2_query'; ---let $d2_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(60%' AND INFO NOT LIKE '%LIKE%'` - ---connection server_1 -SET gtid_domain_id=1; -BEGIN; -# These debug_sync's will linger on and be used to control T3 later. -INSERT INTO t3 VALUES (61, foo(61, - 'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', - 'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); -INSERT INTO t3 VALUES (62, foo(62, - 'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', - 'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); -COMMIT; -SET gtid_domain_id=0; - ---connection server_2 -SET debug_sync='now WAIT_FOR d1_query'; ---let $d1_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(62%' AND INFO NOT LIKE '%LIKE%'` - ---connection server_1 -SET gtid_domain_id=0; -INSERT INTO t3 VALUES (63, foo(63, - 'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', - 'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); - ---connection server_2 -SET debug_sync='now WAIT_FOR d0_query'; ---let $d0_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(63%' AND INFO NOT LIKE '%LIKE%'` - ---connection server_1 -SET gtid_domain_id=3; -BEGIN; -# These debug_sync's will linger on and be used to control T2 later. -INSERT INTO t3 VALUES (68, foo(68, - 'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); -INSERT INTO t3 VALUES (69, foo(69, - 'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', - 'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); -COMMIT; -SET gtid_domain_id=0; - ---connection server_2 -SET debug_sync='now WAIT_FOR d3_query'; ---let $d3_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(69%' AND INFO NOT LIKE '%LIKE%'` - -SET debug_sync='now SIGNAL d2_cont2'; -SET debug_sync='now WAIT_FOR d2_done'; -SET debug_sync='now SIGNAL d1_cont2'; -SET debug_sync='now WAIT_FOR d1_done'; -SET debug_sync='now SIGNAL d0_cont2'; -SET debug_sync='now WAIT_FOR d0_done'; -SET debug_sync='now SIGNAL d3_cont2'; -SET debug_sync='now WAIT_FOR d3_done'; - -# Now prepare the real transactions T1, T2, T3, T4 on the master. - ---connection con_temp3 -# Create transaction T1. -SET binlog_format=statement; -INSERT INTO t3 VALUES (64, foo(64, - 'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); - -# Create transaction T2, as a group commit leader on the master. -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; -send INSERT INTO t3 VALUES (65, foo(65, '', '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued2'; - ---connection con_temp4 -# Create transaction T3, participating in T2's group commit. -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -send INSERT INTO t3 VALUES (66, foo(66, '', '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued3'; - ---connection con_temp5 -# Create transaction T4, participating in group commit with T2 and T3. -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; -send INSERT INTO t3 VALUES (67, foo(67, '', '')); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued4'; -SET debug_sync='now SIGNAL master_cont2'; - ---connection con_temp3 -REAP; ---connection con_temp4 -REAP; ---connection con_temp5 -REAP; - ---connection server_1 -SELECT * FROM t3 WHERE a >= 60 ORDER BY a; -SET debug_sync='RESET'; - ---connection server_2 -# Now we have the four transactions pending for replication on the slave. -# Let them be queued for our three worker threads in a controlled fashion. -# We put them at a stage where T1 is delayed and T3 is waiting for T1 to -# commit before T3 can start. Then we kill T3. - -# Make the worker D0 free, and wait for T1 to be queued in it. -SET debug_sync='now SIGNAL d0_cont'; -SET debug_sync='now WAIT_FOR t1_waiting'; - -# Make the worker D3 free, and wait for T2 to be queued in it. -SET debug_sync='now SIGNAL d3_cont'; -SET debug_sync='now WAIT_FOR t2_waiting'; - -# Now release worker D1, and wait for T3 to be queued in it. -# T3 will wait for T1 to commit before it can start. -SET debug_sync='now SIGNAL d1_cont'; -SET debug_sync='now WAIT_FOR t3_waiting'; - -# Release worker D2. Wait for T4 to be queued, so we are sure it has -# received the debug_sync signal (else we might overwrite it with the -# next debug_sync). -SET debug_sync='now SIGNAL d2_cont'; -SET debug_sync='now WAIT_FOR t4_waiting'; - -# Now we kill the waiting transaction T3 in worker D1. ---replace_result $d1_thd_id THD_ID -eval KILL $d1_thd_id; - -# Wait until T3 has reacted on the kill. -SET debug_sync='now WAIT_FOR t3_killed'; - -# Now we can allow T1 to proceed. -SET debug_sync='now SIGNAL t1_cont'; - ---let $slave_sql_errno= 1317,1927,1964 ---source include/wait_for_slave_sql_error.inc -STOP SLAVE IO_THREAD; -# Since T2, T3, and T4 run in parallel, we can not be sure if T2 will have time -# to commit or not before the stop. However, T1 should commit, and T3/T4 may -# not have committed. (After slave restart we check that all become committed -# eventually). -SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; - -# Now we have to disable the debug_sync statements, so they do not trigger -# when the events are retried. -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - ---connection server_1 -UPDATE t3 SET b=b+1 WHERE a=60; ---save_master_pos - ---connection server_2 ---source include/start_slave.inc ---sync_with_master -SELECT * FROM t3 WHERE a >= 60 ORDER BY a; -# Restore the foo() function. -SET sql_log_bin=0; -DROP FUNCTION foo; ---delimiter || -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) - RETURNS INT DETERMINISTIC - BEGIN - IF d1 != '' THEN - SET debug_sync = d1; - END IF; - IF d2 != '' THEN - SET debug_sync = d2; - END IF; - RETURN x; - END -|| ---delimiter ; -SET sql_log_bin=1; - ---connection server_2 -# Respawn all worker threads to clear any left-over debug_sync or other stuff. ---source include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - - ---echo *** 5. Test killing thread that is waiting for queue of max length to shorten *** - -# Find the thread id of the driver SQL thread that we want to kill. ---let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%' ---source include/wait_condition.inc ---let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%'` -SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; -SET GLOBAL slave_parallel_max_queued=9000; - ---connection server_1 ---let bigstring= `SELECT REPEAT('x', 10000)` -SET binlog_format=statement; -# Create an event that will wait to be signalled. -INSERT INTO t3 VALUES (80, foo(0, - 'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); - ---connection server_2 -SET debug_sync='now WAIT_FOR query_waiting'; -# Inject that the SQL driver thread will signal `wait_queue_ready' to debug_sync -# as it goes to wait for the event queue to become smaller than the value of -# @@slave_parallel_max_queued. -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; - ---connection server_1 ---disable_query_log -# Create an event that will fill up the queue. -# The Xid event at the end of the event group will have to wait for the Query -# event with the INSERT to drain so the queue becomes shorter. However that in -# turn waits for the prior event group to continue. -eval INSERT INTO t3 VALUES (81, LENGTH('$bigstring')); ---enable_query_log -SELECT * FROM t3 WHERE a >= 80 ORDER BY a; - ---connection server_2 -SET debug_sync='now WAIT_FOR wait_queue_ready'; - ---replace_result $thd_id THD_ID -eval KILL $thd_id; - -SET debug_sync='now WAIT_FOR wait_queue_killed'; -SET debug_sync='now SIGNAL query_cont'; - ---let $slave_sql_errno= 1317,1927,1964 ---source include/wait_for_slave_sql_error.inc -STOP SLAVE IO_THREAD; - -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_max_queued= @old_max_queued; - ---connection server_1 -INSERT INTO t3 VALUES (82,0); -SET binlog_format=@old_format; ---save_master_pos - ---connection server_2 -SET debug_sync='RESET'; ---source include/start_slave.inc ---sync_with_master -SELECT * FROM t3 WHERE a >= 80 ORDER BY a; - - ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - ---echo *** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** - ---connection server_2 -# Use just two worker threads, so we are sure to get the rpl_group_info added -# to the free list, which is what triggered the bug. ---source include/stop_slave.inc -SET GLOBAL replicate_ignore_table="test.t3"; -SET GLOBAL slave_parallel_threads=2; ---source include/start_slave.inc - ---connection server_1 -INSERT INTO t3 VALUES (100, rand()); -INSERT INTO t3 VALUES (101, rand()); - ---save_master_pos - ---connection server_2 ---sync_with_master - ---connection server_1 -INSERT INTO t3 VALUES (102, rand()); -INSERT INTO t3 VALUES (103, rand()); -INSERT INTO t3 VALUES (104, rand()); -INSERT INTO t3 VALUES (105, rand()); - ---save_master_pos - ---connection server_2 ---sync_with_master ---source include/stop_slave.inc -SET GLOBAL replicate_ignore_table=""; ---source include/start_slave.inc - ---connection server_1 -INSERT INTO t3 VALUES (106, rand()); -INSERT INTO t3 VALUES (107, rand()); ---save_master_pos - ---connection server_2 ---sync_with_master ---replace_column 2 # -SELECT * FROM t3 WHERE a >= 100 ORDER BY a; - - ---echo *** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** - ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - ---connection server_1 -INSERT INTO t3 VALUES (110, 1); ---save_master_pos - ---connection server_2 ---sync_with_master -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -# Inject a duplicate key error. -SET sql_log_bin=0; -INSERT INTO t3 VALUES (111, 666); -SET sql_log_bin=1; - ---connection server_1 - -# Create a group commit with two inserts, the first one conflicts with a row on the slave ---connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -send INSERT INTO t3 VALUES (111, 2); ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued1'; - ---connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -send INSERT INTO t3 VALUES (112, 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 ---let $slave_sql_errno= 1062 ---source include/wait_for_slave_sql_error.inc ---source include/wait_for_slave_sql_to_stop.inc -# We should not see the row (112,3) here, it should be rolled back due to -# error signal from the prior transaction. -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -SET sql_log_bin=0; -DELETE FROM t3 WHERE a=111 AND b=666; -SET sql_log_bin=1; -START SLAVE SQL_THREAD; ---sync_with_master -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 ---source include/stop_slave.inc - -SELECT * FROM t4 ORDER BY a; - - -# MDEV-6549, failing to update gtid_slave_pos for a transaction that was retried. -# The problem was that when a transaction updates the mysql.gtid_slave_pos -# table, it clears the flag that marks that there is a GTID position that -# needs to be updated. Then, if the transaction got killed after that due -# to a deadlock, the subsequent retry would fail to notice that the GTID needs -# to be recorded in gtid_slave_pos. -# -# (In the original bug report, the symptom was an assertion; this was however -# just a side effect of the missing update of gtid_slave_pos, which also -# happened to cause a missing clear of OPTION_GTID_BEGIN). ---connection server_1 -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); - -# Create two transactions that can run in parallel on the slave but cause -# a deadlock if the second runs before the first. ---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 -# Must use statement-based binlogging. Otherwise the transaction will not be -# binlogged at all, as it modifies no rows. -SET @old_format= @@SESSION.binlog_format; -SET binlog_format='statement'; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -send DELETE FROM t4 WHERE b <= 1; - ---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 @old_format=@@GLOBAL.binlog_format; -SET debug_sync='RESET'; ---save_master_pos ---let $last_gtid= `SELECT @@last_gtid` - ---connection server_2 -# Disable the usual skip of gap locks for transactions that are run in -# parallel, using DBUG. This allows the deadlock to occur, and this in turn -# triggers a retry of the second transaction, and the code that was buggy and -# caused the gtid_slave_pos update to be skipped in the retry. -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; ---source include/start_slave.inc ---sync_with_master -SET GLOBAL debug_dbug=@old_dbug; - -SELECT * FROM t4 ORDER BY a; -# Check that the GTID of the second transaction was correctly recorded in -# gtid_slave_pos, in the variable as well as in the table. ---replace_result $last_gtid GTID -eval SET @last_gtid= '$last_gtid'; -SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", - CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) - AS result; -SELECT "ROW FOUND" AS `Is the row found?` - FROM mysql.gtid_slave_pos - WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; - - ---echo *** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=1; -SET DEBUG_SYNC= 'RESET'; ---source include/start_slave.inc - ---connection server_1 -CREATE TABLE t5 (a INT PRIMARY KEY, b INT); -INSERT INTO t5 VALUES (1,1); -INSERT INTO t5 VALUES (2,2), (3,8); -INSERT INTO t5 VALUES (4,16); ---save_master_pos - ---connection server_2 ---sync_with_master -let $io_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1); -let $io_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); -let $sql_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1); -let $sql_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); ---disable_query_log -eval SELECT IF('$io_file' = '$sql_file', "OK", "Not ok, $io_file <> $sql_file") AS test_check; -eval SELECT IF('$io_pos' = '$sql_pos', "OK", "Not ok, $io_pos <> $sql_pos") AS test_check; ---enable_query_log - ---connection server_1 -FLUSH LOGS; ---source include/wait_for_binlog_checkpoint.inc ---save_master_pos - ---connection server_2 ---sync_with_master -let $io_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1); -let $io_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); -let $sql_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1); -let $sql_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); ---disable_query_log -eval SELECT IF('$io_file' = '$sql_file', "OK", "Not ok, $io_file <> $sql_file") AS test_check; -eval SELECT IF('$io_pos' = '$sql_pos', "OK", "Not ok, $io_pos <> $sql_pos") AS test_check; ---enable_query_log - - ---echo *** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** - ---connection server_1 -CREATE TABLE t6 (a INT) ENGINE=MyISAM; -CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; - ---connection con1 -SET @old_format= @@binlog_format; -SET binlog_format= statement; ---let $conid = `SELECT CONNECTION_ID()` -SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; -send INSERT INTO t6 VALUES (1), (2), (3); - ---connection server_1 -SET debug_sync='now WAIT_FOR ready'; ---replace_result $conid CONID -eval KILL QUERY $conid; -SET debug_sync='now SIGNAL cont'; - ---connection con1 ---error ER_QUERY_INTERRUPTED ---reap -SET binlog_format= @old_format; -SET debug_sync='RESET'; ---let $after_error_gtid_pos= `SELECT @@gtid_binlog_pos` - ---connection server_1 -SET debug_sync='RESET'; - - ---connection server_2 ---let $slave_sql_errno= 1317 ---source include/wait_for_slave_sql_error.inc -STOP SLAVE IO_THREAD; ---replace_result $after_error_gtid_pos AFTER_ERROR_GTID_POS -eval SET GLOBAL gtid_slave_pos= '$after_error_gtid_pos'; ---source include/start_slave.inc - ---connection server_1 -INSERT INTO t6 VALUES (4); -SELECT * FROM t6 ORDER BY a; ---save_master_pos - ---connection server_2 ---sync_with_master -SELECT * FROM t6 ORDER BY a; - - ---echo *** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** - ---connection server_1 -INSERT INTO t2 VALUES (31); ---let $gtid1= `SELECT @@LAST_GTID` ---source include/save_master_gtid.inc - ---connection server_2 ---source include/sync_with_master_gtid.inc ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads= 0; ---source include/start_slave.inc - -# Force a duplicate key error on the slave. -SET sql_log_bin= 0; -INSERT INTO t2 VALUES (32); -SET sql_log_bin= 1; - ---connection server_1 -INSERT INTO t2 VALUES (32); ---let $gtid2= `SELECT @@LAST_GTID` -# Rotate the binlog; the bug is triggered when the master binlog file changes -# after the event group that causes the duplicate key error. -FLUSH LOGS; -INSERT INTO t2 VALUES (33); -INSERT INTO t2 VALUES (34); -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; ---source include/save_master_gtid.inc - ---connection server_2 ---let $slave_sql_errno= 1062 ---source include/wait_for_slave_sql_error.inc - ---connection server_2 ---source include/stop_slave_io.inc -SET GLOBAL slave_parallel_threads=10; -START SLAVE; - ---let $slave_sql_errno= 1062 ---source include/wait_for_slave_sql_error.inc - -# Note: IO thread is still running at this point. -# The bug seems to have been that restarting the SQL thread after an error with -# the IO thread still running, somehow picks up a later relay log position and -# thus ends up skipping the failing event, rather than re-executing. - -START SLAVE SQL_THREAD; ---let $slave_sql_errno= 1062 ---source include/wait_for_slave_sql_error.inc - -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; - -# Skip the duplicate error, so we can proceed. ---error ER_SLAVE_SKIP_NOT_IN_GTID -SET sql_slave_skip_counter= 1; ---source include/stop_slave_io.inc ---disable_query_log -eval SET GLOBAL gtid_slave_pos = REPLACE(@@gtid_slave_pos, "$gtid1", "$gtid2"); ---enable_query_log ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc - -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; - - ---echo *** MDEV-6775: Wrong binlog order in parallel replication *** ---connection server_1 -# A bit tricky bug to reproduce. On the master, we binlog in statement-mode -# two transactions, an UPDATE followed by a DELETE. On the slave, we replicate -# with binlog-mode set to ROW, which means the DELETE, which modifies no rows, -# is not binlogged. Then we inject a wait in the group commit code on the -# slave, shortly before the actual commit of the UPDATE. The bug was that the -# DELETE could wake up from wait_for_prior_commit() before the commit of the -# UPDATE. So the test could see the slave position updated to after DELETE, -# while the UPDATE was still not visible. -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); ---source include/save_master_gtid.inc - ---connection server_2 ---source include/sync_with_master_gtid.inc ---source include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; -SET @old_format=@@GLOBAL.binlog_format; -SET GLOBAL binlog_format=ROW; -# Re-spawn the worker threads to be sure they pick up the new binlog format -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; - ---connection con1 -SET @old_format= @@binlog_format; -SET binlog_format= statement; -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 @old_format= @@binlog_format; -SET binlog_format= statement; -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; -SET binlog_format= @old_format; ---connection con2 -REAP; -SET binlog_format= @old_format; -SET debug_sync='RESET'; ---save_master_pos -SELECT * FROM t4 ORDER BY a; - ---connection server_2 ---source include/start_slave.inc -SET debug_sync= 'now WAIT_FOR waiting'; ---sync_with_master -SELECT * FROM t4 ORDER BY a; -SET debug_sync= 'now SIGNAL cont'; - -# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. ---source include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL binlog_format= @old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - - ---echo *** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** ---connection server_1 -INSERT INTO t2 VALUES (40); ---save_master_pos - ---connection server_2 ---sync_with_master ---source include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; -SET @old_dbug= @@GLOBAL.debug_dbug; -# This DBUG injection causes a DEBUG_SYNC signal "scheduled_gtid_0_x_100" when -# GTID 0-1-100 has been scheduled for and fetched by a worker thread. -SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; -# This DBUG injection causes a DEBUG_SYNC signal "wait_for_done_waiting" when -# STOP SLAVE has signalled all worker threads to stop. -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; -# Reset worker threads to make DBUG setting catch on. -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; - - ---connection server_1 -# Setup some transaction for the slave to replicate. -INSERT INTO t2 VALUES (41); -INSERT INTO t2 VALUES (42); -# Need to log the DELETE in statement format, so we can see it in processlist. -SET @old_format= @@binlog_format; -SET binlog_format= statement; -DELETE FROM t2 WHERE a=40; -SET binlog_format= @old_format; -INSERT INTO t2 VALUES (43); -INSERT INTO t2 VALUES (44); -# Force the slave to switch to a new relay log file. -FLUSH LOGS; -INSERT INTO t2 VALUES (45); -# Inject a GTID 0-1-100, which will trigger a DEBUG_SYNC signal when this -# transaction has been fetched by a worker thread. -SET gtid_seq_no=100; -INSERT INTO t2 VALUES (46); ---save_master_pos - ---connection con_temp2 -# Temporarily block the DELETE on a=40 from completing. -BEGIN; -SELECT * FROM t2 WHERE a=40 FOR UPDATE; - - ---connection server_2 ---source include/start_slave.inc - -# Wait for a worker thread to start on the DELETE that will be blocked -# temporarily by the SELECT FOR UPDATE. ---let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE state='updating' and info LIKE '%DELETE FROM t2 WHERE a=40%' ---source include/wait_condition.inc - -# The DBUG injection set above will make the worker thread signal the following -# debug_sync when the GTID 0-1-100 has been reached by a worker thread. -# Thus, at this point, the SQL driver thread has reached the next -# relay log file name, while a worker thread is still processing a -# transaction in the previous relay log file, blocked on the SELECT FOR -# UPDATE. -SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; -# At this point, the SQL driver thread is in the new relay log file, while -# the DELETE from the old relay log file is not yet complete. We will stop -# the slave at this point. The bug was that the DELETE statement would -# update the slave position to the _new_ relay log file name instead of -# its own old file name. Thus, by stoping and restarting the slave at this -# point, we would get an error at restart due to incorrect position. (If -# we would let the slave catch up before stopping, the incorrect position -# would be corrected by a later transaction). - -send STOP SLAVE; - ---connection con_temp2 -# Wait for STOP SLAVE to have proceeded sufficiently that it has signalled -# all worker threads to stop; this ensures that we will stop after the DELETE -# transaction (and not after a later transaction that might have been able -# to set a fixed position). -SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; -# Now release the row lock that was blocking the replication of DELETE. -ROLLBACK; - ---connection server_2 -reap; ---source include/wait_for_slave_sql_to_stop.inc -SELECT * FROM t2 WHERE a >= 40 ORDER BY a; -# Now restart the slave. With the bug present, this would start at an -# incorrect relay log position, causing relay log read error (or if unlucky, -# silently skip a number of events). ---source include/start_slave.inc ---sync_with_master -SELECT * FROM t2 WHERE a >= 40 ORDER BY a; ---source include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET DEBUG_SYNC= 'RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -CHANGE MASTER TO master_use_gtid=slave_pos; ---source include/start_slave.inc - - ---echo *** MDEV-7326 Server deadlock in connection with parallel replication *** -# We use three transactions, each in a separate group commit. -# T1 does mark_start_commit(), then gets a deadlock error. -# T2 wakes up and starts running -# T1 does unmark_start_commit() -# T3 goes to wait for T2 to start its commit -# T2 does mark_start_commit() -# The bug was that at this point, T3 got deadlocked. Because T1 has unmarked(), -# T3 did not yet see the count_committing_event_groups reach its target value -# yet. But when T1 later re-did mark_start_commit(), it failed to send a wakeup -# to T3. - ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=3; -SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; ---source include/start_slave.inc - ---connection server_1 -SET @old_format= @@SESSION.binlog_format; -SET binlog_format= STATEMENT; -# This debug_sync will linger on and be used to control T3 later. -INSERT INTO t1 VALUES (foo(50, - "rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", - "rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); ---save_master_pos ---connection server_2 -# Wait for the debug_sync point for T3 to be set. But let the preparation -# transaction remain hanging, so that T1 and T2 will be scheduled for the -# remaining two worker threads. -SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; - ---connection server_1 -INSERT INTO t2 VALUES (foo(50, - "rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", - "rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); ---save_master_pos - ---connection server_2 -SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; -# T1 has now done mark_start_commit(). It will later do a rollback and retry. - ---connection server_1 -# Use a MyISAM table for T2 and T3, so they do not trigger the -# rpl_parallel_simulate_temp_err_xid DBUG insertion on XID event. -INSERT INTO t1 VALUES (foo(51, - "rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", - "rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); - ---connection server_2 -SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; -# T2 has now started running, but has not yet done mark_start_commit() -SET DEBUG_SYNC= "now SIGNAL t1_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; -# T1 has now done unmark_start_commit() in preparation for its retry. - ---connection server_1 -INSERT INTO t1 VALUES (52); -SET BINLOG_FORMAT= @old_format; -SELECT * FROM t2 WHERE a>=50 ORDER BY a; -SELECT * FROM t1 WHERE a>=50 ORDER BY a; - ---connection server_2 -# Let the preparation transaction complete, so that the same worker thread -# can continue with the transaction T3. -SET DEBUG_SYNC= "now SIGNAL prep_cont"; -SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; -# T3 has now gone to wait for T2 to start committing -SET DEBUG_SYNC= "now SIGNAL t2_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; -# T2 has now done mark_start_commit(). -# Let things run, and check that T3 does not get deadlocked. -SET DEBUG_SYNC= "now SIGNAL t1_cont2"; ---sync_with_master - ---connection server_1 ---save_master_pos ---connection server_2 ---sync_with_master -SELECT * FROM t2 WHERE a>=50 ORDER BY a; -SELECT * FROM t1 WHERE a>=50 ORDER BY a; -SET DEBUG_SYNC="reset"; - -# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. ---source include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - - ---echo *** MDEV-7326 Server deadlock in connection with parallel replication *** -# Similar to the previous test, but with T2 and T3 in the same GCO. -# We use three transactions, T1 in one group commit and T2/T3 in another. -# T1 does mark_start_commit(), then gets a deadlock error. -# T2 wakes up and starts running -# T1 does unmark_start_commit() -# T3 goes to wait for T1 to start its commit -# T2 does mark_start_commit() -# The bug was that at this point, T3 got deadlocked. T2 increments the -# count_committing_event_groups but does not signal T3, as they are in -# the same GCO. Then later when T1 increments, it would also not signal -# T3, because now the count_committing_event_groups is not equal to the -# wait_count of T3 (it is one larger). - ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=3; -SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; ---source include/start_slave.inc - ---connection server_1 -SET @old_format= @@SESSION.binlog_format; -SET binlog_format= STATEMENT; -# This debug_sync will linger on and be used to control T3 later. -INSERT INTO t1 VALUES (foo(60, - "rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", - "rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); ---save_master_pos ---connection server_2 -# Wait for the debug_sync point for T3 to be set. But let the preparation -# transaction remain hanging, so that T1 and T2 will be scheduled for the -# remaining two worker threads. -SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; - ---connection server_1 -INSERT INTO t2 VALUES (foo(60, - "rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", - "rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); ---save_master_pos - ---connection server_2 -SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; -# T1 has now done mark_start_commit(). It will later do a rollback and retry. - -# Do T2 and T3 in a single group commit. -# Use a MyISAM table for T2 and T3, so they do not trigger the -# rpl_parallel_simulate_temp_err_xid DBUG insertion on XID event. ---connection con_temp3 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -send INSERT INTO t1 VALUES (foo(61, - "rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", - "rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued1'; - ---connection con_temp4 -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -send INSERT INTO t6 VALUES (62); - ---connection server_1 -SET debug_sync='now WAIT_FOR master_queued2'; -SET debug_sync='now SIGNAL master_cont1'; - ---connection con_temp3 -REAP; ---connection con_temp4 -REAP; - ---connection server_1 -SET debug_sync='RESET'; -SET BINLOG_FORMAT= @old_format; -SELECT * FROM t2 WHERE a>=60 ORDER BY a; -SELECT * FROM t1 WHERE a>=60 ORDER BY a; -SELECT * FROM t6 WHERE a>=60 ORDER BY a; - ---connection server_2 -SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; -# T2 has now started running, but has not yet done mark_start_commit() -SET DEBUG_SYNC= "now SIGNAL t1_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; -# T1 has now done unmark_start_commit() in preparation for its retry. - ---connection server_2 -# Let the preparation transaction complete, so that the same worker thread -# can continue with the transaction T3. -SET DEBUG_SYNC= "now SIGNAL prep_cont"; -SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; -# T3 has now gone to wait for T2 to start committing -SET DEBUG_SYNC= "now SIGNAL t2_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; -# T2 has now done mark_start_commit(). -# Let things run, and check that T3 does not get deadlocked. -SET DEBUG_SYNC= "now SIGNAL t1_cont2"; ---sync_with_master - ---connection server_1 ---save_master_pos ---connection server_2 ---sync_with_master -SELECT * FROM t2 WHERE a>=60 ORDER BY a; -SELECT * FROM t1 WHERE a>=60 ORDER BY a; -SELECT * FROM t6 WHERE a>=60 ORDER BY a; -SET DEBUG_SYNC="reset"; - -# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. ---source include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - ---echo *** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** - ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=1; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; - ---connection server_1 -INSERT INTO t2 VALUES (101); -INSERT INTO t2 VALUES (102); -INSERT INTO t2 VALUES (103); -INSERT INTO t2 VALUES (104); -INSERT INTO t2 VALUES (105); -# Inject a partial event group (missing XID at the end). The bug was that such -# partial group was not handled appropriately, leading to server deadlock. -SET gtid_seq_no=1000; -INSERT INTO t2 VALUES (106); -INSERT INTO t2 VALUES (107); -INSERT INTO t2 VALUES (108); -INSERT INTO t2 VALUES (109); -INSERT INTO t2 VALUES (110); -INSERT INTO t2 VALUES (111); -INSERT INTO t2 VALUES (112); -INSERT INTO t2 VALUES (113); -INSERT INTO t2 VALUES (114); -INSERT INTO t2 VALUES (115); -INSERT INTO t2 VALUES (116); -INSERT INTO t2 VALUES (117); -INSERT INTO t2 VALUES (118); -INSERT INTO t2 VALUES (119); -INSERT INTO t2 VALUES (120); -INSERT INTO t2 VALUES (121); -INSERT INTO t2 VALUES (122); -INSERT INTO t2 VALUES (123); -INSERT INTO t2 VALUES (124); -INSERT INTO t2 VALUES (125); -INSERT INTO t2 VALUES (126); -INSERT INTO t2 VALUES (127); -INSERT INTO t2 VALUES (128); -INSERT INTO t2 VALUES (129); -INSERT INTO t2 VALUES (130); ---source include/save_master_gtid.inc - ---connection server_2 ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc -# The partial event group (a=106) should be rolled back and thus missing. -SELECT * FROM t2 WHERE a >= 100 ORDER BY a; - ---source include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=10; ---source include/start_slave.inc - ---echo *** MDEV-6676 - test syntax of @@slave_parallel_mode *** ---connection server_2 - ---let $status_items= Parallel_Mode ---source include/show_slave_status.inc ---source include/stop_slave.inc -SET GLOBAL slave_parallel_mode='aggressive'; ---let $status_items= Parallel_Mode ---source include/show_slave_status.inc -SET GLOBAL slave_parallel_mode='conservative'; ---let $status_items= Parallel_Mode ---source include/show_slave_status.inc - - ---echo *** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** ---connection server_1 -INSERT INTO t2 VALUES (1040); ---source include/save_master_gtid.inc - ---connection server_2 -SET GLOBAL slave_parallel_mode='none'; -# Test that we do not use parallel apply, by injecting an unconditional -# crash in the parallel apply code. -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; ---source include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; - - ---echo *** MDEV-6676 - test disabling domain-based parallel replication *** ---connection server_1 -# Let's do a bunch of transactions that will conflict if run out-of-order in -# domain-based parallel replication mode. -SET gtid_domain_id = 1; -INSERT INTO t2 VALUES (1041); -INSERT INTO t2 VALUES (1042); -INSERT INTO t2 VALUES (1043); -INSERT INTO t2 VALUES (1044); -INSERT INTO t2 VALUES (1045); -INSERT INTO t2 VALUES (1046); -DELETE FROM t2 WHERE a >= 1041; -SET gtid_domain_id = 2; -INSERT INTO t2 VALUES (1041); -INSERT INTO t2 VALUES (1042); -INSERT INTO t2 VALUES (1043); -INSERT INTO t2 VALUES (1044); -INSERT INTO t2 VALUES (1045); -INSERT INTO t2 VALUES (1046); -SET gtid_domain_id = 0; ---source include/save_master_gtid.inc ---connection server_2 -SET GLOBAL slave_parallel_mode=minimal; ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; - ---echo *** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** - ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_mode='conservative'; -SET GLOBAL slave_parallel_threads=10; - -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; - ---connection server_1 -# Inject two group commits. The bug was that ANALYZE TABLE would call -# wakeup_subsequent_commits() too early, allowing the following transaction -# in the same group to run ahead and binlog and free the GCO. Then we get -# wrong binlog order and later access freed GCO, which causes lost wakeup -# of following GCO and thus replication hang. -# We injected a small sleep in ANALYZE to make the race easier to hit (this -# can only cause false negatives in versions with the bug, not false positives, -# so sleep is ok here. And it's in general not possible to trigger reliably -# the race with debug_sync, since the bugfix makes the race impossible). - -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; - -# Group commit with cid=10000, two event groups. -SET @commit_id= 10000; -ANALYZE TABLE t2; -INSERT INTO t3 VALUES (120, 0); - -# Group commit with cid=10001, one event group. -SET @commit_id= 10001; -INSERT INTO t3 VALUES (121, 0); - -SET SESSION debug_dbug=@old_dbug; - -SELECT * FROM t3 WHERE a >= 120 ORDER BY a; ---source include/save_master_gtid.inc - ---connection server_2 ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc - -SELECT * FROM t3 WHERE a >= 120 ORDER BY a; - ---source include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; ---source include/start_slave.inc - - ---echo *** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** - ---connection server_2 ---source include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; - ---connection server_1 -# Inject two group commits. The bug was that record_gtid for a -# non-transactional event group would commit its own transaction, which would -# cause ha_commit_trans() to call wakeup_subsequent_commits() too early. This -# in turn lead to access to freed group_commit_orderer object, losing a wakeup -# and causing slave threads to hang. -# We inject a small sleep in the corresponding record_gtid() to make the race -# easier to hit. - -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; - -# Group commit with cid=10010, two event groups. -SET @old_server_id= @@SESSION.server_id; -SET SESSION server_id= 100; -SET @commit_id= 10010; -ALTER TABLE t1 COMMENT "Hulubulu!"; -SET SESSION server_id= @old_server_id; -INSERT INTO t3 VALUES (130, 0); - -# Group commit with cid=10011, one event group. -SET @commit_id= 10011; -INSERT INTO t3 VALUES (131, 0); - -SET SESSION debug_dbug=@old_dbug; - -SELECT * FROM t3 WHERE a >= 130 ORDER BY a; ---source include/save_master_gtid.inc - ---connection server_2 ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc - -SELECT * FROM t3 WHERE a >= 130 ORDER BY a; - ---source include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; ---source include/start_slave.inc - - ---echo *** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** - ---connection server_1 -INSERT INTO t3 VALUES (201,0), (202,0); ---source include/save_master_gtid.inc - ---connection server_2 ---source include/sync_with_master_gtid.inc ---source include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_mdev8031'; - ---connection server_1 -# We artificially create a situation that hopefully resembles the original -# bug which was only seen "in the wild", and only once. -# Setup a fake group commit with lots of conflicts that will lead to deadloc -# kill. The slave DBUG injection causes the slave to be deadlock killed at -# a particular point during the retry, and then later do a small sleep at -# another critical point where the prior transaction then has a chance to -# complete. Finally an extra KILL check catches an unhandled, lingering -# deadlock kill. So rather artificial, but at least it exercises the -# relevant code paths. -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; - -SET @commit_id= 10200; -INSERT INTO t3 VALUES (203, 1); -INSERT INTO t3 VALUES (204, 1); -INSERT INTO t3 VALUES (205, 1); -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=205; -UPDATE t3 SET b=b+1 WHERE a=205; -SET SESSION debug_dbug=@old_dbug; - -SELECT * FROM t3 WHERE a>=200 ORDER BY a; ---source include/save_master_gtid.inc - ---connection server_2 ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc - -SELECT * FROM t3 WHERE a>=200 ORDER BY a; ---source include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; ---source include/start_slave.inc - - ---echo *** Check getting deadlock killed inside open_binlog() during retry. *** - ---connection server_2 ---source include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; -SET @old_max= @@GLOBAL.max_relay_log_size; -SET GLOBAL max_relay_log_size= 4096; - ---connection server_1 -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; - ---let $large= `SELECT REPEAT("*", 8192)` -SET @commit_id= 10210; ---echo Omit long queries that cause relaylog rotations and transaction retries... ---disable_query_log -eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=205 /* $large */; -eval UPDATE t3 SET b=b+1 WHERE a=205 /* $large */; ---enable_query_log -SET SESSION debug_dbug=@old_dbug; - -SELECT * FROM t3 WHERE a>=200 ORDER BY a; ---source include/save_master_gtid.inc - ---connection server_2 ---source include/start_slave.inc ---source include/sync_with_master_gtid.inc - -SELECT * FROM t3 WHERE a>=200 ORDER BY a; ---source include/stop_slave.inc -SET GLOBAL debug_dbug= @old_debg; -SET GLOBAL max_relay_log_size= @old_max; ---source include/start_slave.inc - ---echo *** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** ---connection server_1 -# Inject an event group terminated by ROLLBACK, by mixing MyISAM and InnoDB -# in a transaction. The bug was an assertion on the ROLLBACK due to -# mark_start_commit() being already called. ---disable_warnings -BEGIN; -INSERT INTO t2 VALUES (2000); -INSERT INTO t1 VALUES (2000); -INSERT INTO t2 VALUES (2001); -ROLLBACK; ---enable_warnings -SELECT * FROM t1 WHERE a>=2000 ORDER BY a; -SELECT * FROM t2 WHERE a>=2000 ORDER BY a; ---source include/save_master_gtid.inc - ---connection server_2 ---source include/sync_with_master_gtid.inc -SELECT * FROM t1 WHERE a>=2000 ORDER BY a; -SELECT * FROM t2 WHERE a>=2000 ORDER BY a; - - -# Clean up. ---connection server_2 ---source include/stop_slave.inc -SET GLOBAL slave_parallel_threads=@old_parallel_threads; ---source include/start_slave.inc -SET DEBUG_SYNC= 'RESET'; - ---connection server_1 -DROP function foo; -DROP TABLE t1,t2,t3,t4,t5,t6; -SET DEBUG_SYNC= 'RESET'; - ---source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_analyze_table_hang.inc b/mysql-test/suite/rpl/include/rpl_parallel_analyze_table_hang.inc new file mode 100644 index 00000000000..62a7501c36b --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_analyze_table_hang.inc @@ -0,0 +1,73 @@ +--echo *** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; + +--connection server_1 +# Inject two group commits. The bug was that ANALYZE TABLE would call +# wakeup_subsequent_commits() too early, allowing the following transaction +# in the same group to run ahead and binlog and free the GCO. Then we get +# wrong binlog order and later access freed GCO, which causes lost wakeup +# of following GCO and thus replication hang. +# We injected a small sleep in ANALYZE to make the race easier to hit (this +# can only cause false negatives in versions with the bug, not false positives, +# so sleep is ok here. And it's in general not possible to trigger reliably +# the race with debug_sync, since the bugfix makes the race impossible). + +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +# Group commit with cid=10000, two event groups. +SET @commit_id= 10000; +ANALYZE TABLE t2; +INSERT INTO t3 VALUES (120, 0); + +# Group commit with cid=10001, one event group. +SET @commit_id= 10001; +INSERT INTO t3 VALUES (121, 0); + +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; + +# Clean up. +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t2,t3; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/include/rpl_parallel_deadlock_corrupt_binlog.inc b/mysql-test/suite/rpl/include/rpl_parallel_deadlock_corrupt_binlog.inc new file mode 100644 index 00000000000..3a135ef5cc4 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_deadlock_corrupt_binlog.inc @@ -0,0 +1,79 @@ +--echo *** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=1; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; + +--connection server_1 +INSERT INTO t2 VALUES (101); +INSERT INTO t2 VALUES (102); +INSERT INTO t2 VALUES (103); +INSERT INTO t2 VALUES (104); +INSERT INTO t2 VALUES (105); +# Inject a partial event group (missing XID at the end). The bug was that such +# partial group was not handled appropriately, leading to server deadlock. +SET gtid_seq_no=1000; +INSERT INTO t2 VALUES (106); +INSERT INTO t2 VALUES (107); +INSERT INTO t2 VALUES (108); +INSERT INTO t2 VALUES (109); +INSERT INTO t2 VALUES (110); +INSERT INTO t2 VALUES (111); +INSERT INTO t2 VALUES (112); +INSERT INTO t2 VALUES (113); +INSERT INTO t2 VALUES (114); +INSERT INTO t2 VALUES (115); +INSERT INTO t2 VALUES (116); +INSERT INTO t2 VALUES (117); +INSERT INTO t2 VALUES (118); +INSERT INTO t2 VALUES (119); +INSERT INTO t2 VALUES (120); +INSERT INTO t2 VALUES (121); +INSERT INTO t2 VALUES (122); +INSERT INTO t2 VALUES (123); +INSERT INTO t2 VALUES (124); +INSERT INTO t2 VALUES (125); +INSERT INTO t2 VALUES (126); +INSERT INTO t2 VALUES (127); +INSERT INTO t2 VALUES (128); +INSERT INTO t2 VALUES (129); +INSERT INTO t2 VALUES (130); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +# The partial event group (a=106) should be rolled back and thus missing. +SELECT * FROM t2 WHERE a >= 100 ORDER BY a; + +# Cleanup +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP TABLE t2; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_domain.inc b/mysql-test/suite/rpl/include/rpl_parallel_domain.inc new file mode 100644 index 00000000000..eda08cc2916 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_domain.inc @@ -0,0 +1,87 @@ +# Test should work with both conservative and optimistic modes + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +# Test various aspects of parallel replication. + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--error ER_SLAVE_MUST_STOP +SET GLOBAL slave_parallel_threads=10; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; + +# Check that we do not spawn any worker threads when no slave is running. +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; + +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +# Check that worker threads get spawned when slave starts. +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +# ... and that worker threads get removed when slave stops. +--source include/stop_slave.inc +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +--source include/start_slave.inc +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; + +--echo *** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master + +# Block the table t1 to simulate a replicated query taking a long time. +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +LOCK TABLE t1 WRITE; + +--connection server_1 +SET gtid_domain_id=1; +# This query will be blocked on the slave until UNLOCK TABLES. +INSERT INTO t1 VALUES (2); +SET gtid_domain_id=0; +# These t2 queries can be replicated in parallel with the prior t1 query, as +# they are in a separate replication domain. +INSERT INTO t2 VALUES (2); +INSERT INTO t2 VALUES (3); +BEGIN; +INSERT INTO t2 VALUES (4); +INSERT INTO t2 VALUES (5); +COMMIT; +INSERT INTO t2 VALUES (6); + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 6 FROM t2 +--source include/wait_condition.inc + +SELECT * FROM t2 ORDER by a; + +--connection con_temp1 +SELECT * FROM t1; +UNLOCK TABLES; + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 2 FROM t1 +--source include/wait_condition.inc + +SELECT * FROM t1 ORDER BY a; + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1,t2; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_domain_slave_single_grp.inc b/mysql-test/suite/rpl/include/rpl_parallel_domain_slave_single_grp.inc new file mode 100644 index 00000000000..856efd065df --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_domain_slave_single_grp.inc @@ -0,0 +1,128 @@ +# Test is independent of slave_parallel_mode +--echo *** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +# Test various aspects of parallel replication. + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +--connection server_1 +# Use a stored function to inject a debug_sync into the appropriate THD. +# The function does nothing on the master, and on the slave it injects the +# desired debug_sync action(s). +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (foo(10, + 'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', + 'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); + +--connection server_2 +FLUSH LOGS; +--source include/wait_for_binlog_checkpoint.inc +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=statement; +# We need to restart all parallel threads for the new global setting to +# be copied to the session-level values. +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--source include/start_slave.inc + +# First make sure the first insert is ready to commit, but not queued yet. +SET debug_sync='now WAIT_FOR ready1'; + +--connection server_1 +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (foo(11, + 'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', + 'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); +SET gtid_domain_id=0; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; + +--connection server_2 +# Now wait for the second insert to queue itself as the leader, and then +# wait for more commits to queue up. +SET debug_sync='now WAIT_FOR ready3'; +SET debug_sync='now SIGNAL cont3'; +SET debug_sync='now WAIT_FOR ready4'; +# Now allow the first insert to queue up to participate in group commit. +SET debug_sync='now SIGNAL cont1'; +SET debug_sync='now WAIT_FOR ready2'; +# Finally allow the second insert to proceed and do the group commit. +SET debug_sync='now SIGNAL cont4'; + +--let $wait_condition= SELECT COUNT(*) = 2 FROM t2 WHERE a >= 10 +--source include/wait_condition.inc +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +# The two INSERT transactions should have been committed in opposite order, +# but in the same group commit (seen by precense of cid=# in the SHOW +# BINLOG output). +--let $binlog_file= slave-bin.000002 +--source include/show_binlog_events.inc +FLUSH LOGS; +--source include/wait_for_binlog_checkpoint.inc + + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL binlog_format=@old_format; + +--connection server_1 +DROP function foo; +DROP TABLE t1,t2; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL binlog_format=@old_format; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_free_deferred_event.inc b/mysql-test/suite/rpl/include/rpl_parallel_free_deferred_event.inc new file mode 100644 index 00000000000..41f372eddf8 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_free_deferred_event.inc @@ -0,0 +1,67 @@ +--echo *** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** + +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +# Use just two worker threads, so we are sure to get the rpl_group_info added +# to the free list, which is what triggered the bug. +--source include/stop_slave.inc +SET GLOBAL replicate_ignore_table="test.t3"; +SET GLOBAL slave_parallel_threads=2; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t3 VALUES (100, rand()); +INSERT INTO t3 VALUES (101, rand()); +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +INSERT INTO t3 VALUES (102, rand()); +INSERT INTO t3 VALUES (103, rand()); +INSERT INTO t3 VALUES (104, rand()); +INSERT INTO t3 VALUES (105, rand()); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET GLOBAL replicate_ignore_table=""; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t3 VALUES (106, rand()); +INSERT INTO t3 VALUES (107, rand()); +--save_master_pos + +--connection server_2 +--sync_with_master +--replace_column 2 # +SELECT * FROM t3 WHERE a >= 100 ORDER BY a; + + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t3; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_gco_wait_kill.inc b/mysql-test/suite/rpl/include/rpl_parallel_gco_wait_kill.inc new file mode 100644 index 00000000000..d918b2ea692 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_gco_wait_kill.inc @@ -0,0 +1,366 @@ +--echo *** Test killing thread that is waiting to start transaction until previous transaction commits *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Slave: Connection was killed"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET sql_log_bin=1; +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode= 'conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +--connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +# Use a stored function to inject a debug_sync into the appropriate THD. +# The function does nothing on the master, and on the slave it injects the +# desired debug_sync action(s). +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_2 +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; +# We need to restart all parallel threads for the new global setting to +# be copied to the session-level values. +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=4; +--source include/start_slave.inc + + +# We set up four transactions T1, T2, T3, and T4 on the master. T2, T3, and T4 +# can run in parallel with each other (same group commit and commit id), +# but not in parallel with T1. +# +# We use four worker threads, each Ti will be queued on each their own +# worker thread. We will delay T1 commit, T3 will wait for T1 to begin +# commit before it can start. We will kill T3 during this wait, and +# check that everything works correctly. +# +# It is rather tricky to get the correct thread id of the worker to kill. +# We start by injecting four dummy transactions in a debug_sync-controlled +# manner to be able to get known thread ids for the workers in a pool with +# just 4 worker threads. Then we let in each of the real test transactions +# T1-T4 one at a time in a way which allows us to know which transaction +# ends up with which thread id. + +--connection server_1 +SET gtid_domain_id=2; +BEGIN; +# This debug_sync will linger on and be used to control T4 later. +INSERT INTO t3 VALUES (70, foo(70, + 'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); +INSERT INTO t3 VALUES (60, foo(60, + 'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', + 'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); +COMMIT; +SET gtid_domain_id=0; + +--connection server_2 +SET debug_sync='now WAIT_FOR d2_query'; +--let $d2_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(60%' AND INFO NOT LIKE '%LIKE%'` + +--connection server_1 +SET gtid_domain_id=1; +BEGIN; +# These debug_sync's will linger on and be used to control T3 later. +INSERT INTO t3 VALUES (61, foo(61, + 'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', + 'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); +INSERT INTO t3 VALUES (62, foo(62, + 'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', + 'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); +COMMIT; +SET gtid_domain_id=0; + +--connection server_2 +SET debug_sync='now WAIT_FOR d1_query'; +--let $d1_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(62%' AND INFO NOT LIKE '%LIKE%'` + +--connection server_1 +SET gtid_domain_id=0; +INSERT INTO t3 VALUES (63, foo(63, + 'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', + 'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); + +--connection server_2 +SET debug_sync='now WAIT_FOR d0_query'; +--let $d0_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(63%' AND INFO NOT LIKE '%LIKE%'` + +--connection server_1 +SET gtid_domain_id=3; +BEGIN; +# These debug_sync's will linger on and be used to control T2 later. +INSERT INTO t3 VALUES (68, foo(68, + 'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); +INSERT INTO t3 VALUES (69, foo(69, + 'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', + 'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); +COMMIT; +SET gtid_domain_id=0; + +--connection server_2 +SET debug_sync='now WAIT_FOR d3_query'; +--let $d3_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(69%' AND INFO NOT LIKE '%LIKE%'` + +SET debug_sync='now SIGNAL d2_cont2'; +SET debug_sync='now WAIT_FOR d2_done'; +SET debug_sync='now SIGNAL d1_cont2'; +SET debug_sync='now WAIT_FOR d1_done'; +SET debug_sync='now SIGNAL d0_cont2'; +SET debug_sync='now WAIT_FOR d0_done'; +SET debug_sync='now SIGNAL d3_cont2'; +SET debug_sync='now WAIT_FOR d3_done'; + +# Now prepare the real transactions T1, T2, T3, T4 on the master. + +--connection con_temp3 +# Create transaction T1. +INSERT INTO t3 VALUES (64, foo(64, + 'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); + +# Create transaction T2, as a group commit leader on the master. +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; +send INSERT INTO t3 VALUES (65, foo(65, '', '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp4 +# Create transaction T3, participating in T2's group commit. +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +send INSERT INTO t3 VALUES (66, foo(66, '', '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; + +--connection con_temp5 +# Create transaction T4, participating in group commit with T2 and T3. +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; +send INSERT INTO t3 VALUES (67, foo(67, '', '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued4'; +SET debug_sync='now SIGNAL master_cont2'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +# Now we have the four transactions pending for replication on the slave. +# Let them be queued for our three worker threads in a controlled fashion. +# We put them at a stage where T1 is delayed and T3 is waiting for T1 to +# commit before T3 can start. Then we kill T3. + +# Make the worker D0 free, and wait for T1 to be queued in it. +SET debug_sync='now SIGNAL d0_cont'; +SET debug_sync='now WAIT_FOR t1_waiting'; + +# Make the worker D3 free, and wait for T2 to be queued in it. +SET debug_sync='now SIGNAL d3_cont'; +SET debug_sync='now WAIT_FOR t2_waiting'; + +# Now release worker D1, and wait for T3 to be queued in it. +# T3 will wait for T1 to commit before it can start. +SET debug_sync='now SIGNAL d1_cont'; +SET debug_sync='now WAIT_FOR t3_waiting'; + +# Release worker D2. Wait for T4 to be queued, so we are sure it has +# received the debug_sync signal (else we might overwrite it with the +# next debug_sync). +SET debug_sync='now SIGNAL d2_cont'; +SET debug_sync='now WAIT_FOR t4_waiting'; + +# Now we kill the waiting transaction T3 in worker D1. +--replace_result $d1_thd_id THD_ID +eval KILL $d1_thd_id; + +# Wait until T3 has reacted on the kill. +SET debug_sync='now WAIT_FOR t3_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--source include/wait_for_slave_sql_error.inc +STOP SLAVE IO_THREAD; +# Since T2, T3, and T4 run in parallel, we can not be sure if T2 will have time +# to commit or not before the stop. However, T1 should commit, and T3/T4 may +# not have committed. (After slave restart we check that all become committed +# eventually). +SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +UPDATE t3 SET b=b+1 WHERE a=60; +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--source include/start_slave.inc + +--echo *** 5. Test killing thread that is waiting for queue of max length to shorten *** + +# Find the thread id of the driver SQL thread that we want to kill. +--let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%' +--source include/wait_condition.inc +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%'` +SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; +SET GLOBAL slave_parallel_max_queued=9000; + +--connection server_1 +--let bigstring= `SELECT REPEAT('x', 10000)` +# Create an event that will wait to be signalled. +INSERT INTO t3 VALUES (80, foo(0, + 'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); + +--connection server_2 +SET debug_sync='now WAIT_FOR query_waiting'; +# Inject that the SQL driver thread will signal `wait_queue_ready' to debug_sync +# as it goes to wait for the event queue to become smaller than the value of +# @@slave_parallel_max_queued. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; + +--connection server_1 +--disable_query_log +# Create an event that will fill up the queue. +# The Xid event at the end of the event group will have to wait for the Query +# event with the INSERT to drain so the queue becomes shorter. However that in +# turn waits for the prior event group to continue. +eval INSERT INTO t3 VALUES (81, LENGTH('$bigstring')); +--enable_query_log +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; + +--connection server_2 +SET debug_sync='now WAIT_FOR wait_queue_ready'; + +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +SET debug_sync='now WAIT_FOR wait_queue_killed'; +SET debug_sync='now SIGNAL query_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--source include/wait_for_slave_sql_error.inc +STOP SLAVE IO_THREAD; + +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_max_queued= @old_max_queued; + +--connection server_1 +INSERT INTO t3 VALUES (82,0); +--save_master_pos + +--connection server_2 +SET debug_sync='RESET'; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP function foo; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_gtid_slave_pos_update_fail.inc b/mysql-test/suite/rpl/include/rpl_parallel_gtid_slave_pos_update_fail.inc new file mode 100644 index 00000000000..da1a07d3b87 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_gtid_slave_pos_update_fail.inc @@ -0,0 +1,98 @@ +# MDEV-6549, failing to update gtid_slave_pos for a transaction that was retried. + +# The problem was that when a transaction updates the mysql.gtid_slave_pos +# table, it clears the flag that marks that there is a GTID position that +# needs to be updated. Then, if the transaction got killed after that due +# to a deadlock, the subsequent retry would fail to notice that the GTID needs +# to be recorded in gtid_slave_pos. +# +# (In the original bug report, the symptom was an assertion; this was however +# just a side effect of the missing update of gtid_slave_pos, which also +# happened to cause a missing clear of OPTION_GTID_BEGIN). +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +# Must use statement-based binlogging. Otherwise the transaction will not be +# binlogged at all, as it modifies no rows. +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +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); +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +# Create two transactions that can run in parallel on the slave but cause +# a deadlock if the second runs before the first. +--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 <= 1; + +--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 +--let $last_gtid= `SELECT @@last_gtid` + +--connection server_2 +# Disable the usual skip of gap locks for transactions that are run in +# parallel, using DBUG. This allows the deadlock to occur, and this in turn +# triggers a retry of the second transaction, and the code that was buggy and +# caused the gtid_slave_pos update to be skipped in the retry. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; +--source include/start_slave.inc +--sync_with_master +SET GLOBAL debug_dbug=@old_dbug; + +SELECT * FROM t4 ORDER BY a; +# Check that the GTID of the second transaction was correctly recorded in +# gtid_slave_pos, in the variable as well as in the table. +--replace_result $last_gtid GTID +eval SET @last_gtid= '$last_gtid'; +SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", + CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) + AS result; +SELECT "ROW FOUND" AS `Is the row found?` + FROM mysql.gtid_slave_pos + WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +--disconnect con1 +--disconnect con2 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_ignore_error_on_rotate.inc b/mysql-test/suite/rpl/include/rpl_parallel_ignore_error_on_rotate.inc new file mode 100644 index 00000000000..2fab9f8032b --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_ignore_error_on_rotate.inc @@ -0,0 +1,96 @@ +--echo *** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** + +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (1); +SET gtid_domain_id=0; +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (2); +SET gtid_domain_id=0; +INSERT INTO t2 VALUES (31); +--let $gtid1= `SELECT @@LAST_GTID` +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads= 0; +--source include/start_slave.inc + +# Force a duplicate key error on the slave. +SET sql_log_bin= 0; +INSERT INTO t2 VALUES (32); +SET sql_log_bin= 1; + +--connection server_1 +INSERT INTO t2 VALUES (32); +--let $gtid2= `SELECT @@LAST_GTID` +# Rotate the binlog; the bug is triggered when the master binlog file changes +# after the event group that causes the duplicate key error. +FLUSH LOGS; +INSERT INTO t2 VALUES (33); +INSERT INTO t2 VALUES (34); +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc + +--connection server_2 +--source include/stop_slave_io.inc +SET GLOBAL slave_parallel_threads=10; +START SLAVE; + +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc + +# Note: IO thread is still running at this point. +# The bug seems to have been that restarting the SQL thread after an error with +# the IO thread still running, somehow picks up a later relay log position and +# thus ends up skipping the failing event, rather than re-executing. + +START SLAVE SQL_THREAD; +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc + +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; + +# Skip the duplicate error, so we can proceed. +--error ER_SLAVE_SKIP_NOT_IN_GTID +SET sql_slave_skip_counter= 1; +--source include/stop_slave_io.inc +--disable_query_log +eval SET GLOBAL gtid_slave_pos = REPLACE(@@gtid_slave_pos, "$gtid1", "$gtid2"); +--enable_query_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc b/mysql-test/suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc new file mode 100644 index 00000000000..3cf0afd63ca --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc @@ -0,0 +1,128 @@ +--echo *** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=10; +# Test assumes that 'conservative' mode is in effect. i.e +# Do not start parallel execution of this event group until all prior groups +# have reached the commit phase. Upon execution of STOP SLAVE there can be one +# group which is executing and the rest are doing group commit order wait. +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (40); +--save_master_pos + +--connection server_2 +--sync_with_master +--connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +SET @old_dbug= @@GLOBAL.debug_dbug; +# This DBUG injection causes a DEBUG_SYNC signal "scheduled_gtid_0_x_100" when +# GTID 0-1-100 has been scheduled for and fetched by a worker thread. +SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; +# This DBUG injection causes a DEBUG_SYNC signal "wait_for_done_waiting" when +# STOP SLAVE has signalled all worker threads to stop. +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +# Reset worker threads to make DBUG setting catch on. +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; + + +--connection server_1 +# Setup some transaction for the slave to replicate. +INSERT INTO t2 VALUES (41); +INSERT INTO t2 VALUES (42); +# Need to log the DELETE in statement format, so we can see it in processlist. +SET @old_format= @@binlog_format; +SET binlog_format= statement; +DELETE FROM t2 WHERE a=40; +SET binlog_format= @old_format; +INSERT INTO t2 VALUES (43); +INSERT INTO t2 VALUES (44); +# Force the slave to switch to a new relay log file. +FLUSH LOGS; +INSERT INTO t2 VALUES (45); +# Inject a GTID 0-1-100, which will trigger a DEBUG_SYNC signal when this +# transaction has been fetched by a worker thread. +SET gtid_seq_no=100; +INSERT INTO t2 VALUES (46); +--save_master_pos + +--connection con_temp2 +# Temporarily block the DELETE on a=40 from completing. +BEGIN; +SELECT * FROM t2 WHERE a=40 FOR UPDATE; + +--connection server_2 +--source include/start_slave.inc + +# Wait for a worker thread to start on the DELETE that will be blocked +# temporarily by the SELECT FOR UPDATE. +--let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE state='updating' and info LIKE '%DELETE FROM t2 WHERE a=40%' +--source include/wait_condition.inc + +# The DBUG injection set above will make the worker thread signal the following +# debug_sync when the GTID 0-1-100 has been reached by a worker thread. +# Thus, at this point, the SQL driver thread has reached the next +# relay log file name, while a worker thread is still processing a +# transaction in the previous relay log file, blocked on the SELECT FOR +# UPDATE. +SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; +# At this point, the SQL driver thread is in the new relay log file, while +# the DELETE from the old relay log file is not yet complete. We will stop +# the slave at this point. The bug was that the DELETE statement would +# update the slave position to the _new_ relay log file name instead of +# its own old file name. Thus, by stoping and restarting the slave at this +# point, we would get an error at restart due to incorrect position. (If +# we would let the slave catch up before stopping, the incorrect position +# would be corrected by a later transaction). + +send STOP SLAVE; + +--connection con_temp2 +# Wait for STOP SLAVE to have proceeded sufficiently that it has signalled +# all worker threads to stop; this ensures that we will stop after the DELETE +# transaction (and not after a later transaction that might have been able +# to set a fixed position). +SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; +# Now release the row lock that was blocking the replication of DELETE. +ROLLBACK; + +--connection server_2 +reap; +--source include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +# Now restart the slave. With the bug present, this would start at an +# incorrect relay log position, causing relay log read error (or if unlucky, +# silently skip a number of events). +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; + +# Clean up. +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_innodb_lock_conflict.inc b/mysql-test/suite/rpl/include/rpl_parallel_innodb_lock_conflict.inc new file mode 100644 index 00000000000..90304937445 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_innodb_lock_conflict.inc @@ -0,0 +1,107 @@ +--echo ***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +SET sql_log_bin=0; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET sql_log_bin=1; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +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); +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) + +# 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 +--source include/stop_slave.inc + +SELECT * FROM t4 ORDER BY a; + + +# Clean up. +--connection server_2 +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +--disconnect con1 +--disconnect con2 +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_missed_error_handling.inc b/mysql-test/suite/rpl/include/rpl_parallel_missed_error_handling.inc new file mode 100644 index 00000000000..33b1bcb11d9 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_missed_error_handling.inc @@ -0,0 +1,87 @@ +--echo *** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +INSERT INTO t3 VALUES (110, 1); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +# Inject a duplicate key error. +SET sql_log_bin=0; +INSERT INTO t3 VALUES (111, 666); +SET sql_log_bin=1; + +--connection server_1 + +# Create a group commit with two inserts, the first one conflicts with a row on the slave +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send INSERT INTO t3 VALUES (111, 2); +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send INSERT INTO t3 VALUES (112, 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 +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc +--source include/wait_for_slave_sql_to_stop.inc +# We should not see the row (112,3) here, it should be rolled back due to +# error signal from the prior transaction. +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +SET sql_log_bin=0; +DELETE FROM t3 WHERE a=111 AND b=666; +SET sql_log_bin=1; +START SLAVE SQL_THREAD; +--sync_with_master +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +--disconnect con1 +--disconnect con2 +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_mode.inc b/mysql-test/suite/rpl/include/rpl_parallel_mode.inc new file mode 100644 index 00000000000..67104069e9a --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_mode.inc @@ -0,0 +1,87 @@ +--echo *** MDEV-6676 - test syntax of @@slave_parallel_mode *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master + +--let $status_items= Parallel_Mode +--source include/show_slave_status.inc +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode='aggressive'; +--let $status_items= Parallel_Mode +--source include/show_slave_status.inc +SET GLOBAL slave_parallel_mode='conservative'; +--let $status_items= Parallel_Mode +--source include/show_slave_status.inc + +--echo *** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** +--connection server_1 +INSERT INTO t2 VALUES (1040); +--source include/save_master_gtid.inc + +--connection server_2 +SET GLOBAL slave_parallel_mode='none'; +# Test that we do not use parallel apply, by injecting an unconditional +# crash in the parallel apply code. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; + + +--echo *** MDEV-6676 - test disabling domain-based parallel replication *** +--connection server_1 +# Let's do a bunch of transactions that will conflict if run out-of-order in +# domain-based parallel replication mode. +SET gtid_domain_id = 1; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +DELETE FROM t2 WHERE a >= 1041; +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +SET gtid_domain_id = 0; +--source include/save_master_gtid.inc +--connection server_2 +SET GLOBAL slave_parallel_mode=minimal; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; + +# Cleanup +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t2; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_partial_binlog_trans.inc b/mysql-test/suite/rpl/include/rpl_parallel_partial_binlog_trans.inc new file mode 100644 index 00000000000..7247925285f --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_partial_binlog_trans.inc @@ -0,0 +1,71 @@ +--echo *** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) + +--connection con1 +--let $conid = `SELECT CONNECTION_ID()` +SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; +send INSERT INTO t6 VALUES (1), (2), (3); + +--connection server_1 +SET debug_sync='now WAIT_FOR ready'; +--replace_result $conid CONID +eval KILL QUERY $conid; +SET debug_sync='now SIGNAL cont'; + +--connection con1 +--error ER_QUERY_INTERRUPTED +--reap +SET debug_sync='RESET'; +--let $after_error_gtid_pos= `SELECT @@gtid_binlog_pos` + +--connection server_1 +SET debug_sync='RESET'; + +--connection server_2 +--let $slave_sql_errno= 1317 +--source include/wait_for_slave_sql_error.inc +STOP SLAVE IO_THREAD; +--replace_result $after_error_gtid_pos AFTER_ERROR_GTID_POS +eval SET GLOBAL gtid_slave_pos= '$after_error_gtid_pos'; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t6 VALUES (4); +SELECT * FROM t6 ORDER BY a; +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t6 ORDER BY a; + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP TABLE t6; +SET DEBUG_SYNC= 'RESET'; +--disconnect con1 + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_record_gtid_wakeup.inc b/mysql-test/suite/rpl/include/rpl_parallel_record_gtid_wakeup.inc new file mode 100644 index 00000000000..0f94d8f9943 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_record_gtid_wakeup.inc @@ -0,0 +1,72 @@ +--echo *** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; + +--connection server_1 +# Inject two group commits. The bug was that record_gtid for a +# non-transactional event group would commit its own transaction, which would +# cause ha_commit_trans() to call wakeup_subsequent_commits() too early. This +# in turn lead to access to freed group_commit_orderer object, losing a wakeup +# and causing slave threads to hang. +# We inject a small sleep in the corresponding record_gtid() to make the race +# easier to hit. + +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +# Group commit with cid=10010, two event groups. +SET @old_server_id= @@SESSION.server_id; +SET SESSION server_id= 100; +SET @commit_id= 10010; +ALTER TABLE t1 COMMENT "Hulubulu!"; +SET SESSION server_id= @old_server_id; +INSERT INTO t3 VALUES (130, 0); + +# Group commit with cid=10011, one event group. +SET @commit_id= 10011; +INSERT INTO t3 VALUES (131, 0); + +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; + +# Clean up. +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1,t3; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/include/rpl_parallel_retry_deadlock.inc b/mysql-test/suite/rpl/include/rpl_parallel_retry_deadlock.inc new file mode 100644 index 00000000000..54ac859bb33 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_retry_deadlock.inc @@ -0,0 +1,281 @@ +--echo *** MDEV-7326 Server deadlock in connection with parallel replication *** +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +# Test assumes that 'conservative' mode is in effect. i.e +# Do not start parallel execution of this event group until all prior groups +# have reached the commit phase. Refer 'rpl_parallel_start_waiting_for_prior' +# debug simumation. +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +# Use a stored function to inject a debug_sync into the appropriate THD. +# The function does nothing on the master, and on the slave it injects the +# desired debug_sync action(s). +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_2 +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +# We use three transactions, each in a separate group commit. +# T1 does mark_start_commit(), then gets a deadlock error. +# T2 wakes up and starts running +# T1 does unmark_start_commit() +# T3 goes to wait for T2 to start its commit +# T2 does mark_start_commit() +# The bug was that at this point, T3 got deadlocked. Because T1 has unmarked(), +# T3 did not yet see the count_committing_event_groups reach its target value +# yet. But when T1 later re-did mark_start_commit(), it failed to send a wakeup +# to T3. + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +--source include/start_slave.inc + +--connection server_1 +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +# This debug_sync will linger on and be used to control T3 later. +INSERT INTO t1 VALUES (foo(50, + "rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", + "rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +--save_master_pos +--connection server_2 +# Wait for the debug_sync point for T3 to be set. But let the preparation +# transaction remain hanging, so that T1 and T2 will be scheduled for the +# remaining two worker threads. +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; + +--connection server_1 +INSERT INTO t2 VALUES (foo(50, + "rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", + "rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +--save_master_pos + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +# T1 has now done mark_start_commit(). It will later do a rollback and retry. + +--connection server_1 +# Use a MyISAM table for T2 and T3, so they do not trigger the +# rpl_parallel_simulate_temp_err_xid DBUG insertion on XID event. +INSERT INTO t1 VALUES (foo(51, + "rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", + "rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +# T2 has now started running, but has not yet done mark_start_commit() +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +# T1 has now done unmark_start_commit() in preparation for its retry. + +--connection server_1 +INSERT INTO t1 VALUES (52); +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +SELECT * FROM t1 WHERE a>=50 ORDER BY a; + +--connection server_2 +# Let the preparation transaction complete, so that the same worker thread +# can continue with the transaction T3. +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +# T3 has now gone to wait for T2 to start committing +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +# T2 has now done mark_start_commit(). +# Let things run, and check that T3 does not get deadlocked. +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +--sync_with_master + +--connection server_1 +--save_master_pos +--connection server_2 +--sync_with_master +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +SET DEBUG_SYNC="reset"; + +# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--source include/start_slave.inc + + +--echo *** MDEV-7326 Server deadlock in connection with parallel replication *** +# Similar to the previous test, but with T2 and T3 in the same GCO. +# We use three transactions, T1 in one group commit and T2/T3 in another. +# T1 does mark_start_commit(), then gets a deadlock error. +# T2 wakes up and starts running +# T1 does unmark_start_commit() +# T3 goes to wait for T1 to start its commit +# T2 does mark_start_commit() +# The bug was that at this point, T3 got deadlocked. T2 increments the +# count_committing_event_groups but does not signal T3, as they are in +# the same GCO. Then later when T1 increments, it would also not signal +# T3, because now the count_committing_event_groups is not equal to the +# wait_count of T3 (it is one larger). + +--connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +--source include/start_slave.inc + +--connection server_1 +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +# This debug_sync will linger on and be used to control T3 later. +INSERT INTO t1 VALUES (foo(60, + "rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", + "rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +--save_master_pos +--connection server_2 +# Wait for the debug_sync point for T3 to be set. But let the preparation +# transaction remain hanging, so that T1 and T2 will be scheduled for the +# remaining two worker threads. +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; + +--connection server_1 +INSERT INTO t2 VALUES (foo(60, + "rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", + "rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +--save_master_pos + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +# T1 has now done mark_start_commit(). It will later do a rollback and retry. + +# Do T2 and T3 in a single group commit. +# Use a MyISAM table for T2 and T3, so they do not trigger the +# rpl_parallel_simulate_temp_err_xid DBUG insertion on XID event. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t1 VALUES (foo(61, + "rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", + "rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send INSERT INTO t6 VALUES (62); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; + +--connection server_1 +SET debug_sync='RESET'; +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +SELECT * FROM t6 WHERE a>=60 ORDER BY a; + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +# T2 has now started running, but has not yet done mark_start_commit() +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +# T1 has now done unmark_start_commit() in preparation for its retry. + +--connection server_2 +# Let the preparation transaction complete, so that the same worker thread +# can continue with the transaction T3. +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +# T3 has now gone to wait for T2 to start committing +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +# T2 has now done mark_start_commit(). +# Let things run, and check that T3 does not get deadlocked. +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +--sync_with_master + +--connection server_1 +--save_master_pos +--connection server_2 +--sync_with_master +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +SET DEBUG_SYNC="reset"; + +# Clean up. +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP function foo; +DROP TABLE t1,t2,t6; +--disconnect con_temp3 +--disconnect con_temp4 +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_rollback_assert.inc b/mysql-test/suite/rpl/include/rpl_parallel_rollback_assert.inc new file mode 100644 index 00000000000..eec331b3d64 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_rollback_assert.inc @@ -0,0 +1,62 @@ +--echo *** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +# Inject an event group terminated by ROLLBACK, by mixing MyISAM and InnoDB +# in a transaction. The bug was an assertion on the ROLLBACK due to +# mark_start_commit() being already called. +--disable_warnings +BEGIN; +INSERT INTO t2 VALUES (2000); +INSERT INTO t1 VALUES (2000); +INSERT INTO t2 VALUES (2001); +ROLLBACK; +--enable_warnings +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +--connection server_1 +INSERT INTO t2 VALUES (2020); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +let $rows_in_t1= `SELECT COUNT(*) FROM t1 WHERE a>=2000 ORDER BY a`; +if ($rows_in_t1 == 0) +{ +--query_vertical SHOW SLAVE STATUS +} +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; + +# Clean up. +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1,t2; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/include/rpl_parallel_single_grpcmt.inc b/mysql-test/suite/rpl/include/rpl_parallel_single_grpcmt.inc new file mode 100644 index 00000000000..cf4c547b73b --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_single_grpcmt.inc @@ -0,0 +1,170 @@ +--echo *** Test that group-committed transactions on the master can replicate in parallel on the slave. *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +# Test various aspects of parallel replication. + +--connection server_1 +# The function does nothing on the master, and on the slave it injects the +# desired debug_sync action(s). +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_2 +--source include/stop_slave.inc +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +# We need to restart all parallel threads for the new global setting to +# be copied to the session-level values. +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +# Create some sentinel rows so that the rows inserted in parallel fall into +# separate gaps and do not cause gap lock conflicts. +INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); +--save_master_pos +--connection server_2 +--sync_with_master + + +# We want to test that the transactions can execute out-of-order on +# the slave, but still end up committing in-order, and in a single +# group commit. +# +# The idea is to group-commit three transactions together on the master: +# A, B, and C. On the slave, C will execute the insert first, then A, +# and then B. But B manages to complete before A has time to commit, so +# all three end up committing together. +# +# So we start by setting up some row locks that will block transactions +# A and B from executing, allowing C to run first. + +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +BEGIN; +INSERT INTO t3 VALUES (2,102); +--connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +BEGIN; +INSERT INTO t3 VALUES (4,104); + +# On the master, queue three INSERT transactions as a single group commit. +--connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (2, foo(12, + 'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (4, foo(14, + 'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connect (con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (6, foo(16, + 'group_commit_waiting_for_prior SIGNAL slave_queued3', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; +SET debug_sync='RESET'; + +--connection server_1 +SELECT * FROM t3 ORDER BY a; +--let $binlog_file= master-bin.000001 +--source include/show_binlog_events.inc + +# First, wait until insert 3 is ready to queue up for group commit, but is +# waiting for insert 2 to commit before it can do so itself. +--connection server_2 +SET debug_sync='now WAIT_FOR slave_queued3'; + +# Next, let insert 1 proceed, and allow it to queue up as the group commit +# leader, but let it wait for insert 2 to also queue up before proceeding. +--connection con_temp1 +ROLLBACK; +--connection server_2 +SET debug_sync='now WAIT_FOR slave_queued1'; + +# Now let insert 2 proceed and queue up. +--connection con_temp2 +ROLLBACK; +--connection server_2 +SET debug_sync='now WAIT_FOR slave_queued2'; +# And finally, we can let insert 1 proceed and do the group commit with all +# three insert transactions together. +SET debug_sync='now SIGNAL slave_cont1'; + +# Wait for the commit to complete and check that all three transactions +# group-committed together (will be seen in the binlog as all three having +# cid=# on their GTID event). +--let $wait_condition= SELECT COUNT(*) = 3 FROM t3 WHERE a IN (2,4,6) +--source include/wait_condition.inc +SELECT * FROM t3 ORDER BY a; +--let $binlog_file= slave-bin.000001 +--source include/show_binlog_events.inc + + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP function foo; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_slave_bgc_kill.inc b/mysql-test/suite/rpl/include/rpl_parallel_slave_bgc_kill.inc new file mode 100644 index 00000000000..a78dbad052f --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_slave_bgc_kill.inc @@ -0,0 +1,454 @@ +--echo *** Test killing slave threads at various wait points *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +# Test various aspects of parallel replication. + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +--connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +# Use a stored function to inject a debug_sync into the appropriate THD. +# The function does nothing on the master, and on the slave it injects the +# desired debug_sync action(s). +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_2 +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--echo *** 1. Test killing transaction waiting in commit for previous transaction to commit *** + +# Set up three transactions on the master that will be group-committed +# together so they can be replicated in parallel on the slave. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send INSERT INTO t3 VALUES (31, foo(31, + 'commit_before_prepare_ordered WAIT_FOR t2_waiting', + 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +# This insert is just so we can get T2 to wait while a query is running that we +# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. +INSERT INTO t3 VALUES (32, foo(32, + 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', + '')); +# This insert sets up debug_sync points so that T2 will tell when it is at its +# wait point where we want to kill it - and when it has been killed. +INSERT INTO t3 VALUES (33, foo(33, + 'group_commit_waiting_for_prior SIGNAL t2_waiting', + 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp5 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +send INSERT INTO t3 VALUES (34, foo(34, + '', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +CALL mtr.add_suppression("Slave: Connection was killed"); +SET sql_log_bin=1; +# Wait until T2 is inside executing its insert of 32, then find it in SHOW +# PROCESSLIST to know its thread id for KILL later. +SET debug_sync='now WAIT_FOR t2_query'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(32%' AND INFO NOT LIKE '%LIKE%'` +SET debug_sync='now SIGNAL t2_cont'; + +# Wait until T2 has entered its wait for T1 to commit, and T1 has +# progressed into its commit phase. +SET debug_sync='now WAIT_FOR t1_ready'; + +# Now kill the transaction T2. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +# Wait until T2 has reacted on the kill. +SET debug_sync='now WAIT_FOR t2_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--source include/wait_for_slave_sql_error.inc +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +INSERT INTO t3 VALUES (39,0); +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--source include/start_slave.inc + + +--echo *** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** + +# Set up three transactions on the master that will be group-committed +# together so they can be replicated in parallel on the slave. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send INSERT INTO t3 VALUES (41, foo(41, + 'commit_before_prepare_ordered WAIT_FOR t2_waiting', + 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +# This insert is just so we can get T2 to wait while a query is running that we +# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. +INSERT INTO t3 VALUES (42, foo(42, + 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', + '')); +# This insert sets up debug_sync points so that T2 will tell when it is at its +# wait point where we want to kill it - and when it has been killed. +INSERT INTO t3 VALUES (43, foo(43, + 'group_commit_waiting_for_prior SIGNAL t2_waiting', + 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp5 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +send INSERT INTO t3 VALUES (44, foo(44, + '', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +# Wait until T2 is inside executing its insert of 42, then find it in SHOW +# PROCESSLIST to know its thread id for KILL later. +SET debug_sync='now WAIT_FOR t2_query'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(42%' AND INFO NOT LIKE '%LIKE%'` +SET debug_sync='now SIGNAL t2_cont'; + +# Wait until T2 has entered its wait for T1 to commit, and T1 has +# progressed into its commit phase. +SET debug_sync='now WAIT_FOR t1_ready'; + +# Now kill the transaction T2. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +# Wait until T2 has reacted on the kill. +SET debug_sync='now WAIT_FOR t2_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--source include/wait_for_slave_sql_error.inc + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +INSERT INTO t3 VALUES (49,0); +--save_master_pos + +--connection server_2 +START SLAVE SQL_THREAD; +--sync_with_master +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--source include/start_slave.inc + + +--echo *** 3. Same as (2), but not using gtid mode *** + +--connection server_2 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +--source include/start_slave.inc + +--connection server_1 +# Set up three transactions on the master that will be group-committed +# together so they can be replicated in parallel on the slave. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send INSERT INTO t3 VALUES (51, foo(51, + 'commit_before_prepare_ordered WAIT_FOR t2_waiting', + 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +# This insert is just so we can get T2 to wait while a query is running that we +# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. +INSERT INTO t3 VALUES (52, foo(52, + 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', + '')); +# This insert sets up debug_sync points so that T2 will tell when it is at its +# wait point where we want to kill it - and when it has been killed. +INSERT INTO t3 VALUES (53, foo(53, + 'group_commit_waiting_for_prior SIGNAL t2_waiting', + 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp5 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +send INSERT INTO t3 VALUES (54, foo(54, + '', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +# Wait until T2 is inside executing its insert of 52, then find it in SHOW +# PROCESSLIST to know its thread id for KILL later. +SET debug_sync='now WAIT_FOR t2_query'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(52%' AND INFO NOT LIKE '%LIKE%'` +SET debug_sync='now SIGNAL t2_cont'; + +# Wait until T2 has entered its wait for T1 to commit, and T1 has +# progressed into its commit phase. +SET debug_sync='now WAIT_FOR t1_ready'; + +# Now kill the transaction T2. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +# Wait until T2 has reacted on the kill. +SET debug_sync='now WAIT_FOR t2_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--source include/wait_for_slave_sql_error.inc +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +INSERT INTO t3 VALUES (59,0); +--save_master_pos + +--connection server_2 +START SLAVE SQL_THREAD; +--sync_with_master +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP function foo; +DROP TABLE t1,t2,t3; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_stop_on_con_kill.inc b/mysql-test/suite/rpl/include/rpl_parallel_stop_on_con_kill.inc new file mode 100644 index 00000000000..63c483ea6ad --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_stop_on_con_kill.inc @@ -0,0 +1,129 @@ +--echo *** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (201,0), (202,0); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_mdev8031'; + +--connection server_1 +# We artificially create a situation that hopefully resembles the original +# bug which was only seen "in the wild", and only once. +# Setup a fake group commit with lots of conflicts that will lead to deadloc +# kill. The slave DBUG injection causes the slave to be deadlock killed at +# a particular point during the retry, and then later do a small sleep at +# another critical point where the prior transaction then has a chance to +# complete. Finally an extra KILL check catches an unhandled, lingering +# deadlock kill. So rather artificial, but at least it exercises the +# relevant code paths. +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +SET @commit_id= 10200; +INSERT INTO t3 VALUES (203, 1); +INSERT INTO t3 VALUES (204, 1); +INSERT INTO t3 VALUES (205, 1); +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=205; +UPDATE t3 SET b=b+1 WHERE a=205; +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +--source include/start_slave.inc + + +--echo *** Check getting deadlock killed inside open_binlog() during retry. *** + +--connection server_2 +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; +SET @old_max= @@GLOBAL.max_relay_log_size; +SET GLOBAL max_relay_log_size= 4096; + +--connection server_1 +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +--let $large= `SELECT REPEAT("*", 8192)` +SET @commit_id= 10210; +--echo Omit long queries that cause relaylog rotations and transaction retries... +--disable_query_log +eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=205 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=205 /* $large */; +--enable_query_log +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; + +# Cleanup +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_debg; +SET GLOBAL max_relay_log_size= @old_max; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t3; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/include/rpl_parallel_stop_slave.inc b/mysql-test/suite/rpl/include/rpl_parallel_stop_slave.inc new file mode 100644 index 00000000000..4eeddc927e0 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_stop_slave.inc @@ -0,0 +1,114 @@ +--echo *** Test STOP SLAVE in parallel mode *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; + +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +--connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +--connection server_1 +# Set up a couple of transactions. The first will be blocked halfway +# through on a lock, and while it is blocked we initiate STOP SLAVE. +# We then test that the halfway-initiated transaction is allowed to +# complete, but no subsequent ones. +# We have to use statement-based mode and set +# binlog_direct_non_transactional_updates=0; otherwise the binlog will +# be split into two event groups, one for the MyISAM part and one for the +# InnoDB part. +SET binlog_direct_non_transactional_updates=0; +SET sql_log_bin=0; +CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); +SET sql_log_bin=1; +BEGIN; +INSERT INTO t2 VALUES (20); +--disable_warnings +INSERT INTO t1 VALUES (20); +--enable_warnings +INSERT INTO t2 VALUES (21); +INSERT INTO t3 VALUES (20, 20); +COMMIT; +INSERT INTO t3 VALUES(21, 21); +INSERT INTO t3 VALUES(22, 22); +--save_master_pos + +# Start a connection that will block the replicated transaction halfway. +--connection con_temp1 +BEGIN; +INSERT INTO t2 VALUES (21); + +--connection server_2 +START SLAVE; +# Wait for the MyISAM change to be visible, after which replication will wait +# for con_temp1 to roll back. +--let $wait_condition= SELECT COUNT(*) = 1 FROM t1 WHERE a=20 +--source include/wait_condition.inc + +--connection con_temp2 +# Initiate slave stop. It will have to wait for the current event group +# to complete. +# The dbug injection causes debug_sync to signal 'wait_for_done_waiting' +# when the SQL driver thread is ready. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +send STOP SLAVE; + +--connection con_temp1 +SET debug_sync='now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; + +--connection con_temp2 +reap; +SET GLOBAL debug_dbug=@old_dbug; +SET debug_sync='RESET'; + +--connection server_2 +--source include/wait_for_slave_to_stop.inc +# We should see the first transaction applied, but not the two others. +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; + +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +--disconnect con_temp1 +--disconnect con_temp2 + +--connection server_1 +DROP TABLE t1,t2,t3; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_wrong_binlog_order.inc b/mysql-test/suite/rpl/include/rpl_parallel_wrong_binlog_order.inc new file mode 100644 index 00000000000..093693d453e --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_wrong_binlog_order.inc @@ -0,0 +1,91 @@ +--echo *** MDEV-6775: Wrong binlog order in parallel replication *** + +# A bit tricky bug to reproduce. On the master, we binlog in statement-mode +# two transactions, an UPDATE followed by a DELETE. On the slave, we replicate +# with binlog-mode set to ROW, which means the DELETE, which modifies no rows, +# is not binlogged. Then we inject a wait in the group commit code on the +# slave, shortly before the actual commit of the UPDATE. The bug was that the +# DELETE could wake up from wait_for_prior_commit() before the commit of the +# UPDATE. So the test could see the slave position updated to after DELETE, +# while the UPDATE was still not visible. + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB; +INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=ROW; +# Re-spawn the worker threads to be sure they pick up the new binlog format +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; + +--connection con1 +SET @old_format= @@binlog_format; +SET binlog_format= statement; +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 @old_format= @@binlog_format; +SET binlog_format= statement; +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; +SET binlog_format= @old_format; +--connection con2 +REAP; +SET binlog_format= @old_format; +SET debug_sync='RESET'; +--save_master_pos +SELECT * FROM t4 ORDER BY a; + +--connection server_2 +--source include/start_slave.inc +SET debug_sync= 'now WAIT_FOR waiting'; +--sync_with_master +SELECT * FROM t4 ORDER BY a; +SET debug_sync= 'now SIGNAL cont'; + +# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL binlog_format= @old_format; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +--disconnect con1 +--disconnect con2 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_parallel_wrong_exec_master_pos.inc b/mysql-test/suite/rpl/include/rpl_parallel_wrong_exec_master_pos.inc new file mode 100644 index 00000000000..672ade57ca3 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_wrong_exec_master_pos.inc @@ -0,0 +1,56 @@ +--echo *** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t5 (a INT PRIMARY KEY, b INT); +INSERT INTO t5 VALUES (1,1); +INSERT INTO t5 VALUES (2,2), (3,8); +INSERT INTO t5 VALUES (4,16); +--save_master_pos + +--connection server_2 +--sync_with_master +let $io_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1); +let $io_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); +let $sql_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1); +let $sql_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval SELECT IF('$io_file' = '$sql_file', "OK", "Not ok, $io_file <> $sql_file") AS test_check; +eval SELECT IF('$io_pos' = '$sql_pos', "OK", "Not ok, $io_pos <> $sql_pos") AS test_check; +--enable_query_log + +--connection server_1 +FLUSH LOGS; +--source include/wait_for_binlog_checkpoint.inc +--save_master_pos + +--connection server_2 +--sync_with_master +let $io_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1); +let $io_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); +let $sql_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1); +let $sql_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval SELECT IF('$io_file' = '$sql_file', "OK", "Not ok, $io_file <> $sql_file") AS test_check; +eval SELECT IF('$io_pos' = '$sql_pos', "OK", "Not ok, $io_pos <> $sql_pos") AS test_check; +--enable_query_log + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t5; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_delayed_slave.result b/mysql-test/suite/rpl/r/rpl_delayed_slave.result index bcfd49934b4..e7daa3328ce 100644 --- a/mysql-test/suite/rpl/r/rpl_delayed_slave.result +++ b/mysql-test/suite/rpl/r/rpl_delayed_slave.result @@ -185,7 +185,7 @@ DROP FUNCTION delay_on_slave; connection slave; SELECT @@GLOBAL.slave_parallel_mode; @@GLOBAL.slave_parallel_mode -conservative +optimistic SELECT @@GLOBAL.slave_parallel_threads; @@GLOBAL.slave_parallel_threads 0 diff --git a/mysql-test/suite/rpl/r/rpl_mdev6386.result b/mysql-test/suite/rpl/r/rpl_mdev6386.result index 91ba9569343..d0e5144857a 100644 --- a/mysql-test/suite/rpl/r/rpl_mdev6386.result +++ b/mysql-test/suite/rpl/r/rpl_mdev6386.result @@ -7,6 +7,7 @@ connection slave; connection slave; include/stop_slave.inc SET sql_log_bin= 0; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); INSERT INTO t1 VALUES (1, 2); SET sql_log_bin= 1; CHANGE MASTER TO master_use_gtid= current_pos; diff --git a/mysql-test/suite/rpl/r/rpl_parallel.result b/mysql-test/suite/rpl/r/rpl_parallel.result deleted file mode 100644 index 9258deadaca..00000000000 --- a/mysql-test/suite/rpl/r/rpl_parallel.result +++ /dev/null @@ -1,1690 +0,0 @@ -include/master-slave.inc -[connection master] -connection server_2; -SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; -SET GLOBAL slave_parallel_threads=10; -ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=10; -SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) -OK -CHANGE MASTER TO master_use_gtid=slave_pos; -include/start_slave.inc -SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) -OK -include/stop_slave.inc -SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) -OK -include/start_slave.inc -SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; -IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) -OK -*** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** -connection server_1; -ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; -CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; -CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1); -INSERT INTO t2 VALUES (1); -connection server_2; -connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; -LOCK TABLE t1 WRITE; -connection server_1; -SET gtid_domain_id=1; -INSERT INTO t1 VALUES (2); -SET gtid_domain_id=0; -INSERT INTO t2 VALUES (2); -INSERT INTO t2 VALUES (3); -BEGIN; -INSERT INTO t2 VALUES (4); -INSERT INTO t2 VALUES (5); -COMMIT; -INSERT INTO t2 VALUES (6); -connection server_2; -SELECT * FROM t2 ORDER by a; -a -1 -2 -3 -4 -5 -6 -connection con_temp1; -SELECT * FROM t1; -a -1 -UNLOCK TABLES; -connection server_2; -SELECT * FROM t1 ORDER BY a; -a -1 -2 -*** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** -connection server_2; -include/stop_slave.inc -connection server_1; -SET sql_log_bin=0; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format='statement'; -SET gtid_domain_id=1; -INSERT INTO t2 VALUES (foo(10, -'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); -connection server_2; -FLUSH LOGS; -SET sql_log_bin=0; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -SET @old_format=@@GLOBAL.binlog_format; -SET GLOBAL binlog_format=statement; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -SET debug_sync='now WAIT_FOR ready1'; -connection server_1; -SET gtid_domain_id=2; -INSERT INTO t2 VALUES (foo(11, -'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); -SET gtid_domain_id=0; -SELECT * FROM t2 WHERE a >= 10 ORDER BY a; -a -10 -11 -connection server_2; -SET debug_sync='now WAIT_FOR ready3'; -SET debug_sync='now SIGNAL cont3'; -SET debug_sync='now WAIT_FOR ready4'; -SET debug_sync='now SIGNAL cont1'; -SET debug_sync='now WAIT_FOR ready2'; -SET debug_sync='now SIGNAL cont4'; -SELECT * FROM t2 WHERE a >= 10 ORDER BY a; -a -10 -11 -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 -slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(11, -'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')) -slave-bin.000002 # Xid # # COMMIT /* XID */ -slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(10, -'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', -'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')) -slave-bin.000002 # Xid # # COMMIT /* XID */ -FLUSH LOGS; -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET debug_sync='RESET'; -include/start_slave.inc -*** Test that group-committed transactions on the master can replicate in parallel on the slave. *** -connection server_1; -SET debug_sync='RESET'; -FLUSH LOGS; -CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; -INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); -connection server_2; -connection con_temp1; -BEGIN; -INSERT INTO t3 VALUES (2,102); -connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; -BEGIN; -INSERT INTO t3 VALUES (4,104); -connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (2, foo(12, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (4, foo(14, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (6, foo(16, -'group_commit_waiting_for_prior SIGNAL slave_queued3', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -SET debug_sync='RESET'; -connection server_1; -SELECT * FROM t3 ORDER BY a; -a b -1 1 -2 12 -3 3 -4 14 -5 5 -6 16 -7 7 -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000002 # Binlog_checkpoint # # master-bin.000002 -master-bin.000002 # Gtid # # GTID #-#-# -master-bin.000002 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB -master-bin.000002 # Gtid # # BEGIN GTID #-#-# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) -master-bin.000002 # Xid # # COMMIT /* XID */ -master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', -'')) -master-bin.000002 # Xid # # COMMIT /* XID */ -master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', -'')) -master-bin.000002 # Xid # # COMMIT /* XID */ -master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# -master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, -'group_commit_waiting_for_prior SIGNAL slave_queued3', -'')) -master-bin.000002 # Xid # # COMMIT /* XID */ -connection server_2; -SET debug_sync='now WAIT_FOR slave_queued3'; -connection con_temp1; -ROLLBACK; -connection server_2; -SET debug_sync='now WAIT_FOR slave_queued1'; -connection con_temp2; -ROLLBACK; -connection server_2; -SET debug_sync='now WAIT_FOR slave_queued2'; -SET debug_sync='now SIGNAL slave_cont1'; -SELECT * FROM t3 ORDER BY a; -a b -1 1 -2 12 -3 3 -4 14 -5 5 -6 16 -7 7 -include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000003 # Binlog_checkpoint # # slave-bin.000003 -slave-bin.000003 # Gtid # # GTID #-#-# -slave-bin.000003 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) -slave-bin.000003 # Xid # # COMMIT /* XID */ -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', -'')) -slave-bin.000003 # Xid # # COMMIT /* XID */ -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, -'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', -'')) -slave-bin.000003 # Xid # # COMMIT /* XID */ -slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# -slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, -'group_commit_waiting_for_prior SIGNAL slave_queued3', -'')) -slave-bin.000003 # Xid # # COMMIT /* XID */ -*** Test STOP SLAVE in parallel mode *** -connection server_2; -include/stop_slave.inc -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -connection server_1; -SET binlog_direct_non_transactional_updates=0; -SET sql_log_bin=0; -CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); -SET sql_log_bin=1; -BEGIN; -INSERT INTO t2 VALUES (20); -INSERT INTO t1 VALUES (20); -INSERT INTO t2 VALUES (21); -INSERT INTO t3 VALUES (20, 20); -COMMIT; -INSERT INTO t3 VALUES(21, 21); -INSERT INTO t3 VALUES(22, 22); -SET binlog_format=@old_format; -connection con_temp1; -BEGIN; -INSERT INTO t2 VALUES (21); -connection server_2; -START SLAVE; -connection con_temp2; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; -STOP SLAVE; -connection con_temp1; -SET debug_sync='now WAIT_FOR wait_for_done_waiting'; -ROLLBACK; -connection con_temp2; -SET GLOBAL debug_dbug=@old_dbug; -SET debug_sync='RESET'; -connection server_2; -include/wait_for_slave_to_stop.inc -SELECT * FROM t1 WHERE a >= 20 ORDER BY a; -a -20 -SELECT * FROM t2 WHERE a >= 20 ORDER BY a; -a -20 -21 -SELECT * FROM t3 WHERE a >= 20 ORDER BY a; -a b -20 20 -include/start_slave.inc -SELECT * FROM t1 WHERE a >= 20 ORDER BY a; -a -20 -SELECT * FROM t2 WHERE a >= 20 ORDER BY a; -a -20 -21 -SELECT * FROM t3 WHERE a >= 20 ORDER BY a; -a b -20 20 -21 21 -22 22 -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** Test killing slave threads at various wait points *** -*** 1. Test killing transaction waiting in commit for previous transaction to commit *** -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (31, foo(31, -'commit_before_prepare_ordered WAIT_FOR t2_waiting', -'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -INSERT INTO t3 VALUES (32, foo(32, -'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', -'')); -INSERT INTO t3 VALUES (33, foo(33, -'group_commit_waiting_for_prior SIGNAL t2_waiting', -'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -COMMIT; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (34, foo(34, -'', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -a b -31 31 -32 32 -33 33 -34 34 -SET debug_sync='RESET'; -connection server_2; -SET sql_log_bin=0; -CALL mtr.add_suppression("Query execution was interrupted"); -CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); -CALL mtr.add_suppression("Slave: Connection was killed"); -SET sql_log_bin=1; -SET debug_sync='now WAIT_FOR t2_query'; -SET debug_sync='now SIGNAL t2_cont'; -SET debug_sync='now WAIT_FOR t1_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t2_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -STOP SLAVE IO_THREAD; -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -a b -31 31 -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -INSERT INTO t3 VALUES (39,0); -connection server_2; -include/start_slave.inc -SELECT * FROM t3 WHERE a >= 30 ORDER BY a; -a b -31 31 -32 32 -33 33 -34 34 -39 0 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (41, foo(41, -'commit_before_prepare_ordered WAIT_FOR t2_waiting', -'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -INSERT INTO t3 VALUES (42, foo(42, -'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', -'')); -INSERT INTO t3 VALUES (43, foo(43, -'group_commit_waiting_for_prior SIGNAL t2_waiting', -'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -COMMIT; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (44, foo(44, -'', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 40 ORDER BY a; -a b -41 41 -42 42 -43 43 -44 44 -SET debug_sync='RESET'; -connection server_2; -SET debug_sync='now WAIT_FOR t2_query'; -SET debug_sync='now SIGNAL t2_cont'; -SET debug_sync='now WAIT_FOR t1_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t2_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -INSERT INTO t3 VALUES (49,0); -connection server_2; -START SLAVE SQL_THREAD; -SELECT * FROM t3 WHERE a >= 40 ORDER BY a; -a b -41 41 -42 42 -43 43 -44 44 -49 0 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** 3. Same as (2), but not using gtid mode *** -connection server_2; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; -include/start_slave.inc -connection server_1; -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (51, foo(51, -'commit_before_prepare_ordered WAIT_FOR t2_waiting', -'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -SET binlog_format=statement; -BEGIN; -INSERT INTO t3 VALUES (52, foo(52, -'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', -'')); -INSERT INTO t3 VALUES (53, foo(53, -'group_commit_waiting_for_prior SIGNAL t2_waiting', -'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); -COMMIT; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -SET binlog_format=statement; -INSERT INTO t3 VALUES (54, foo(54, -'', -'')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -a b -51 51 -52 52 -53 53 -54 54 -SET debug_sync='RESET'; -connection server_2; -SET debug_sync='now WAIT_FOR t2_query'; -SET debug_sync='now SIGNAL t2_cont'; -SET debug_sync='now WAIT_FOR t1_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t2_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -a b -51 51 -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -INSERT INTO t3 VALUES (59,0); -connection server_2; -START SLAVE SQL_THREAD; -SELECT * FROM t3 WHERE a >= 50 ORDER BY a; -a b -51 51 -52 52 -53 53 -54 54 -59 0 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=slave_pos; -include/start_slave.inc -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=4; -include/start_slave.inc -*** 4. Test killing thread that is waiting to start transaction until previous transaction commits *** -connection server_1; -SET binlog_format=statement; -SET gtid_domain_id=2; -BEGIN; -INSERT INTO t3 VALUES (70, foo(70, -'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); -INSERT INTO t3 VALUES (60, foo(60, -'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', -'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); -COMMIT; -SET gtid_domain_id=0; -connection server_2; -SET debug_sync='now WAIT_FOR d2_query'; -connection server_1; -SET gtid_domain_id=1; -BEGIN; -INSERT INTO t3 VALUES (61, foo(61, -'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', -'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); -INSERT INTO t3 VALUES (62, foo(62, -'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', -'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); -COMMIT; -SET gtid_domain_id=0; -connection server_2; -SET debug_sync='now WAIT_FOR d1_query'; -connection server_1; -SET gtid_domain_id=0; -INSERT INTO t3 VALUES (63, foo(63, -'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', -'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); -connection server_2; -SET debug_sync='now WAIT_FOR d0_query'; -connection server_1; -SET gtid_domain_id=3; -BEGIN; -INSERT INTO t3 VALUES (68, foo(68, -'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); -INSERT INTO t3 VALUES (69, foo(69, -'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', -'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); -COMMIT; -SET gtid_domain_id=0; -connection server_2; -SET debug_sync='now WAIT_FOR d3_query'; -SET debug_sync='now SIGNAL d2_cont2'; -SET debug_sync='now WAIT_FOR d2_done'; -SET debug_sync='now SIGNAL d1_cont2'; -SET debug_sync='now WAIT_FOR d1_done'; -SET debug_sync='now SIGNAL d0_cont2'; -SET debug_sync='now WAIT_FOR d0_done'; -SET debug_sync='now SIGNAL d3_cont2'; -SET debug_sync='now WAIT_FOR d3_done'; -connection con_temp3; -SET binlog_format=statement; -INSERT INTO t3 VALUES (64, foo(64, -'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; -INSERT INTO t3 VALUES (65, foo(65, '', '')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; -INSERT INTO t3 VALUES (66, foo(66, '', '')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued3'; -connection con_temp5; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; -INSERT INTO t3 VALUES (67, foo(67, '', '')); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued4'; -SET debug_sync='now SIGNAL master_cont2'; -connection con_temp3; -connection con_temp4; -connection con_temp5; -connection server_1; -SELECT * FROM t3 WHERE a >= 60 ORDER BY a; -a b -60 60 -61 61 -62 62 -63 63 -64 64 -65 65 -66 66 -67 67 -68 68 -69 69 -70 70 -SET debug_sync='RESET'; -connection server_2; -SET debug_sync='now SIGNAL d0_cont'; -SET debug_sync='now WAIT_FOR t1_waiting'; -SET debug_sync='now SIGNAL d3_cont'; -SET debug_sync='now WAIT_FOR t2_waiting'; -SET debug_sync='now SIGNAL d1_cont'; -SET debug_sync='now WAIT_FOR t3_waiting'; -SET debug_sync='now SIGNAL d2_cont'; -SET debug_sync='now WAIT_FOR t4_waiting'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR t3_killed'; -SET debug_sync='now SIGNAL t1_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -STOP SLAVE IO_THREAD; -SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; -a b -60 60 -61 61 -62 62 -63 63 -64 64 -68 68 -69 69 -70 70 -SET debug_sync='RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_1; -UPDATE t3 SET b=b+1 WHERE a=60; -connection server_2; -include/start_slave.inc -SELECT * FROM t3 WHERE a >= 60 ORDER BY a; -a b -60 61 -61 61 -62 62 -63 63 -64 64 -65 65 -66 66 -67 67 -68 68 -69 69 -70 70 -SET sql_log_bin=0; -DROP FUNCTION foo; -CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) -RETURNS INT DETERMINISTIC -BEGIN -IF d1 != '' THEN -SET debug_sync = d1; -END IF; -IF d2 != '' THEN -SET debug_sync = d2; -END IF; -RETURN x; -END -|| -SET sql_log_bin=1; -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** 5. Test killing thread that is waiting for queue of max length to shorten *** -SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; -SET GLOBAL slave_parallel_max_queued=9000; -connection server_1; -SET binlog_format=statement; -INSERT INTO t3 VALUES (80, foo(0, -'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); -connection server_2; -SET debug_sync='now WAIT_FOR query_waiting'; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; -connection server_1; -SELECT * FROM t3 WHERE a >= 80 ORDER BY a; -a b -80 0 -81 10000 -connection server_2; -SET debug_sync='now WAIT_FOR wait_queue_ready'; -KILL THD_ID; -SET debug_sync='now WAIT_FOR wait_queue_killed'; -SET debug_sync='now SIGNAL query_cont'; -include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] -STOP SLAVE IO_THREAD; -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_max_queued= @old_max_queued; -connection server_1; -INSERT INTO t3 VALUES (82,0); -SET binlog_format=@old_format; -connection server_2; -SET debug_sync='RESET'; -include/start_slave.inc -SELECT * FROM t3 WHERE a >= 80 ORDER BY a; -a b -80 0 -81 10000 -82 0 -connection server_2; -include/stop_slave.inc -SET GLOBAL binlog_format=@old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL replicate_ignore_table="test.t3"; -SET GLOBAL slave_parallel_threads=2; -include/start_slave.inc -connection server_1; -INSERT INTO t3 VALUES (100, rand()); -INSERT INTO t3 VALUES (101, rand()); -connection server_2; -connection server_1; -INSERT INTO t3 VALUES (102, rand()); -INSERT INTO t3 VALUES (103, rand()); -INSERT INTO t3 VALUES (104, rand()); -INSERT INTO t3 VALUES (105, rand()); -connection server_2; -include/stop_slave.inc -SET GLOBAL replicate_ignore_table=""; -include/start_slave.inc -connection server_1; -INSERT INTO t3 VALUES (106, rand()); -INSERT INTO t3 VALUES (107, rand()); -connection server_2; -SELECT * FROM t3 WHERE a >= 100 ORDER BY a; -a b -106 # -107 # -*** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -connection server_1; -INSERT INTO t3 VALUES (110, 1); -connection server_2; -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -a b -110 1 -SET sql_log_bin=0; -INSERT INTO t3 VALUES (111, 666); -SET sql_log_bin=1; -connection server_1; -connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -INSERT INTO t3 VALUES (111, 2); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -INSERT INTO t3 VALUES (112, 3); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -SET debug_sync='now SIGNAL master_cont1'; -connection con1; -connection con2; -SET debug_sync='RESET'; -connection server_2; -include/wait_for_slave_sql_error.inc [errno=1062] -include/wait_for_slave_sql_to_stop.inc -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -a b -110 1 -111 666 -SET sql_log_bin=0; -DELETE FROM t3 WHERE a=111 AND b=666; -SET sql_log_bin=1; -START SLAVE SQL_THREAD; -SELECT * FROM t3 WHERE a >= 110 ORDER BY a; -a b -110 1 -111 2 -112 3 -***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts *** -connection server_2; -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); -connection con1; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -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'; -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; -connection con2; -SET debug_sync='RESET'; -connection server_2; -include/start_slave.inc -include/stop_slave.inc -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 NULL -connection server_1; -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); -connection con1; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -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'; -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; -connection con2; -SET debug_sync='RESET'; -connection server_2; -include/start_slave.inc -include/stop_slave.inc -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 6 -7 NULL -connection server_1; -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); -connection con1; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -UPDATE t4 SET b=NULL WHERE a=6; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con2; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format='statement'; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -DELETE FROM t4 WHERE b <= 1; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -SET debug_sync='now SIGNAL master_cont1'; -connection con1; -connection con2; -SET @old_format=@@GLOBAL.binlog_format; -SET debug_sync='RESET'; -connection server_2; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; -include/start_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -2 2 -3 NULL -4 4 -5 NULL -6 NULL -SET @last_gtid= 'GTID'; -SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", -CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) -AS result; -result -GTID found ok -SELECT "ROW FOUND" AS `Is the row found?` - FROM mysql.gtid_slave_pos -WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; -Is the row found? -ROW FOUND -*** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=1; -SET DEBUG_SYNC= 'RESET'; -include/start_slave.inc -connection server_1; -CREATE TABLE t5 (a INT PRIMARY KEY, b INT); -INSERT INTO t5 VALUES (1,1); -INSERT INTO t5 VALUES (2,2), (3,8); -INSERT INTO t5 VALUES (4,16); -connection server_2; -test_check -OK -test_check -OK -connection server_1; -FLUSH LOGS; -connection server_2; -test_check -OK -test_check -OK -*** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** -connection server_1; -CREATE TABLE t6 (a INT) ENGINE=MyISAM; -CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; -connection con1; -SET @old_format= @@binlog_format; -SET binlog_format= statement; -SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; -INSERT INTO t6 VALUES (1), (2), (3); -connection server_1; -SET debug_sync='now WAIT_FOR ready'; -KILL QUERY CONID; -SET debug_sync='now SIGNAL cont'; -connection con1; -ERROR 70100: Query execution was interrupted -SET binlog_format= @old_format; -SET debug_sync='RESET'; -connection server_1; -SET debug_sync='RESET'; -connection server_2; -include/wait_for_slave_sql_error.inc [errno=1317] -STOP SLAVE IO_THREAD; -SET GLOBAL gtid_slave_pos= 'AFTER_ERROR_GTID_POS'; -include/start_slave.inc -connection server_1; -INSERT INTO t6 VALUES (4); -SELECT * FROM t6 ORDER BY a; -a -1 -4 -connection server_2; -SELECT * FROM t6 ORDER BY a; -a -4 -*** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** -connection server_1; -INSERT INTO t2 VALUES (31); -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -include/stop_slave.inc -SET GLOBAL slave_parallel_threads= 0; -include/start_slave.inc -SET sql_log_bin= 0; -INSERT INTO t2 VALUES (32); -SET sql_log_bin= 1; -connection server_1; -INSERT INTO t2 VALUES (32); -FLUSH LOGS; -INSERT INTO t2 VALUES (33); -INSERT INTO t2 VALUES (34); -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; -a -31 -32 -33 -34 -include/save_master_gtid.inc -connection server_2; -include/wait_for_slave_sql_error.inc [errno=1062] -connection server_2; -include/stop_slave_io.inc -SET GLOBAL slave_parallel_threads=10; -START SLAVE; -include/wait_for_slave_sql_error.inc [errno=1062] -START SLAVE SQL_THREAD; -include/wait_for_slave_sql_error.inc [errno=1062] -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; -a -31 -32 -SET sql_slave_skip_counter= 1; -ERROR HY000: When using parallel replication and GTID with multiple replication domains, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position -include/stop_slave_io.inc -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 30 ORDER BY a; -a -31 -32 -33 -34 -*** MDEV-6775: Wrong binlog order in parallel replication *** -connection server_1; -DELETE FROM t4; -INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; -SET @old_format=@@GLOBAL.binlog_format; -SET GLOBAL binlog_format=ROW; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -connection con1; -SET @old_format= @@binlog_format; -SET binlog_format= statement; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -UPDATE t4 SET b=NULL WHERE a=6; -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con2; -SET @old_format= @@binlog_format; -SET binlog_format= statement; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -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; -SET binlog_format= @old_format; -connection con2; -SET binlog_format= @old_format; -SET debug_sync='RESET'; -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 NULL -connection server_2; -include/start_slave.inc -SET debug_sync= 'now WAIT_FOR waiting'; -SELECT * FROM t4 ORDER BY a; -a b -1 NULL -3 NULL -4 4 -5 NULL -6 NULL -SET debug_sync= 'now SIGNAL cont'; -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL binlog_format= @old_format; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** -connection server_1; -INSERT INTO t2 VALUES (40); -connection server_2; -include/stop_slave.inc -CHANGE MASTER TO master_use_gtid=no; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; -SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -connection server_1; -INSERT INTO t2 VALUES (41); -INSERT INTO t2 VALUES (42); -SET @old_format= @@binlog_format; -SET binlog_format= statement; -DELETE FROM t2 WHERE a=40; -SET binlog_format= @old_format; -INSERT INTO t2 VALUES (43); -INSERT INTO t2 VALUES (44); -FLUSH LOGS; -INSERT INTO t2 VALUES (45); -SET gtid_seq_no=100; -INSERT INTO t2 VALUES (46); -connection con_temp2; -BEGIN; -SELECT * FROM t2 WHERE a=40 FOR UPDATE; -a -40 -connection server_2; -include/start_slave.inc -SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; -STOP SLAVE; -connection con_temp2; -SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; -ROLLBACK; -connection server_2; -include/wait_for_slave_sql_to_stop.inc -SELECT * FROM t2 WHERE a >= 40 ORDER BY a; -a -41 -42 -include/start_slave.inc -SELECT * FROM t2 WHERE a >= 40 ORDER BY a; -a -41 -42 -43 -44 -45 -46 -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET DEBUG_SYNC= 'RESET'; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -CHANGE MASTER TO master_use_gtid=slave_pos; -include/start_slave.inc -*** MDEV-7326 Server deadlock in connection with parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=3; -SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; -include/start_slave.inc -connection server_1; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format= STATEMENT; -INSERT INTO t1 VALUES (foo(50, -"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", -"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; -connection server_1; -INSERT INTO t2 VALUES (foo(50, -"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", -"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; -connection server_1; -INSERT INTO t1 VALUES (foo(51, -"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", -"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; -SET DEBUG_SYNC= "now SIGNAL t1_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; -connection server_1; -INSERT INTO t1 VALUES (52); -SET BINLOG_FORMAT= @old_format; -SELECT * FROM t2 WHERE a>=50 ORDER BY a; -a -50 -SELECT * FROM t1 WHERE a>=50 ORDER BY a; -a -50 -51 -52 -connection server_2; -SET DEBUG_SYNC= "now SIGNAL prep_cont"; -SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; -SET DEBUG_SYNC= "now SIGNAL t2_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; -SET DEBUG_SYNC= "now SIGNAL t1_cont2"; -connection server_1; -connection server_2; -SELECT * FROM t2 WHERE a>=50 ORDER BY a; -a -50 -SELECT * FROM t1 WHERE a>=50 ORDER BY a; -a -50 -51 -52 -SET DEBUG_SYNC="reset"; -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-7326 Server deadlock in connection with parallel replication *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=3; -SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; -include/start_slave.inc -connection server_1; -SET @old_format= @@SESSION.binlog_format; -SET binlog_format= STATEMENT; -INSERT INTO t1 VALUES (foo(60, -"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", -"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; -connection server_1; -INSERT INTO t2 VALUES (foo(60, -"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", -"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; -connection con_temp3; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; -SET binlog_format=statement; -INSERT INTO t1 VALUES (foo(61, -"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", -"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued1'; -connection con_temp4; -SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; -INSERT INTO t6 VALUES (62); -connection server_1; -SET debug_sync='now WAIT_FOR master_queued2'; -SET debug_sync='now SIGNAL master_cont1'; -connection con_temp3; -connection con_temp4; -connection server_1; -SET debug_sync='RESET'; -SET BINLOG_FORMAT= @old_format; -SELECT * FROM t2 WHERE a>=60 ORDER BY a; -a -60 -SELECT * FROM t1 WHERE a>=60 ORDER BY a; -a -60 -61 -SELECT * FROM t6 WHERE a>=60 ORDER BY a; -a -62 -connection server_2; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; -SET DEBUG_SYNC= "now SIGNAL t1_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; -connection server_2; -SET DEBUG_SYNC= "now SIGNAL prep_cont"; -SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; -SET DEBUG_SYNC= "now SIGNAL t2_cont1"; -SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; -SET DEBUG_SYNC= "now SIGNAL t1_cont2"; -connection server_1; -connection server_2; -SELECT * FROM t2 WHERE a>=60 ORDER BY a; -a -60 -SELECT * FROM t1 WHERE a>=60 ORDER BY a; -a -60 -61 -SELECT * FROM t6 WHERE a>=60 ORDER BY a; -a -62 -SET DEBUG_SYNC="reset"; -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=0; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=1; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; -connection server_1; -INSERT INTO t2 VALUES (101); -INSERT INTO t2 VALUES (102); -INSERT INTO t2 VALUES (103); -INSERT INTO t2 VALUES (104); -INSERT INTO t2 VALUES (105); -SET gtid_seq_no=1000; -INSERT INTO t2 VALUES (106); -INSERT INTO t2 VALUES (107); -INSERT INTO t2 VALUES (108); -INSERT INTO t2 VALUES (109); -INSERT INTO t2 VALUES (110); -INSERT INTO t2 VALUES (111); -INSERT INTO t2 VALUES (112); -INSERT INTO t2 VALUES (113); -INSERT INTO t2 VALUES (114); -INSERT INTO t2 VALUES (115); -INSERT INTO t2 VALUES (116); -INSERT INTO t2 VALUES (117); -INSERT INTO t2 VALUES (118); -INSERT INTO t2 VALUES (119); -INSERT INTO t2 VALUES (120); -INSERT INTO t2 VALUES (121); -INSERT INTO t2 VALUES (122); -INSERT INTO t2 VALUES (123); -INSERT INTO t2 VALUES (124); -INSERT INTO t2 VALUES (125); -INSERT INTO t2 VALUES (126); -INSERT INTO t2 VALUES (127); -INSERT INTO t2 VALUES (128); -INSERT INTO t2 VALUES (129); -INSERT INTO t2 VALUES (130); -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 100 ORDER BY a; -a -101 -102 -103 -104 -105 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -SET GLOBAL slave_parallel_threads=10; -include/start_slave.inc -*** MDEV-6676 - test syntax of @@slave_parallel_mode *** -connection server_2; -Parallel_Mode = 'conservative' -include/stop_slave.inc -SET GLOBAL slave_parallel_mode='aggressive'; -Parallel_Mode = 'aggressive' -SET GLOBAL slave_parallel_mode='conservative'; -Parallel_Mode = 'conservative' -*** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** -connection server_1; -INSERT INTO t2 VALUES (1040); -include/save_master_gtid.inc -connection server_2; -SET GLOBAL slave_parallel_mode='none'; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; -a -1040 -include/stop_slave.inc -SET GLOBAL debug_dbug=@old_dbug; -*** MDEV-6676 - test disabling domain-based parallel replication *** -connection server_1; -SET gtid_domain_id = 1; -INSERT INTO t2 VALUES (1041); -INSERT INTO t2 VALUES (1042); -INSERT INTO t2 VALUES (1043); -INSERT INTO t2 VALUES (1044); -INSERT INTO t2 VALUES (1045); -INSERT INTO t2 VALUES (1046); -DELETE FROM t2 WHERE a >= 1041; -SET gtid_domain_id = 2; -INSERT INTO t2 VALUES (1041); -INSERT INTO t2 VALUES (1042); -INSERT INTO t2 VALUES (1043); -INSERT INTO t2 VALUES (1044); -INSERT INTO t2 VALUES (1045); -INSERT INTO t2 VALUES (1046); -SET gtid_domain_id = 0; -include/save_master_gtid.inc -connection server_2; -SET GLOBAL slave_parallel_mode=minimal; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; -a -1040 -1041 -1042 -1043 -1044 -1045 -1046 -*** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_mode='conservative'; -SET GLOBAL slave_parallel_threads=10; -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @commit_id= 10000; -ANALYZE TABLE t2; -Table Op Msg_type Msg_text -test.t2 analyze status Engine-independent statistics collected -test.t2 analyze status OK -INSERT INTO t3 VALUES (120, 0); -SET @commit_id= 10001; -INSERT INTO t3 VALUES (121, 0); -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a >= 120 ORDER BY a; -a b -120 0 -121 0 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a >= 120 ORDER BY a; -a b -120 0 -121 0 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; -include/start_slave.inc -*** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** -connection server_2; -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @old_server_id= @@SESSION.server_id; -SET SESSION server_id= 100; -SET @commit_id= 10010; -ALTER TABLE t1 COMMENT "Hulubulu!"; -SET SESSION server_id= @old_server_id; -INSERT INTO t3 VALUES (130, 0); -SET @commit_id= 10011; -INSERT INTO t3 VALUES (131, 0); -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a >= 130 ORDER BY a; -a b -130 0 -131 0 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a >= 130 ORDER BY a; -a b -130 0 -131 0 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; -include/start_slave.inc -*** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** -connection server_1; -INSERT INTO t3 VALUES (201,0), (202,0); -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_mdev8031'; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @commit_id= 10200; -INSERT INTO t3 VALUES (203, 1); -INSERT INTO t3 VALUES (204, 1); -INSERT INTO t3 VALUES (205, 1); -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=201; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=202; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=204; -UPDATE t3 SET b=b+1 WHERE a=203; -UPDATE t3 SET b=b+1 WHERE a=205; -UPDATE t3 SET b=b+1 WHERE a=205; -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 3 -202 4 -203 4 -204 4 -205 3 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 3 -202 4 -203 4 -204 4 -205 3 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_dbug; -include/start_slave.inc -*** Check getting deadlock killed inside open_binlog() during retry. *** -connection server_2; -include/stop_slave.inc -SET @old_dbug= @@GLOBAL.debug_dbug; -SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; -SET @old_max= @@GLOBAL.max_relay_log_size; -SET GLOBAL max_relay_log_size= 4096; -connection server_1; -SET @old_dbug= @@SESSION.debug_dbug; -SET SESSION debug_dbug="+d,binlog_force_commit_id"; -SET @commit_id= 10210; -Omit long queries that cause relaylog rotations and transaction retries... -SET SESSION debug_dbug=@old_dbug; -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 6 -202 8 -203 7 -204 7 -205 5 -include/save_master_gtid.inc -connection server_2; -include/start_slave.inc -include/sync_with_master_gtid.inc -SELECT * FROM t3 WHERE a>=200 ORDER BY a; -a b -201 6 -202 8 -203 7 -204 7 -205 5 -include/stop_slave.inc -SET GLOBAL debug_dbug= @old_debg; -SET GLOBAL max_relay_log_size= @old_max; -include/start_slave.inc -*** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** -connection server_1; -BEGIN; -INSERT INTO t2 VALUES (2000); -INSERT INTO t1 VALUES (2000); -INSERT INTO t2 VALUES (2001); -ROLLBACK; -SELECT * FROM t1 WHERE a>=2000 ORDER BY a; -a -2000 -SELECT * FROM t2 WHERE a>=2000 ORDER BY a; -a -include/save_master_gtid.inc -connection server_2; -include/sync_with_master_gtid.inc -SELECT * FROM t1 WHERE a>=2000 ORDER BY a; -a -2000 -SELECT * FROM t2 WHERE a>=2000 ORDER BY a; -a -connection server_2; -include/stop_slave.inc -SET GLOBAL slave_parallel_threads=@old_parallel_threads; -include/start_slave.inc -SET DEBUG_SYNC= 'RESET'; -connection server_1; -DROP function foo; -DROP TABLE t1,t2,t3,t4,t5,t6; -SET DEBUG_SYNC= 'RESET'; -include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_analyze_table_hang.result b/mysql-test/suite/rpl/r/rpl_parallel_analyze_table_hang.result new file mode 100644 index 00000000000..3c3cd2601e8 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_analyze_table_hang.result @@ -0,0 +1,51 @@ +*** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10000; +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +INSERT INTO t3 VALUES (120, 0); +SET @commit_id= 10001; +INSERT INTO t3 VALUES (121, 0); +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +a b +120 0 +121 0 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +a b +120 0 +121 0 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t2,t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_conflicts.result b/mysql-test/suite/rpl/r/rpl_parallel_conflicts.result index b15de6fc215..09597ba81c1 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_conflicts.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_conflicts.result @@ -8,6 +8,12 @@ CREATE TABLE t7 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; CREATE TABLE t8 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; connection server_2; include/stop_slave.inc +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='conservative'; +SET @old_threads= @@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=40; +SET @old_transaction_retries= @@GLOBAL.slave_transaction_retries; +SET GLOBAL slave_transaction_retries=5; connection server_1; INSERT INTO t7 VALUES (1,1), (2,2), (3,3), (4,4), (5,5); SET @old_dbug= @@SESSION.debug_dbug; @@ -325,6 +331,9 @@ a b 104 4 include/stop_slave.inc SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_mode; +SET GLOBAL slave_parallel_threads=@old_threads; +SET GLOBAL slave_transaction_retries=@old_transaction_retries; include/start_slave.inc SET DEBUG_SYNC= 'RESET'; connection server_1; diff --git a/mysql-test/suite/rpl/r/rpl_parallel_deadlock_corrupt_binlog.result b/mysql-test/suite/rpl/r/rpl_parallel_deadlock_corrupt_binlog.result new file mode 100644 index 00000000000..74d1d53b67c --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_deadlock_corrupt_binlog.result @@ -0,0 +1,93 @@ +*** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=1; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; +connection server_1; +INSERT INTO t2 VALUES (101); +INSERT INTO t2 VALUES (102); +INSERT INTO t2 VALUES (103); +INSERT INTO t2 VALUES (104); +INSERT INTO t2 VALUES (105); +SET gtid_seq_no=1000; +INSERT INTO t2 VALUES (106); +INSERT INTO t2 VALUES (107); +INSERT INTO t2 VALUES (108); +INSERT INTO t2 VALUES (109); +INSERT INTO t2 VALUES (110); +INSERT INTO t2 VALUES (111); +INSERT INTO t2 VALUES (112); +INSERT INTO t2 VALUES (113); +INSERT INTO t2 VALUES (114); +INSERT INTO t2 VALUES (115); +INSERT INTO t2 VALUES (116); +INSERT INTO t2 VALUES (117); +INSERT INTO t2 VALUES (118); +INSERT INTO t2 VALUES (119); +INSERT INTO t2 VALUES (120); +INSERT INTO t2 VALUES (121); +INSERT INTO t2 VALUES (122); +INSERT INTO t2 VALUES (123); +INSERT INTO t2 VALUES (124); +INSERT INTO t2 VALUES (125); +INSERT INTO t2 VALUES (126); +INSERT INTO t2 VALUES (127); +INSERT INTO t2 VALUES (128); +INSERT INTO t2 VALUES (129); +INSERT INTO t2 VALUES (130); +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 100 ORDER BY a; +a +101 +102 +103 +104 +105 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t2; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_domain.result b/mysql-test/suite/rpl/r/rpl_parallel_domain.result new file mode 100644 index 00000000000..69b9678d149 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_domain.result @@ -0,0 +1,71 @@ +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) +OK +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) +OK +include/stop_slave.inc +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) +OK +include/start_slave.inc +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) +OK +*** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +connection server_2; +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +LOCK TABLE t1 WRITE; +connection server_1; +SET gtid_domain_id=1; +INSERT INTO t1 VALUES (2); +SET gtid_domain_id=0; +INSERT INTO t2 VALUES (2); +INSERT INTO t2 VALUES (3); +BEGIN; +INSERT INTO t2 VALUES (4); +INSERT INTO t2 VALUES (5); +COMMIT; +INSERT INTO t2 VALUES (6); +connection server_2; +SELECT * FROM t2 ORDER by a; +a +1 +2 +3 +4 +5 +6 +connection con_temp1; +SELECT * FROM t1; +a +1 +UNLOCK TABLES; +connection server_2; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t1,t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_domain_slave_single_grp.result b/mysql-test/suite/rpl/r/rpl_parallel_domain_slave_single_grp.result new file mode 100644 index 00000000000..613aac64487 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_domain_slave_single_grp.result @@ -0,0 +1,101 @@ +*** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +connection server_2; +include/stop_slave.inc +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (foo(10, +'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); +connection server_2; +FLUSH LOGS; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=statement; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +SET debug_sync='now WAIT_FOR ready1'; +connection server_1; +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (foo(11, +'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); +SET gtid_domain_id=0; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +a +10 +11 +connection server_2; +SET debug_sync='now WAIT_FOR ready3'; +SET debug_sync='now SIGNAL cont3'; +SET debug_sync='now WAIT_FOR ready4'; +SET debug_sync='now SIGNAL cont1'; +SET debug_sync='now WAIT_FOR ready2'; +SET debug_sync='now SIGNAL cont4'; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +a +10 +11 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 +slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(11, +'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')) +slave-bin.000002 # Xid # # COMMIT /* XID */ +slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(10, +'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')) +slave-bin.000002 # Xid # # COMMIT /* XID */ +FLUSH LOGS; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL binlog_format=@old_format; +connection server_1; +DROP function foo; +DROP TABLE t1,t2; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL binlog_format=@old_format; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_free_deferred_event.result b/mysql-test/suite/rpl/r/rpl_parallel_free_deferred_event.result new file mode 100644 index 00000000000..6718561a321 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_free_deferred_event.result @@ -0,0 +1,44 @@ +*** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL replicate_ignore_table="test.t3"; +SET GLOBAL slave_parallel_threads=2; +include/start_slave.inc +connection server_1; +INSERT INTO t3 VALUES (100, rand()); +INSERT INTO t3 VALUES (101, rand()); +connection server_2; +connection server_1; +INSERT INTO t3 VALUES (102, rand()); +INSERT INTO t3 VALUES (103, rand()); +INSERT INTO t3 VALUES (104, rand()); +INSERT INTO t3 VALUES (105, rand()); +connection server_2; +include/stop_slave.inc +SET GLOBAL replicate_ignore_table=""; +include/start_slave.inc +connection server_1; +INSERT INTO t3 VALUES (106, rand()); +INSERT INTO t3 VALUES (107, rand()); +connection server_2; +SELECT * FROM t3 WHERE a >= 100 ORDER BY a; +a b +106 # +107 # +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_gco_wait_kill.result b/mysql-test/suite/rpl/r/rpl_parallel_gco_wait_kill.result new file mode 100644 index 00000000000..4472550c4f2 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_gco_wait_kill.result @@ -0,0 +1,257 @@ +*** Test killing thread that is waiting to start transaction until previous transaction commits *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Slave: Connection was killed"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET sql_log_bin=1; +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode= 'conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=4; +include/start_slave.inc +connection server_1; +SET gtid_domain_id=2; +BEGIN; +INSERT INTO t3 VALUES (70, foo(70, +'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); +INSERT INTO t3 VALUES (60, foo(60, +'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', +'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d2_query'; +connection server_1; +SET gtid_domain_id=1; +BEGIN; +INSERT INTO t3 VALUES (61, foo(61, +'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', +'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); +INSERT INTO t3 VALUES (62, foo(62, +'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', +'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d1_query'; +connection server_1; +SET gtid_domain_id=0; +INSERT INTO t3 VALUES (63, foo(63, +'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', +'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); +connection server_2; +SET debug_sync='now WAIT_FOR d0_query'; +connection server_1; +SET gtid_domain_id=3; +BEGIN; +INSERT INTO t3 VALUES (68, foo(68, +'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); +INSERT INTO t3 VALUES (69, foo(69, +'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', +'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d3_query'; +SET debug_sync='now SIGNAL d2_cont2'; +SET debug_sync='now WAIT_FOR d2_done'; +SET debug_sync='now SIGNAL d1_cont2'; +SET debug_sync='now WAIT_FOR d1_done'; +SET debug_sync='now SIGNAL d0_cont2'; +SET debug_sync='now WAIT_FOR d0_done'; +SET debug_sync='now SIGNAL d3_cont2'; +SET debug_sync='now WAIT_FOR d3_done'; +connection con_temp3; +INSERT INTO t3 VALUES (64, foo(64, +'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; +INSERT INTO t3 VALUES (65, foo(65, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (66, foo(66, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; +INSERT INTO t3 VALUES (67, foo(67, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued4'; +SET debug_sync='now SIGNAL master_cont2'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +a b +60 60 +61 61 +62 62 +63 63 +64 64 +65 65 +66 66 +67 67 +68 68 +69 69 +70 70 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now SIGNAL d0_cont'; +SET debug_sync='now WAIT_FOR t1_waiting'; +SET debug_sync='now SIGNAL d3_cont'; +SET debug_sync='now WAIT_FOR t2_waiting'; +SET debug_sync='now SIGNAL d1_cont'; +SET debug_sync='now WAIT_FOR t3_waiting'; +SET debug_sync='now SIGNAL d2_cont'; +SET debug_sync='now WAIT_FOR t4_waiting'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t3_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; +a b +60 60 +61 61 +62 62 +63 63 +64 64 +68 68 +69 69 +70 70 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +UPDATE t3 SET b=b+1 WHERE a=60; +connection server_2; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +a b +60 61 +61 61 +62 62 +63 63 +64 64 +65 65 +66 66 +67 67 +68 68 +69 69 +70 70 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 5. Test killing thread that is waiting for queue of max length to shorten *** +SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; +SET GLOBAL slave_parallel_max_queued=9000; +connection server_1; +INSERT INTO t3 VALUES (80, foo(0, +'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); +connection server_2; +SET debug_sync='now WAIT_FOR query_waiting'; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; +connection server_1; +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; +a b +80 0 +81 10000 +connection server_2; +SET debug_sync='now WAIT_FOR wait_queue_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR wait_queue_killed'; +SET debug_sync='now SIGNAL query_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_max_queued= @old_max_queued; +connection server_1; +INSERT INTO t3 VALUES (82,0); +connection server_2; +SET debug_sync='RESET'; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; +a b +80 0 +81 10000 +82 0 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP function foo; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_gtid_slave_pos_update_fail.result b/mysql-test/suite/rpl/r/rpl_parallel_gtid_slave_pos_update_fail.result new file mode 100644 index 00000000000..2e7e7f547af --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_gtid_slave_pos_update_fail.result @@ -0,0 +1,65 @@ +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +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); +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection server_2; +include/stop_slave.inc +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +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'; +DELETE FROM t4 WHERE b <= 1; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET debug_sync='RESET'; +connection server_2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; +include/start_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +2 2 +3 NULL +4 4 +5 NULL +6 NULL +SET @last_gtid= 'GTID'; +SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", +CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) +AS result; +result +GTID found ok +SELECT "ROW FOUND" AS `Is the row found?` + FROM mysql.gtid_slave_pos +WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; +Is the row found? +ROW FOUND +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +disconnect con1; +disconnect con2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_ignore_error_on_rotate.result b/mysql-test/suite/rpl/r/rpl_parallel_ignore_error_on_rotate.result new file mode 100644 index 00000000000..d00740dba3d --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_ignore_error_on_rotate.result @@ -0,0 +1,74 @@ +*** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (1); +SET gtid_domain_id=0; +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (2); +SET gtid_domain_id=0; +INSERT INTO t2 VALUES (31); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET GLOBAL slave_parallel_threads= 0; +include/start_slave.inc +SET sql_log_bin= 0; +INSERT INTO t2 VALUES (32); +SET sql_log_bin= 1; +connection server_1; +INSERT INTO t2 VALUES (32); +FLUSH LOGS; +INSERT INTO t2 VALUES (33); +INSERT INTO t2 VALUES (34); +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +include/save_master_gtid.inc +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1062] +connection server_2; +include/stop_slave_io.inc +SET GLOBAL slave_parallel_threads=10; +START SLAVE; +include/wait_for_slave_sql_error.inc [errno=1062] +START SLAVE SQL_THREAD; +include/wait_for_slave_sql_error.inc [errno=1062] +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +SET sql_slave_skip_counter= 1; +ERROR HY000: When using parallel replication and GTID with multiple replication domains, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position +include/stop_slave_io.inc +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_incorrect_relay_pos.result b/mysql-test/suite/rpl/r/rpl_parallel_incorrect_relay_pos.result new file mode 100644 index 00000000000..6ca7f2b68e8 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_incorrect_relay_pos.result @@ -0,0 +1,75 @@ +*** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (40); +connection server_2; +connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +connection server_1; +INSERT INTO t2 VALUES (41); +INSERT INTO t2 VALUES (42); +SET @old_format= @@binlog_format; +SET binlog_format= statement; +DELETE FROM t2 WHERE a=40; +SET binlog_format= @old_format; +INSERT INTO t2 VALUES (43); +INSERT INTO t2 VALUES (44); +FLUSH LOGS; +INSERT INTO t2 VALUES (45); +SET gtid_seq_no=100; +INSERT INTO t2 VALUES (46); +connection con_temp2; +BEGIN; +SELECT * FROM t2 WHERE a=40 FOR UPDATE; +a +40 +connection server_2; +include/start_slave.inc +SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; +STOP SLAVE; +connection con_temp2; +SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; +connection server_2; +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a +41 +42 +include/start_slave.inc +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a +41 +42 +43 +44 +45 +46 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_innodb_lock_conflict.result b/mysql-test/suite/rpl/r/rpl_parallel_innodb_lock_conflict.result new file mode 100644 index 00000000000..1411db16af6 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_innodb_lock_conflict.result @@ -0,0 +1,79 @@ +***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts *** +include/master-slave.inc +[connection master] +connection server_2; +SET sql_log_bin=0; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET sql_log_bin=1; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +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); +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +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'; +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; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/start_slave.inc +include/stop_slave.inc +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +connection server_1; +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +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'; +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; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/start_slave.inc +include/stop_slave.inc +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 6 +7 NULL +connection server_2; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +disconnect con1; +disconnect con2; +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_mdev6589.result b/mysql-test/suite/rpl/r/rpl_parallel_mdev6589.result index e05e824eed3..47cdb3496da 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel_mdev6589.result +++ b/mysql-test/suite/rpl/r/rpl_parallel_mdev6589.result @@ -92,6 +92,7 @@ MASTER_GTID_WAIT('WAIT_POS') 0 connection con_temp1; COMMIT; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); SET sql_log_bin=1; connection server_2; include/wait_for_slave_sql_error.inc [errno=1062] diff --git a/mysql-test/suite/rpl/r/rpl_parallel_missed_error_handling.result b/mysql-test/suite/rpl/r/rpl_parallel_missed_error_handling.result new file mode 100644 index 00000000000..e9d04c02d7a --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_missed_error_handling.result @@ -0,0 +1,65 @@ +*** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +connection server_1; +INSERT INTO t3 VALUES (110, 1); +connection server_2; +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +SET sql_log_bin=0; +INSERT INTO t3 VALUES (111, 666); +SET sql_log_bin=1; +connection server_1; +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (111, 2); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +INSERT INTO t3 VALUES (112, 3); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1062] +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +111 666 +SET sql_log_bin=0; +DELETE FROM t3 WHERE a=111 AND b=666; +SET sql_log_bin=1; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +111 2 +112 3 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +disconnect con1; +disconnect con2; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_mode.result b/mysql-test/suite/rpl/r/rpl_parallel_mode.result new file mode 100644 index 00000000000..313290b1fd2 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_mode.result @@ -0,0 +1,75 @@ +*** MDEV-6676 - test syntax of @@slave_parallel_mode *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +connection server_2; +Parallel_Mode = 'optimistic' +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='aggressive'; +Parallel_Mode = 'aggressive' +SET GLOBAL slave_parallel_mode='conservative'; +Parallel_Mode = 'conservative' +*** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** +connection server_1; +INSERT INTO t2 VALUES (1040); +include/save_master_gtid.inc +connection server_2; +SET GLOBAL slave_parallel_mode='none'; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +a +1040 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +*** MDEV-6676 - test disabling domain-based parallel replication *** +connection server_1; +SET gtid_domain_id = 1; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +DELETE FROM t2 WHERE a >= 1041; +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +SET gtid_domain_id = 0; +include/save_master_gtid.inc +connection server_2; +SET GLOBAL slave_parallel_mode=minimal; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +a +1040 +1041 +1042 +1043 +1044 +1045 +1046 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_partial_binlog_trans.result b/mysql-test/suite/rpl/r/rpl_parallel_partial_binlog_trans.result new file mode 100644 index 00000000000..ab1cac692a0 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_partial_binlog_trans.result @@ -0,0 +1,51 @@ +*** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection con1; +SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; +INSERT INTO t6 VALUES (1), (2), (3); +connection server_1; +SET debug_sync='now WAIT_FOR ready'; +KILL QUERY CONID; +SET debug_sync='now SIGNAL cont'; +connection con1; +ERROR 70100: Query execution was interrupted +SET debug_sync='RESET'; +connection server_1; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1317] +STOP SLAVE IO_THREAD; +SET GLOBAL gtid_slave_pos= 'AFTER_ERROR_GTID_POS'; +include/start_slave.inc +connection server_1; +INSERT INTO t6 VALUES (4); +SELECT * FROM t6 ORDER BY a; +a +1 +4 +connection server_2; +SELECT * FROM t6 ORDER BY a; +a +4 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t6; +SET DEBUG_SYNC= 'RESET'; +disconnect con1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_record_gtid_wakeup.result b/mysql-test/suite/rpl/r/rpl_parallel_record_gtid_wakeup.result new file mode 100644 index 00000000000..cbe53e4f623 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_record_gtid_wakeup.result @@ -0,0 +1,48 @@ +*** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @old_server_id= @@SESSION.server_id; +SET SESSION server_id= 100; +SET @commit_id= 10010; +ALTER TABLE t1 COMMENT "Hulubulu!"; +SET SESSION server_id= @old_server_id; +INSERT INTO t3 VALUES (130, 0); +SET @commit_id= 10011; +INSERT INTO t3 VALUES (131, 0); +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +a b +130 0 +131 0 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +a b +130 0 +131 0 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t1,t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_retry_deadlock.result b/mysql-test/suite/rpl/r/rpl_parallel_retry_deadlock.result new file mode 100644 index 00000000000..1f5a23db848 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_retry_deadlock.result @@ -0,0 +1,192 @@ +*** MDEV-7326 Server deadlock in connection with parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +connection server_2; +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +include/start_slave.inc +connection server_1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +INSERT INTO t1 VALUES (foo(50, +"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", +"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; +connection server_1; +INSERT INTO t2 VALUES (foo(50, +"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", +"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +connection server_1; +INSERT INTO t1 VALUES (foo(51, +"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", +"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +connection server_1; +INSERT INTO t1 VALUES (52); +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +a +50 +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +a +50 +51 +52 +connection server_2; +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +connection server_1; +connection server_2; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +a +50 +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +a +50 +51 +52 +SET DEBUG_SYNC="reset"; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-7326 Server deadlock in connection with parallel replication *** +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connection server_2; +include/stop_slave.inc +SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='conservative'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +include/start_slave.inc +connection server_1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +INSERT INTO t1 VALUES (foo(60, +"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", +"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; +connection server_1; +INSERT INTO t2 VALUES (foo(60, +"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", +"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t1 VALUES (foo(61, +"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", +"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +INSERT INTO t6 VALUES (62); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection server_1; +SET debug_sync='RESET'; +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +a +60 +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +a +60 +61 +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +a +62 +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +connection server_2; +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +connection server_1; +connection server_2; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +a +60 +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +a +60 +61 +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +a +62 +SET DEBUG_SYNC="reset"; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP function foo; +DROP TABLE t1,t2,t6; +disconnect con_temp3; +disconnect con_temp4; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_rollback_assert.result b/mysql-test/suite/rpl/r/rpl_parallel_rollback_assert.result new file mode 100644 index 00000000000..af9c5f14687 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_rollback_assert.result @@ -0,0 +1,45 @@ +*** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +connection server_2; +connection server_1; +BEGIN; +INSERT INTO t2 VALUES (2000); +INSERT INTO t1 VALUES (2000); +INSERT INTO t2 VALUES (2001); +ROLLBACK; +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +a +2000 +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +a +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +connection server_1; +INSERT INTO t2 VALUES (2020); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +a +2020 +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +a +2000 +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t1,t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_single_grpcmt.result b/mysql-test/suite/rpl/r/rpl_parallel_single_grpcmt.result new file mode 100644 index 00000000000..18ffac4fa5d --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_single_grpcmt.result @@ -0,0 +1,160 @@ +*** Test that group-committed transactions on the master can replicate in parallel on the slave. *** +include/master-slave.inc +[connection master] +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); +connection server_2; +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +BEGIN; +INSERT INTO t3 VALUES (2,102); +connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +BEGIN; +INSERT INTO t3 VALUES (4,104); +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +SET debug_sync='RESET'; +connection server_1; +SELECT * FROM t3 ORDER BY a; +a b +1 1 +2 12 +3 3 +4 14 +5 5 +6 16 +7 7 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')) +master-bin.000001 # Xid # # COMMIT /* XID */ +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued3'; +connection con_temp1; +ROLLBACK; +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued1'; +connection con_temp2; +ROLLBACK; +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued2'; +SET debug_sync='now SIGNAL slave_cont1'; +SELECT * FROM t3 ORDER BY a; +a b +1 1 +2 12 +3 3 +4 14 +5 5 +6 16 +7 7 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')) +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')) +slave-bin.000001 # Xid # # COMMIT /* XID */ +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')) +slave-bin.000001 # Xid # # COMMIT /* XID */ +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP function foo; +DROP TABLE t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_slave_bgc_kill.result b/mysql-test/suite/rpl/r/rpl_parallel_slave_bgc_kill.result new file mode 100644 index 00000000000..320bf0e49f8 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_slave_bgc_kill.result @@ -0,0 +1,323 @@ +*** Test killing slave threads at various wait points *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +*** 1. Test killing transaction waiting in commit for previous transaction to commit *** +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (31, foo(31, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +INSERT INTO t3 VALUES (32, foo(32, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (33, foo(33, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (34, foo(34, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +32 32 +33 33 +34 34 +SET debug_sync='RESET'; +connection server_2; +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +CALL mtr.add_suppression("Slave: Connection was killed"); +SET sql_log_bin=1; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (39,0); +connection server_2; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +32 32 +33 33 +34 34 +39 0 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (41, foo(41, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +INSERT INTO t3 VALUES (42, foo(42, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (43, foo(43, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (44, foo(44, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +a b +41 41 +42 42 +43 43 +44 44 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (49,0); +connection server_2; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +a b +41 41 +42 42 +43 43 +44 44 +49 0 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 3. Same as (2), but not using gtid mode *** +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +include/start_slave.inc +connection server_1; +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (51, foo(51, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +BEGIN; +INSERT INTO t3 VALUES (52, foo(52, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (53, foo(53, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (54, foo(54, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +52 52 +53 53 +54 54 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (59,0); +connection server_2; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +52 52 +53 53 +54 54 +59 0 +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP function foo; +DROP TABLE t1,t2,t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_stop_on_con_kill.result b/mysql-test/suite/rpl/r/rpl_parallel_stop_on_con_kill.result new file mode 100644 index 00000000000..bf0ed9e4374 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_stop_on_con_kill.result @@ -0,0 +1,102 @@ +*** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (201,0), (202,0); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_mdev8031'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10200; +INSERT INTO t3 VALUES (203, 1); +INSERT INTO t3 VALUES (204, 1); +INSERT INTO t3 VALUES (205, 1); +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=205; +UPDATE t3 SET b=b+1 WHERE a=205; +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 3 +202 4 +203 4 +204 4 +205 3 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 3 +202 4 +203 4 +204 4 +205 3 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +include/start_slave.inc +*** Check getting deadlock killed inside open_binlog() during retry. *** +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; +SET @old_max= @@GLOBAL.max_relay_log_size; +SET GLOBAL max_relay_log_size= 4096; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10210; +Omit long queries that cause relaylog rotations and transaction retries... +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 6 +202 8 +203 7 +204 7 +205 5 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 6 +202 8 +203 7 +204 7 +205 5 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_debg; +SET GLOBAL max_relay_log_size= @old_max; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t3; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_stop_slave.result b/mysql-test/suite/rpl/r/rpl_parallel_stop_slave.result new file mode 100644 index 00000000000..6c9fd168e73 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_stop_slave.result @@ -0,0 +1,85 @@ +*** Test STOP SLAVE in parallel mode *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +connection server_1; +SET binlog_direct_non_transactional_updates=0; +SET sql_log_bin=0; +CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); +SET sql_log_bin=1; +BEGIN; +INSERT INTO t2 VALUES (20); +INSERT INTO t1 VALUES (20); +INSERT INTO t2 VALUES (21); +INSERT INTO t3 VALUES (20, 20); +COMMIT; +INSERT INTO t3 VALUES(21, 21); +INSERT INTO t3 VALUES(22, 22); +connection con_temp1; +BEGIN; +INSERT INTO t2 VALUES (21); +connection server_2; +START SLAVE; +connection con_temp2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +STOP SLAVE; +connection con_temp1; +SET debug_sync='now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; +connection con_temp2; +SET GLOBAL debug_dbug=@old_dbug; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_to_stop.inc +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +a +20 +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +a +20 +21 +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; +a b +20 20 +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +a +20 +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +a +20 +21 +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; +a b +20 20 +21 21 +22 22 +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +disconnect con_temp1; +disconnect con_temp2; +connection server_1; +DROP TABLE t1,t2,t3; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_wrong_binlog_order.result b/mysql-test/suite/rpl/r/rpl_parallel_wrong_binlog_order.result new file mode 100644 index 00000000000..f6781f64d30 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_wrong_binlog_order.result @@ -0,0 +1,75 @@ +*** MDEV-6775: Wrong binlog order in parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB; +INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=ROW; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +connection con1; +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +UPDATE t4 SET b=NULL WHERE a=6; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con2; +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +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; +SET binlog_format= @old_format; +connection con2; +SET binlog_format= @old_format; +SET debug_sync='RESET'; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +connection server_2; +include/start_slave.inc +SET debug_sync= 'now WAIT_FOR waiting'; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +SET debug_sync= 'now SIGNAL cont'; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL binlog_format= @old_format; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP TABLE t4; +SET DEBUG_SYNC= 'RESET'; +disconnect con1; +disconnect con2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_parallel_wrong_exec_master_pos.result b/mysql-test/suite/rpl/r/rpl_parallel_wrong_exec_master_pos.result new file mode 100644 index 00000000000..47cfa5e08e2 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_wrong_exec_master_pos.result @@ -0,0 +1,34 @@ +*** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** +include/master-slave.inc +[connection master] +connection server_2; +include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t5 (a INT PRIMARY KEY, b INT); +INSERT INTO t5 VALUES (1,1); +INSERT INTO t5 VALUES (2,2), (3,8); +INSERT INTO t5 VALUES (4,16); +connection server_2; +test_check +OK +test_check +OK +connection server_1; +FLUSH LOGS; +connection server_2; +test_check +OK +test_check +OK +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +connection server_1; +DROP TABLE t5; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_delayed_slave.combinations b/mysql-test/suite/rpl/t/rpl_delayed_slave.combinations index 8adc75e834f..bac7cb337c9 100644 --- a/mysql-test/suite/rpl/t/rpl_delayed_slave.combinations +++ b/mysql-test/suite/rpl/t/rpl_delayed_slave.combinations @@ -1,5 +1,4 @@ [nonparallel] [parallel] ---slave-parallel-mode=conservative --slave-parallel-threads=10 diff --git a/mysql-test/suite/rpl/t/rpl_mdev6386.test b/mysql-test/suite/rpl/t/rpl_mdev6386.test index e85b1ae0132..e6fb72dc788 100644 --- a/mysql-test/suite/rpl/t/rpl_mdev6386.test +++ b/mysql-test/suite/rpl/t/rpl_mdev6386.test @@ -10,6 +10,7 @@ CREATE TABLE t1 (a INT PRIMARY KEY, b INT) Engine=InnoDB; --source include/stop_slave.inc # Provoke a duplicate key error on replication. SET sql_log_bin= 0; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); INSERT INTO t1 VALUES (1, 2); SET sql_log_bin= 1; CHANGE MASTER TO master_use_gtid= current_pos; diff --git a/mysql-test/suite/rpl/t/rpl_parallel.test b/mysql-test/suite/rpl/t/rpl_parallel.test deleted file mode 100644 index ee39bfa7a39..00000000000 --- a/mysql-test/suite/rpl/t/rpl_parallel.test +++ /dev/null @@ -1 +0,0 @@ ---source include/rpl_parallel.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_analyze_table_hang.test b/mysql-test/suite/rpl/t/rpl_parallel_analyze_table_hang.test new file mode 100644 index 00000000000..c1f1b9bac43 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_analyze_table_hang.test @@ -0,0 +1 @@ +--source include/rpl_parallel_analyze_table_hang.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_conflicts-slave.opt b/mysql-test/suite/rpl/t/rpl_parallel_conflicts-slave.opt deleted file mode 100644 index af7bd138793..00000000000 --- a/mysql-test/suite/rpl/t/rpl_parallel_conflicts-slave.opt +++ /dev/null @@ -1 +0,0 @@ ---slave_parallel_threads=40 --slave_parallel_mode=conservative --slave_transaction_retries=5 diff --git a/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test b/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test index fc294f68197..0ba6a2b2dc1 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test @@ -15,7 +15,12 @@ CREATE TABLE t8 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; --connection server_2 --sync_with_master --source include/stop_slave.inc - +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='conservative'; +SET @old_threads= @@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=40; +SET @old_transaction_retries= @@GLOBAL.slave_transaction_retries; +SET GLOBAL slave_transaction_retries=5; # Using dbug error injection, we artificially create event groups with a lot of # conflicting transactions in each event group. The bugs were originally seen @@ -249,6 +254,9 @@ SELECT * FROM t7 ORDER BY a; --source include/stop_slave.inc SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_mode; +SET GLOBAL slave_parallel_threads=@old_threads; +SET GLOBAL slave_transaction_retries=@old_transaction_retries; # Clean up. --source include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_deadlock_corrupt_binlog.test b/mysql-test/suite/rpl/t/rpl_parallel_deadlock_corrupt_binlog.test new file mode 100644 index 00000000000..9ee06f59858 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_deadlock_corrupt_binlog.test @@ -0,0 +1 @@ +--source include/rpl_parallel_deadlock_corrupt_binlog.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_domain.test b/mysql-test/suite/rpl/t/rpl_parallel_domain.test new file mode 100644 index 00000000000..f5864380f02 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_domain.test @@ -0,0 +1 @@ +--source include/rpl_parallel_domain.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_domain_slave_single_grp.test b/mysql-test/suite/rpl/t/rpl_parallel_domain_slave_single_grp.test new file mode 100644 index 00000000000..5ddd2af323c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_domain_slave_single_grp.test @@ -0,0 +1 @@ +--source include/rpl_parallel_domain_slave_single_grp.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_free_deferred_event.test b/mysql-test/suite/rpl/t/rpl_parallel_free_deferred_event.test new file mode 100644 index 00000000000..e2a41d0db7e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_free_deferred_event.test @@ -0,0 +1 @@ +--source include/rpl_parallel_free_deferred_event.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test new file mode 100644 index 00000000000..d9dc4dfd293 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test @@ -0,0 +1 @@ +--source include/rpl_parallel_gco_wait_kill.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_gtid_slave_pos_update_fail.test b/mysql-test/suite/rpl/t/rpl_parallel_gtid_slave_pos_update_fail.test new file mode 100644 index 00000000000..0756caca084 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_gtid_slave_pos_update_fail.test @@ -0,0 +1 @@ +--source include/rpl_parallel_gtid_slave_pos_update_fail.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_ignore_error_on_rotate.test b/mysql-test/suite/rpl/t/rpl_parallel_ignore_error_on_rotate.test new file mode 100644 index 00000000000..92c84d497a7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_ignore_error_on_rotate.test @@ -0,0 +1 @@ +--source include/rpl_parallel_ignore_error_on_rotate.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_incorrect_relay_pos.test b/mysql-test/suite/rpl/t/rpl_parallel_incorrect_relay_pos.test new file mode 100644 index 00000000000..e0226d9453e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_incorrect_relay_pos.test @@ -0,0 +1 @@ +--source include/rpl_parallel_incorrect_relay_pos.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_innodb_lock_conflict.test b/mysql-test/suite/rpl/t/rpl_parallel_innodb_lock_conflict.test new file mode 100644 index 00000000000..3838973c201 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_innodb_lock_conflict.test @@ -0,0 +1 @@ +--source include/rpl_parallel_innodb_lock_conflict.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test b/mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test index 5929fad71df..981c6216376 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test @@ -99,6 +99,7 @@ eval SELECT MASTER_GTID_WAIT('$wait_pos'); # duplicate key error. --connection con_temp1 COMMIT; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); SET sql_log_bin=1; --connection server_2 diff --git a/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test b/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test new file mode 100644 index 00000000000..de9dc7f782a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test @@ -0,0 +1 @@ +--source include/rpl_parallel_missed_error_handling.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_mode.test b/mysql-test/suite/rpl/t/rpl_parallel_mode.test new file mode 100644 index 00000000000..afd9e038912 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_mode.test @@ -0,0 +1 @@ +--source include/rpl_parallel_mode.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_partial_binlog_trans.test b/mysql-test/suite/rpl/t/rpl_parallel_partial_binlog_trans.test new file mode 100644 index 00000000000..7be26edabb8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_partial_binlog_trans.test @@ -0,0 +1 @@ +--source include/rpl_parallel_partial_binlog_trans.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_record_gtid_wakeup.test b/mysql-test/suite/rpl/t/rpl_parallel_record_gtid_wakeup.test new file mode 100644 index 00000000000..4529a268103 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_record_gtid_wakeup.test @@ -0,0 +1 @@ +--source include/rpl_parallel_record_gtid_wakeup.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_retry_deadlock.test b/mysql-test/suite/rpl/t/rpl_parallel_retry_deadlock.test new file mode 100644 index 00000000000..50b216b6f58 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_retry_deadlock.test @@ -0,0 +1 @@ +--source include/rpl_parallel_retry_deadlock.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_rollback_assert.test b/mysql-test/suite/rpl/t/rpl_parallel_rollback_assert.test new file mode 100644 index 00000000000..f66375b7fb4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_rollback_assert.test @@ -0,0 +1 @@ +--source include/rpl_parallel_rollback_assert.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_single_grpcmt.test b/mysql-test/suite/rpl/t/rpl_parallel_single_grpcmt.test new file mode 100644 index 00000000000..20919823945 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_single_grpcmt.test @@ -0,0 +1 @@ +--source include/rpl_parallel_single_grpcmt.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test new file mode 100644 index 00000000000..7b0f9485e5e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test @@ -0,0 +1 @@ +--source include/rpl_parallel_slave_bgc_kill.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_stop_on_con_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_stop_on_con_kill.test new file mode 100644 index 00000000000..64b4cb77dd4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_stop_on_con_kill.test @@ -0,0 +1 @@ +--source include/rpl_parallel_stop_on_con_kill.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test b/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test new file mode 100644 index 00000000000..131ddc2efd9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test @@ -0,0 +1 @@ +--source include/rpl_parallel_stop_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_wrong_binlog_order.test b/mysql-test/suite/rpl/t/rpl_parallel_wrong_binlog_order.test new file mode 100644 index 00000000000..3c920e1539a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_wrong_binlog_order.test @@ -0,0 +1 @@ +--source include/rpl_parallel_wrong_binlog_order.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_wrong_exec_master_pos.test b/mysql-test/suite/rpl/t/rpl_parallel_wrong_exec_master_pos.test new file mode 100644 index 00000000000..9cd700f57fa --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_wrong_exec_master_pos.test @@ -0,0 +1 @@ +--source include/rpl_parallel_wrong_exec_master_pos.inc diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b7f7615636b..09d8b4b7d1c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -536,7 +536,7 @@ ulong stored_program_cache_size= 0; ulong opt_slave_parallel_threads= 0; ulong opt_slave_domain_parallel_threads= 0; -ulong opt_slave_parallel_mode= SLAVE_PARALLEL_CONSERVATIVE; +ulong opt_slave_parallel_mode; ulong opt_binlog_commit_wait_count= 0; ulong opt_binlog_commit_wait_usec= 0; ulong opt_slave_parallel_max_queued= 131072; diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index b167b849923..5d10cc661ca 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -24,7 +24,7 @@ #define TABLE_RULE_ARR_SIZE 16 Rpl_filter::Rpl_filter() : - parallel_mode(SLAVE_PARALLEL_CONSERVATIVE), + parallel_mode(SLAVE_PARALLEL_OPTIMISTIC), table_rules_on(0), do_table_inited(0), ignore_table_inited(0), wild_do_table_inited(0), wild_ignore_table_inited(0) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 3441a1ae4b1..0d035d002c4 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2224,7 +2224,7 @@ static Sys_var_slave_parallel_mode Sys_slave_parallel_mode( "\"minimal\" only parallelizes the commit steps of transactions. " "\"none\" disables parallel apply completely.", GLOBAL_VAR(opt_slave_parallel_mode), NO_CMD_LINE, - slave_parallel_mode_names, DEFAULT(SLAVE_PARALLEL_CONSERVATIVE)); + slave_parallel_mode_names, DEFAULT(SLAVE_PARALLEL_OPTIMISTIC)); static Sys_var_bit Sys_skip_parallel_replication(