include/master-slave.inc [connection master] connection slave; include/stop_slave.inc SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads; SET GLOBAL slave_parallel_threads=3; SET @old_parallel_mode= @@GLOBAL.slave_parallel_mode; SET GLOBAL slave_parallel_mode=aggressive; SET @old_dbug= @@GLOBAL.debug_dbug; CHANGE MASTER TO master_use_gtid=slave_pos; include/start_slave.inc *** MDEV-31509: Lost data with FTWRL and STOP SLAVE connection master; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=MyISAM; INSERT INTO t1 VALUES (0,0); INSERT INTO t2 VALUES (0,0); include/save_master_gtid.inc connection slave; include/sync_with_master_gtid.inc connection slave; *** Arrange for T1 to delay before entering GCO wait. SET GLOBAL debug_dbug="+d,gco_wait_delay_gtid_0_x_99"; *** Arrange for T2 to wait for FTWRL to start. SET GLOBAL debug_dbug="+d,hold_worker_on_schedule"; *** Arrange for T2 to delay wakeup from FTWRL pause. SET GLOBAL debug_dbug="+d,delay_ftwrl_wait_gtid_0_x_100"; connection master; *** Event group T1 SET SESSION gtid_seq_no=99; INSERT INTO t1 VALUES (1,1); connection slave; *** 1a. Wait for T1 to be queued. SET debug_sync="now WAIT_FOR gco_wait_paused"; connection master; *** Event group T2 SET SESSION gtid_seq_no=100; INSERT INTO t2 VALUES (2,2); connection slave; *** 1b. Wait for T2 to be queued. SET debug_sync= "now WAIT_FOR reached_pause"; connection slave1; *** 2. Run FTWRL SET GLOBAL debug_dbug= "+d,pause_for_ftwrl_wait"; FLUSH TABLES WITH READ LOCK; connection slave; SET debug_sync= "now WAIT_FOR pause_ftwrl_waiting"; *** 3. Wait for T2 to be waiting for FTWRL pause SET debug_sync= "now SIGNAL continue_worker"; *** 4. FTWRL completes, UNLOCK TABLES. SET debug_sync="now SIGNAL pause_ftwrl_cont"; connection slave1; UNLOCK TABLES; connection slave; *** T2 is now ready to proceed after FTWRL pause, but did not wake up yet. SET debug_sync="now WAIT_FOR pause_wait_started"; *** 5. STOP SLAVE is run. connection slave1; SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; STOP SLAVE; connection slave; SET debug_sync="now WAIT_FOR wait_for_done_waiting"; *** 5. T2 wakes up after FTWRL pause, reaches wait_for_prior_commit(). SET debug_sync="now SIGNAL pause_wait_continue"; *** 6. T1 starts. SET debug_sync="now SIGNAL gco_wait_cont"; connection slave1; connection slave; include/wait_for_slave_to_stop.inc connection master; SELECT * FROM t1 ORDER BY a; a b 0 0 1 1 SELECT * FROM t2 ORDER BY a; a b 0 0 2 2 include/save_master_gtid.inc connection slave; include/start_slave.inc include/sync_with_master_gtid.inc SELECT @@GLOBAL.gtid_slave_pos; @@GLOBAL.gtid_slave_pos 0-1-100 SELECT * FROM t1 ORDER BY a; a b 0 0 1 1 SELECT * FROM t2 ORDER BY a; a b 0 0 2 2 *** Clean up. connection slave; include/stop_slave.inc SET DEBUG_SYNC= "RESET"; SET GLOBAL slave_parallel_threads= @old_parallel_threads; SET GLOBAL slave_parallel_mode= @old_parallel_mode; SET GLOBAL debug_dbug=@old_dbug; include/start_slave.inc connection master; DROP TABLE t1, t2; include/rpl_end.inc