mirror of
https://github.com/MariaDB/server.git
synced 2025-02-05 13:22:17 +01:00
![Kristian Nielsen](/assets/img/avatar_default.png)
The largest_started_sub_id needs to be set under LOCK_parallel_entry together with testing stop_sub_id. However, in-between was the logic for do_ftwrl_wait(), which temporarily releases the mutex. This could lead to inconsistent stopping amongst worker threads and lost data. Fix by moving all the stop-related logic out from unrelated do_gco_wait() and do_ftwrl_wait() and into its own function do_stop_handling(). Reviewed-by: Andrei Elkin <andrei.elkin@mariadb.com> Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
105 lines
3.1 KiB
Text
105 lines
3.1 KiB
Text
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
|