mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-13915: STOP SLAVE takes very long time on a busy system
The problem is that a parallel replica would not immediately stop running/queued transactions when issued STOP SLAVE. That is, it allowed the current group of transactions to run, and sometimes the transactions which belong to the next group could be started and run through commit after STOP SLAVE was issued too, if the last group had started committing. This would lead to long periods to wait for all waiting transactions to finish. This patch updates a parallel replica to try and abort immediately and roll-back any ongoing transactions. The exception to this is any transactions which are non-transactional (e.g. those modifying sequences or non-transactional tables), and any prior transactions, will be run to completion. The specifics are as follows: 1. A new stage was added to SHOW PROCESSLIST output for the SQL Thread when it is waiting for a replica thread to either rollback or finish its transaction before stopping. This stage presents as “Waiting for worker thread to stop” 2. Worker threads which error or are killed no longer perform GCO cleanup if there is a concurrently running prior transaction. This is because a worker thread scheduled to run in a future GCO could be killed and incorrectly perform cleanup of the active GCO. 3. Refined cases when the FL_TRANSACTIONAL flag is added to GTID binlog events to disallow adding it to transactions which modify both transactional and non-transactional engines when the binlogging configuration allow the modifications to exist in the same event, i.e. when using binlog_direct_non_trans_update == 0 and binlog_format == statement. 4. A few existing MTR tests relied on the completion of certain transactions after issuing STOP SLAVE, and were re-recorded (potentially with added synchronizations) under the new rollback behavior. Reviewed By =========== Andrei Elkin <andrei.elkin@mariadb.com>
This commit is contained in:
@@ -0,0 +1,608 @@
|
||||
#
|
||||
# The stop_slave_quick suite of tests aims to validate that stopping a replica
|
||||
# with parallelization enabled will stop in a timely manner. That is, a
|
||||
# parallel replica should try to immediately stop and roll-back any ongoing
|
||||
# transactions. If any threads have a non-transactional workload, then it
|
||||
# along with all prior transactions are executed before stopping.
|
||||
#
|
||||
# This file provides test cases that should be binlog format independent. There
|
||||
# is, however, behavior that is specific to either statement or row format,
|
||||
# which each have their own test files that include this file.
|
||||
#
|
||||
# Requirements:
|
||||
# 1. Tables named `ti`, `ti2`, and `ti3` have already been created with
|
||||
# storage engine InnoDB; and a table named `tm` has been created with
|
||||
# storage engine MyIsam.
|
||||
# 2. Test variables ti_ctr, ti2_ctr, ti3_ctr, and tm_ctr have been created
|
||||
# to serve as dynamic values to insert into their respective tables
|
||||
#
|
||||
# References:
|
||||
# MDEV-13915: STOP SLAVE takes very long time on a busy system
|
||||
#
|
||||
|
||||
--echo #
|
||||
--echo # Common Test Case 1:
|
||||
--echo # Using one parallel replication worker thread on workload {T,T}, ensure
|
||||
--echo # the replica immediately rolls back the transaction and stops the
|
||||
--echo # SQL thread
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
--let $row_count_initial=`select count(*) from ti`
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
BEGIN;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
COMMIT;
|
||||
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti WRITE;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to begin executing the first transaction
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $row_count_end=`select count(*) from ti`
|
||||
--let $row_count_diff=`select ($row_count_end-$row_count_initial)`
|
||||
--let $assert_text= No new rows should have been inserted
|
||||
--let $assert_cond= $row_count_diff = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= GTID slave state should not change
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Common Test Case 2:
|
||||
--echo # Using multiple parallel replication threads (two) on workload {T,T},
|
||||
--echo # ensure both transactions are rolled back if stop slave is issued
|
||||
--echo # in the middle of the first transaction.
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=2;
|
||||
--let $row_count_initial=`select count(*) from ti`
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
BEGIN;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
COMMIT;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti WRITE;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to begin executing the first transaction
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--echo # Wait for second transaction to begin
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=0 FROM information_schema.processlist WHERE state LIKE 'Waiting for work from SQL thread' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $row_count_end=`select count(*) from ti`
|
||||
--let $row_count_diff=`select ($row_count_end-$row_count_initial)`
|
||||
--let $assert_text= No insertions should have committed
|
||||
--let $assert_cond= $row_count_diff = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= GTID slave state should not change
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--echo # Slave should be error-free
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
|
||||
--let $assert_text= Slave should be error free
|
||||
--let $assert_cond= $last_error = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Common Test Case 3:
|
||||
--echo # Using multiple parallel replication threads (two) on workload {T,T},
|
||||
--echo # with the same commit id (cid), ensure both transactions are rolled
|
||||
--echo # back if stop slave is issued
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
set @@global.slave_parallel_threads=2;
|
||||
--let $row_count_initial=`select count(*) from ti`
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10000;
|
||||
BEGIN;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
COMMIT;
|
||||
--eval insert into ti2 values ($ti2_ctr)
|
||||
--inc $ti2_ctr
|
||||
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti WRITE;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to begin executing the first transactions
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--echo # Wait for second transaction to start group commit
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to commit' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $row_count_end=`select count(*) from ti`
|
||||
--let $row_count_diff=`select ($row_count_end-$row_count_initial)`
|
||||
--let $assert_text= No insertions should have committed
|
||||
--let $assert_cond= $row_count_diff = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= GTID slave state should not change
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Common Test Case 4:
|
||||
--echo # Using multiple parallel replication threads (4) on workload
|
||||
--echo # T (long running); should commit
|
||||
--echo # N (waiting for prior commit); should commit
|
||||
--echo # T (long running); should rollback
|
||||
--echo # T (waiting for prior commit); should rollback
|
||||
--echo # Issuing STOP SLAVE should allow the first two transactions to commit
|
||||
--echo # while preventing and rolling back the third
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=optimistic;
|
||||
set @@global.slave_parallel_threads=4;
|
||||
|
||||
--connection master
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10001;
|
||||
BEGIN;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
COMMIT;
|
||||
|
||||
--connection master
|
||||
--eval insert into tm values ($tm_ctr)
|
||||
--inc $tm_ctr
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--eval insert into ti2 values ($ti2_ctr)
|
||||
--inc $ti2_ctr
|
||||
|
||||
--eval insert into ti3 values ($ti3_ctr)
|
||||
--inc $ti3_ctr
|
||||
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti WRITE, ti2 WRITE;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
--let $wait_condition= SELECT count(*)=2 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--echo # Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=2 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to commit' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= GTID slave state should reach first N transaction
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Common Test Case 5:
|
||||
--echo # Using multiple parallel replication threads (5) on workload
|
||||
--echo # T (long running); should commit
|
||||
--echo # N (waiting for prior commit); should commit
|
||||
--echo # T (waiting for prior commit); should commit
|
||||
--echo # N (waiting for prior commit); should commit
|
||||
--echo # T (long running); should rollback
|
||||
--echo # Issuing STOP SLAVE should allow all transactions up to and including
|
||||
--echo # the last N (4th) to commit, while preventing and rolling back the
|
||||
--echo # final transaction (5th)
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=optimistic;
|
||||
set @@global.slave_parallel_threads=5;
|
||||
|
||||
--connection master
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10002;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
--eval insert into tm values ($tm_ctr)
|
||||
--inc $tm_ctr
|
||||
|
||||
--eval insert into ti2 values ($ti2_ctr)
|
||||
--inc $ti2_ctr
|
||||
|
||||
--eval insert into tm2 values ($tm2_ctr)
|
||||
--inc $tm2_ctr
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--eval insert into ti3 values ($ti3_ctr)
|
||||
--inc $ti3_ctr
|
||||
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti WRITE, ti3 WRITE;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
--let $wait_condition= SELECT count(*)=2 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--echo # Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=3 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to commit' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= GTID slave state should reach second N transaction
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Common Test Case 6:
|
||||
--echo # If retrying a T transaction while STOP SLAVE is issued, the
|
||||
--echo # transaction should be rolled back and the slave abruptly stopped
|
||||
|
||||
--connection master
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
|
||||
--let $save_innodb_lock_wait_timeout= `SELECT @@global.innodb_lock_wait_timeout`
|
||||
# 2 second buffer to give ample time to wait for transaction and issue stop slave
|
||||
set @@global.innodb_lock_wait_timeout= 2;
|
||||
BEGIN;
|
||||
--eval SELECT * FROM ti WHERE a=$ti_ctr FOR UPDATE
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--eval update ti set a=a+1 where a=$ti_ctr
|
||||
--inc $ti_ctr
|
||||
--inc $ti_ctr
|
||||
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--let $retried_tx_initial= query_get_value(SHOW ALL SLAVES STATUS, Retried_transactions, 1)
|
||||
|
||||
if (`SELECT @@global.binlog_format = 'ROW'`)
|
||||
{
|
||||
--let $update_state=Update_rows_log_event::find_row(-1)
|
||||
}
|
||||
if (`SELECT @@global.binlog_format = 'STATEMENT'`)
|
||||
{
|
||||
--let $update_state=Updating
|
||||
}
|
||||
--echo # Wait for replicating transaction to wait for innodb table lock
|
||||
--source include/start_slave.inc
|
||||
--let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state LIKE "$update_state" and command like 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
connection slave;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
--let $retried_tx_test= query_get_value(SHOW ALL SLAVES STATUS, Retried_transactions, 1)
|
||||
if ($retried_tx_initial != $retried_tx_test)
|
||||
{
|
||||
--echo T transaction should have been rolled back without retry
|
||||
--die T transaction should have been rolled back without retry
|
||||
}
|
||||
|
||||
# End the SELECT ... FOR UPDATE
|
||||
ROLLBACK;
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= The retried T transaction should have been rolled back
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--eval set @@global.innodb_lock_wait_timeout= $save_innodb_lock_wait_timeout
|
||||
|
||||
--echo #
|
||||
--echo # Common Test Case 7:
|
||||
--echo # Using multiple parallel replication threads on a workload with a
|
||||
--echo # non-transactional transaction in-between transactional transactions..
|
||||
--echo # 7a: with AGGRESSIVE replication where the N statement has been
|
||||
--echo # executed already, all transactions up to and including N should
|
||||
--echo # be replicated, and all transactions afterwards should be rolled
|
||||
--echo # back.
|
||||
--echo # 7b: with MINIMAL replication, the N statement should not execute
|
||||
--echo # concurrently, but should wait along with the other later
|
||||
--echo # transactions, and all future transactions except the first should
|
||||
--echo # be rolled back.
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=4;
|
||||
|
||||
--let $mode_ctr=2
|
||||
while ($mode_ctr)
|
||||
{
|
||||
--connection slave
|
||||
if ($mode_ctr == 2)
|
||||
{
|
||||
--echo #
|
||||
--echo # 7a: slave_parallel_mode=AGGRESSIVE
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
}
|
||||
if ($mode_ctr == 1)
|
||||
{
|
||||
--echo #
|
||||
--echo # 7b: slave_parallel_mode=MINIMAL
|
||||
set @@global.slave_parallel_mode=MINIMAL;
|
||||
}
|
||||
|
||||
--connection slave
|
||||
--let $row_count_initial=`select count(*) from (select * from ti UNION ALL select * from tm UNION ALL select * from ti2 UNION ALL select * from tm2 UNION ALL select * from ti3) t`
|
||||
|
||||
--connection master
|
||||
if ($mode_ctr == 1)
|
||||
{
|
||||
--let $master_gtid_cmp= `select @@global.gtid_binlog_pos`
|
||||
}
|
||||
|
||||
--connection master
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
--eval insert into tm values ($tm_ctr)
|
||||
if ($mode_ctr == 2)
|
||||
{
|
||||
# AGGRESSIVE mode should allow N trx to complete
|
||||
--let $master_gtid_cmp= `select @@global.gtid_binlog_pos`
|
||||
}
|
||||
--eval insert into ti2 values ($ti2_ctr)
|
||||
--inc $ti2_ctr
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti WRITE;
|
||||
--connection slave_lock_extra
|
||||
LOCK TABLES ti2 WRITE;
|
||||
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to halt due to locks and dependency requirements
|
||||
--connection slave
|
||||
|
||||
if ($mode_ctr == 2)
|
||||
{
|
||||
# AGGRESSIVE allows for more concurrency that we need to wait for
|
||||
--let $wait_condition= SELECT count(*)=3 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to commit' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
}
|
||||
if ($mode_ctr == 1)
|
||||
{
|
||||
# MINIMAL will only have the first transaction begun
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
--let $wait_condition= SELECT count(*)=3 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to start commit%' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
}
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UNLOCK TABLES;
|
||||
--connection slave_lock_extra
|
||||
UNLOCK TABLES;
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--let $row_count_end=`select count(*) from (select * from ti UNION ALL select * from tm UNION ALL select * from ti2 UNION ALL select * from tm2 UNION ALL select * from ti3) t`
|
||||
--let $row_count_diff=`select ($row_count_end-$row_count_initial)`
|
||||
|
||||
if ($mode_ctr == 2)
|
||||
{
|
||||
--let $assert_text= The entirety of the first two transactions should have committed with AGGRESSIVE parallelization
|
||||
--let $assert_cond= $row_count_diff = 2
|
||||
}
|
||||
if ($mode_ctr == 1)
|
||||
{
|
||||
--let $assert_text= All transactions should have rolled back with MINIMAL parallelization
|
||||
--let $assert_cond= $row_count_diff = 0
|
||||
}
|
||||
|
||||
--source include/assert.inc
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= Slave state should be consistent
|
||||
--let $assert_cond= $master_gtid_cmp = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
--source include/stop_slave.inc
|
||||
--dec $mode_ctr
|
||||
}
|
||||
--source include/start_slave.inc
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
@@ -731,7 +731,7 @@ 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';
|
||||
# Wait for replica to signal worker threads to stop
|
||||
SET debug_sync='now SIGNAL t1_cont';
|
||||
include/wait_for_slave_sql_error.inc [errno=1317,1927,1964]
|
||||
STOP SLAVE IO_THREAD;
|
||||
@@ -741,7 +741,6 @@ a b
|
||||
61 61
|
||||
62 62
|
||||
63 63
|
||||
64 64
|
||||
68 68
|
||||
69 69
|
||||
70 70
|
||||
@@ -815,6 +814,7 @@ connection server_2;
|
||||
SET debug_sync='now WAIT_FOR wait_queue_ready';
|
||||
KILL THD_ID;
|
||||
SET debug_sync='now WAIT_FOR wait_queue_killed';
|
||||
# Wait for replica to signal worker threads to stop
|
||||
SET debug_sync='now SIGNAL query_cont';
|
||||
include/wait_for_slave_sql_error.inc [errno=1317,1927,1964]
|
||||
STOP SLAVE IO_THREAD;
|
||||
@@ -826,6 +826,8 @@ SET binlog_format=@old_format;
|
||||
connection server_2;
|
||||
SET debug_sync='RESET';
|
||||
include/start_slave.inc
|
||||
SET debug_sync='now WAIT_FOR query_waiting';
|
||||
SET debug_sync='now SIGNAL query_cont';
|
||||
SELECT * FROM t3 WHERE a >= 80 ORDER BY a;
|
||||
a b
|
||||
80 0
|
||||
@@ -1214,6 +1216,7 @@ connection server_2;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
SELECT * FROM t2 WHERE a >= 40 ORDER BY a;
|
||||
a
|
||||
40
|
||||
41
|
||||
42
|
||||
include/start_slave.inc
|
||||
|
@@ -1,6 +1,7 @@
|
||||
include/rpl_init.inc [topology=1->2]
|
||||
*** MDEV-5509: Incorrect value for Seconds_Behind_Master if parallel replication ***
|
||||
connection server_2;
|
||||
SET STATEMENT sql_log_bin=0 FOR 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;
|
||||
include/stop_slave.inc
|
||||
|
507
mysql-test/suite/rpl/r/rpl_row_par_stop_slave_quick.result
Normal file
507
mysql-test/suite/rpl/r/rpl_row_par_stop_slave_quick.result
Normal file
@@ -0,0 +1,507 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# Setup
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression("Can't find record");
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression("Commit failed due to failure");
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
connect slave_lock_extra,127.0.0.1,root,,test,$SLAVE_MYPORT;
|
||||
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
|
||||
include/start_slave.inc
|
||||
#
|
||||
# Initialize test data
|
||||
connection master;
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
|
||||
create sequence s1;
|
||||
create table ti (a int) engine=innodb;
|
||||
create table ti2 (a int) engine=innodb;
|
||||
create table ti3 (a int) engine=innodb;
|
||||
create table tm (a int) engine=myisam;
|
||||
create table tm2 (a int) engine=myisam;
|
||||
connection slave;
|
||||
# Run binlog format independent test cases
|
||||
#
|
||||
# Common Test Case 1:
|
||||
# Using one parallel replication worker thread on workload {T,T}, ensure
|
||||
# the replica immediately rolls back the transaction and stops the
|
||||
# SQL thread
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
BEGIN;
|
||||
insert into ti values (100);
|
||||
insert into ti values (101);
|
||||
COMMIT;
|
||||
insert into ti values (102);
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to begin executing the first transaction
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [No new rows should have been inserted]
|
||||
include/assert.inc [GTID slave state should not change]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 2:
|
||||
# Using multiple parallel replication threads (two) on workload {T,T},
|
||||
# ensure both transactions are rolled back if stop slave is issued
|
||||
# in the middle of the first transaction.
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=2;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
BEGIN;
|
||||
insert into ti values (103);
|
||||
insert into ti values (104);
|
||||
COMMIT;
|
||||
insert into ti values (105);
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to begin executing the first transaction
|
||||
connection slave;
|
||||
# Wait for second transaction to begin
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [No insertions should have committed]
|
||||
include/assert.inc [GTID slave state should not change]
|
||||
# Slave should be error-free
|
||||
include/assert.inc [Slave should be error free]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 3:
|
||||
# Using multiple parallel replication threads (two) on workload {T,T},
|
||||
# with the same commit id (cid), ensure both transactions are rolled
|
||||
# back if stop slave is issued
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
set @@global.slave_parallel_threads=2;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10000;
|
||||
BEGIN;
|
||||
insert into ti values (106);
|
||||
insert into ti values (107);
|
||||
COMMIT;
|
||||
insert into ti2 values (400);
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to begin executing the first transactions
|
||||
connection slave;
|
||||
# Wait for second transaction to start group commit
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [No insertions should have committed]
|
||||
include/assert.inc [GTID slave state should not change]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 4:
|
||||
# Using multiple parallel replication threads (4) on workload
|
||||
# T (long running); should commit
|
||||
# N (waiting for prior commit); should commit
|
||||
# T (long running); should rollback
|
||||
# T (waiting for prior commit); should rollback
|
||||
# Issuing STOP SLAVE should allow the first two transactions to commit
|
||||
# while preventing and rolling back the third
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=optimistic;
|
||||
set @@global.slave_parallel_threads=4;
|
||||
connection master;
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10001;
|
||||
BEGIN;
|
||||
insert into ti values (108);
|
||||
insert into ti values (109);
|
||||
COMMIT;
|
||||
connection master;
|
||||
insert into tm values (200);
|
||||
include/save_master_gtid.inc
|
||||
insert into ti2 values (401);
|
||||
insert into ti3 values (500);
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE, ti2 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
# Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [GTID slave state should reach first N transaction]
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 5:
|
||||
# Using multiple parallel replication threads (5) on workload
|
||||
# T (long running); should commit
|
||||
# N (waiting for prior commit); should commit
|
||||
# T (waiting for prior commit); should commit
|
||||
# N (waiting for prior commit); should commit
|
||||
# T (long running); should rollback
|
||||
# Issuing STOP SLAVE should allow all transactions up to and including
|
||||
# the last N (4th) to commit, while preventing and rolling back the
|
||||
# final transaction (5th)
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=optimistic;
|
||||
set @@global.slave_parallel_threads=5;
|
||||
connection master;
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10002;
|
||||
insert into ti values (110);
|
||||
insert into tm values (201);
|
||||
insert into ti2 values (402);
|
||||
insert into tm2 values (300);
|
||||
include/save_master_gtid.inc
|
||||
insert into ti3 values (501);
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE, ti3 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
# Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [GTID slave state should reach second N transaction]
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 6:
|
||||
# If retrying a T transaction while STOP SLAVE is issued, the
|
||||
# transaction should be rolled back and the slave abruptly stopped
|
||||
connection master;
|
||||
insert into ti values (111);
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
set @@global.innodb_lock_wait_timeout= 2;
|
||||
BEGIN;
|
||||
SELECT * FROM ti WHERE a=111 FOR UPDATE;
|
||||
a
|
||||
111
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
update ti set a=a+1 where a=111;
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
# Wait for replicating transaction to wait for innodb table lock
|
||||
include/start_slave.inc
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
ROLLBACK;
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [The retried T transaction should have been rolled back]
|
||||
set @@global.innodb_lock_wait_timeout= 50;
|
||||
#
|
||||
# Common Test Case 7:
|
||||
# Using multiple parallel replication threads on a workload with a
|
||||
# non-transactional transaction in-between transactional transactions..
|
||||
# 7a: with AGGRESSIVE replication where the N statement has been
|
||||
# executed already, all transactions up to and including N should
|
||||
# be replicated, and all transactions afterwards should be rolled
|
||||
# back.
|
||||
# 7b: with MINIMAL replication, the N statement should not execute
|
||||
# concurrently, but should wait along with the other later
|
||||
# transactions, and all future transactions except the first should
|
||||
# be rolled back.
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
Warnings:
|
||||
Note 1255 Slave already has been stopped
|
||||
set @@global.slave_parallel_threads=4;
|
||||
connection slave;
|
||||
#
|
||||
# 7a: slave_parallel_mode=AGGRESSIVE
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
connection slave;
|
||||
connection master;
|
||||
connection master;
|
||||
insert into ti values (113);
|
||||
insert into tm values (202);
|
||||
insert into ti2 values (403);
|
||||
insert into ti values (114);
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
connection slave_lock_extra;
|
||||
LOCK TABLES ti2 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to halt due to locks and dependency requirements
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
connection slave_lock_extra;
|
||||
UNLOCK TABLES;
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
include/assert.inc [The entirety of the first two transactions should have committed with AGGRESSIVE parallelization]
|
||||
include/assert.inc [Slave state should be consistent]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
connection slave;
|
||||
#
|
||||
# 7b: slave_parallel_mode=MINIMAL
|
||||
set @@global.slave_parallel_mode=MINIMAL;
|
||||
connection slave;
|
||||
connection master;
|
||||
connection master;
|
||||
insert into ti values (115);
|
||||
insert into tm values (202);
|
||||
insert into ti2 values (404);
|
||||
insert into ti values (116);
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
connection slave_lock_extra;
|
||||
LOCK TABLES ti2 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to halt due to locks and dependency requirements
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
connection slave_lock_extra;
|
||||
UNLOCK TABLES;
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
include/assert.inc [All transactions should have rolled back with MINIMAL parallelization]
|
||||
include/assert.inc [Slave state should be consistent]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
include/start_slave.inc
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# ROW Test Case 1:
|
||||
# Using an N multi-statement transaction, ensure if STOP SLAVE is
|
||||
# issued in-between row updates, that the transaction is finished.
|
||||
connection master;
|
||||
truncate table ti;
|
||||
truncate table tm;
|
||||
# Set up multiple rows to allow a multi-statement update rows event
|
||||
insert into tm values (202);
|
||||
insert into tm values (203);
|
||||
connection slave;
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
connection master;
|
||||
# Next-to-commit non-transactional transaction should finish
|
||||
update tm set a=a+1;
|
||||
include/save_master_gtid.inc
|
||||
# This should not be committed because it is after next-to-commit
|
||||
insert into ti values (117);
|
||||
connection slave;
|
||||
set @@global.debug_dbug="+d,pause_after_next_row_exec";
|
||||
START SLAVE;
|
||||
set debug_sync= "now WAIT_FOR row_executed";
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
set @@global.debug_dbug="";
|
||||
set debug_sync= "now SIGNAL continue_row_execution";
|
||||
connection slave1;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
# Slave should be error-free
|
||||
include/assert.inc [Slave should be error free]
|
||||
set debug_sync= "RESET";
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# ROW Test Case 2:
|
||||
# Using a T multi-statement transaction, ensure if STOP SLAVE is
|
||||
# issued in-between row updates, that the transaction is rolled back.
|
||||
connection master;
|
||||
truncate table ti;
|
||||
truncate table ti2;
|
||||
truncate table tm;
|
||||
insert into ti values (118);
|
||||
insert into ti values (119);
|
||||
connection slave;
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
connection master;
|
||||
# Next-to-commit transactional multi-row event should be rolled back
|
||||
include/save_master_gtid.inc
|
||||
update ti set a=a+1;
|
||||
insert into ti values (120);
|
||||
connection slave;
|
||||
set @@global.debug_dbug="+d,pause_after_next_row_exec";
|
||||
START SLAVE;
|
||||
set debug_sync= "now WAIT_FOR row_executed";
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
set @@global.debug_dbug="";
|
||||
set debug_sync= "now SIGNAL continue_row_execution";
|
||||
connection slave1;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
include/assert.inc [No new rows should have been inserted]
|
||||
# Comparing master gtid 0-1-42 to slaves 0-1-42
|
||||
include/assert.inc [No transactions should have committed]
|
||||
# Slave should be error-free
|
||||
include/assert.inc [Slave should be error free]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
set debug_sync= "RESET";
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Row Test Case 3:
|
||||
# A workload with a later transaction that updates a sequence table
|
||||
# should complete all transactions up to the sequence table update.
|
||||
# Workload:
|
||||
# T (long running); should commit
|
||||
# S (waiting for prior commit); should commit
|
||||
# T (long running); should rollback
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
set @@global.slave_parallel_threads=3;
|
||||
connection master;
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10002;
|
||||
insert into ti values (121);
|
||||
select next value for s1;
|
||||
next value for s1
|
||||
1
|
||||
include/save_master_gtid.inc
|
||||
insert into ti2 values (405);
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
connection slave;
|
||||
LOCK TABLES ti write, ti2 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
# Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [GTID slave state should not change]
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Cleanup
|
||||
connection master;
|
||||
DROP TABLE ti, ti2, ti3, tm, tm2, s1;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
set @@global.debug_dbug="";
|
||||
set @@global.slave_parallel_threads=0;
|
||||
set @@global.slave_parallel_mode=conservative;
|
||||
include/start_slave.inc
|
||||
include/rpl_end.inc
|
||||
# End of tests
|
461
mysql-test/suite/rpl/r/rpl_stm_par_stop_slave_quick.result
Normal file
461
mysql-test/suite/rpl/r/rpl_stm_par_stop_slave_quick.result
Normal file
@@ -0,0 +1,461 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# Setup
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
change master to master_use_gtid=slave_pos;
|
||||
include/start_slave.inc
|
||||
connect slave_lock_extra,127.0.0.1,root,,test,$SLAVE_MYPORT;
|
||||
#
|
||||
# Initialize test data
|
||||
connection master;
|
||||
set statement sql_log_bin=0 for call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
|
||||
create table ti (a int primary key) engine=innodb;
|
||||
create table ti2 (a int) engine=innodb;
|
||||
create table ti3 (a int) engine=innodb;
|
||||
create table tm (a int) engine=myisam;
|
||||
create table tm2 (a int) engine=myisam;
|
||||
connection slave;
|
||||
# Run binlog format independent test cases
|
||||
#
|
||||
# Common Test Case 1:
|
||||
# Using one parallel replication worker thread on workload {T,T}, ensure
|
||||
# the replica immediately rolls back the transaction and stops the
|
||||
# SQL thread
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
BEGIN;
|
||||
insert into ti values (100);
|
||||
insert into ti values (101);
|
||||
COMMIT;
|
||||
insert into ti values (102);
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to begin executing the first transaction
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [No new rows should have been inserted]
|
||||
include/assert.inc [GTID slave state should not change]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 2:
|
||||
# Using multiple parallel replication threads (two) on workload {T,T},
|
||||
# ensure both transactions are rolled back if stop slave is issued
|
||||
# in the middle of the first transaction.
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=2;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
BEGIN;
|
||||
insert into ti values (103);
|
||||
insert into ti values (104);
|
||||
COMMIT;
|
||||
insert into ti values (105);
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to begin executing the first transaction
|
||||
connection slave;
|
||||
# Wait for second transaction to begin
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [No insertions should have committed]
|
||||
include/assert.inc [GTID slave state should not change]
|
||||
# Slave should be error-free
|
||||
include/assert.inc [Slave should be error free]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 3:
|
||||
# Using multiple parallel replication threads (two) on workload {T,T},
|
||||
# with the same commit id (cid), ensure both transactions are rolled
|
||||
# back if stop slave is issued
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
set @@global.slave_parallel_threads=2;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10000;
|
||||
BEGIN;
|
||||
insert into ti values (106);
|
||||
insert into ti values (107);
|
||||
COMMIT;
|
||||
insert into ti2 values (400);
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to begin executing the first transactions
|
||||
connection slave;
|
||||
# Wait for second transaction to start group commit
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [No insertions should have committed]
|
||||
include/assert.inc [GTID slave state should not change]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 4:
|
||||
# Using multiple parallel replication threads (4) on workload
|
||||
# T (long running); should commit
|
||||
# N (waiting for prior commit); should commit
|
||||
# T (long running); should rollback
|
||||
# T (waiting for prior commit); should rollback
|
||||
# Issuing STOP SLAVE should allow the first two transactions to commit
|
||||
# while preventing and rolling back the third
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=optimistic;
|
||||
set @@global.slave_parallel_threads=4;
|
||||
connection master;
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10001;
|
||||
BEGIN;
|
||||
insert into ti values (108);
|
||||
insert into ti values (109);
|
||||
COMMIT;
|
||||
connection master;
|
||||
insert into tm values (200);
|
||||
include/save_master_gtid.inc
|
||||
insert into ti2 values (401);
|
||||
insert into ti3 values (500);
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE, ti2 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
# Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [GTID slave state should reach first N transaction]
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 5:
|
||||
# Using multiple parallel replication threads (5) on workload
|
||||
# T (long running); should commit
|
||||
# N (waiting for prior commit); should commit
|
||||
# T (waiting for prior commit); should commit
|
||||
# N (waiting for prior commit); should commit
|
||||
# T (long running); should rollback
|
||||
# Issuing STOP SLAVE should allow all transactions up to and including
|
||||
# the last N (4th) to commit, while preventing and rolling back the
|
||||
# final transaction (5th)
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=optimistic;
|
||||
set @@global.slave_parallel_threads=5;
|
||||
connection master;
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10002;
|
||||
insert into ti values (110);
|
||||
insert into tm values (201);
|
||||
insert into ti2 values (402);
|
||||
insert into tm2 values (300);
|
||||
include/save_master_gtid.inc
|
||||
insert into ti3 values (501);
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE, ti3 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
# Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [GTID slave state should reach second N transaction]
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Common Test Case 6:
|
||||
# If retrying a T transaction while STOP SLAVE is issued, the
|
||||
# transaction should be rolled back and the slave abruptly stopped
|
||||
connection master;
|
||||
insert into ti values (111);
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
set @@global.innodb_lock_wait_timeout= 2;
|
||||
BEGIN;
|
||||
SELECT * FROM ti WHERE a=111 FOR UPDATE;
|
||||
a
|
||||
111
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
update ti set a=a+1 where a=111;
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
# Wait for replicating transaction to wait for innodb table lock
|
||||
include/start_slave.inc
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
ROLLBACK;
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [The retried T transaction should have been rolled back]
|
||||
set @@global.innodb_lock_wait_timeout= 50;
|
||||
#
|
||||
# Common Test Case 7:
|
||||
# Using multiple parallel replication threads on a workload with a
|
||||
# non-transactional transaction in-between transactional transactions..
|
||||
# 7a: with AGGRESSIVE replication where the N statement has been
|
||||
# executed already, all transactions up to and including N should
|
||||
# be replicated, and all transactions afterwards should be rolled
|
||||
# back.
|
||||
# 7b: with MINIMAL replication, the N statement should not execute
|
||||
# concurrently, but should wait along with the other later
|
||||
# transactions, and all future transactions except the first should
|
||||
# be rolled back.
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
Warnings:
|
||||
Note 1255 Slave already has been stopped
|
||||
set @@global.slave_parallel_threads=4;
|
||||
connection slave;
|
||||
#
|
||||
# 7a: slave_parallel_mode=AGGRESSIVE
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
connection slave;
|
||||
connection master;
|
||||
connection master;
|
||||
insert into ti values (113);
|
||||
insert into tm values (202);
|
||||
insert into ti2 values (403);
|
||||
insert into ti values (114);
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
connection slave_lock_extra;
|
||||
LOCK TABLES ti2 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to halt due to locks and dependency requirements
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
connection slave_lock_extra;
|
||||
UNLOCK TABLES;
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
include/assert.inc [The entirety of the first two transactions should have committed with AGGRESSIVE parallelization]
|
||||
include/assert.inc [Slave state should be consistent]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
connection slave;
|
||||
#
|
||||
# 7b: slave_parallel_mode=MINIMAL
|
||||
set @@global.slave_parallel_mode=MINIMAL;
|
||||
connection slave;
|
||||
connection master;
|
||||
connection master;
|
||||
insert into ti values (115);
|
||||
insert into tm values (202);
|
||||
insert into ti2 values (404);
|
||||
insert into ti values (116);
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
connection slave_lock_extra;
|
||||
LOCK TABLES ti2 WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to halt due to locks and dependency requirements
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
connection slave_lock_extra;
|
||||
UNLOCK TABLES;
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
include/assert.inc [All transactions should have rolled back with MINIMAL parallelization]
|
||||
include/assert.inc [Slave state should be consistent]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
include/start_slave.inc
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
Warnings:
|
||||
Note 1254 Slave is already running
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Statement Test Case 1:
|
||||
# Using one parallel replication worker thread on workload {N,T}, ensure
|
||||
# the replica finishes the non-transactional transaction, and does not
|
||||
# start the next
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
connection master;
|
||||
SET @@session.binlog_direct_non_transactional_updates= 0;
|
||||
BEGIN;
|
||||
insert into ti values (117);
|
||||
insert into tm values (202);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction
|
||||
insert into tm2 values (301);
|
||||
Warnings:
|
||||
Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction
|
||||
COMMIT;
|
||||
include/save_master_gtid.inc
|
||||
insert into ti values (118);
|
||||
connection slave;
|
||||
lock tables tm2 write;
|
||||
START SLAVE;
|
||||
# Wait for replica to get stuck on held lock
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
# Unlock row-level lock holding transaction
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [Transaction should have committed]
|
||||
include/assert.inc [N should have been applied]
|
||||
# Slave should be error-free
|
||||
include/assert.inc [Slave should be error free]
|
||||
connection master;
|
||||
include/save_master_gtid.inc
|
||||
SET @@session.binlog_direct_non_transactional_updates= 1;
|
||||
connection slave;
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Statement Test Case 2:
|
||||
# If STOP SLAVE is issued on a parallel slave, such that the next to
|
||||
# commit transaction is T; even if the next event from the group will
|
||||
# commit the transaction (e.g. XID_EVENT), the transaction should be
|
||||
# stopped and rolled back.
|
||||
connection slave;
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
connection master;
|
||||
insert into ti values (119);
|
||||
insert into ti values (120);
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
LOCK TABLES ti WRITE;
|
||||
include/start_slave.inc
|
||||
# Wait for replica to begin executing the first transaction
|
||||
connection slave;
|
||||
connection slave1;
|
||||
STOP SLAVE;;
|
||||
connection slave;
|
||||
# Wait for replica to signal worker threads to stop
|
||||
UNLOCK TABLES;
|
||||
include/wait_for_slave_sql_to_stop.inc
|
||||
connection slave1;
|
||||
connection slave;
|
||||
include/assert.inc [No insertions should have committed]
|
||||
include/assert.inc [GTID slave state should increment to the first transaction]
|
||||
include/start_slave.inc
|
||||
include/sync_with_master_gtid.inc
|
||||
#
|
||||
# Cleanup
|
||||
connection master;
|
||||
DROP TABLE ti, tm, ti2, tm2, ti3;
|
||||
include/save_master_gtid.inc
|
||||
connection slave;
|
||||
include/sync_with_master_gtid.inc
|
||||
include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=0;
|
||||
set @@global.slave_domain_parallel_threads=0;
|
||||
set @@global.slave_parallel_mode=conservative;
|
||||
set @@global.debug_dbug="";
|
||||
include/start_slave.inc
|
||||
include/rpl_end.inc
|
||||
# End of tests
|
@@ -949,8 +949,9 @@ SET debug_sync='now WAIT_FOR t4_waiting';
|
||||
--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';
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# Now we can allow T1 to proceed.
|
||||
SET debug_sync='now SIGNAL t1_cont';
|
||||
@@ -959,7 +960,7 @@ SET debug_sync='now SIGNAL t1_cont';
|
||||
--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
|
||||
# to commit or not before the stop. However, T1 should rollback, 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;
|
||||
@@ -1058,6 +1059,11 @@ SET debug_sync='now WAIT_FOR wait_queue_ready';
|
||||
eval KILL $thd_id;
|
||||
|
||||
SET debug_sync='now WAIT_FOR wait_queue_killed';
|
||||
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SET debug_sync='now SIGNAL query_cont';
|
||||
|
||||
--let $slave_sql_errno= 1317,1927,1964
|
||||
@@ -1075,6 +1081,14 @@ SET binlog_format=@old_format;
|
||||
--connection server_2
|
||||
SET debug_sync='RESET';
|
||||
--source include/start_slave.inc
|
||||
|
||||
# Test amendment from MDEV-13915:
|
||||
# A worker thread's event queue is no longer executed on replica stop.
|
||||
# The signal query_cont needs to be re-sent because the transaction was
|
||||
# aborted.
|
||||
SET debug_sync='now WAIT_FOR query_waiting';
|
||||
SET debug_sync='now SIGNAL query_cont';
|
||||
|
||||
--sync_with_master
|
||||
SELECT * FROM t3 WHERE a >= 80 ORDER BY a;
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
--echo *** MDEV-5509: Incorrect value for Seconds_Behind_Master if parallel replication ***
|
||||
|
||||
--connection server_2
|
||||
SET STATEMENT sql_log_bin=0 FOR 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;
|
||||
--source include/stop_slave.inc
|
||||
|
@@ -122,10 +122,10 @@ SELECT COUNT(*) = 1 as "W4 remains with the same status" FROM information_schema
|
||||
--echo # Slave_SQL_Running YES = $status
|
||||
|
||||
# B. In the fixed version W3 is waiting for W2,...
|
||||
--let $wait_condition= SELECT count(*) = 1 as "W4 is waiting" FROM information_schema.processlist WHERE state LIKE "Waiting for prior transaction to commit%"
|
||||
--let $wait_condition= SELECT count(*) = 1 as "W3 is waiting" FROM information_schema.processlist WHERE state LIKE "Waiting for prior transaction to commit%"
|
||||
--source include/wait_condition.inc
|
||||
--echo # while W2 is held back ...
|
||||
--let $wait_condition= SELECT count(*) = 1 as "W2 simulates slowness" FROM information_schema.processlist WHERE state LIKE "debug sync point: now"
|
||||
--let $wait_condition= SELECT count(*) >= 1 as "W2 simulates slowness" FROM information_schema.processlist WHERE state LIKE "debug sync point: now"
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# C. # ...until NOW.
|
||||
@@ -143,7 +143,7 @@ if ($old_version_regression)
|
||||
--let $wait_condition= SELECT count(*) = 0 as "W3 does not wait on W2" FROM information_schema.processlist WHERE state LIKE "Waiting for prior transaction to commit%"
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--let $wait_condition= SELECT count(*) = 1 as "W2 simulates slowness" FROM information_schema.processlist WHERE state LIKE "debug sync point: now"
|
||||
--let $wait_condition= SELECT count(*) >= 1 as "W2 simulates slowness" FROM information_schema.processlist WHERE state LIKE "debug sync point: now"
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# Like above, but signaling is done after W4 is done to violate the commit order
|
||||
|
268
mysql-test/suite/rpl/t/rpl_row_par_stop_slave_quick.test
Normal file
268
mysql-test/suite/rpl/t/rpl_row_par_stop_slave_quick.test
Normal file
@@ -0,0 +1,268 @@
|
||||
#
|
||||
# Validate that STOP SLAVE works in a timely manner on a parallel replica with
|
||||
# ROW binary logging format.
|
||||
#
|
||||
--source include/have_debug.inc
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/master-slave.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_binlog_format_row.inc
|
||||
|
||||
--echo #
|
||||
--echo # Setup
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression("Can't find record");
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression("Commit failed due to failure");
|
||||
--let $old_debug= `SELECT @@global.debug_dbug`
|
||||
--let $old_threads= `SELECT @@global.slave_parallel_threads`
|
||||
--let $old_slave_mode= `SELECT @@global.slave_parallel_mode`
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
--connect(slave_lock_extra,127.0.0.1,root,,test,$SLAVE_MYPORT)
|
||||
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo #
|
||||
--echo # Initialize test data
|
||||
--connection master
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
|
||||
|
||||
# Needed by this test and include/rpl_par_stop_slave_quick.inc
|
||||
|
||||
create sequence s1;
|
||||
create table ti (a int) engine=innodb;
|
||||
create table ti2 (a int) engine=innodb;
|
||||
create table ti3 (a int) engine=innodb;
|
||||
create table tm (a int) engine=myisam;
|
||||
create table tm2 (a int) engine=myisam;
|
||||
--let $ti_ctr= 100
|
||||
--let $tm_ctr= 200
|
||||
--let $tm2_ctr= 300
|
||||
--let $ti2_ctr= 400
|
||||
--let $ti3_ctr= 500
|
||||
--sync_slave_with_master
|
||||
|
||||
--echo # Run binlog format independent test cases
|
||||
--source include/rpl_par_stop_slave_quick_common.test
|
||||
|
||||
--echo #
|
||||
--echo # ROW Test Case 1:
|
||||
--echo # Using an N multi-statement transaction, ensure if STOP SLAVE is
|
||||
--echo # issued in-between row updates, that the transaction is finished.
|
||||
|
||||
--connection master
|
||||
truncate table ti;
|
||||
truncate table tm;
|
||||
--echo # Set up multiple rows to allow a multi-statement update rows event
|
||||
--eval insert into tm values ($tm_ctr)
|
||||
--inc $tm_ctr
|
||||
--eval insert into tm values ($tm_ctr)
|
||||
--inc $tm_ctr
|
||||
--sync_slave_with_master
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
--let $row_count_initial=`select count(*) from (select * from ti UNION ALL select * from tm) t`
|
||||
|
||||
--connection master
|
||||
|
||||
--echo # Next-to-commit non-transactional transaction should finish
|
||||
--eval update tm set a=a+1
|
||||
--source include/save_master_gtid.inc
|
||||
--let $master_gtid_after_update= `select @@global.gtid_binlog_pos`
|
||||
|
||||
--echo # This should not be committed because it is after next-to-commit
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
--connection slave
|
||||
set @@global.debug_dbug="+d,pause_after_next_row_exec";
|
||||
|
||||
START SLAVE;
|
||||
set debug_sync= "now WAIT_FOR row_executed";
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
set @@global.debug_dbug="";
|
||||
set debug_sync= "now SIGNAL continue_row_execution";
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--echo # Slave should be error-free
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
|
||||
--let $assert_text= Slave should be error free
|
||||
--let $assert_cond= $last_error = 0
|
||||
--source include/assert.inc
|
||||
|
||||
set debug_sync= "RESET";
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # ROW Test Case 2:
|
||||
--echo # Using a T multi-statement transaction, ensure if STOP SLAVE is
|
||||
--echo # issued in-between row updates, that the transaction is rolled back.
|
||||
|
||||
--connection master
|
||||
truncate table ti;
|
||||
truncate table ti2;
|
||||
truncate table tm;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--sync_slave_with_master
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
--let $row_count_initial=`select count(*) from (select * from ti UNION ALL select * from tm) t`
|
||||
|
||||
--connection master
|
||||
|
||||
--echo # Next-to-commit transactional multi-row event should be rolled back
|
||||
--source include/save_master_gtid.inc
|
||||
--let $master_gtid_initial= `select @@global.gtid_binlog_pos`
|
||||
--eval update ti set a=a+1
|
||||
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
--connection slave
|
||||
set @@global.debug_dbug="+d,pause_after_next_row_exec";
|
||||
START SLAVE;
|
||||
set debug_sync= "now WAIT_FOR row_executed";
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
set @@global.debug_dbug="";
|
||||
set debug_sync= "now SIGNAL continue_row_execution";
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--let $row_count_end=`select count(*) from (select * from ti UNION ALL select * from tm) t`
|
||||
--let $row_count_diff=`select ($row_count_end-$row_count_initial)`
|
||||
--let $assert_text= No new rows should have been inserted
|
||||
--let $assert_cond= $row_count_diff = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--echo # Comparing master gtid $master_pos to slaves $slave_gtid
|
||||
--let $assert_text= No transactions should have committed
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--echo # Slave should be error-free
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
|
||||
--let $assert_text= Slave should be error free
|
||||
--let $assert_cond= $last_error = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
set debug_sync= "RESET";
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Row Test Case 3:
|
||||
--echo # A workload with a later transaction that updates a sequence table
|
||||
--echo # should complete all transactions up to the sequence table update.
|
||||
--echo # Workload:
|
||||
--echo # T (long running); should commit
|
||||
--echo # S (waiting for prior commit); should commit
|
||||
--echo # T (long running); should rollback
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_mode=AGGRESSIVE;
|
||||
set @@global.slave_parallel_threads=3;
|
||||
|
||||
--connection master
|
||||
SET @old_dbug= @@SESSION.debug_dbug;
|
||||
SET @@SESSION.debug_dbug="+d,binlog_force_commit_id";
|
||||
SET @commit_id= 10002;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
select next value for s1;
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--eval insert into ti2 values ($ti2_ctr)
|
||||
--inc $ti2_ctr
|
||||
|
||||
SET @@SESSION.debug_dbug=@old_dbug;
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti write, ti2 WRITE;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to progress until the transactions targeting locked tables are stuck on their locks..
|
||||
--let $wait_condition= SELECT count(*)=2 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--echo # Wait for replica to progress until unblocked transactions are queued for group commit..
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to commit' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= GTID slave state should not change
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Cleanup
|
||||
--connection master
|
||||
DROP TABLE ti, ti2, ti3, tm, tm2, s1;
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
--source include/sync_with_master_gtid.inc
|
||||
--source include/stop_slave.inc
|
||||
--eval set @@global.debug_dbug="$old_debug"
|
||||
--eval set @@global.slave_parallel_threads=$old_threads
|
||||
--eval set @@global.slave_parallel_mode=$old_slave_mode
|
||||
--source include/start_slave.inc
|
||||
|
||||
--source include/rpl_end.inc
|
||||
|
||||
--echo # End of tests
|
200
mysql-test/suite/rpl/t/rpl_stm_par_stop_slave_quick.test
Normal file
200
mysql-test/suite/rpl/t/rpl_stm_par_stop_slave_quick.test
Normal file
@@ -0,0 +1,200 @@
|
||||
#
|
||||
# Validate that STOP SLAVE works in a timely manner on a parallel replica with
|
||||
# STATEMENT binary logging format.
|
||||
#
|
||||
--source include/have_debug.inc
|
||||
--source include/master-slave.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_binlog_format_statement.inc
|
||||
|
||||
--echo #
|
||||
--echo # Setup
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
|
||||
SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
|
||||
--let $old_threads= `SELECT @@global.slave_parallel_threads`
|
||||
--let $old_domain_threads= `SELECT @@global.slave_domain_parallel_threads`
|
||||
--let $old_slave_mode= `SELECT @@global.slave_parallel_mode`
|
||||
--let $old_debug_dbug= `SELECT @@global.debug_dbug`
|
||||
set @@global.slave_parallel_mode=CONSERVATIVE;
|
||||
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
change master to master_use_gtid=slave_pos;
|
||||
--source include/start_slave.inc
|
||||
--connect(slave_lock_extra,127.0.0.1,root,,test,$SLAVE_MYPORT)
|
||||
|
||||
--echo #
|
||||
--echo # Initialize test data
|
||||
--connection master
|
||||
set statement sql_log_bin=0 for call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
|
||||
create table ti (a int primary key) engine=innodb;
|
||||
create table ti2 (a int) engine=innodb;
|
||||
create table ti3 (a int) engine=innodb;
|
||||
create table tm (a int) engine=myisam;
|
||||
create table tm2 (a int) engine=myisam;
|
||||
--let $ti_ctr= 100
|
||||
--let $tm_ctr= 200
|
||||
--let $tm2_ctr= 300
|
||||
--let $ti2_ctr= 400
|
||||
--let $ti3_ctr= 500
|
||||
--sync_slave_with_master
|
||||
|
||||
--echo # Run binlog format independent test cases
|
||||
--source include/rpl_par_stop_slave_quick_common.test
|
||||
|
||||
--echo #
|
||||
--echo # Statement Test Case 1:
|
||||
--echo # Using one parallel replication worker thread on workload {N,T}, ensure
|
||||
--echo # the replica finishes the non-transactional transaction, and does not
|
||||
--echo # start the next
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
--let $row_count_initial=`select count(*) from (select * from ti UNION ALL select * from tm UNION ALL select * from tm2) t`
|
||||
|
||||
--connection master
|
||||
--let $old_binlog_direct= `SELECT @@global.binlog_direct_non_transactional_updates`
|
||||
SET @@session.binlog_direct_non_transactional_updates= 0;
|
||||
BEGIN;
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--eval insert into tm values ($tm_ctr)
|
||||
--inc $tm_ctr
|
||||
--eval insert into tm2 values ($tm2_ctr)
|
||||
--inc $tm_ctr
|
||||
COMMIT;
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
|
||||
--connection slave
|
||||
lock tables tm2 write;
|
||||
START SLAVE;
|
||||
|
||||
--echo # Wait for replica to get stuck on held lock
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--echo # Unlock row-level lock holding transaction
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $row_count_end=`select count(*) from (select * from ti UNION ALL select * from tm UNION ALL select * from tm2) t`
|
||||
--let $row_count_diff=`select ($row_count_end-$row_count_initial)`
|
||||
--let $assert_text= Transaction should have committed
|
||||
--let $assert_cond= $row_count_diff = 3
|
||||
--source include/assert.inc
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
# N is the non-transactional transaction
|
||||
--let $assert_text= N should have been applied
|
||||
--let $assert_cond= $master_pos = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--echo # Slave should be error-free
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
|
||||
--let $assert_text= Slave should be error free
|
||||
--let $assert_cond= $last_error = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--connection master
|
||||
--source include/save_master_gtid.inc
|
||||
--eval SET @@session.binlog_direct_non_transactional_updates= $old_binlog_direct
|
||||
|
||||
--connection slave
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Statement Test Case 2:
|
||||
--echo # If STOP SLAVE is issued on a parallel slave, such that the next to
|
||||
--echo # commit transaction is T; even if the next event from the group will
|
||||
--echo # commit the transaction (e.g. XID_EVENT), the transaction should be
|
||||
--echo # stopped and rolled back.
|
||||
|
||||
--connection slave
|
||||
--source include/stop_slave.inc
|
||||
set @@global.slave_parallel_threads=1;
|
||||
--let $row_count_initial=`select count(*) from (select * from ti UNION ALL select * from tm) t`
|
||||
|
||||
--connection master
|
||||
--let $master_gtid_cmp= `select @@global.gtid_binlog_pos`
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--eval insert into ti values ($ti_ctr)
|
||||
--inc $ti_ctr
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
LOCK TABLES ti WRITE;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--echo # Wait for replica to begin executing the first transaction
|
||||
--connection slave
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock' and command LIKE 'Slave_worker';
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection slave1
|
||||
--send STOP SLAVE;
|
||||
|
||||
--connection slave
|
||||
--echo # Wait for replica to signal worker threads to stop
|
||||
--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for worker thread to stop';
|
||||
--source include/wait_condition.inc
|
||||
UNLOCK TABLES;
|
||||
--source include/wait_for_slave_sql_to_stop.inc
|
||||
|
||||
--connection slave1
|
||||
--reap
|
||||
--connection slave
|
||||
|
||||
--let $row_count_end=`select count(*) from (select * from ti UNION ALL select * from tm) t`
|
||||
--let $row_count_diff=`select ($row_count_end-$row_count_initial)`
|
||||
--let $assert_text= No insertions should have committed
|
||||
--let $assert_cond= $row_count_diff = 0
|
||||
--source include/assert.inc
|
||||
|
||||
--let $slave_gtid= `select @@global.gtid_slave_pos`
|
||||
--let $assert_text= GTID slave state should increment to the first transaction
|
||||
--let $assert_cond= $master_gtid_cmp = $slave_gtid
|
||||
--source include/assert.inc
|
||||
|
||||
--source include/start_slave.inc
|
||||
--source include/sync_with_master_gtid.inc
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Cleanup
|
||||
--connection master
|
||||
DROP TABLE ti, tm, ti2, tm2, ti3;
|
||||
--source include/save_master_gtid.inc
|
||||
|
||||
--connection slave
|
||||
--source include/sync_with_master_gtid.inc
|
||||
--source include/stop_slave.inc
|
||||
--eval set @@global.slave_parallel_threads=$old_threads
|
||||
--eval set @@global.slave_domain_parallel_threads=$old_domain_threads
|
||||
--eval set @@global.slave_parallel_mode=$old_slave_mode
|
||||
--eval set @@global.debug_dbug="$old_debug_dbug"
|
||||
--source include/start_slave.inc
|
||||
|
||||
--source include/rpl_end.inc
|
||||
|
||||
--echo # End of tests
|
Reference in New Issue
Block a user