diff options
-rw-r--r-- | mysql-test/r/rpl_multi_delete2.result | 21 | ||||
-rw-r--r-- | mysql-test/t/rpl_multi_delete2-slave.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/rpl_multi_delete2.test | 23 | ||||
-rw-r--r-- | sql/slave.cc | 18 |
4 files changed, 61 insertions, 2 deletions
diff --git a/mysql-test/r/rpl_multi_delete2.result b/mysql-test/r/rpl_multi_delete2.result new file mode 100644 index 00000000000..8b6d87801fe --- /dev/null +++ b/mysql-test/r/rpl_multi_delete2.result @@ -0,0 +1,21 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +create table t1 (a int); +create table t2 (a int); +insert into t1 values (1); +insert into t2 values (1); +delete t1.* from t1, t2 where t1.a = t2.a; +select * from t1; +a +select * from t2; +a +1 +select * from t1; +Table 'test.t1' doesn't exist +select * from t2; +Table 'test.t2' doesn't exist +drop table t1,t2; diff --git a/mysql-test/t/rpl_multi_delete2-slave.opt b/mysql-test/t/rpl_multi_delete2-slave.opt new file mode 100644 index 00000000000..b828d03fafb --- /dev/null +++ b/mysql-test/t/rpl_multi_delete2-slave.opt @@ -0,0 +1 @@ +--replicate-wild-ignore-table=test.% diff --git a/mysql-test/t/rpl_multi_delete2.test b/mysql-test/t/rpl_multi_delete2.test new file mode 100644 index 00000000000..c5128833843 --- /dev/null +++ b/mysql-test/t/rpl_multi_delete2.test @@ -0,0 +1,23 @@ +source include/master-slave.inc; +create table t1 (a int); +create table t2 (a int); + +insert into t1 values (1); +insert into t2 values (1); + +delete t1.* from t1, t2 where t1.a = t2.a; + +save_master_pos; +select * from t1; +select * from t2; + +connection slave; +# BUG#3461 would cause sync to fail +sync_with_master; +error 1146; +select * from t1; +error 1146; +select * from t2; + +connection master; +drop table t1,t2; diff --git a/sql/slave.cc b/sql/slave.cc index e79e70e0395..0476fb83abe 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -699,7 +699,16 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len) Note that changing the order of the tables in the list can lead to different results. Note also the order of precedence of the do/ignore rules (see code below). For that reason, users should not set conflicting - rules because they may get unpredicted results. + rules because they may get unpredicted results (precedence order is + explained in the manual). + If no table of the list is marked "updating" (so far this can only happen + if the statement is a multi-delete (SQLCOM_DELETE_MULTI) and the "tables" + is the tables in the FROM): then we always return 0, because there is no + reason we play this statement on this slave if it updates nothing. In the + case of SQLCOM_DELETE_MULTI, there will be a second call to tables_ok(), + with tables having "updating==TRUE" (those after the DELETE), so this + second call will make the decision (because + all_tables_not_ok() = !tables_ok(1st_list) && !tables_ok(2nd_list)). RETURN VALUES 0 should not be logged/replicated @@ -708,6 +717,7 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len) int tables_ok(THD* thd, TABLE_LIST* tables) { + bool some_tables_updating= 0; DBUG_ENTER("tables_ok"); for (; tables; tables = tables->next) @@ -718,6 +728,7 @@ int tables_ok(THD* thd, TABLE_LIST* tables) if (!tables->updating) continue; + some_tables_updating= 1; end= strmov(hash_key, tables->db ? tables->db : thd->db); *end++= '.'; len= (uint) (strmov(end, tables->real_name) - hash_key); @@ -740,10 +751,13 @@ int tables_ok(THD* thd, TABLE_LIST* tables) } /* + If no table was to be updated, ignore statement (no reason we play it on + slave, slave is supposed to replicate _changes_ only). If no explicit rule found and there was a do list, do not replicate. If there was no do list, go ahead */ - DBUG_RETURN(!do_table_inited && !wild_do_table_inited); + DBUG_RETURN(some_tables_updating && + !do_table_inited && !wild_do_table_inited); } |