diff options
Diffstat (limited to 'mysql-test')
-rw-r--r-- | mysql-test/include/commit.inc | 2 | ||||
-rw-r--r-- | mysql-test/lib/My/Debugger.pm | 2 | ||||
-rw-r--r-- | mysql-test/main/commit_1innodb.result | 2 | ||||
-rw-r--r-- | mysql-test/main/mdev_22370.result | 4 | ||||
-rw-r--r-- | mysql-test/main/mdev_22370.test | 17 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result | 40 | ||||
-rw-r--r-- | mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test | 95 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result | 77 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_slave_shutdown_mdev20821.result | 79 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test | 142 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.cnf | 19 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.test | 171 |
12 files changed, 647 insertions, 3 deletions
diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index a28d3e5f3d1..1844a5320f7 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -770,7 +770,7 @@ call p_verify_status_increment(2, 0, 2, 0); commit; call p_verify_status_increment(0, 0, 0, 0); check table t1, t2, t3; -call p_verify_status_increment(6, 0, 6, 0); +call p_verify_status_increment(4, 0, 4, 0); commit; call p_verify_status_increment(0, 0, 0, 0); drop view v1; diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index 5e04c070e7f..cc151b233d5 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -139,7 +139,7 @@ sub do_args($$$$$) { my $v = $debuggers{$k}; # on windows mtr args are quoted (for system), otherwise not (for exec) - sub quote($) { $_[0] =~ / / ? "\"$_[0]\"" : $_[0] } + sub quote($) { $_[0] =~ /[; ]/ ? "\"$_[0]\"" : $_[0] } sub unquote($) { $_[0] =~ s/^"(.*)"$/$1/; $_[0] } sub quote_from_mtr($) { IS_WINDOWS() ? $_[0] : quote($_[0]) } sub unquote_for_mtr($) { IS_WINDOWS() ? $_[0] : unquote($_[0]) } diff --git a/mysql-test/main/commit_1innodb.result b/mysql-test/main/commit_1innodb.result index 7d21540b548..a7b544dc282 100644 --- a/mysql-test/main/commit_1innodb.result +++ b/mysql-test/main/commit_1innodb.result @@ -874,7 +874,7 @@ Table Op Msg_type Msg_text test.t1 check status OK test.t2 check status OK test.t3 check status OK -call p_verify_status_increment(6, 0, 6, 0); +call p_verify_status_increment(4, 0, 4, 0); SUCCESS commit; diff --git a/mysql-test/main/mdev_22370.result b/mysql-test/main/mdev_22370.result new file mode 100644 index 00000000000..d422ee6e81f --- /dev/null +++ b/mysql-test/main/mdev_22370.result @@ -0,0 +1,4 @@ +connect con1,localhost,root,,; +SET DEBUG_DBUG='+d,mark_busy_mdev_22370'; +FLUSH TABLES WITH READ LOCK; +connection default; diff --git a/mysql-test/main/mdev_22370.test b/mysql-test/main/mdev_22370.test new file mode 100644 index 00000000000..86bc527ebc0 --- /dev/null +++ b/mysql-test/main/mdev_22370.test @@ -0,0 +1,17 @@ +# +# MDEV-22370 safe_mutex: Trying to lock uninitialized mutex at +# /data/src/10.4-bug/sql/rpl_parallel.cc, line 470 upon shutdown during FTWRL +# +# Purpose of this test case to test crash while FTWRL and shutdown is in race +# condition +# Shutdown can execute first and destroy the mutex making mutex_lock in pool_mark_busy +# to crash + +--source include/have_debug.inc +--connect (con1,localhost,root,,) +SET DEBUG_DBUG='+d,mark_busy_mdev_22370'; +--send + FLUSH TABLES WITH READ LOCK; + +--connection default +--source include/restart_mysqld.inc diff --git a/mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result b/mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result new file mode 100644 index 00000000000..a2eb7ee5c0a --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result @@ -0,0 +1,40 @@ +# +# Kill OPTIMIZE command prior to table modification +# +RESET MASTER; +CREATE TABLE t1 (f INT) ENGINE=INNODB; +CREATE TABLE t2 (f INT) ENGINE=INNODB; +connect con1,127.0.0.1,root,,test,$MASTER_MYPORT,; +connection con1; +SET debug_sync='admin_command_kill_before_modify SIGNAL ready_to_be_killed WAIT_FOR master_cont'; +OPTIMIZE TABLE t1,t2; +connection default; +SET debug_sync='now WAIT_FOR ready_to_be_killed'; +KILL THD_ID; +SET debug_sync = 'reset'; +disconnect con1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f INT) ENGINE=INNODB +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f INT) ENGINE=INNODB +DROP TABLE t1,t2; +FLUSH LOGS; +# +# Kill OPTIMIZE command after table modification +# +CREATE TABLE t1 (f INT) ENGINE=INNODB; +CREATE TABLE t2 (f INT) ENGINE=INNODB; +connect con1,127.0.0.1,root,,test,$MASTER_MYPORT,; +connection con1; +SET debug_sync='admin_command_kill_after_modify SIGNAL ready_to_be_killed WAIT_FOR master_cont'; +OPTIMIZE TABLE t1,t2; +connection default; +SET debug_sync='now WAIT_FOR ready_to_be_killed'; +KILL THD_ID; +SET debug_sync = 'reset'; +disconnect con1; +DROP TABLE t1,t2; +FLUSH LOGS; +FOUND 1 /OPTIMIZE TABLE t1,t2/ in mysqlbinlog.out diff --git a/mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test b/mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test new file mode 100644 index 00000000000..9b248097ae2 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test @@ -0,0 +1,95 @@ +# ==== Purpose ==== +# +# Test verifies that when an admin command execution is interrupted by KILL +# command it should stop its execution. The admin command in binary log should +# contain only the list of tables which have successfully executed admin +# command prior to kill. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create two table t1,t2. +# 1 - Execute OPTIMIZE TABLE t1,t2 command. +# 2 - Using debug sync mechanism kill OPTIMIZE TABLE command at a stage +# where it has not optimized any table. +# 3 - Check that OPTIMIZE TABLE command is not written to binary log. +# 4 - Using debug sync mechanism hold the execution of OPTIMIZE TABLE after +# t1 table optimization. Now kill the OPTIMIZE TABLE command. +# 5 - Observe the binlog output, the OPTIMIZE TABLE command should display `t1,t2`. +# 6 - Please note that, we binlog the entire query even if at least one +# table is modified as admin commands are safe to replicate and they will +# not make the slave to diverge. +# +# ==== References ==== +# +# MDEV-22530: Aborting OPTIMIZE TABLE still logs in binary log and replicates to the Slave server. +# +--source include/have_log_bin.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_innodb.inc + +--echo # +--echo # Kill OPTIMIZE command prior to table modification +--echo # +RESET MASTER; + +CREATE TABLE t1 (f INT) ENGINE=INNODB; +CREATE TABLE t2 (f INT) ENGINE=INNODB; + +--connect(con1,127.0.0.1,root,,test,$MASTER_MYPORT,) +--connection con1 +SET debug_sync='admin_command_kill_before_modify SIGNAL ready_to_be_killed WAIT_FOR master_cont'; +--send OPTIMIZE TABLE t1,t2 + +--connection default +SET debug_sync='now WAIT_FOR ready_to_be_killed'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%OPTIMIZE TABLE %'` + +# Now kill. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +SET debug_sync = 'reset'; +--disconnect con1 + +--source include/show_binlog_events.inc +DROP TABLE t1,t2; + +FLUSH LOGS; + +--echo # +--echo # Kill OPTIMIZE command after table modification +--echo # + +CREATE TABLE t1 (f INT) ENGINE=INNODB; +CREATE TABLE t2 (f INT) ENGINE=INNODB; + +--connect(con1,127.0.0.1,root,,test,$MASTER_MYPORT,) +--connection con1 +SET debug_sync='admin_command_kill_after_modify SIGNAL ready_to_be_killed WAIT_FOR master_cont'; +--send OPTIMIZE TABLE t1,t2 + +--connection default +SET debug_sync='now WAIT_FOR ready_to_be_killed'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%OPTIMIZE TABLE %'` + +# Now kill. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +SET debug_sync = 'reset'; +--disconnect con1 + +DROP TABLE t1,t2; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +FLUSH LOGS; + +--let $MYSQLD_DATADIR= `select @@datadir` +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out + +--let SEARCH_PATTERN= OPTIMIZE TABLE t1,t2 +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out diff --git a/mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result b/mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result new file mode 100644 index 00000000000..a39dad85244 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_mark_optimize_tbl_ddl.result @@ -0,0 +1,77 @@ +include/rpl_init.inc [topology=1->2] +connection server_1; +FLUSH TABLES; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +connection server_2; +SET @save_slave_parallel_threads= @@GLOBAL.slave_parallel_threads; +SET @save_slave_parallel_mode= @@GLOBAL.slave_parallel_mode; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=2; +SET GLOBAL slave_parallel_mode=optimistic; +include/start_slave.inc +connection server_1; +CREATE TABLE t1(a INT) ENGINE=INNODB; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +INSERT INTO t1 VALUES(1); +INSERT INTO t1 SELECT 1+a FROM t1; +INSERT INTO t1 SELECT 2+a FROM t1; +connection server_2; +# +# Verify that following admin commands are marked as ddl +# 'OPTIMIZE TABLE', 'REPAIR TABLE' and 'ANALYZE TABLE' +# +connection server_1; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair note The storage engine for the table doesn't support repair +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +FLUSH LOGS; +FOUND 1 /GTID 0-1-8 ddl/ in mysqlbinlog.out +FOUND 1 /GTID 0-1-9 ddl/ in mysqlbinlog.out +FOUND 1 /GTID 0-1-10 ddl/ in mysqlbinlog.out +# +# Clean up +# +DROP TABLE t1; +connection server_2; +FLUSH LOGS; +# +# Check that ALTER TABLE commands with ANALYZE, OPTIMIZE and REPAIR on +# partitions will be marked as DDL in binary log. +# +connection server_1; +CREATE TABLE t1(id INT) PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (100), +PARTITION pmax VALUES LESS THAN (MAXVALUE)); +INSERT INTO t1 VALUES (1), (10), (100), (1000); +ALTER TABLE t1 ANALYZE PARTITION p0; +Table Op Msg_type Msg_text +test.t1 analyze status OK +ALTER TABLE t1 OPTIMIZE PARTITION p0; +Table Op Msg_type Msg_text +test.t1 optimize status OK +ALTER TABLE t1 REPAIR PARTITION p0; +Table Op Msg_type Msg_text +test.t1 repair status OK +FLUSH LOGS; +FOUND 1 /GTID 0-1-14 ddl/ in mysqlbinlog.out +FOUND 1 /GTID 0-1-15 ddl/ in mysqlbinlog.out +FOUND 1 /GTID 0-1-16 ddl/ in mysqlbinlog.out +# +# Clean up +# +DROP TABLE t1; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads= @save_slave_parallel_threads; +SET GLOBAL slave_parallel_mode= @save_slave_parallel_mode; +include/start_slave.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_slave_shutdown_mdev20821.result b/mysql-test/suite/rpl/r/rpl_slave_shutdown_mdev20821.result new file mode 100644 index 00000000000..f90d2126103 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_slave_shutdown_mdev20821.result @@ -0,0 +1,79 @@ +include/rpl_init.inc [topology=1->3] +connection server_3; +set default_master_connection = ''; +include/start_slave.inc +Warnings: +Note 1254 Slave is already running +set default_master_connection = 'm2'; +change master to master_host='127.0.0.1', master_port=SERVER_MYPORT_2, master_user='root', master_use_gtid=slave_pos; +include/start_slave.inc +select @@global.slave_parallel_workers as two; +two +2 +connection server_3; +SHUTDOWN; +connection server_3; +connection server_3; +connection server_1; +create table t1 (i int primary key) engine=Innodb; +connection server_2; +create table t2 (i int primary key) engine=Innodb; +connection server_3; +set default_master_connection = ''; +include/start_slave.inc +Warnings: +Note 1254 Slave is already running +set default_master_connection = 'm2'; +include/start_slave.inc +Warnings: +Note 1254 Slave is already running +connection server_2; +insert into t2 values (1); +connection server_3; +connection server_1; +insert into t1 values (1); +connection server_3; +connection server_3; +SHUTDOWN; +connection server_3; +connection server_3; +connection server_3; +set default_master_connection = ''; +include/start_slave.inc +Warnings: +Note 1254 Slave is already running +set default_master_connection = 'm2'; +include/start_slave.inc +Warnings: +Note 1254 Slave is already running +connect conn_block_server3, 127.0.0.1, root,, test, $SERVER_MYPORT_3,; +begin; +insert into t1 values (2); +insert into t2 values (2); +connection server_1; +insert into t1 values (2); +connection server_2; +insert into t2 values (2); +connection server_3; +SHUTDOWN; +connection server_3; +connection server_3; +connection server_3; +set default_master_connection = ''; +include/start_slave.inc +Warnings: +Note 1254 Slave is already running +set default_master_connection = 'm2'; +include/start_slave.inc +Warnings: +Note 1254 Slave is already running +connection server_1; +drop table t1; +connection server_2; +drop table t2; +connection server_3; +set default_master_connection = 'm2'; +include/stop_slave.inc +RESET SLAVE ALL; +set default_master_connection = ''; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test b/mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test new file mode 100644 index 00000000000..6d66e3fd088 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test @@ -0,0 +1,142 @@ +# ==== Purpose ==== +# +# Test verifies that there is no deadlock or assertion in +# slave_parallel_mode=optimistic configuration while applying admin command +# like 'OPTIMIZE TABLE', 'REPAIR TABLE' and 'ANALYZE TABLE'. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create a table, execute OPTIMIZE TABLE command on the table followed +# by some DMLS. +# 1 - No assert should happen on slave server. +# 2 - Assert that 'OPTIMIZE TABLE', 'REPAIR TABLE' and 'ANALYZE TABLE' are +# marked as 'DDL' in the binary log. +# +# ==== References ==== +# +# MDEV-17515: GTID Replication in optimistic mode deadlock +# +--source include/have_partition.inc +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_1 +FLUSH TABLES; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + +--connection server_2 +SET @save_slave_parallel_threads= @@GLOBAL.slave_parallel_threads; +SET @save_slave_parallel_mode= @@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=2; +SET GLOBAL slave_parallel_mode=optimistic; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1(a INT) ENGINE=INNODB; +OPTIMIZE TABLE t1; +INSERT INTO t1 VALUES(1); +INSERT INTO t1 SELECT 1+a FROM t1; +INSERT INTO t1 SELECT 2+a FROM t1; +--save_master_pos + +--connection server_2 +--sync_with_master + +--echo # +--echo # Verify that following admin commands are marked as ddl +--echo # 'OPTIMIZE TABLE', 'REPAIR TABLE' and 'ANALYZE TABLE' +--echo # +--connection server_1 + +OPTIMIZE TABLE t1; +--let optimize_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +REPAIR TABLE t1; +--let repair_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +ANALYZE TABLE t1; +--let analyze_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +FLUSH LOGS; + +--let $MYSQLD_DATADIR= `select @@datadir` +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out + +--let SEARCH_PATTERN= GTID $optimize_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $repair_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $analyze_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--echo # +--echo # Clean up +--echo # +DROP TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--save_master_pos + +--connection server_2 +--sync_with_master +FLUSH LOGS; + +--echo # +--echo # Check that ALTER TABLE commands with ANALYZE, OPTIMIZE and REPAIR on +--echo # partitions will be marked as DDL in binary log. +--echo # +--connection server_1 +CREATE TABLE t1(id INT) PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (100), + PARTITION pmax VALUES LESS THAN (MAXVALUE)); +INSERT INTO t1 VALUES (1), (10), (100), (1000); + +ALTER TABLE t1 ANALYZE PARTITION p0; +--let analyze_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +ALTER TABLE t1 OPTIMIZE PARTITION p0; +--let optimize_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +ALTER TABLE t1 REPAIR PARTITION p0; +--let repair_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +FLUSH LOGS; + +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out + +--let SEARCH_PATTERN= GTID $analyze_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $optimize_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $repair_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--echo # +--echo # Clean up +--echo # +DROP TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--save_master_pos + +--connection server_2 +--sync_with_master + +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads= @save_slave_parallel_threads; +SET GLOBAL slave_parallel_mode= @save_slave_parallel_mode; +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.cnf b/mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.cnf new file mode 100644 index 00000000000..1e7cdee510b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.cnf @@ -0,0 +1,19 @@ +!include suite/rpl/rpl_1slave_base.cnf +!include include/default_client.cnf + +[mysqld.1] +log-slave-updates +gtid-domain-id=1 + +[mysqld.2] +log-slave-updates +gtid-domain-id=2 + +[mysqld.3] +log-slave-updates +gtid-domain-id=3 +slave_parallel_threads=2 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.test b/mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.test new file mode 100644 index 00000000000..6f73de984d3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.test @@ -0,0 +1,171 @@ +# MDEV-20821 parallel slave server shutdown hang +# +# Test the bug condition of a parallel slave server shutdown +# hang when the parallel workers were idle. +# The bug reported scenario is extented to cover the multi-sources case as well as +# checking is done for both the idle and busy workers cases. +# +# MDEV-25336 Parallel replication causes failed assert while restarting +# Since this test case involves slave restart this will help in testing +# Mdev-25336 too. + +--source include/have_innodb.inc +--source include/have_binlog_format_mixed.inc +--let $rpl_topology= 1->3 +--source include/rpl_init.inc + +# +# A. idle workers. +# +--connection server_3 +set default_master_connection = ''; +--source include/start_slave.inc + +set default_master_connection = 'm2'; +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval change master to master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=slave_pos; +--source include/start_slave.inc + +select @@global.slave_parallel_workers as two; + +# At this point worker threads have no assignement. +# Shutdown must not hang. +# In 10.2/10.3 there should not be any assert failure `prev != 0 && next != 0' +--connection server_3 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +wait +EOF +--send SHUTDOWN +--reap +--source include/wait_until_disconnected.inc + +--connection server_3 +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +restart +EOF + +# No hang is *proved* to occur when this point is reached. +--connection server_3 +--enable_reconnect +--source include/wait_until_connected_again.inc + +# +# B. resting workers after some busy time +# +--connection server_1 +create table t1 (i int primary key) engine=Innodb; + +--connection server_2 +create table t2 (i int primary key) engine=Innodb; + +--connection server_3 +set default_master_connection = ''; +--source include/start_slave.inc + +set default_master_connection = 'm2'; +--source include/start_slave.inc + +--connection server_2 +insert into t2 values (1); +--save_master_pos + +--connection server_3 +--sync_with_master 0,'m2' + +--connection server_1 +insert into t1 values (1); +--save_master_pos + +--connection server_3 +--sync_with_master 0,'' + +# In 10.2/10.3 there should not be any assert failure `prev != 0 && next != 0' +# At this point worker threads have no assignement. +# Shutdown must not hang. + +--connection server_3 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +wait +EOF +--send SHUTDOWN +--reap +--source include/wait_until_disconnected.inc + +--connection server_3 +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +restart +EOF + +# No hang is *proved* to occur when this point is reached. +--connection server_3 +--enable_reconnect +--source include/wait_until_connected_again.inc + +# +# C. busy workers +# +--connection server_3 +set default_master_connection = ''; +--source include/start_slave.inc + +set default_master_connection = 'm2'; +--source include/start_slave.inc + +--connect (conn_block_server3, 127.0.0.1, root,, test, $SERVER_MYPORT_3,) +begin; + insert into t1 values (2); + insert into t2 values (2); + +--connection server_1 +insert into t1 values (2); +--connection server_2 +insert into t2 values (2); + + +# In 10.2/10.3 there should not be any assert failure `prev != 0 && next != 0' +# At this point there's a good chance the worker threads are busy. +# SHUTDOWN must proceed without any delay as above. +--connection server_3 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +wait +EOF +--send SHUTDOWN +--reap +--source include/wait_until_disconnected.inc + +--connection server_3 +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +restart +EOF + +# No hang is *proved* to occur when this point is reached. +--connection server_3 +--enable_reconnect +--source include/wait_until_connected_again.inc + + +# Cleanup + +--connection server_3 +set default_master_connection = ''; +--source include/start_slave.inc + +set default_master_connection = 'm2'; +--source include/start_slave.inc + +--connection server_1 +drop table t1; + +--connection server_2 +drop table t2; +--save_master_pos + +# (!) The following block is critical to avoid check-mysqld_3.reject by mtr: +--connection server_3 +--sync_with_master 0,'m2' +set default_master_connection = 'm2'; +--source include/stop_slave.inc +RESET SLAVE ALL; +set default_master_connection = ''; + +--source include/rpl_end.inc |