List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:March 15 2011 10:55am
Subject:bzr push into mysql-5.5 branch (jon.hauglid:3368 to 3369) Bug#11765416
View as plain text  
 3369 Jon Olav Hauglid	2011-03-15
      Bug #11765416 (former 58381)
      FAILED DROP DATABASE CAN BREAK STATEMENT BASED REPLICATION
      
      The first phase of DROP DATABASE is to delete the tables in the database.
      If deletion of one or more of the tables fail (e.g. due to a FOREIGN KEY
      constraint), DROP DATABASE will be aborted. However, some tables could
      still have been deleted. The problem was that nothing would be written
      to the binary log in this case, so any slaves would not delete these tables.
      Therefore the master and the slaves would get out of sync.
      
      This patch fixes the problem by making sure that DROP TABLE is written
      to the binary log for the tables that were in fact deleted by the failed
      DROP DATABASE statement.
      
      Test case added to binlog.binlog_database.test.

    modified:
      mysql-test/extra/binlog_tests/database.test
      mysql-test/suite/binlog/r/binlog_database.result
      sql/sql_db.cc
 3368 Bjorn Munch	2011-03-15
      Add warning suppression to test rpl.rpl_slave_load_remove_tmpfile

    modified:
      mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result
      mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test
=== modified file 'mysql-test/extra/binlog_tests/database.test'
--- a/mysql-test/extra/binlog_tests/database.test	2009-01-23 12:22:05 +0000
+++ b/mysql-test/extra/binlog_tests/database.test	2011-03-15 10:49:14 +0000
@@ -30,3 +30,30 @@ drop table tt1, t1;
 source include/show_binlog_events.inc;
 
 FLUSH STATUS;
+
+
+--echo #
+--echo # Bug#11765416 58381: FAILED DROP DATABASE CAN BREAK STATEMENT
+--echo #              BASED REPLICATION
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+CREATE TABLE db1.t2 (b INT, KEY(b)) engine=innodb;
+CREATE TABLE t3 (a INT, KEY (a), FOREIGN KEY(a) REFERENCES db1.t2(b))
+  engine=innodb;
+RESET MASTER;
+
+--error ER_ROW_IS_REFERENCED
+DROP DATABASE db1;                      # Fails because of the fk
+SHOW TABLES FROM db1;                   # t1 was dropped, t2 remains
+--source include/show_binlog_events.inc # Check that the binlog drops t1
+
+# Cleanup
+DROP TABLE t3;
+DROP DATABASE db1;

=== modified file 'mysql-test/suite/binlog/r/binlog_database.result'
--- a/mysql-test/suite/binlog/r/binlog_database.result	2010-08-20 02:59:58 +0000
+++ b/mysql-test/suite/binlog/r/binlog_database.result	2011-03-15 10:49:14 +0000
@@ -39,6 +39,28 @@ master-bin.000001	#	Query	#	#	COMMIT
 master-bin.000001	#	Query	#	#	use `test`; DROP TEMPORARY TABLE `tt1` /* generated by server */
 master-bin.000001	#	Query	#	#	use `test`; DROP TABLE `t1` /* generated by server */
 FLUSH STATUS;
+#
+# Bug#11765416 58381: FAILED DROP DATABASE CAN BREAK STATEMENT
+#              BASED REPLICATION
+#
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t3;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+CREATE TABLE db1.t2 (b INT, KEY(b)) engine=innodb;
+CREATE TABLE t3 (a INT, KEY (a), FOREIGN KEY(a) REFERENCES db1.t2(b))
+engine=innodb;
+RESET MASTER;
+DROP DATABASE db1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+SHOW TABLES FROM db1;
+Tables_in_db1
+t2
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `db1`; drop table `t1`
+DROP TABLE t3;
+DROP DATABASE db1;
 set binlog_format=mixed;
 reset master;
 create database testing_1;
