mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 02:46:29 +01:00 
			
		
		
		
	 a7d186a17d
			
		
	
	
	a7d186a17d
	
	
	
		
			
			- Reviewer: <knielsen@knielsen-hq.org>
            <brandon.nesterenko@mariadb.com>
            <andrei.elkin@mariadb.com>
		
	
			
		
			
				
	
	
		
			348 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			348 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| # 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;
 | |
| # ER_ROW_IS_REFERENCED_2 # Cannot add or update a child row: a foreign key constraint fails 
 | |
| --let slave_sql_errno= 1451
 | |
| source include/wait_for_slave_sql_error.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;
 | |
| # ER_NO_REFERENCED_ROW_2 # Cannot add or update a parent row: a foreign key constraint fails
 | |
| --let slave_sql_errno= 1452
 | |
| source include/wait_for_slave_sql_error.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 duplicate key)
 | |
| connection slave;
 | |
| # ER_DUP_ENTRY # Duplicate entry for key
 | |
| --let slave_sql_errno= 1062
 | |
| source include/wait_for_slave_sql_error.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;
 | |
| # ER_KEY_NOT_FOUND # Can't find record
 | |
| --let slave_sql_errno= 1032
 | |
| source include/wait_for_slave_sql_error.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;
 | |
| # ER_KEY_NOT_FOUND # Can't find record
 | |
| --let slave_sql_errno= 1032
 | |
| source include/wait_for_slave_sql_error.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;
 | |
| # ER_KEY_NOT_FOUND # Can't find record
 | |
| --let slave_sql_errno= 1032
 | |
| source include/wait_for_slave_sql_error.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;
 | |
| # ER_KEY_NOT_FOUND # Can't find record
 | |
| --let slave_sql_errno= 1032
 | |
| source include/wait_for_slave_sql_error.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
 |