diff options
Diffstat (limited to 'mysql-test/suite/rpl/t')
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_gtid_basic.test | 4 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_gtid_crash.test | 37 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test | 64 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_temporary_error2.test | 77 |
5 files changed, 183 insertions, 0 deletions
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_basic.test b/mysql-test/suite/rpl/t/rpl_gtid_basic.test index 37f7886118a..687c0d62cb1 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_basic.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.test @@ -190,6 +190,7 @@ SET GLOBAL gtid_binlog_state = @old_state; # restored the state. CREATE TABLE t1 (a INT PRIMARY KEY); +SET gtid_seq_no=100; INSERT INTO t1 VALUES (1); --let $master_pos= `SELECT @@GLOBAL.gtid_binlog_pos` @@ -202,6 +203,9 @@ INSERT INTO t1 VALUES (1); --source include/wait_condition.inc SELECT * FROM t1; +# Check that the IO gtid position in SHOW SLAVE STATUS is also correct. +--let $status_items= Gtid_IO_Pos +--source include/show_slave_status.inc --connection server_1 DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test index 2a9e0ef232a..913a87f9862 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_crash.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test @@ -257,6 +257,43 @@ EOF SELECT * FROM t1 ORDER BY a; +--echo *** MDEV-4725: Incorrect recovery when crash in the middle of writing an event group *** + +--connection server_2 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF + +--let $old_gtid_strict= `SELECT @@gtid_strict_mode` +SET GLOBAL debug_dbug="+d,crash_before_writing_xid"; + +--connection server_1 +INSERT INTO t1 VALUES (9), (10); +--save_master_pos + +--connection server_2 +--source include/wait_until_disconnected.inc + +# The bug was that during crash recovery we would update the binlog state +# with the GTID of the half-written event group at the end of the slaves +# binlog, even though this event group was not committed. +# We restart the server with gtid_strict_mode; this way, we get an error +# about duplicate gtid when the slave re-executes the event group, if the +# binlog crash recovery is incorrect. +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --gtid_strict_mode=1 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +SHOW VARIABLES like 'gtid_strict_mode'; +--source include/start_slave.inc +--sync_with_master +--disable_query_log +eval SET GLOBAL gtid_strict_mode= $old_gtid_strict; +--enable_query_log + --connection server_1 DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt new file mode 100644 index 00000000000..32711eb9726 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt @@ -0,0 +1 @@ +--skip-stack-trace --skip-core-file --skip-innodb diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test new file mode 100644 index 00000000000..faf388f5bed --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test @@ -0,0 +1,64 @@ +--source include/have_debug.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc + +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test crashing master with InnoDB disabled, the binlog gtid state should still be correctly recovered. *** + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--connection server_1 + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +FLUSH TABLES; +SET SESSION debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +SELECT 1; + +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart-rpl_gtid_crash.test +EOF + +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc + +INSERT INTO t1 VALUES (3); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--connection server_1 +DROP TABLE t1; + +--connection default +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_temporary_error2.test b/mysql-test/suite/rpl/t/rpl_temporary_error2.test new file mode 100644 index 00000000000..b4fbca7113b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_temporary_error2.test @@ -0,0 +1,77 @@ +--source include/have_innodb.inc +--source include/master-slave.inc + +--echo *** Provoke a deadlock on the slave, check that transaction retry succeeds. *** +--connection master +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +INSERT INTO t1(a) VALUES (1), (2), (3), (4), (5); + +--sync_slave_with_master +SELECT * FROM t1 ORDER BY a; +# Use MyISAM for t2 on the slave, so we have a way to see how far the +# slave replication thread has proceeded in the transaction. +SET sql_log_bin=0; +ALTER TABLE t2 ENGINE=MyISAM; +SET sql_log_bin=1; +let $old_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); + +# Setup a separate connection that can deadlock with the replication thread. +# Docs say that InnoDB will try to roll back the smaller transaction. So +# let us make this transaction a big one, so the one in the replication +# thread will be selected for rollback and retry. +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +--connection con_temp1 +BEGIN; +UPDATE t1 SET b=2 WHERE a=4; +--disable_query_log +--let $count=200 +while ($count) +{ + eval INSERT INTO t1(a) VALUES ($count + 10); + dec $count; +} +--enable_query_log +# Note that InnoDB also (undocumented?) tries to avoid rolling back a +# "transaction" that modified non-transactional tables. So be sure to also +# touch the MyISAM table in this transaction. +INSERT INTO t2 VALUES (2); +DELETE FROM t2 WHERE a=2; + +# Create the transaction that should participate in the deadlock on the slave. +--connection master +BEGIN; +UPDATE t1 SET b=1 WHERE a=2; +INSERT INTO t2 VALUES (1); +UPDATE t1 SET b=1 WHERE a=4; +COMMIT; +--save_master_pos + +--connection slave +# Wait until replication thread has gone to wait on the a=4 row lock. +--let $wait_condition= SELECT COUNT(*) = 1 FROM t2 WHERE a=1 +--source include/wait_condition.inc + +# Now provoke the deadlock by waiting on the a=2 row lock while the +# other thread is waiting for our a=4 row lock. +--connection con_temp1 +UPDATE t1 SET b=2 WHERE a=2; +SELECT * FROM t1 WHERE a<10 ORDER BY a; +ROLLBACK; + +--connection slave +--sync_with_master +SELECT * FROM t1 ORDER BY a; +--echo * There will be two rows in t2 due to the retry. +SELECT * FROM t2 ORDER BY a; +let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--disable_query_log +eval SELECT $new_retry - $old_retry AS retries; +--enable_query_log +--let $status_items= Last_SQL_Errno, Last_SQL_Error +--source include/show_slave_status.inc + +--connection master +DROP TABLE t1; +DROP TABLE t2; +--source include/rpl_end.inc |