diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2023-01-31 09:33:58 +0100 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2023-01-31 09:33:58 +0100 |
commit | b923b80cfd8628ef973019bf3dba76dda8d940c4 (patch) | |
tree | 5511aaddb3b3a750cdca5c12906c7ccd58e0b628 /mysql-test/suite | |
parent | cea50896d2ea0d18924d92d62a7ec1607d55e509 (diff) | |
parent | c3a5cf2b5bb0c0e1623a0ddc8e3d49557f35e800 (diff) | |
download | mariadb-git-b923b80cfd8628ef973019bf3dba76dda8d940c4.tar.gz |
Merge branch '10.6' into 10.7
Diffstat (limited to 'mysql-test/suite')
27 files changed, 1445 insertions, 7 deletions
diff --git a/mysql-test/suite/binlog/r/innodb_rc_insert_before_delete.result b/mysql-test/suite/binlog/r/innodb_rc_insert_before_delete.result new file mode 100644 index 00000000000..d4bd5ee07bf --- /dev/null +++ b/mysql-test/suite/binlog/r/innodb_rc_insert_before_delete.result @@ -0,0 +1,53 @@ +RESET MASTER; +connect pause_purge,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +CREATE TABLE t (pk int PRIMARY KEY, sk INT UNIQUE) ENGINE=InnoDB; +INSERT INTO t VALUES (10, 100); +connect con1,localhost,root; +BEGIN; +SELECT * FROM t WHERE sk = 100 FOR UPDATE; +pk sk +10 100 +connect con2,localhost,root; +SET DEBUG_SYNC="lock_wait_start SIGNAL insert_wait_started"; +INSERT INTO t VALUES (5, 100) # trx 1; +connect con3,localhost,root; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET DEBUG_SYNC="now WAIT_FOR insert_wait_started"; +SET DEBUG_SYNC="lock_wait_start SIGNAL delete_started_waiting"; +BEGIN; +UPDATE t SET sk = 200 WHERE sk = 100; # trx 2; +connection con1; +SET DEBUG_SYNC="now WAIT_FOR delete_started_waiting"; +DELETE FROM t WHERE sk=100; +COMMIT; +disconnect con1; +connection con2; +disconnect con2; +connection con3; +must be logged in ROW format as the only event of trx 2 (con3) +INSERT INTO t VALUES (11, 101); +COMMIT; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; DELETE FROM t WHERE sk=100 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; INSERT INTO t VALUES (5, 100) # trx 1 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # INSERT INTO t VALUES (11, 101) +master-bin.000001 # Table_map # # table_id: # (test.t) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +disconnect con3; +connection default; +SELECT * FROM t; +pk sk +5 100 +11 101 +disconnect pause_purge; +SET DEBUG_SYNC="RESET"; +DROP TABLE t; diff --git a/mysql-test/suite/binlog/t/innodb_rc_insert_before_delete.test b/mysql-test/suite/binlog/t/innodb_rc_insert_before_delete.test new file mode 100644 index 00000000000..228d9778f56 --- /dev/null +++ b/mysql-test/suite/binlog/t/innodb_rc_insert_before_delete.test @@ -0,0 +1,92 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_mixed.inc +--source include/count_sessions.inc + +RESET MASTER; + +# MDEV-30010 merely adds is a Read-Committed version MDEV-30225 test +# solely to prove the RC isolation yields ROW binlog format as it is +# supposed to: +# https://mariadb.com/kb/en/unsafe-statements-for-statement-based-replication/#isolation-levels. +# The original MDEV-30225 test is adapted to the RC to create +# a similar safisticated scenario which does not lead to any deadlock though. + +--connect (pause_purge,localhost,root) +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +--connection default +CREATE TABLE t (pk int PRIMARY KEY, sk INT UNIQUE) ENGINE=InnoDB; +INSERT INTO t VALUES (10, 100); + +--connect (con1,localhost,root) +BEGIN; # trx 0 +SELECT * FROM t WHERE sk = 100 FOR UPDATE; + +--connect (con2,localhost,root) +SET DEBUG_SYNC="lock_wait_start SIGNAL insert_wait_started"; +# trx 1 is locked on try to read the record in secondary index during duplicates +# check. It's the first in waiting queue, that's why it will be woken up firstly +# when trx 0 commits. +--send INSERT INTO t VALUES (5, 100) # trx 1 + +--connect (con3,localhost,root) +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET DEBUG_SYNC="now WAIT_FOR insert_wait_started"; +SET DEBUG_SYNC="lock_wait_start SIGNAL delete_started_waiting"; +# trx 2 can delete (5, 100) on master, but not on slave, as on slave trx 1 +# can insert (5, 100) after trx 2 positioned it's cursor. Trx 2 lock is placed +# in waiting queue after trx 1 lock, but its persistent cursor position was +# stored on (100, 10) record in secondary index before suspending. After trx 1 +# is committed, trx 2 will restore persistent cursor position on (100, 10). As +# (100, 5) secondary index record was inserted before (100, 10) in logical +# order, and (100, 10) record is delete-marked, trx 2 just continues scanning. +# +# Note. There can be several records with the same key in unique secondary +# index, but only one of them must be non-delete-marked. That's why when we do +# point query, cursor position is set in the first record in logical order, and +# then records are iterated until either non-delete-marked record is found or +# all records with the same unique fields are iterated. + +# to prepare showing interesting binlog events +--let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1) +BEGIN; +--send UPDATE t SET sk = 200 WHERE sk = 100; # trx 2 + +--connection con1 +SET DEBUG_SYNC="now WAIT_FOR delete_started_waiting"; +DELETE FROM t WHERE sk=100; # trx 0 +COMMIT; +--disconnect con1 + +--connection con2 +--reap +--disconnect con2 + +--connection con3 +--error 0 +--reap +if (`SELECT ROW_COUNT() > 0`) +{ + --echo unexpected effective UPDATE + --die +} +--echo must be logged in ROW format as the only event of trx 2 (con3) +INSERT INTO t VALUES (11, 101); +COMMIT; +--source include/show_binlog_events.inc +--disconnect con3 + +--connection default +# If the bug is not fixed, we will see the row inserted by trx 1 here. This can +# cause duplicate key error on slave, when some other trx tries in insert row +# with the same secondary key, as was inserted by trx 1, and not deleted by trx +# 2. +SELECT * FROM t; + +--disconnect pause_purge +SET DEBUG_SYNC="RESET"; +DROP TABLE t; +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result index 026a7cd3f42..ba8f5b2fe85 100644 --- a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result +++ b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result @@ -4,6 +4,7 @@ call mtr.add_suppression("InnoDB: Recovery cannot access file"); call mtr.add_suppression("InnoDB: Plugin initialization aborted"); call mtr.add_suppression("Plugin 'InnoDB' init function returned error\\."); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); +call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page "); call mtr.add_suppression("InnoDB: Cannot apply log to \\[page id: space=[1-9][0-9]*, page number=0\\] of corrupted file '.*test.t[1-5]\\.ibd'"); call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index 2b91cd638e2..8582d5dc713 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -4345,6 +4345,46 @@ pk a bit_or DROP TABLE t2; DROP TABLE t1; # +# MDEV-15178: Filesort::make_sortorder: Assertion `pos->field != __null | +# +CREATE TABLE t1 (i1 int, a int); +INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3); +CREATE TABLE t2 (i2 int); +INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3); +SELECT +a, +RANK() OVER (ORDER BY SUM(DISTINCT i1)) +FROM +t1, t2 WHERE t2.i2 = t1.i1 +GROUP BY +a; +a RANK() OVER (ORDER BY SUM(DISTINCT i1)) +1 1 +2 2 +3 3 +DROP TABLE t1, t2; +# +# MDEV-17014: Crash server using ROW_NUMBER() OVER (PARTITION ..) +# +CREATE TABLE t1 (UID BIGINT); +CREATE TABLE t2 (UID BIGINT); +CREATE TABLE t3 (UID BIGINT); +insert into t1 VALUES (1),(2); +insert into t2 VALUES (1),(2); +insert into t3 VALUES (1),(2); +SELECT +ROW_NUMBER() OVER (PARTITION BY GROUP_CONCAT(TT1.UID)) +FROM t1 TT1, +t2 TT2, +t3 TT3 +WHERE TT3.UID = TT1.UID AND TT2.UID = TT3.UID +GROUP BY TT1.UID +; +ROW_NUMBER() OVER (PARTITION BY GROUP_CONCAT(TT1.UID)) +1 +1 +DROP TABLE t1, t2, t3; +# # End of 10.3 tests # # diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test index d3088204b96..ab77b3747b8 100644 --- a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test +++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test @@ -9,6 +9,7 @@ call mtr.add_suppression("InnoDB: Recovery cannot access file"); call mtr.add_suppression("InnoDB: Plugin initialization aborted"); call mtr.add_suppression("Plugin 'InnoDB' init function returned error\\."); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); +call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page "); call mtr.add_suppression("InnoDB: Cannot apply log to \\[page id: space=[1-9][0-9]*, page number=0\\] of corrupted file '.*test.t[1-5]\\.ibd'"); call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); diff --git a/mysql-test/suite/galera/r/galera_UK_conflict.result b/mysql-test/suite/galera/r/galera_UK_conflict.result index 402289d7ef8..b0420d58ede 100644 --- a/mysql-test/suite/galera/r/galera_UK_conflict.result +++ b/mysql-test/suite/galera/r/galera_UK_conflict.result @@ -144,7 +144,6 @@ SET debug_sync='RESET'; connection node_1; SET GLOBAL wsrep_slave_threads = DEFAULT; connection node_2; -SET SESSION wsrep_sync_wait=15; SELECT * FROM t1; f1 f2 f3 1 1 0 diff --git a/mysql-test/suite/galera/t/galera_UK_conflict.test b/mysql-test/suite/galera/t/galera_UK_conflict.test index fb4cdb416c3..7a14821cc32 100644 --- a/mysql-test/suite/galera/t/galera_UK_conflict.test +++ b/mysql-test/suite/galera/t/galera_UK_conflict.test @@ -140,6 +140,14 @@ SELECT * FROM t1; # original state in node 1 INSERT INTO t1 VALUES (7,7,7); INSERT INTO t1 VALUES (8,8,8); +SELECT COUNT(*) FROM t1; +SELECT * FROM t1; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 7 FROM t1 +--source include/wait_condition.inc +SELECT COUNT(*) FROM t1; +SELECT * FROM t1; DROP TABLE t1; @@ -268,7 +276,6 @@ SET debug_sync='RESET'; SET GLOBAL wsrep_slave_threads = DEFAULT; --connection node_2 -SET SESSION wsrep_sync_wait=15; SELECT * FROM t1; # replicate some transactions, so that wsrep slave thread count can reach @@ -276,4 +283,13 @@ SELECT * FROM t1; INSERT INTO t1 VALUES (7,7,7); INSERT INTO t1 VALUES (8,8,8); +SELECT COUNT(*) FROM t1; +SELECT * FROM t1; + +--connection node_1 +--let $wait_condition = SELECT COUNT(*) = 7 FROM t1 +--source include/wait_condition.inc +SELECT COUNT(*) FROM t1; +SELECT * FROM t1; + DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test index 8f0f0ed65ea..214d5166781 100644 --- a/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test +++ b/mysql-test/suite/galera/t/galera_gcache_recover_manytrx.test @@ -205,8 +205,3 @@ CALL mtr.add_suppression("conflict state 7 after post commit"); # Warning happens when the cluster is started for the first time CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); - ---connection node_2 -call mtr.add_suppression("Error in Log_event::read_log_event():.*"); -CALL mtr.add_suppression("Skipped GCache ring buffer recovery"); - diff --git a/mysql-test/suite/mariabackup/incremental_drop_db.result b/mysql-test/suite/mariabackup/incremental_drop_db.result new file mode 100644 index 00000000000..3a6c89f8de0 --- /dev/null +++ b/mysql-test/suite/mariabackup/incremental_drop_db.result @@ -0,0 +1,30 @@ +call mtr.add_suppression("InnoDB: New log files created"); +# +# Start of 10.3 tests +# +# +# MDEV-23335 MariaBackup Incremental Does Not Reflect Dropped/Created Databases +# +CREATE DATABASE db1; +CREATE DATABASE db2; +CREATE TABLE db1.t1 (a INT) ENGINE=MyISAM; +CREATE TABLE db1.t2 (a INT) ENGINE=InnoDB; +# Create base backup +DROP DATABASE db1; +# Create incremental backup +# Remove incremental_dir/db2/db.opt file to make incremental_dir/db2/ empty +# Prepare base backup, apply incremental one +# shutdown server +# remove datadir +# xtrabackup move back +# restart +# Expect no 'db1' in the output, because it was really dropped. +# Expect 'db2' in the ouput, because it was not dropped! +# (its incremental directory was emptied only) +SHOW DATABASES LIKE 'db%'; +Database (db%) +db2 +DROP DATABASE db2; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/mariabackup/incremental_drop_db.test b/mysql-test/suite/mariabackup/incremental_drop_db.test new file mode 100644 index 00000000000..de270435e9d --- /dev/null +++ b/mysql-test/suite/mariabackup/incremental_drop_db.test @@ -0,0 +1,68 @@ +--source include/have_innodb.inc +call mtr.add_suppression("InnoDB: New log files created"); + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-23335 MariaBackup Incremental Does Not Reflect Dropped/Created Databases +--echo # + +--let $datadir=`SELECT @@datadir` +--let $basedir=$MYSQLTEST_VARDIR/tmp/backup +--let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1 + +# Create two databases: +# - db1 is dropped normally below +# - db2 is used to cover a corner case: its db.opt file is removed + +# Incremental backup contains: +# - no directory for db1 +# - an empty directory for db2 (after we remove db2/db.opt) + + +CREATE DATABASE db1; +CREATE DATABASE db2; + +# Add some tables to db1 +CREATE TABLE db1.t1 (a INT) ENGINE=MyISAM; +CREATE TABLE db1.t2 (a INT) ENGINE=InnoDB; + +--echo # Create base backup +--disable_result_log +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir +--enable_result_log + +DROP DATABASE db1; + +--echo # Create incremental backup +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir + +--echo # Remove incremental_dir/db2/db.opt file to make incremental_dir/db2/ empty +--remove_file $incremental_dir/db2/db.opt + + +--echo # Prepare base backup, apply incremental one +--disable_result_log +--exec $XTRABACKUP --prepare --target-dir=$basedir +--exec $XTRABACKUP --prepare --target-dir=$basedir --incremental-dir=$incremental_dir +--enable_result_log + +--let $targetdir=$basedir +--source include/restart_and_restore.inc +--enable_result_log + +--echo # Expect no 'db1' in the output, because it was really dropped. +--echo # Expect 'db2' in the ouput, because it was not dropped! +--echo # (its incremental directory was emptied only) + +SHOW DATABASES LIKE 'db%'; +DROP DATABASE db2; + +--rmdir $basedir +--rmdir $incremental_dir + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index 9768040aa94..fc9d98f5d0a 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -521,3 +521,10 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'show status like \'server_audit_ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'show variables like \'server_audit%\'',0 TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,plugin, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'uninstall plugin server_audit',0 +# +# MDEV-27631 Assertion `global_status_var.global_memory_used == 0' failed in mysqld_exit +# +install plugin server_audit soname 'server_audit'; +uninstall plugin server_audit; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index d8f8b9d0165..5048ccc2446 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -235,3 +235,8 @@ uninstall plugin server_audit; cat_file $MYSQLD_DATADIR/server_audit.log; remove_file $MYSQLD_DATADIR/server_audit.log; +--echo # +--echo # MDEV-27631 Assertion `global_status_var.global_memory_used == 0' failed in mysqld_exit +--echo # +install plugin server_audit soname 'server_audit'; +uninstall plugin server_audit; diff --git a/mysql-test/suite/rpl/include/create_or_drop_sync_func.inc b/mysql-test/suite/rpl/include/create_or_drop_sync_func.inc new file mode 100644 index 00000000000..74cde5de1db --- /dev/null +++ b/mysql-test/suite/rpl/include/create_or_drop_sync_func.inc @@ -0,0 +1,75 @@ +# Creates or drops a stored function as a part of debug-sync based +# synchronization mechanism between replication servers. +# +# Parameters: +# $create_or_drop= [create] +# $server_master = [master] +# $server_slave = [slave] +if (!$create_or_drop) +{ + --let $create_or_drop=create +} + +if (`select strcmp('$create_or_drop', 'create') = 0`) +{ + if (!$server_master) + { + --let $server_master=master + } + if (!$server_slave) + { + --let $server_slave=slave + } + + --connection $server_master + # Use a stored function to inject a debug_sync into the appropriate THD. + # The function does nothing on the master, and on the slave it injects the + # desired debug_sync action(s). + SET sql_log_bin=0; + --delimiter || + CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END + || + --delimiter ; + SET sql_log_bin=1; + + --connection $server_slave + + SET sql_log_bin=0; + --delimiter || + CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END + || + --delimiter ; +SET sql_log_bin=1; +} + +if (`select strcmp('$create_or_drop', 'drop') = 0`) +{ + if (!$server_slave) + { + --let $server_slave=slave= + } + if (!$server_master) + { + --let $server_master=master + } + --connection $server_slave + SET DEBUG_SYNC='RESET'; + + --connection $server_master + SET DEBUG_SYNC='RESET'; + DROP FUNCTION foo; +} diff --git a/mysql-test/suite/rpl/r/parallel_backup.result b/mysql-test/suite/rpl/r/parallel_backup.result index 9d394a220d5..7cf72ed15e4 100644 --- a/mysql-test/suite/rpl/r/parallel_backup.result +++ b/mysql-test/suite/rpl/r/parallel_backup.result @@ -8,6 +8,8 @@ connection master; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE = innodb; INSERT INTO t1 VALUES(100); connection slave; +call mtr.add_suppression("Deadlock found when trying to get lock"); +call mtr.add_suppression("Commit failed due to failure of an earlier commit"); include/stop_slave.inc SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads; SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; @@ -31,6 +33,167 @@ connection backup_slave; BACKUP STAGE END; connection slave; include/diff_tables.inc [master:t1,slave:t1] +# MDEV-30423: dealock XA COMMIT vs BACKUP +# +# Normal XA COMMIT +connection slave; +include/stop_slave.inc +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (102); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (101); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (102); +connection master; +XA COMMIT '1'; +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +# +# Normal XA ROLLBACK +connection slave; +include/stop_slave.inc +Warnings: +Note 1255 Slave already has been stopped +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (104); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (103); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (104); +connection master; +XA ROLLBACK '1'; +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +# +# Errored out XA COMMIT +connection slave; +include/stop_slave.inc +Warnings: +Note 1255 Slave already has been stopped +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (106); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (105); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (106); +connection master; +XA COMMIT '1'; +include/save_master_gtid.inc +connection slave; +SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; +SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; +SET @@global.innodb_lock_wait_timeout =1; +SET @@global.slave_transaction_retries=0; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/stop_slave.inc +SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout; +SET @@global.slave_transaction_retries= @sav_slave_transaction_retries; +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc +# +# Errored out XA ROLLBACK +connection slave; +include/stop_slave.inc +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (108); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (107); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (108); +connection master; +XA ROLLBACK '1'; +include/save_master_gtid.inc +connection slave; +SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; +SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; +SET @@global.innodb_lock_wait_timeout =1; +SET @@global.slave_transaction_retries=0; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/stop_slave.inc +SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout; +SET @@global.slave_transaction_retries= @sav_slave_transaction_retries; +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc connection slave; include/stop_slave.inc SET @@global.slave_parallel_threads= @old_parallel_threads; diff --git a/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result b/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result new file mode 100644 index 00000000000..b89cb154f24 --- /dev/null +++ b/mysql-test/suite/rpl/r/parallel_backup_lsu_off.result @@ -0,0 +1,207 @@ +# Specialized --log-slave-updates = 0 version of parallel_backup test. +# MDEV-21953: deadlock between BACKUP STAGE BLOCK_COMMIT and parallel +# MDEV-30423: dealock XA COMMIT vs BACKUP +include/master-slave.inc +[connection master] +# +# MDEV-21953: deadlock between BACKUP STAGE BLOCK_COMMIT and parallel +# replication +# +connection master; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE = innodb; +INSERT INTO t1 VALUES(100); +connection slave; +call mtr.add_suppression("Deadlock found when trying to get lock"); +call mtr.add_suppression("Commit failed due to failure of an earlier commit"); +include/stop_slave.inc +SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; +SET @@global.slave_parallel_threads= 2; +SET @@global.slave_parallel_mode = 'optimistic'; +connection master; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +connect aux_slave,127.0.0.1,root,,test,$SLAVE_MYPORT,; +BEGIN; +INSERT INTO t1 VALUES (1); +connection slave; +include/start_slave.inc +connection aux_slave; +connect backup_slave,127.0.0.1,root,,test,$SLAVE_MYPORT,; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +# MDEV-30423: dealock XA COMMIT vs BACKUP +# +# Normal XA COMMIT +connection slave; +include/stop_slave.inc +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (102); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (101); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (102); +connection master; +XA COMMIT '1'; +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +# +# Normal XA ROLLBACK +connection slave; +include/stop_slave.inc +Warnings: +Note 1255 Slave already has been stopped +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (104); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (103); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (104); +connection master; +XA ROLLBACK '1'; +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +# +# Errored out XA COMMIT +connection slave; +include/stop_slave.inc +Warnings: +Note 1255 Slave already has been stopped +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (106); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (105); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (106); +connection master; +XA COMMIT '1'; +include/save_master_gtid.inc +connection slave; +SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; +SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; +SET @@global.innodb_lock_wait_timeout =1; +SET @@global.slave_transaction_retries=0; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/stop_slave.inc +SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout; +SET @@global.slave_transaction_retries= @sav_slave_transaction_retries; +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc +# +# Errored out XA ROLLBACK +connection slave; +include/stop_slave.inc +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (108); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (107); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (108); +connection master; +XA ROLLBACK '1'; +include/save_master_gtid.inc +connection slave; +SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; +SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; +SET @@global.innodb_lock_wait_timeout =1; +SET @@global.slave_transaction_retries=0; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/stop_slave.inc +SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout; +SET @@global.slave_transaction_retries= @sav_slave_transaction_retries; +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc +connection slave; +include/stop_slave.inc +SET @@global.slave_parallel_threads= @old_parallel_threads; +SET @@global.slave_parallel_mode = @old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result b/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result new file mode 100644 index 00000000000..111bc7fb76f --- /dev/null +++ b/mysql-test/suite/rpl/r/parallel_backup_slave_binlog_off.result @@ -0,0 +1,207 @@ +# Specialized --skip-log-bin slave version of parallel_backup test. +# MDEV-21953: deadlock between BACKUP STAGE BLOCK_COMMIT and parallel +# MDEV-30423: dealock XA COMMIT vs BACKUP +include/master-slave.inc +[connection master] +# +# MDEV-21953: deadlock between BACKUP STAGE BLOCK_COMMIT and parallel +# replication +# +connection master; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE = innodb; +INSERT INTO t1 VALUES(100); +connection slave; +call mtr.add_suppression("Deadlock found when trying to get lock"); +call mtr.add_suppression("Commit failed due to failure of an earlier commit"); +include/stop_slave.inc +SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; +SET @@global.slave_parallel_threads= 2; +SET @@global.slave_parallel_mode = 'optimistic'; +connection master; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +connect aux_slave,127.0.0.1,root,,test,$SLAVE_MYPORT,; +BEGIN; +INSERT INTO t1 VALUES (1); +connection slave; +include/start_slave.inc +connection aux_slave; +connect backup_slave,127.0.0.1,root,,test,$SLAVE_MYPORT,; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +# MDEV-30423: dealock XA COMMIT vs BACKUP +# +# Normal XA COMMIT +connection slave; +include/stop_slave.inc +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (102); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (101); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (102); +connection master; +XA COMMIT '1'; +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +# +# Normal XA ROLLBACK +connection slave; +include/stop_slave.inc +Warnings: +Note 1255 Slave already has been stopped +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (104); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (103); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (104); +connection master; +XA ROLLBACK '1'; +include/save_master_gtid.inc +connection slave; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +# +# Errored out XA COMMIT +connection slave; +include/stop_slave.inc +Warnings: +Note 1255 Slave already has been stopped +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (106); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (105); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (106); +connection master; +XA COMMIT '1'; +include/save_master_gtid.inc +connection slave; +SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; +SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; +SET @@global.innodb_lock_wait_timeout =1; +SET @@global.slave_transaction_retries=0; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/stop_slave.inc +SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout; +SET @@global.slave_transaction_retries= @sav_slave_transaction_retries; +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc +# +# Errored out XA ROLLBACK +connection slave; +include/stop_slave.inc +connection master; +connection aux_slave; +BEGIN; +INSERT INTO t1 VALUES (108); +connection master; +XA START '1'; +INSERT INTO t1 VALUES (107); +XA END '1'; +XA PREPARE '1'; +connection master1; +INSERT INTO t1 VALUES (108); +connection master; +XA ROLLBACK '1'; +include/save_master_gtid.inc +connection slave; +SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; +SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; +SET @@global.innodb_lock_wait_timeout =1; +SET @@global.slave_transaction_retries=0; +include/start_slave.inc +connection aux_slave; +# Xid '1' must be in the output: +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 1 +connection backup_slave; +BACKUP STAGE START; +BACKUP STAGE BLOCK_COMMIT; +connection aux_slave; +ROLLBACK; +connection backup_slave; +BACKUP STAGE END; +connection slave; +include/stop_slave.inc +SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout; +SET @@global.slave_transaction_retries= @sav_slave_transaction_retries; +connection slave; +include/start_slave.inc +include/sync_with_master_gtid.inc +connection slave; +include/stop_slave.inc +SET @@global.slave_parallel_threads= @old_parallel_threads; +SET @@global.slave_parallel_mode = @old_parallel_mode; +include/start_slave.inc +connection server_1; +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_delayed_parallel_slave_sbm.result b/mysql-test/suite/rpl/r/rpl_delayed_parallel_slave_sbm.result new file mode 100644 index 00000000000..f783b1e0783 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_delayed_parallel_slave_sbm.result @@ -0,0 +1,60 @@ +include/master-slave.inc +[connection master] +connection slave; +include/stop_slave.inc +change master to master_delay=3, master_use_gtid=Slave_Pos; +set @@GLOBAL.slave_parallel_threads=2; +include/start_slave.inc +connection master; +create table t1 (a int); +include/sync_slave_sql_with_master.inc +# +# Pt 1) Ensure SBM is updated immediately upon arrival of the next event +# Lock t1 on slave so the first received transaction does not complete/commit +connection slave; +LOCK TABLES t1 WRITE; +connection master; +# Sleep 2 to allow a buffer between events for SBM check +insert into t1 values (0); +include/save_master_gtid.inc +connection slave; +# Waiting for transaction to arrive on slave and begin SQL Delay.. +# Validating SBM is updated on event arrival.. +# ..done +connection slave; +UNLOCK TABLES; +include/sync_with_master_gtid.inc +# +# Pt 2) If the SQL thread has not entered an idle state, ensure +# following events do not update SBM +# Stop slave IO thread so it receives both events together on restart +connection slave; +include/stop_slave_io.inc +connection master; +# Sleep 2 to allow a buffer between events for SBM check +insert into t1 values (1); +# Sleep 3 to create gap between events +insert into t1 values (2); +connection slave; +LOCK TABLES t1 WRITE; +START SLAVE IO_THREAD; +# Wait for first transaction to complete SQL delay and begin execution.. +# Validate SBM calculation doesn't use the second transaction because SQL thread shouldn't have gone idle.. +# ..and that SBM wasn't calculated using prior committed transactions +# ..done +connection slave; +UNLOCK TABLES; +# +# Cleanup +# Reset master_delay +include/stop_slave.inc +CHANGE MASTER TO master_delay=0; +set @@GLOBAL.slave_parallel_threads=4; +include/start_slave.inc +connection master; +DROP TABLE t1; +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +include/rpl_end.inc +# End of rpl_delayed_parallel_slave_sbm.test diff --git a/mysql-test/suite/rpl/r/rpl_parallel_analyze.result b/mysql-test/suite/rpl/r/rpl_parallel_analyze.result new file mode 100644 index 00000000000..c0a2abbc1ee --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_parallel_analyze.result @@ -0,0 +1,76 @@ +include/master-slave.inc +[connection master] +# Initialize +connection slave; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +# Setup data +connection master; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE ta (a int); +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +connection master; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection slave; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +include/stop_slave.inc +SET @old_parallel_threads =@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode =@@GLOBAL.slave_parallel_mode; +SET @old_gtid_strict_mode =@@GLOBAL.gtid_strict_mode; +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode=conservative; +SET GLOBAL gtid_strict_mode=ON; +include/start_slave.inc +connection master; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format=statement; +INSERT INTO t1 VALUES (foo(1, 'rpl_parallel_after_mark_start_commit WAIT_FOR sig_go', '')); +ANALYZE TABLE ta; +Table Op Msg_type Msg_text +test.ta analyze status Engine-independent statistics collected +test.ta analyze status Table is already up to date +include/save_master_gtid.inc +connection slave; +SELECT info FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit"; +info +ANALYZE TABLE ta +set @@debug_sync="now signal sig_go"; +include/sync_with_master_gtid.inc +# Cleanup +connection master; +DROP TABLE t1,ta; +connection slave; +SET DEBUG_SYNC='RESET'; +connection master; +SET DEBUG_SYNC='RESET'; +DROP FUNCTION foo; +include/save_master_gtid.inc +connection slave; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @@GLOBAL.slave_parallel_threads=@old_parallel_threads; +SET @@GLOBAL.slave_parallel_mode =@old_parallel_mode; +SET @@GLOBAL.gtid_strict_mode =@old_gtid_strict_mode; +include/start_slave.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/parallel_backup.test b/mysql-test/suite/rpl/t/parallel_backup.test index 964e2a30309..4f5ffa9f291 100644 --- a/mysql-test/suite/rpl/t/parallel_backup.test +++ b/mysql-test/suite/rpl/t/parallel_backup.test @@ -15,6 +15,9 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE = innodb; INSERT INTO t1 VALUES(100); --sync_slave_with_master +call mtr.add_suppression("Deadlock found when trying to get lock"); +call mtr.add_suppression("Commit failed due to failure of an earlier commit"); + --source include/stop_slave.inc SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads; SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; @@ -64,6 +67,32 @@ BACKUP STAGE END; --let $diff_tables= master:t1,slave:t1 --source include/diff_tables.inc +# +--echo # MDEV-30423: dealock XA COMMIT vs BACKUP +# Prove XA "COMPLETE" 'xid' does not dealock similary to the normal trx case. +# The slave binlog group commit leader is blocked by a local trx like in +# the above normal trx case. +# [Notice a reuse of t1,aux_conn from above.] +# +--let $complete = COMMIT +--source parallel_backup_xa.inc +--let $complete = ROLLBACK +--source parallel_backup_xa.inc + +--let $slave_ooo_error = 1 +--let $complete = COMMIT +--source parallel_backup_xa.inc +--connection slave +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +--let $slave_ooo_error = 1 +--let $complete = ROLLBACK +--source parallel_backup_xa.inc +--connection slave +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + # Clean up. --connection slave diff --git a/mysql-test/suite/rpl/t/parallel_backup_lsu_off-slave.opt b/mysql-test/suite/rpl/t/parallel_backup_lsu_off-slave.opt new file mode 100644 index 00000000000..2f2a9c436fc --- /dev/null +++ b/mysql-test/suite/rpl/t/parallel_backup_lsu_off-slave.opt @@ -0,0 +1,2 @@ +--log-slave-updates=0 + diff --git a/mysql-test/suite/rpl/t/parallel_backup_lsu_off.test b/mysql-test/suite/rpl/t/parallel_backup_lsu_off.test new file mode 100644 index 00000000000..8e2663077b2 --- /dev/null +++ b/mysql-test/suite/rpl/t/parallel_backup_lsu_off.test @@ -0,0 +1,7 @@ +# +--echo # Specialized --log-slave-updates = 0 version of parallel_backup test. +# +--echo # MDEV-21953: deadlock between BACKUP STAGE BLOCK_COMMIT and parallel +--echo # MDEV-30423: dealock XA COMMIT vs BACKUP +--let $rpl_skip_reset_master_and_slave = 1 +--source parallel_backup.test diff --git a/mysql-test/suite/rpl/t/parallel_backup_slave_binlog_off-slave.opt b/mysql-test/suite/rpl/t/parallel_backup_slave_binlog_off-slave.opt new file mode 100644 index 00000000000..a02b6d05829 --- /dev/null +++ b/mysql-test/suite/rpl/t/parallel_backup_slave_binlog_off-slave.opt @@ -0,0 +1 @@ +--skip-log-bin
\ No newline at end of file diff --git a/mysql-test/suite/rpl/t/parallel_backup_slave_binlog_off.test b/mysql-test/suite/rpl/t/parallel_backup_slave_binlog_off.test new file mode 100644 index 00000000000..7cefbdb3ddd --- /dev/null +++ b/mysql-test/suite/rpl/t/parallel_backup_slave_binlog_off.test @@ -0,0 +1,7 @@ +# +--echo # Specialized --skip-log-bin slave version of parallel_backup test. +# +--echo # MDEV-21953: deadlock between BACKUP STAGE BLOCK_COMMIT and parallel +--echo # MDEV-30423: dealock XA COMMIT vs BACKUP +--let $rpl_server_skip_log_bin= 1 +--source parallel_backup.test diff --git a/mysql-test/suite/rpl/t/parallel_backup_xa.inc b/mysql-test/suite/rpl/t/parallel_backup_xa.inc new file mode 100644 index 00000000000..2d831199aa8 --- /dev/null +++ b/mysql-test/suite/rpl/t/parallel_backup_xa.inc @@ -0,0 +1,79 @@ +# Invoked from parallel_backup.test +# Parameters: +# $complete = COMMIT or ROLLBACK +# $slave_ooo_error = 1 means slave group commit did not succeed +# +--let $kind = Normal +if ($slave_ooo_error) +{ + --let $kind = Errored out +} +--echo # +--echo # $kind XA $complete + +--connection slave +--source include/stop_slave.inc + +--connection master +# val_0 is the first value to insert on master in prepared xa +# val_1 is the next one to insert which is the value to block on slave +--let $val_0 = `SELECT max(a)+1 FROM t1` +--let $val_1 = $val_0 +--inc $val_1 + +--connection aux_slave +BEGIN; +--eval INSERT INTO t1 VALUES ($val_1) + +--connection master +XA START '1'; +--eval INSERT INTO t1 VALUES ($val_0) +XA END '1'; +XA PREPARE '1'; +--connection master1 +--eval INSERT INTO t1 VALUES ($val_1) +--connection master +--eval XA $complete '1' +--source include/save_master_gtid.inc + +--connection slave +if ($slave_ooo_error) +{ + SET @sav_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout; + SET @sav_slave_transaction_retries = @@global.slave_transaction_retries; + SET @@global.innodb_lock_wait_timeout =1; + SET @@global.slave_transaction_retries=0; +} +--source include/start_slave.inc +--connection aux_slave +--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc +--echo # Xid '1' must be in the output: +XA RECOVER; +--connection backup_slave + BACKUP STAGE START; +--send BACKUP STAGE BLOCK_COMMIT +--connection aux_slave + --sleep 1 + if ($slave_ooo_error) + { + --let $wait_condition= SELECT COUNT(*) = 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" + --source include/wait_condition.inc + } + ROLLBACK; +--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for backup lock" +--source include/wait_condition.inc +--connection backup_slave + --reap + BACKUP STAGE END; +--connection slave +if (!$slave_ooo_error) +{ + --source include/sync_with_master_gtid.inc +} +--source include/stop_slave.inc +if ($slave_ooo_error) +{ + SET @@global.innodb_lock_wait_timeout = @sav_innodb_lock_wait_timeout; + SET @@global.slave_transaction_retries= @sav_slave_transaction_retries; +} diff --git a/mysql-test/suite/rpl/t/rpl_delayed_parallel_slave_sbm-slave.opt b/mysql-test/suite/rpl/t/rpl_delayed_parallel_slave_sbm-slave.opt new file mode 100644 index 00000000000..9eea6a54b68 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_delayed_parallel_slave_sbm-slave.opt @@ -0,0 +1 @@ +--slave-parallel-threads=4 diff --git a/mysql-test/suite/rpl/t/rpl_delayed_parallel_slave_sbm.test b/mysql-test/suite/rpl/t/rpl_delayed_parallel_slave_sbm.test new file mode 100644 index 00000000000..4bcb7ad9e3f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_delayed_parallel_slave_sbm.test @@ -0,0 +1,133 @@ +# +# This test ensures that after a delayed parallel slave has idled, i.e. +# executed everything in its relay log, the next event group that the SQL +# thread reads from the relay log will immediately be used in the +# Seconds_Behind_Master. In particular, it ensures that the calculation for +# Seconds_Behind_Master is based on the timestamp of the new transaction, +# rather than the last committed transaction. +# +# References: +# MDEV-29639: Seconds_Behind_Master is incorrect for Delayed, Parallel +# Replicas +# + +--source include/master-slave.inc + +--connection slave +--source include/stop_slave.inc +--let $master_delay= 3 +--eval change master to master_delay=$master_delay, master_use_gtid=Slave_Pos +--let $old_slave_threads= `SELECT @@GLOBAL.slave_parallel_threads` +set @@GLOBAL.slave_parallel_threads=2; +--source include/start_slave.inc + +--connection master +create table t1 (a int); +--source include/sync_slave_sql_with_master.inc + +--echo # +--echo # Pt 1) Ensure SBM is updated immediately upon arrival of the next event + +--echo # Lock t1 on slave so the first received transaction does not complete/commit +--connection slave +LOCK TABLES t1 WRITE; + +--connection master +--echo # Sleep 2 to allow a buffer between events for SBM check +sleep 2; + +--let $ts_trx_before_ins= `SELECT UNIX_TIMESTAMP()` +--let insert_ctr= 0 +--eval insert into t1 values ($insert_ctr) +--inc $insert_ctr +--source include/save_master_gtid.inc + +--connection slave + +--echo # Waiting for transaction to arrive on slave and begin SQL Delay.. +--let $wait_condition= SELECT count(*) FROM information_schema.processlist WHERE state LIKE 'Waiting until MASTER_DELAY seconds after master executed event'; +--source include/wait_condition.inc + +--echo # Validating SBM is updated on event arrival.. +--let $sbm_trx1_arrive= query_get_value(SHOW SLAVE STATUS, Seconds_Behind_Master, 1) +--let $seconds_since_idling= `SELECT UNIX_TIMESTAMP() - $ts_trx_before_ins` +if (`SELECT $sbm_trx1_arrive > ($seconds_since_idling + 1)`) +{ + --echo # SBM was $sbm_trx1_arrive yet shouldn't have been larger than $seconds_since_idling + 1 (for possible negative clock_diff_with_master) + --die Seconds_Behind_Master should reset after idling +} +--echo # ..done + +--connection slave +UNLOCK TABLES; +--source include/sync_with_master_gtid.inc + +--echo # +--echo # Pt 2) If the SQL thread has not entered an idle state, ensure +--echo # following events do not update SBM + +--echo # Stop slave IO thread so it receives both events together on restart +--connection slave +--source include/stop_slave_io.inc + +--connection master + +--echo # Sleep 2 to allow a buffer between events for SBM check +sleep 2; +--let $ts_trxpt2_before_ins= `SELECT UNIX_TIMESTAMP()` +--eval insert into t1 values ($insert_ctr) +--inc $insert_ctr +--echo # Sleep 3 to create gap between events +sleep 3; +--eval insert into t1 values ($insert_ctr) +--inc $insert_ctr +--let $ts_trx_after_ins= `SELECT UNIX_TIMESTAMP()` + +--connection slave +LOCK TABLES t1 WRITE; + +START SLAVE IO_THREAD; + +--echo # Wait for first transaction to complete SQL delay and begin execution.. +--let $wait_condition= SELECT count(*) FROM information_schema.processlist WHERE state LIKE 'Waiting for table metadata lock%' AND command LIKE 'Slave_Worker'; +--source include/wait_condition.inc + +--echo # Validate SBM calculation doesn't use the second transaction because SQL thread shouldn't have gone idle.. +--let $sbm_after_trx_no_idle= query_get_value(SHOW SLAVE STATUS, Seconds_Behind_Master, 1) +--let $timestamp_trxpt2_arrive= `SELECT UNIX_TIMESTAMP()` +if (`SELECT $sbm_after_trx_no_idle < $timestamp_trxpt2_arrive - $ts_trx_after_ins`) +{ + --let $cmpv= `SELECT $timestamp_trxpt2_arrive - $ts_trx_after_ins` + --echo # SBM $sbm_after_trx_no_idle was more recent than time since last transaction ($cmpv seconds) + --die Seconds_Behind_Master should not have used second transaction timestamp +} +--let $seconds_since_idling= `SELECT ($timestamp_trxpt2_arrive - $ts_trxpt2_before_ins)` +--echo # ..and that SBM wasn't calculated using prior committed transactions +if (`SELECT $sbm_after_trx_no_idle > ($seconds_since_idling + 1)`) +{ + --echo # SBM was $sbm_after_trx_no_idle yet shouldn't have been larger than $seconds_since_idling + 1 (for possible negative clock_diff_with_master) + --die Seconds_Behind_Master calculation should not have used prior committed transaction +} +--echo # ..done + +--connection slave +UNLOCK TABLES; + +--echo # +--echo # Cleanup + +--echo # Reset master_delay +--source include/stop_slave.inc +--eval CHANGE MASTER TO master_delay=0 +--eval set @@GLOBAL.slave_parallel_threads=$old_slave_threads +--source include/start_slave.inc + +--connection master +DROP TABLE t1; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + +--source include/rpl_end.inc +--echo # End of rpl_delayed_parallel_slave_sbm.test diff --git a/mysql-test/suite/rpl/t/rpl_parallel_analyze.test b/mysql-test/suite/rpl/t/rpl_parallel_analyze.test new file mode 100644 index 00000000000..921c6f02904 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_analyze.test @@ -0,0 +1,84 @@ +# The test file is created to prove fixes to +# MDEV-30323 Some DDLs like ANALYZE can complete on parallel slave out of order +# Debug-sync tests aiming at parallel replication of ADMIN commands +# are welcome here. + +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--echo # Initialize +--connection slave +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + +--echo # Setup data +--connection master +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE ta (a int); +--let $pre_load_gtid=`SELECT @@last_gtid` +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + +--source suite/rpl/include/create_or_drop_sync_func.inc + +# configure MDEV-30323 slave +--source include/stop_slave.inc +SET @old_parallel_threads =@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode =@@GLOBAL.slave_parallel_mode; +SET @old_gtid_strict_mode =@@GLOBAL.gtid_strict_mode; +SET GLOBAL slave_parallel_threads=10; +SET GLOBAL slave_parallel_mode=conservative; +SET GLOBAL gtid_strict_mode=ON; +--source include/start_slave.inc + +# MDEV-30323 setup needs two group of events the first of which is a DML +# and ANALYZE is the 2nd. +# The latter is made to race in slave execution over the DML thanks +# to a DML latency simulation. +# In the fixed case the race-over should not be a problem: ultimately +# ANALYZE must wait for its turn to update slave@@global.gtid_binlog_pos. +# Otherwise the reported OOO error must be issued. + +--connection master +SET @old_format= @@SESSION.binlog_format; +SET binlog_format=statement; +INSERT INTO t1 VALUES (foo(1, 'rpl_parallel_after_mark_start_commit WAIT_FOR sig_go', '')); + +ANALYZE TABLE ta; +--source include/save_master_gtid.inc + +--connection slave +--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc + +SELECT info FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit"; +if (`select strcmp(@@global.gtid_binlog_pos, '$pre_load_gtid') <> 0 or strcmp(@@global.gtid_slave_pos, '$pre_load_gtid') <> 0`) +{ + --let $bs=`SELECT @@global.gtid_binlog_pos` + --let $es=`SELECT @@global.gtid_slave_pos` + --echo Mismatch between expected $pre_load_gtid state and the actual binlog state " @@global.gtid_binlog_pos = $bs or/and slave execution state @@global.gtid_slave_pos = $es. + --die +} + +set @@debug_sync="now signal sig_go"; +--source include/sync_with_master_gtid.inc + +--echo # Cleanup +--connection master +DROP TABLE t1,ta; +--let $create_or_drop=drop +--source suite/rpl/include/create_or_drop_sync_func.inc + +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET @@GLOBAL.slave_parallel_threads=@old_parallel_threads; +SET @@GLOBAL.slave_parallel_mode =@old_parallel_mode; +SET @@GLOBAL.gtid_strict_mode =@old_gtid_strict_mode; +--source include/start_slave.inc + +--source include/rpl_end.inc |