diff options
author | Luis Soares <luis.soares@oracle.com> | 2011-07-14 12:15:24 +0100 |
---|---|---|
committer | Luis Soares <luis.soares@oracle.com> | 2011-07-14 12:15:24 +0100 |
commit | bf7d414b40b19ba7ec73b21aa00b1277e42cd1b2 (patch) | |
tree | 2d2044fad381e74cdb87c8b0d5c28501e45dbbda /mysql-test/suite | |
parent | 624ed50ef3f46ff23db74ac07502d63a2f21c8a1 (diff) | |
download | mariadb-git-bf7d414b40b19ba7ec73b21aa00b1277e42cd1b2.tar.gz |
BUG#11753004: 44360: REPLICATION FAILED
The server crashes if it processes table map events that are
corrupted, especially if they map different tables to the same
identifier. This could happen, for instance, due to BUG 56226.
We fix this by checking whether the table map has already been
mapped before actually applying the event. If it has been mapped
with different settings an error is raised and the slave SQL
thread stops. If it has been mapped with same settings the event
is skipped. If the table is set to be ignored by the filtering
rules, there is no change in behavior: the event is skipped and
ids are not checked.
mysql-test/suite/rpl/t/rpl_row_corruption.test:
Added a simple test case that checks both cases:
- multiple table maps with the same identifier
- multiple table maps with the same identifier, but only one
is processed (the others are filtered out)
Diffstat (limited to 'mysql-test/suite')
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_row_corruption.result | 49 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_row_corruption.test | 115 |
3 files changed, 165 insertions, 0 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_row_corruption.result b/mysql-test/suite/rpl/r/rpl_row_corruption.result new file mode 100644 index 00000000000..7fd47a20f03 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_corruption.result @@ -0,0 +1,49 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1_11753004 (c1 INT); +CREATE TABLE t2_11753004 (c1 INT); +INSERT INTO t1_11753004 VALUES (1); +INSERT INTO t2_11753004 VALUES (2); +call mtr.add_suppression(".*Found table map event mapping table id 0 which was already mapped but with different settings.*"); +include/stop_slave.inc +SET @save_debug= @@global.debug; +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +include/start_slave.inc +UPDATE t1_11753004, t2_11753004 SET t1_11753004.c1=3, t2_11753004.c1=4 WHERE t1_11753004.c1=1 OR t2_11753004.c1=2; +include/wait_for_slave_sql_error.inc [errno=1593 ] +include/stop_slave.inc +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +include/start_slave.inc +include/rpl_reset.inc +DROP TABLE t1_11753004, t2_11753004; +include/stop_slave.inc +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +include/start_slave.inc +include/rpl_reset.inc +CREATE TABLE t1_11753004 (c1 INT); +CREATE TABLE t2_11753004_ign (c1 INT); +INSERT INTO t1_11753004 VALUES (1); +INSERT INTO t2_11753004_ign VALUES (2); +UPDATE t1_11753004, t2_11753004_ign SET t1_11753004.c1=3, t2_11753004_ign.c1=4 WHERE t1_11753004.c1=1 OR t2_11753004_ign.c1=2; +CREATE TABLE t1 (c1 INT); +CREATE TABLE t2 (c1 INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +BINLOG ' +SOgWTg8BAAAAbgAAAHIAAAAAAAQANS42LjMtbTUtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8= +'/*!*/; +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +BINLOG ' +SOgWThMBAAAAKQAAAAYDAAAAAEIAAAAAAAEABHRlc3QAAnQxAAEDAAE= +SOgWThMBAAAAKQAAAC8DAAAAAEMAAAAAAAEABHRlc3QAAnQyAAEDAAE= +SOgWThgBAAAAKAAAAFcDAAAAAEIAAAAAAAAAAf///gEAAAD+AwAAAA== +SOgWThgBAAAAKAAAAH8DAAAAAEMAAAAAAAEAAf///gEAAAD+BAAAAA== +'/*!*/; +ERROR HY000: Fatal error: Found table map event mapping table id 0 which was already mapped but with different settings. +DROP TABLE t1,t2; +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +DROP TABLE t1_11753004; +DROP TABLE t2_11753004_ign; +SET GLOBAL debug= @save_debug; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt b/mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt new file mode 100644 index 00000000000..da199510eb3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t2_11753004_ign diff --git a/mysql-test/suite/rpl/t/rpl_row_corruption.test b/mysql-test/suite/rpl/t/rpl_row_corruption.test new file mode 100644 index 00000000000..a7650c615a3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_corruption.test @@ -0,0 +1,115 @@ +# +--source include/master-slave.inc +--source include/have_debug.inc +--source include/have_binlog_format_row.inc + +# BUG#11753004: 44360: REPLICATION FAILED + +## assert that we get an error when checking the +## identifiers at the slave (instead of a crash or +## different table being updated) + +--let $t1= t1_11753004 +--let $t2= t2_11753004 +--let $t2_ign= t2_11753004_ign + +## test #1: assert that we get an error raised when multiple +## tables in the same RBR statement are mapped with the +## same identifier + +--eval CREATE TABLE $t1 (c1 INT) +--eval CREATE TABLE $t2 (c1 INT) +--eval INSERT INTO $t1 VALUES (1) +--eval INSERT INTO $t2 VALUES (2) + +--sync_slave_with_master +call mtr.add_suppression(".*Found table map event mapping table id 0 which was already mapped but with different settings.*"); + +# stop the slave and inject corruption +--source include/stop_slave.inc +SET @save_debug= @@global.debug; +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +--source include/start_slave.inc +--connection master +# both tables get mapped to 0 (in a way, simulating scenario +# originated by BUG#56226) +--eval UPDATE $t1, $t2 SET $t1.c1=3, $t2.c1=4 WHERE $t1.c1=1 OR $t2.c1=2 +--connection slave + +# wait for error 1593 (ER_SLAVE_FATAL_ERROR) +--let $slave_sql_errno=1593 +--source include/wait_for_slave_sql_error.inc +--source include/stop_slave.inc + +# clean up +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +--source include/start_slave.inc +--connection master +--source include/rpl_reset.inc +--eval DROP TABLE $t1, $t2 +--sync_slave_with_master + +## test #2: assert that ignored tables that may have been mapped +## with the same identifier are skipped, thus no error +## is raised. + +--connection slave +--source include/stop_slave.inc +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +--source include/start_slave.inc +--source include/rpl_reset.inc +--connection master +--eval CREATE TABLE $t1 (c1 INT) +--eval CREATE TABLE $t2_ign (c1 INT) +--eval INSERT INTO $t1 VALUES (1) +--eval INSERT INTO $t2_ign VALUES (2) +--eval UPDATE $t1, $t2_ign SET $t1.c1=3, $t2_ign.c1=4 WHERE $t1.c1=1 OR $t2_ign.c1=2 + +# must not raise error as second table is filtered +--sync_slave_with_master + + +## test #3: check that BINLOG statements will also raise an +## error if containing table map events mapping different +## tables to same table identifier. + +CREATE TABLE t1 (c1 INT); +CREATE TABLE t2 (c1 INT); + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); + +# FD event +BINLOG ' +SOgWTg8BAAAAbgAAAHIAAAAAAAQANS42LjMtbTUtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8= +'/*!*/; + +#110708 12:21:44 server id 1 end_log_pos 774 Table_map: `test`.`t1` mapped to number 66 +# at 774 +#110708 12:21:44 server id 1 end_log_pos 815 Table_map: `test`.`t2` mapped to number 67 +# at 815 +#110708 12:21:44 server id 1 end_log_pos 855 Update_rows: table id 66 +# at 855 +#110708 12:21:44 server id 1 end_log_pos 895 Update_rows: table id 67 flags: STMT_END_F +SET GLOBAL debug="+d,inject_tblmap_same_id_maps_diff_table"; +--error ER_SLAVE_FATAL_ERROR +BINLOG ' +SOgWThMBAAAAKQAAAAYDAAAAAEIAAAAAAAEABHRlc3QAAnQxAAEDAAE= +SOgWThMBAAAAKQAAAC8DAAAAAEMAAAAAAAEABHRlc3QAAnQyAAEDAAE= +SOgWThgBAAAAKAAAAFcDAAAAAEIAAAAAAAAAAf///gEAAAD+AwAAAA== +SOgWThgBAAAAKAAAAH8DAAAAAEMAAAAAAAEAAf///gEAAAD+BAAAAA== +'/*!*/; + + +# clean up +DROP TABLE t1,t2; +--connection slave +SET GLOBAL debug="-d,inject_tblmap_same_id_maps_diff_table"; +--connection master +--eval DROP TABLE $t1 +--eval DROP TABLE $t2_ign +--sync_slave_with_master +SET GLOBAL debug= @save_debug; + +--source include/rpl_end.inc |