summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/extra/binlog_tests/database.test27
-rw-r--r--mysql-test/suite/binlog/r/binlog_database.result66
-rw-r--r--sql/sql_db.cc23
3 files changed, 108 insertions, 8 deletions
diff --git a/mysql-test/extra/binlog_tests/database.test b/mysql-test/extra/binlog_tests/database.test
index 326ecedb60e..d071415bf65 100644
--- a/mysql-test/extra/binlog_tests/database.test
+++ b/mysql-test/extra/binlog_tests/database.test
@@ -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;
diff --git a/mysql-test/suite/binlog/r/binlog_database.result b/mysql-test/suite/binlog/r/binlog_database.result
index b6299f9a940..0eaed3c97d7 100644
--- a/mysql-test/suite/binlog/r/binlog_database.result
+++ b/mysql-test/suite/binlog/r/binlog_database.result
@@ -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
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 38f39ec0be7..665bcbbbe9f 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -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 if_exists, bool silent)
}
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;