1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Revert "MDEV-13915: STOP SLAVE takes very long time on a busy system"

This reverts commit 0a99d457b3
because it should go into only 10.5+
This commit is contained in:
Brandon Nesterenko
2023-06-06 08:11:38 -06:00
parent 677d6f0f23
commit 8ed88e3455
20 changed files with 24 additions and 2187 deletions

View File

@@ -1,608 +0,0 @@
#
# 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

View File

@@ -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;
# Wait for replica to signal worker threads to stop
SET debug_sync='now WAIT_FOR t3_killed';
SET debug_sync='now SIGNAL t1_cont';
include/wait_for_slave_sql_error.inc [errno=1317,1927,1964]
STOP SLAVE IO_THREAD;
@@ -741,6 +741,7 @@ a b
61 61
62 62
63 63
64 64
68 68
69 69
70 70
@@ -814,7 +815,6 @@ 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,8 +826,6 @@ 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
@@ -1216,7 +1214,6 @@ 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

View File

@@ -1,7 +1,6 @@
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

View File

@@ -1,507 +0,0 @@
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

View File

@@ -1,461 +0,0 @@
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

View File

@@ -949,9 +949,8 @@ SET debug_sync='now WAIT_FOR t4_waiting';
--replace_result $d1_thd_id THD_ID
eval KILL $d1_thd_id;
--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
# Wait until T3 has reacted on the kill.
SET debug_sync='now WAIT_FOR t3_killed';
# Now we can allow T1 to proceed.
SET debug_sync='now SIGNAL t1_cont';
@@ -960,7 +959,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 rollback, and T3/T4 may
# to commit or not before the stop. However, T1 should commit, and T3/T4 may
# not have committed. (After slave restart we check that all become committed
# eventually).
SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a;
@@ -1059,11 +1058,6 @@ 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
@@ -1081,14 +1075,6 @@ 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;

View File

@@ -7,7 +7,6 @@
--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

View File

@@ -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 "W3 is waiting" FROM information_schema.processlist WHERE state LIKE "Waiting for prior transaction to commit%"
--let $wait_condition= SELECT count(*) = 1 as "W4 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

View File

@@ -1,268 +0,0 @@
#
# 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

View File

@@ -1,200 +0,0 @@
#
# 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