mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#31552 Replication breaks when deleting rows from out-of-sync table
without PK Bug#31609 Not all RBR slave errors reported as errors bug#32468 delete rows event on a table with foreign key constraint fails The first two bugs comprise idempotency issues. First, there was no error code reported under conditions of the bug description although the slave sql thread halted. Second, executions were different with and without presence of prim key in the table. Third, there was no way to instruct the slave whether to ignore an error and skip to the following event or to halt. Fourth, there are handler errors which might happen due to idempotent applying of binlog but those were not listed among the "idempotent" error list. All the named issues are addressed. Wrt to the 3rd, there is the new global system variable, changeble at run time, which controls the slave sql thread behaviour. The new variable allows further extensions to mimic the sql_mode session/global variable. To address the 4th, the new bug#32468 had to be fixed as it was staying in the way. include/my_bitmap.h: basic operations with bits of an integer type are added. mysql-test/extra/rpl_tests/rpl_foreign_key.test: regression test for bug#32468 mysql-test/extra/rpl_tests/rpl_row_basic.test: changes due to bug#31552/31609 idempotency is not default any longer mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: changes due to bug#31552/31609 idempotency is not default any longer mysql-test/suite/rpl/r/rpl_foreign_key_innodb.result: results changed mysql-test/suite/rpl/r/rpl_idempotency.result: results changed mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result: results changed mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result: results changed mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result: results changed mysql-test/suite/rpl/r/rpl_row_mystery22.result: results changed mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result: results changed mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result: results changed mysql-test/suite/rpl/r/rpl_temporary_errors.result: results changed mysql-test/suite/rpl/t/rpl_idempotency.test: extenstions to the test providing testing of complements to the idempotent error set and checking how slave halts when it faces an error from the list when the mode is STRICT. mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test: changes due to bug#31552/31609 idempotency is not default any longer. mysql-test/suite/rpl/t/rpl_row_mystery22.test: changes due to bug#31552/31609 idempotency is not default any longer mysql-test/suite/rpl/t/rpl_temporary_errors.test: changes due to bug#31552/31609 idempotency is not default any longer mysql-test/suite/rpl_ndb/r/rpl_ndb_dd_advance.result: results changed mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result: results changed sql/log_event.cc: the fix for bug#32468 delete rows event on a table with foreign key constraint fails ensures the flags are set at proper time so that their values will be caught by innodb. reseting the flags is done along the common error and errorless execution path. The list of idempotent error is extended with foreign keys related items. NDB engine write events are designed with the replace sematics in mind. Therefore the corrsponding ndb handler's flag are (re)set regardless of the slave's execution mode. Rows_log_event::write_row() starts using the bool replace argument as its caller sets it depending on the event's execution mode. sql/log_event.h: adding a new member to hold the slave's mode during execution of the event. sql/mysql_priv.h: changes to link the command line option with the new global sys var. sql/mysqld.cc: introduction of the new command line option. providing its initialization to a default. changes to link the command line option with the new global sys var. sql/rpl_rli.cc: rli post-event-execution cleanup restores the default bits. sql/set_var.cc: The new "standard" sys_var_set class' and the new global system var related declarations and definitions. fix_slave_exec_mode() is used as with the update method of a new class so as at time of the command line arguments parsing. sql/set_var.h: new declarations. The class for the new global sys var is based on yet another new "standard" one. sql/share/errmsg.txt: slave_exec_mode setting error; slave inconsistency error which may be not an error when the intention is "idempotent". I.e consisting of row-based events binlog is being applied for the 2nd (more) time. sql/sql_class.h: The names for the bits of the new sever slave_exec_mode_options. mysql-test/suite/rpl/t/rpl_idempotency-master.opt: innodb is necessary mysql-test/suite/rpl/t/rpl_idempotency-slave.opt: innodb is necessary, as well as the tests start with non-default IDEMPOTENT slave execution mode.
This commit is contained in:
@ -32,3 +32,34 @@ SET FOREIGN_KEY_CHECKS=0;
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
sync_slave_with_master;
|
||||
|
||||
#
|
||||
# Bug #32468 delete rows event on a table with foreign key constraint fails
|
||||
#
|
||||
|
||||
connection master;
|
||||
|
||||
eval create table t1 (b int primary key) engine = $engine_type;
|
||||
eval create table t2 (a int primary key, b int, foreign key (b) references t1(b))
|
||||
engine = $engine_type;
|
||||
|
||||
insert into t1 set b=1;
|
||||
insert into t2 set a=1, b=1;
|
||||
|
||||
set foreign_key_checks=0;
|
||||
set @@session.binlog_format=row;
|
||||
delete from t1;
|
||||
|
||||
--echo must sync w/o a problem (could not with the buggy code)
|
||||
sync_slave_with_master;
|
||||
select count(*) from t1 /* must be zero */;
|
||||
|
||||
|
||||
# cleanup for bug#32468
|
||||
|
||||
connection master;
|
||||
drop table t2,t1;
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
|
||||
|
@ -174,11 +174,18 @@ sync_slave_with_master;
|
||||
INSERT INTO t7 VALUES (1,3), (2,6), (3,9);
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
|
||||
# since bug#31552/31609 idempotency is not default any longer. In order
|
||||
# the preceeding test INSERT INTO t7 to pass the mode is switched
|
||||
# temprorarily
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
|
||||
connection master;
|
||||
--echo --- on master: new values inserted ---
|
||||
INSERT INTO t7 VALUES (1,2), (2,4), (3,6);
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
sync_slave_with_master;
|
||||
|
||||
set @@global.slave_exec_mode= default;
|
||||
--echo --- on slave: old values should be overwritten by replicated values ---
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
|
||||
@ -206,12 +213,19 @@ SELECT * FROM t8 ORDER BY a;
|
||||
INSERT INTO t8 VALUES (1,2,3), (2,4,6), (3,6,9);
|
||||
SELECT * FROM t8 ORDER BY a;
|
||||
|
||||
# since bug#31552/31609 idempotency is not default any longer. In order
|
||||
# the preceeding test INSERT INTO t8 to pass the mode is switched
|
||||
# temprorarily
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
|
||||
connection master;
|
||||
--echo --- on master ---
|
||||
# We insert a row that will cause conflict on the primary key but not
|
||||
# on the other keys.
|
||||
INSERT INTO t8 VALUES (2,4,8);
|
||||
sync_slave_with_master;
|
||||
set @@global.slave_exec_mode= default;
|
||||
|
||||
--echo --- on slave ---
|
||||
SELECT * FROM t8 ORDER BY a;
|
||||
|
||||
|
@ -69,6 +69,11 @@ ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0,
|
||||
|
||||
# Insert some values for tables on slave side. These should not be
|
||||
# modified when the row from the master is applied.
|
||||
# since bug#31552/31609 idempotency is not default any longer. In order
|
||||
# the following INSERTs to pass the mode is switched temprorarily
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
|
||||
# so the inserts are going to be overriden
|
||||
INSERT INTO t1_int VALUES (2, 4, 4711);
|
||||
INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar');
|
||||
INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01');
|
||||
@ -86,6 +91,8 @@ SELECT * FROM t1_bit ORDER BY a;
|
||||
SELECT * FROM t1_char ORDER BY a;
|
||||
--echo **** On Slave ****
|
||||
sync_slave_with_master;
|
||||
set @@global.slave_exec_mode= default;
|
||||
|
||||
SELECT a,b,x FROM t1_int ORDER BY a;
|
||||
SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit ORDER BY a;
|
||||
SELECT a,b,x FROM t1_char ORDER BY a;
|
||||
|
35
mysql-test/r/bdb_notembedded.result
Normal file
35
mysql-test/r/bdb_notembedded.result
Normal file
@ -0,0 +1,35 @@
|
||||
set autocommit=1;
|
||||
reset master;
|
||||
create table bug16206 (a int);
|
||||
insert into bug16206 values(1);
|
||||
start transaction;
|
||||
insert into bug16206 values(2);
|
||||
commit;
|
||||
show binlog events;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
|
||||
f n Query 1 n use `test`; create table bug16206 (a int)
|
||||
f n Query 1 n use `test`; insert into bug16206 values(1)
|
||||
f n Query 1 n use `test`; insert into bug16206 values(2)
|
||||
drop table bug16206;
|
||||
reset master;
|
||||
create table bug16206 (a int) engine= bdb;
|
||||
insert into bug16206 values(0);
|
||||
insert into bug16206 values(1);
|
||||
start transaction;
|
||||
insert into bug16206 values(2);
|
||||
commit;
|
||||
insert into bug16206 values(3);
|
||||
show binlog events;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
|
||||
f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb
|
||||
f n Query 1 n use `test`; insert into bug16206 values(0)
|
||||
f n Query 1 n use `test`; insert into bug16206 values(1)
|
||||
f n Query 1 n use `test`; BEGIN
|
||||
f n Query 1 n use `test`; insert into bug16206 values(2)
|
||||
f n Query 1 n use `test`; COMMIT
|
||||
f n Query 1 n use `test`; insert into bug16206 values(3)
|
||||
drop table bug16206;
|
||||
set autocommit=0;
|
||||
End of 5.0 tests
|
@ -40,3 +40,16 @@ Got one of the listed errors
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
create table t1 (b int primary key) engine = INNODB;
|
||||
create table t2 (a int primary key, b int, foreign key (b) references t1(b))
|
||||
engine = INNODB;
|
||||
insert into t1 set b=1;
|
||||
insert into t2 set a=1, b=1;
|
||||
set foreign_key_checks=0;
|
||||
set @@session.binlog_format=row;
|
||||
delete from t1;
|
||||
must sync w/o a problem (could not with the buggy code)
|
||||
select count(*) from t1 /* must be zero */;
|
||||
count(*)
|
||||
0
|
||||
drop table t2,t1;
|
||||
|
@ -69,3 +69,158 @@ a
|
||||
Last_SQL_Error
|
||||
0
|
||||
DROP TABLE t1, t2;
|
||||
select @@global.slave_exec_mode /* must be IDEMPOTENT */;
|
||||
@@global.slave_exec_mode
|
||||
IDEMPOTENT
|
||||
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;
|
||||
select * from ti1 order by b /* must be (1),(2),(3) */;
|
||||
b
|
||||
1
|
||||
2
|
||||
3
|
||||
insert into ti2 set a=1, b=1;
|
||||
select * from ti2 order by b /* must be (1,1) (2,2) */;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
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) */;
|
||||
b
|
||||
2
|
||||
3
|
||||
select * from ti1 order by b /* must stays as were on master (1),(2),(3) */;
|
||||
b
|
||||
1
|
||||
2
|
||||
3
|
||||
delete from ti1 where b=3;
|
||||
insert into ti2 set a=3, b=3;
|
||||
select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
set global slave_exec_mode='IDEMPOTENT';
|
||||
set global slave_exec_mode='STRICT';
|
||||
set global slave_exec_mode='IDEMPOTENT,STRICT';
|
||||
ERROR HY000: Ambiguous slave modes combination.
|
||||
select @@global.slave_exec_mode /* must be STRICT */;
|
||||
@@global.slave_exec_mode
|
||||
STRICT
|
||||
*** foreign keys errors as above now forces to stop
|
||||
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;
|
||||
select * from ti1 order by b /* must be (1),(2),(3) */;
|
||||
b
|
||||
1
|
||||
2
|
||||
3
|
||||
*** conspire future problem
|
||||
insert into ti2 set a=1, b=1;
|
||||
select * from ti2 order by b /* must be (1,1) (2,2) */;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
delete from ti1 where b=1 /* offending delete event */;
|
||||
select * from ti1 order by b /* must be (2),(3) */;
|
||||
b
|
||||
2
|
||||
3
|
||||
*** slave must stop
|
||||
Last_SQL_Error
|
||||
0
|
||||
select * from ti1 order by b /* must be (1),(2),(3) - not deleted */;
|
||||
b
|
||||
1
|
||||
2
|
||||
3
|
||||
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;
|
||||
set global slave_exec_mode='STRICT';
|
||||
*** conspire the following insert failure
|
||||
*** conspire future problem
|
||||
delete from ti1 where b=3;
|
||||
insert into ti2 set a=3, b=3 /* offending write event */;
|
||||
*** slave must stop
|
||||
Last_SQL_Error
|
||||
1452
|
||||
select * from ti2 order by b /* must be (2,2) */;
|
||||
a b
|
||||
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;
|
||||
set global slave_exec_mode='STRICT';
|
||||
select * from ti2 order by b /* must be (2,2),(3,3) */;
|
||||
a b
|
||||
2 2
|
||||
3 3
|
||||
*** other errors
|
||||
*** conspiring query
|
||||
insert into ti1 set b=1;
|
||||
insert into ti1 set b=1 /* offending write event */;
|
||||
*** slave must stop
|
||||
Last_SQL_Error
|
||||
1062
|
||||
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;
|
||||
set global slave_exec_mode='STRICT';
|
||||
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);
|
||||
DELETE FROM t1 WHERE a = -2;
|
||||
DELETE FROM t2 WHERE a = -2;
|
||||
DELETE FROM t1 WHERE a = -2;
|
||||
*** slave must stop
|
||||
Last_SQL_Error
|
||||
1032
|
||||
set global slave_exec_mode='IDEMPOTENT';
|
||||
start slave sql_thread;
|
||||
set global slave_exec_mode='STRICT';
|
||||
DELETE FROM t2 WHERE a = -2;
|
||||
*** slave must stop
|
||||
Last_SQL_Error
|
||||
0
|
||||
set global slave_exec_mode='IDEMPOTENT';
|
||||
start slave sql_thread;
|
||||
set global slave_exec_mode='STRICT';
|
||||
UPDATE t1 SET a = 1 WHERE a = -1;
|
||||
UPDATE t2 SET a = 1 WHERE a = -1;
|
||||
UPDATE t1 SET a = 1 WHERE a = -1;
|
||||
*** slave must stop
|
||||
Last_SQL_Error
|
||||
1032
|
||||
set global slave_exec_mode='IDEMPOTENT';
|
||||
start slave sql_thread;
|
||||
set global slave_exec_mode='STRICT';
|
||||
UPDATE t2 SET a = 1 WHERE a = -1;
|
||||
*** slave must stop
|
||||
Last_SQL_Error
|
||||
0
|
||||
set global slave_exec_mode='IDEMPOTENT';
|
||||
start slave sql_thread;
|
||||
set global slave_exec_mode='STRICT';
|
||||
set @@session.binlog_format= @save_binlog_format;
|
||||
drop table t1,t2,ti2,ti1;
|
||||
*** end of tests
|
||||
|
@ -257,6 +257,7 @@ SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
2 master,slave
|
||||
5 slave
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
**** On Master ****
|
||||
UPDATE t1 SET a = 5, b = 'master' WHERE a = 1;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
@ -264,6 +265,7 @@ a b
|
||||
2 master,slave
|
||||
5 master
|
||||
**** On Slave ****
|
||||
set @@global.slave_exec_mode= default;
|
||||
Last_SQL_Error
|
||||
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
@ -370,6 +370,7 @@ C1 C2
|
||||
1 3
|
||||
2 6
|
||||
3 9
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
--- on master: new values inserted ---
|
||||
INSERT INTO t7 VALUES (1,2), (2,4), (3,6);
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
@ -377,6 +378,7 @@ C1 C2
|
||||
1 2
|
||||
2 4
|
||||
3 6
|
||||
set @@global.slave_exec_mode= default;
|
||||
--- on slave: old values should be overwritten by replicated values ---
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
C1 C2
|
||||
@ -406,8 +408,10 @@ a b c
|
||||
2 4 6
|
||||
3 6 9
|
||||
99 99 99
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
--- on master ---
|
||||
INSERT INTO t8 VALUES (2,4,8);
|
||||
set @@global.slave_exec_mode= default;
|
||||
--- on slave ---
|
||||
SELECT * FROM t8 ORDER BY a;
|
||||
a b c
|
||||
|
@ -370,6 +370,7 @@ C1 C2
|
||||
1 3
|
||||
2 6
|
||||
3 9
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
--- on master: new values inserted ---
|
||||
INSERT INTO t7 VALUES (1,2), (2,4), (3,6);
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
@ -377,6 +378,7 @@ C1 C2
|
||||
1 2
|
||||
2 4
|
||||
3 6
|
||||
set @@global.slave_exec_mode= default;
|
||||
--- on slave: old values should be overwritten by replicated values ---
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
C1 C2
|
||||
@ -406,8 +408,10 @@ a b c
|
||||
2 4 6
|
||||
3 6 9
|
||||
99 99 99
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
--- on master ---
|
||||
INSERT INTO t8 VALUES (2,4,8);
|
||||
set @@global.slave_exec_mode= default;
|
||||
--- on slave ---
|
||||
SELECT * FROM t8 ORDER BY a;
|
||||
a b c
|
||||
|
@ -5,6 +5,7 @@ reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
create table t1(n int auto_increment primary key, s char(10));
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
insert into t1 values (2,'old');
|
||||
insert into t1 values(NULL,'new');
|
||||
insert into t1 values(NULL,'new');
|
||||
@ -28,3 +29,4 @@ n s
|
||||
1 new
|
||||
3 new
|
||||
drop table t1;
|
||||
set @@global.slave_exec_mode= default;
|
||||
|
@ -37,6 +37,7 @@ ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0,
|
||||
ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0,
|
||||
ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0,
|
||||
ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0;
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
INSERT INTO t1_int VALUES (2, 4, 4711);
|
||||
INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar');
|
||||
INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01');
|
||||
@ -60,6 +61,7 @@ a b
|
||||
1 2
|
||||
2 5
|
||||
**** On Slave ****
|
||||
set @@global.slave_exec_mode= default;
|
||||
SELECT a,b,x FROM t1_int ORDER BY a;
|
||||
a b x
|
||||
1 2 42
|
||||
@ -123,7 +125,7 @@ Replicate_Ignore_Table
|
||||
Replicate_Wild_Do_Table
|
||||
Replicate_Wild_Ignore_Table
|
||||
Last_Errno 1364
|
||||
Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
|
||||
Last_Error Could not execute Write_rows event on table test.t1_nodef; handler error <unknown>; the event's master log master-bin.000001, end_log_pos 2674
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos #
|
||||
Relay_Log_Space #
|
||||
@ -141,7 +143,7 @@ Master_SSL_Verify_Server_Cert No
|
||||
Last_IO_Errno 0
|
||||
Last_IO_Error
|
||||
Last_SQL_Errno 1364
|
||||
Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
|
||||
Last_SQL_Error Could not execute Write_rows event on table test.t1_nodef; handler error <unknown>; the event's master log master-bin.000001, end_log_pos 2674
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
|
||||
START SLAVE;
|
||||
INSERT INTO t9 VALUES (2);
|
||||
|
@ -37,6 +37,7 @@ ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0,
|
||||
ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0,
|
||||
ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0,
|
||||
ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0;
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
INSERT INTO t1_int VALUES (2, 4, 4711);
|
||||
INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar');
|
||||
INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01');
|
||||
@ -60,6 +61,7 @@ a b
|
||||
1 2
|
||||
2 5
|
||||
**** On Slave ****
|
||||
set @@global.slave_exec_mode= default;
|
||||
SELECT a,b,x FROM t1_int ORDER BY a;
|
||||
a b x
|
||||
1 2 42
|
||||
@ -123,7 +125,7 @@ Replicate_Ignore_Table
|
||||
Replicate_Wild_Do_Table
|
||||
Replicate_Wild_Ignore_Table
|
||||
Last_Errno 1364
|
||||
Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
|
||||
Last_Error Could not execute Write_rows event on table test.t1_nodef; handler error <unknown>; the event's master log master-bin.000001, end_log_pos 2944
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos #
|
||||
Relay_Log_Space #
|
||||
@ -141,7 +143,7 @@ Master_SSL_Verify_Server_Cert No
|
||||
Last_IO_Errno 0
|
||||
Last_IO_Error
|
||||
Last_SQL_Errno 1364
|
||||
Last_SQL_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef.
|
||||
Last_SQL_Error Could not execute Write_rows event on table test.t1_nodef; handler error <unknown>; the event's master log master-bin.000001, end_log_pos 2944
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
|
||||
START SLAVE;
|
||||
INSERT INTO t9 VALUES (2);
|
||||
|
@ -12,6 +12,7 @@ INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
|
||||
SHOW STATUS LIKE 'Slave_retried_transactions';
|
||||
Variable_name Value
|
||||
Slave_retried_transactions 0
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
UPDATE t1 SET a = 5, b = 47 WHERE a = 1;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
@ -28,6 +29,7 @@ a b
|
||||
3 3
|
||||
4 4
|
||||
**** On Slave ****
|
||||
set @@global.slave_exec_mode= default;
|
||||
SHOW STATUS LIKE 'Slave_retried_transactions';
|
||||
Variable_name Value
|
||||
Slave_retried_transactions 0
|
||||
|
2
mysql-test/suite/rpl/t/rpl_idempotency-master.opt
Normal file
2
mysql-test/suite/rpl/t/rpl_idempotency-master.opt
Normal file
@ -0,0 +1,2 @@
|
||||
--innodb
|
||||
|
2
mysql-test/suite/rpl/t/rpl_idempotency-slave.opt
Normal file
2
mysql-test/suite/rpl/t/rpl_idempotency-slave.opt
Normal file
@ -0,0 +1,2 @@
|
||||
--slave-exec-mode=IDEMPOTENT --innodb
|
||||
|
@ -77,3 +77,335 @@ enable_query_log;
|
||||
connection master;
|
||||
DROP TABLE t1, t2;
|
||||
sync_slave_with_master;
|
||||
|
||||
# bug#31609 Not all RBR slave errors reported as errors
|
||||
# bug#31552 Replication breaks when deleting rows from out-of-sync table
|
||||
# without PK
|
||||
|
||||
#
|
||||
# Idempotent applying is not default any longer.
|
||||
# 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
|
||||
#
|
||||
|
||||
select @@global.slave_exec_mode /* must be 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_SLAVE_AMBIGOUS_EXEC_MODE
|
||||
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
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
connection slave;
|
||||
|
||||
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
|
||||
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
connection slave;
|
||||
|
||||
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
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
connection slave;
|
||||
|
||||
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
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
connection slave;
|
||||
|
||||
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
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
connection slave;
|
||||
|
||||
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
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
connection slave;
|
||||
|
||||
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
|
||||
source include/wait_for_slave_sql_to_stop.inc;
|
||||
|
||||
connection slave;
|
||||
|
||||
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';
|
||||
|
||||
|
||||
# cleanup for bug#31609 tests
|
||||
|
||||
connection master;
|
||||
set @@session.binlog_format= @save_binlog_format;
|
||||
drop table t1,t2,ti2,ti1;
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
|
||||
--echo *** end of tests
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -242,12 +242,17 @@ INSERT INTO t1 VALUES (1,'master,slave'), (2,'master,slave');
|
||||
sync_slave_with_master;
|
||||
UPDATE t1 SET a = 5, b = 'slave' WHERE a = 1;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
# since bug#31552/31609 idempotency is not default any longer. In
|
||||
# order the preceeding test UPDATE t1 to pass the mode is switched
|
||||
# temprorarily
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
--echo **** On Master ****
|
||||
connection master;
|
||||
UPDATE t1 SET a = 5, b = 'master' WHERE a = 1;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
--echo **** On Slave ****
|
||||
sync_slave_with_master;
|
||||
set @@global.slave_exec_mode= default;
|
||||
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
|
||||
disable_query_log;
|
||||
eval SELECT "$last_error" AS Last_SQL_Error;
|
||||
|
@ -9,6 +9,12 @@
|
||||
# first, cause a duplicate key problem on the slave
|
||||
create table t1(n int auto_increment primary key, s char(10));
|
||||
sync_slave_with_master;
|
||||
|
||||
# bug#31552/31609 idempotency is not default any longer
|
||||
# so that the declared in heading comments aim of the test
|
||||
# should be backed up with explicit setting of the slave mode
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
|
||||
insert into t1 values (2,'old');
|
||||
connection master;
|
||||
insert into t1 values(NULL,'new');
|
||||
@ -43,3 +49,4 @@ select * from t1 order by n;
|
||||
connection master;
|
||||
drop table t1;
|
||||
sync_slave_with_master;
|
||||
set @@global.slave_exec_mode= default;
|
||||
|
@ -8,6 +8,9 @@ INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
|
||||
--echo **** On Slave ****
|
||||
sync_slave_with_master;
|
||||
SHOW STATUS LIKE 'Slave_retried_transactions';
|
||||
# since bug#31552/31609 idempotency is not default any longer. In order
|
||||
# the following UPDATE t1 to pass the mode is switched temprorarily
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
UPDATE t1 SET a = 5, b = 47 WHERE a = 1;
|
||||
SELECT * FROM t1;
|
||||
--echo **** On Master ****
|
||||
@ -17,6 +20,7 @@ SELECT * FROM t1;
|
||||
#SHOW BINLOG EVENTS;
|
||||
--echo **** On Slave ****
|
||||
sync_slave_with_master;
|
||||
set @@global.slave_exec_mode= default;
|
||||
SHOW STATUS LIKE 'Slave_retried_transactions';
|
||||
SELECT * FROM t1;
|
||||
source include/show_slave_status.inc;
|
||||
|
@ -301,6 +301,7 @@ SELECT COUNT(*) FROM history;
|
||||
COUNT(*)
|
||||
400
|
||||
*** DUMP MASTER & SLAVE FOR COMPARE ********
|
||||
set @@global.slave_exec_mode='IDEMPOTENT' /* to ignore missed records in mysql.proc */;
|
||||
*************** TEST 2 CLEANUP SECTION ********************
|
||||
DROP PROCEDURE IF EXISTS tpcb.load;
|
||||
DROP PROCEDURE IF EXISTS tpcb.trans;
|
||||
|
@ -370,6 +370,7 @@ C1 C2
|
||||
1 3
|
||||
2 6
|
||||
3 9
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
--- on master: new values inserted ---
|
||||
INSERT INTO t7 VALUES (1,2), (2,4), (3,6);
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
@ -377,6 +378,7 @@ C1 C2
|
||||
1 2
|
||||
2 4
|
||||
3 6
|
||||
set @@global.slave_exec_mode= 'STRICT';
|
||||
--- on slave: old values should be overwritten by replicated values ---
|
||||
SELECT * FROM t7 ORDER BY C1;
|
||||
C1 C2
|
||||
@ -406,8 +408,10 @@ a b c
|
||||
2 4 6
|
||||
3 6 9
|
||||
99 99 99
|
||||
set @@global.slave_exec_mode= 'IDEMPOTENT';
|
||||
--- on master ---
|
||||
INSERT INTO t8 VALUES (2,4,8);
|
||||
set @@global.slave_exec_mode= default;
|
||||
--- on slave ---
|
||||
SELECT * FROM t8 ORDER BY a;
|
||||
a b c
|
||||
|
38
mysql-test/t/bdb_notembedded.test
Normal file
38
mysql-test/t/bdb_notembedded.test
Normal file
@ -0,0 +1,38 @@
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_bdb.inc
|
||||
|
||||
#
|
||||
# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode
|
||||
#
|
||||
set autocommit=1;
|
||||
|
||||
let $VERSION=`select version()`;
|
||||
|
||||
reset master;
|
||||
create table bug16206 (a int);
|
||||
insert into bug16206 values(1);
|
||||
start transaction;
|
||||
insert into bug16206 values(2);
|
||||
commit;
|
||||
--replace_result $VERSION VERSION
|
||||
--replace_column 1 f 2 n 5 n
|
||||
show binlog events;
|
||||
drop table bug16206;
|
||||
|
||||
reset master;
|
||||
create table bug16206 (a int) engine= bdb;
|
||||
insert into bug16206 values(0);
|
||||
insert into bug16206 values(1);
|
||||
start transaction;
|
||||
insert into bug16206 values(2);
|
||||
commit;
|
||||
insert into bug16206 values(3);
|
||||
--replace_result $VERSION VERSION
|
||||
--replace_column 1 f 2 n 5 n
|
||||
show binlog events;
|
||||
drop table bug16206;
|
||||
|
||||
set autocommit=0;
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
Reference in New Issue
Block a user