123 lines
4.2 KiB
Plaintext
123 lines
4.2 KiB
Plaintext
###############################################################################
|
||
# Bug#20369401: MTS STOP SLAVE TAKES WAY TOO LONG(WHEN WORKER THREADS ARE SLOW)
|
||
#
|
||
# Problem:
|
||
# ========
|
||
# TOP SLAVE waits workers to catch up the queue, which may
|
||
# take a lot of time for the command to finish. STOP SLAVE
|
||
# must be executed quickly, even if workers are slow.
|
||
###############################################################################
|
||
# Following test demonstrates that STOP SLAVE command will not leave any gaps.
|
||
# It first creates two databases (d1 and d2) and setup slave to use two parallel
|
||
# workers. The test case then insert on the slave a tuple that will block
|
||
# writes on d2 and generate gaps. Finally, the test case executes "STOP SLAVE"
|
||
# and verify that the SQL thread was properly stopped and left no gaps.
|
||
|
||
--source include/have_binlog_format_statement.inc
|
||
--source include/only_mts_slave_parallel_workers.inc
|
||
--source include/only_mts_slave_parallel_type_database.inc
|
||
--source include/master-slave.inc
|
||
|
||
--let $slave_stop_wait=5
|
||
|
||
--echo #### I. Initialize ####
|
||
|
||
--source include/rpl_connection_slave.inc
|
||
--source include/stop_slave.inc
|
||
SET @save.innodb_lock_wait_timeout= @@global.innodb_lock_wait_timeout;
|
||
--eval set @@global.innodb_lock_wait_timeout=$slave_stop_wait + 1000
|
||
|
||
--source include/start_slave.inc
|
||
|
||
--source include/rpl_connection_master.inc
|
||
CREATE DATABASE d1;
|
||
CREATE DATABASE d2;
|
||
CREATE TABLE d1.t (a INT PRIMARY KEY, name text) ENGINE=INNODB;
|
||
CREATE TABLE d2.t (a INT PRIMARY KEY, name text) ENGINE=INNODB;
|
||
|
||
--echo #### II. Prepare test scenario ####
|
||
|
||
--source include/sync_slave_sql_with_master.inc
|
||
BEGIN;
|
||
INSERT INTO d2.t VALUES (2, 'Slave local'); # Hold T3
|
||
INSERT INTO d1.t VALUES (3, 'Slave local'); # Hold T6
|
||
|
||
--source include/rpl_connection_master.inc
|
||
INSERT INTO d1.t VALUES (1, 'T1');
|
||
INSERT INTO d2.t VALUES (1, 'T2');
|
||
INSERT INTO d2.t VALUES (2, 'T3'); # This will be a gap when executed on slave
|
||
INSERT INTO d2.t VALUES (3, 'T4'); # This will be a gap when executed on slave
|
||
INSERT INTO d1.t VALUES (2, 'T5');
|
||
INSERT INTO d1.t VALUES (3, 'T6');
|
||
INSERT INTO d2.t VALUES (4, 'T7'); # This should not be executed after STOP SLAVE
|
||
INSERT INTO d2.t VALUES (5, 'T8'); # This should not be executed after STOP SLAVE
|
||
INSERT INTO d1.t VALUES (4, 'T9'); # This should not be executed after STOP SLAVE
|
||
|
||
--source include/rpl_connection_slave1.inc
|
||
--let $table=d2.t
|
||
--let $count=1
|
||
--source include/wait_until_rows_count.inc
|
||
|
||
--let $table=d1.t
|
||
--let $count=2
|
||
--source include/wait_until_rows_count.inc
|
||
|
||
--echo # Now d1.t has two rows and d2.t has one row.
|
||
|
||
# Wait for coordinator to populate worker's queues.
|
||
--let $show_statement= SHOW PROCESSLIST
|
||
--let $field= State
|
||
--let $condition= = 'Slave has read all relay log; waiting for more updates'
|
||
--source include/wait_show_condition.inc
|
||
|
||
--echo # Now coordinator has read the entire relay log and populated workers' queues.
|
||
|
||
# There is now a gap at T3,T4
|
||
SELECT * FROM d2.t;
|
||
SELECT * FROM d1.t;
|
||
|
||
--echo #### Verify that STOP SLAVE stops at gap less state ####
|
||
|
||
--send STOP SLAVE
|
||
|
||
--source include/rpl_connection_slave.inc
|
||
# Despite time elapsed, the slave should still be running, waiting for the
|
||
# queue to be completed.
|
||
--sleep $slave_stop_wait
|
||
--let $show_statement= SHOW PROCESSLIST
|
||
--let $field= State
|
||
--let $condition= = 'Waiting for workers to exit'
|
||
--source include/wait_show_condition.inc
|
||
|
||
--echo # Now coordinator is waiting for the worker to consume its queue.
|
||
ROLLBACK;
|
||
--source include/wait_for_slave_sql_to_stop.inc
|
||
|
||
|
||
--echo # III. Now all slave threads have stopped. Verify that worker completed its queue:
|
||
--echo # d2 should contain Т2, Т3, Т4.
|
||
--let $assert_cond= MAX(a)=3 FROM d2.t;
|
||
--let $assert_text= Rows until T3 in d2.t must be replicated now
|
||
--source include/assert.inc
|
||
|
||
--echo # d1 should contain Т1, Т5, T6.
|
||
--let $assert_cond= MAX(a)=3 FROM d1.t;
|
||
--let $assert_text= Rows until 2 in d1.t must be replicated now
|
||
--source include/assert.inc
|
||
--source include/start_slave.inc
|
||
|
||
--source include/rpl_connection_slave1.inc
|
||
--reap
|
||
|
||
#
|
||
# Cleanup
|
||
#
|
||
--source include/rpl_connection_slave.inc
|
||
SET @@global.innodb_lock_wait_timeout= @save.innodb_lock_wait_timeout;
|
||
--source include/rpl_connection_master.inc
|
||
DROP DATABASE d1;
|
||
DROP DATABASE d2;
|
||
--source include/sync_slave_sql_with_master.inc
|
||
|
||
--source include/rpl_end.inc
|