mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
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.
This commit is contained in:
49
mysql-test/suite/rpl/r/rpl_row_corruption.result
Normal file
49
mysql-test/suite/rpl/r/rpl_row_corruption.result
Normal file
@@ -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
|
1
mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt
Normal file
1
mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt
Normal file
@@ -0,0 +1 @@
|
||||
--replicate-ignore-table=test.t2_11753004_ign
|
115
mysql-test/suite/rpl/t/rpl_row_corruption.test
Normal file
115
mysql-test/suite/rpl/t/rpl_row_corruption.test
Normal file
@@ -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
|
Reference in New Issue
Block a user