From 8746a25554d18f03fc32ca5d338850f9308bee88 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jan 2004 19:22:29 +0100 Subject: [PATCH] Fix for BUG#2527 "Multi-Table Delete - Not Replication use replicate-wild-do-table" (as long as replicate-*-table rules were defined, multi-table DELETE was never replicated by the slave). sql/sql_parse.cc: For a multi-table DELETE, there are two lists of tables: - 'tables' contains the tables in the FROM. They have 'updating==0'. - 'thd->lex.auxilliary_table_list.first' contains the tables between the DELETE and the FROM. They have 'updating==1'. So the bug was that the slave only tests 'tables' and as all its elements have updating==0, tables_ok() always returns 0. So for a multi DELETE the slave now tests the 2nd list too. I started with the other tip of the sausage: I thought of changing multi DELETE to use only one list (given that 'updating' can be used to separate it in two when needed) (with one list we wouldn't need to change the slave code), but finally hit the unicity check in add_table_to_list() which started to return ER_NONUNIQ_TABLE (logical). --- mysql-test/r/rpl_multi_delete.result | 22 ++++++++++++++++++++++ mysql-test/t/rpl_multi_delete-slave.opt | 1 + mysql-test/t/rpl_multi_delete.test | 23 +++++++++++++++++++++++ sql/sql_parse.cc | 4 +++- 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/rpl_multi_delete.result create mode 100644 mysql-test/t/rpl_multi_delete-slave.opt create mode 100644 mysql-test/t/rpl_multi_delete.test diff --git a/mysql-test/r/rpl_multi_delete.result b/mysql-test/r/rpl_multi_delete.result new file mode 100644 index 00000000000..fa254d76393 --- /dev/null +++ b/mysql-test/r/rpl_multi_delete.result @@ -0,0 +1,22 @@ +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; +a +select * from t2; +a +1 +drop table t1,t2; diff --git a/mysql-test/t/rpl_multi_delete-slave.opt b/mysql-test/t/rpl_multi_delete-slave.opt new file mode 100644 index 00000000000..c98fe0b0a46 --- /dev/null +++ b/mysql-test/t/rpl_multi_delete-slave.opt @@ -0,0 +1 @@ +--replicate-wild-do-table=test.% diff --git a/mysql-test/t/rpl_multi_delete.test b/mysql-test/t/rpl_multi_delete.test new file mode 100644 index 00000000000..299cb720b62 --- /dev/null +++ b/mysql-test/t/rpl_multi_delete.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; +sync_with_master; +select * from t1; +select * from t2; + +connection master; +drop table t1,t2; +save_master_pos; +connection slave; +sync_with_master; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 608cdd23282..0d22704ef3c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1334,7 +1334,9 @@ mysql_execute_command(void) Skip if we are in the slave thread, some table rules have been given and the table list says the query should not be replicated */ - if (table_rules_on && tables && !tables_ok(thd,tables)) + if (table_rules_on && tables && !tables_ok(thd,tables) && + ((lex->sql_command != SQLCOM_DELETE_MULTI) || + !tables_ok(thd,(TABLE_LIST *)thd->lex.auxilliary_table_list.first))) { /* we warn the slave SQL thread */ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));