diff options
-rw-r--r-- | mysql-test/extra/binlog_tests/database.test | 27 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_database.result | 66 | ||||
-rw-r--r-- | sql/sql_db.cc | 23 |
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; |