diff options
Diffstat (limited to 'mysql-test/suite/rpl/t/rpl_row_idempotency.test')
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_row_idempotency.test | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/mysql-test/suite/rpl/t/rpl_row_idempotency.test b/mysql-test/suite/rpl/t/rpl_row_idempotency.test new file mode 100644 index 00000000..85775832 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_idempotency.test @@ -0,0 +1,333 @@ +# Testing various forms of idempotency for replication. This file is +# for tests that should only be executed in row mode. + +source include/have_binlog_format_row.inc; +source include/master-slave.inc; +connection master; +source include/have_innodb.inc; +connection slave; +source include/have_innodb.inc; + +# Add suppression for expected warning(s) in slaves error log +call mtr.add_suppression("Can.t find record in .t[12].* error.* 1032"); +call mtr.add_suppression("Cannot delete or update a parent row: a foreign key constraint fails .* error.* 1451"); +call mtr.add_suppression("Cannot add or update a child row: a foreign key constraint fails .* error.* 1452"); +call mtr.add_suppression("Duplicate entry .1. for key .PRIMARY.* error.* 1062"); +call mtr.add_suppression("Can't find record in 't1'"); +call mtr.add_suppression("Can't find record in 't2'"); + + +# bug#31609 Not all RBR slave errors reported as errors +# bug#31552 Replication breaks when deleting rows from out-of-sync table +# without PK + +# The default for slave-exec-mode option and server +# variable slave_exec_mode is 'STRICT'. +# When 'STRICT' mode is set, the slave SQL thread will stop whenever +# the row to change is not found. In 'IDEMPOTENT' mode, the SQL thread +# will continue running and apply the row - replace if it's Write_rows event - +# or skip to the next event. + +# the previous part of the tests was with IDEMPOTENT slave's mode. + + +# +# Other than above idempotent errors dealing with foreign keys constraint +# +connection slave; + +set @old_slave_exec_mode= @@global.slave_exec_mode; +set @@global.slave_exec_mode= IDEMPOTENT; + +connection master; + +create table ti1 (b int primary key) engine = innodb; +create table ti2 (a int primary key, b int, foreign key (b) references ti1(b)) + engine = innodb; +set foreign_key_checks=1 /* ensure the check */; + +insert into ti1 values (1),(2),(3); +insert into ti2 set a=2, b=2; + +sync_slave_with_master; + +#connection slave; +select * from ti1 order by b /* must be (1),(2),(3) */; +insert into ti2 set a=1, b=1; +select * from ti2 order by b /* must be (1,1) (2,2) */; + +connection master; + +# from now on checking rbr specific idempotent errors +set @save_binlog_format= @@session.binlog_format; +set @@session.binlog_format= row; +delete from ti1 where b=1; + +select * from ti1 order by b /* must be (2),(3) */; + +# slave must catch up (expect some warnings in error.log) +sync_slave_with_master; + +#connection slave; +select * from ti1 order by b /* must stays as were on master (1),(2),(3) */; + +delete from ti1 where b=3; + +connection master; +insert into ti2 set a=3, b=3; + +# slave must catch up (expect some warnings in error.log) +sync_slave_with_master; + +#connection slave; +select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */; + + +# +# Checking the new global sys variable +# + +connection slave; + +set global slave_exec_mode='IDEMPOTENT'; +set global slave_exec_mode='STRICT'; + +# checking mutual exclusion for the options +--error ER_WRONG_VALUE_FOR_VAR +set global slave_exec_mode='IDEMPOTENT,STRICT'; + +select @@global.slave_exec_mode /* must be STRICT */; + +# +# Checking stops. +# In the following sections strict slave sql thread is going to +# stop when faces an idempotent error. In order to proceed +# the mode is temporarily switched to indempotent. +# + +# +--echo *** foreign keys errors as above now forces to stop +# + +connection master; + +set foreign_key_checks=0; +drop table ti2, ti1; + +create table ti1 (b int primary key) engine = innodb; +create table ti2 (a int primary key, b int, foreign key (b) references ti1(b)) + engine = innodb; +set foreign_key_checks=1 /* ensure the check */; + +insert into ti1 values (1),(2),(3); +insert into ti2 set a=2, b=2; + +sync_slave_with_master; + +#connection slave; +select * from ti1 order by b /* must be (1),(2),(3) */; +--echo *** conspire future problem +insert into ti2 set a=1, b=1; +select * from ti2 order by b /* must be (1,1) (2,2) */; + +connection master; + +delete from ti1 where b=1 /* offending delete event */; +select * from ti1 order by b /* must be (2),(3) */; + +# foreign key: row is referenced + +--echo *** slave must stop (Trying to delete a referenced foreing key) +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +select * from ti1 order by b /* must be (1),(2),(3) - not deleted */; +set foreign_key_checks= 0; +delete from ti2 where b=1; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +connection master; + +sync_slave_with_master; + +#connection slave; +--echo *** conspire the following insert failure +# foreign key: no referenced row + +--echo *** conspire future problem +delete from ti1 where b=3; + +connection master; +insert into ti2 set a=3, b=3 /* offending write event */; + +--echo *** slave must stop (Trying to insert an invalid foreign key) +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +select * from ti2 order by b /* must be (2,2) */; +set foreign_key_checks= 0; +insert into ti1 set b=3; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +connection master; + +sync_slave_with_master; + +select * from ti2 order by b /* must be (2,2),(3,3) */; + +# +--echo *** other errors +# + +# dup key insert + +#connection slave; +--echo *** conspiring query +insert into ti1 set b=1; + +connection master; +insert into ti1 set b=1 /* offending write event */; + +--echo *** slave must stop (Trying to insert a dupliacte key) +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set foreign_key_checks= 0; +delete from ti1 where b=1; +set foreign_key_checks= 1; +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +# key not found + +connection master; + +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE TABLE t2 (a INT); +INSERT INTO t1 VALUES (-1),(-2),(-3); +INSERT INTO t2 VALUES (-1),(-2),(-3); +sync_slave_with_master; + +#connection slave; +DELETE FROM t1 WHERE a = -2; +DELETE FROM t2 WHERE a = -2; +connection master; +DELETE FROM t1 WHERE a = -2; + +--echo *** slave must stop (Key was not found) +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +connection master; +DELETE FROM t2 WHERE a = -2; +--echo *** slave must stop (Key was not found) +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + +UPDATE t1 SET a = 1 WHERE a = -1; +UPDATE t2 SET a = 1 WHERE a = -1; + +connection master; +UPDATE t1 SET a = 1 WHERE a = -1; + +--echo *** slave must stop (Key was not found) +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +set global slave_exec_mode='STRICT'; + + +connection master; +UPDATE t2 SET a = 1 WHERE a = -1; + +--echo *** slave must stop (Key was not found) +connection slave; +source include/wait_for_slave_sql_to_stop.inc; + +let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); +disable_query_log; +eval SELECT "$last_error" AS Last_SQL_Error; +enable_query_log; + +set global slave_exec_mode='IDEMPOTENT'; +start slave sql_thread; +connection master; +sync_slave_with_master; +#connection slave; +SET @@global.slave_exec_mode= @old_slave_exec_mode; + +# cleanup for bug#31609 tests + +connection master; + +drop table t1,t2,ti2,ti1; +sync_slave_with_master; +set @@global.slave_exec_mode= @old_slave_exec_mode; + +--echo *** end of tests +--source include/rpl_end.inc |