@@ -80,6 +102,28 @@ master-bin.000001	#	Query	#	#	COMMIT
 master-bin.000001	#	Query	#	#	use `test`; DROP TEMPORARY TABLE `tt1` /* generated by server */
 master-bin.000001	#	Query	#	#	use `test`; DROP TABLE `t1` /* generated by server */
 FLUSH STATUS;
+#
+# Bug#11765416 58381: FAILED DROP DATABASE CAN BREAK STATEMENT
+#              BASED REPLICATION
+#
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t3;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+CREATE TABLE db1.t2 (b INT, KEY(b)) engine=innodb;
+CREATE TABLE t3 (a INT, KEY (a), FOREIGN KEY(a) REFERENCES db1.t2(b))
+engine=innodb;
+RESET MASTER;
+DROP DATABASE db1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+SHOW TABLES FROM db1;
+Tables_in_db1
+t2
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `db1`; drop table `t1`
+DROP TABLE t3;
+DROP DATABASE db1;
 set binlog_format=row;
 reset master;
 create database testing_1;
@@ -122,6 +166,28 @@ master-bin.000001	#	Query	#	#	COMMIT
 master-bin.000001	#	Query	#	#	use `test`; DROP TEMPORARY TABLE IF EXISTS `tt1` /* generated by server */
 master-bin.000001	#	Query	#	#	use `test`; DROP TABLE `t1` /* generated by server */
 FLUSH STATUS;
+#
+# Bug#11765416 58381: FAILED DROP DATABASE CAN BREAK STATEMENT
+#              BASED REPLICATION
+#
+DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t3;
+CREATE DATABASE db1;
+CREATE TABLE db1.t1 (a INT);
+CREATE TABLE db1.t2 (b INT, KEY(b)) engine=innodb;
+CREATE TABLE t3 (a INT, KEY (a), FOREIGN KEY(a) REFERENCES db1.t2(b))
+engine=innodb;
+RESET MASTER;
+DROP DATABASE db1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+SHOW TABLES FROM db1;
+Tables_in_db1
+t2
+show binlog events from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `db1`; drop table `t1`
+DROP TABLE t3;
+DROP DATABASE db1;
 show databases;
 Database
 information_schema

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2010-12-10 11:32:58 +0000
+++ b/sql/sql_db.cc	2011-03-15 10:49:14 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -833,12 +833,9 @@ bool mysql_rm_db(THD *thd,char *db,bool
   }
 
   thd->push_internal_handler(&err_handler);
-  if (thd->killed ||
-      (tables && mysql_rm_table_no_locks(thd, tables, true, false, true, true)))
-  {
-    tables= NULL;
-  }
-  else
+  if (!thd->killed &&
+      !(tables &&
+        mysql_rm_table_no_locks(thd, tables, true, false, true, true)))
   {
     /*
       We temporarily disable the binary log while dropping the objects
@@ -923,7 +920,7 @@ update_binlog:
     thd->server_status|= SERVER_STATUS_DB_DROPPED;
     my_ok(thd, deleted_tables);
   }
-  else if (mysql_bin_log.is_open())
+  else if (mysql_bin_log.is_open() && !silent)
   {
     char *query, *query_pos, *query_end, *query_data_start;
     TABLE_LIST *tbl;
@@ -938,6 +935,16 @@ update_binlog:
     for (tbl= tables; tbl; tbl= tbl->next_local)
     {
       uint tbl_name_len;
+      bool exists;
+
+      // Only write drop table to the binlog for tables that no longer exist.
+      if (check_if_table_exists(thd, tbl, &exists))
+      {
+        error= true;
+        goto exit;
+      }
+      if (exists)
+        continue;
 
       /* 3 for the quotes and the comma*/
       tbl_name_len= strlen(tbl->table_name) + 3;

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5 branch (jon.hauglid:3368 to 3369) Bug#11765416Jon Olav Hauglid15 Mar