diff --git a/mysql-test/extra/binlog_tests/database.test b/mysql-test/extra/binlog_tests/database.test index 11a8f53a6d7..2e445f98adf 100644 --- a/mysql-test/extra/binlog_tests/database.test +++ b/mysql-test/extra/binlog_tests/database.test @@ -13,3 +13,18 @@ create trigger tr1 before insert on t1 for each row insert into t2 values (2*new create procedure sp1 (a int) insert into t1 values(a); drop database testing_1; source include/show_binlog_events.inc; + +# BUG#38773: DROP DATABASE cause switch to stmt-mode when there are +# temporary tables open + +use test; +reset master; +create temporary table tt1 (a int); +create table t1 (a int); +insert into t1 values (1); +disable_warnings; +drop database if exists mysqltest1; +enable_warnings; +insert into t1 values (1); +drop table tt1, t1; +source include/show_binlog_events.inc; diff --git a/mysql-test/suite/binlog/r/binlog_database.result b/mysql-test/suite/binlog/r/binlog_database.result index 7121d458077..d64d902217b 100644 --- a/mysql-test/suite/binlog/r/binlog_database.result +++ b/mysql-test/suite/binlog/r/binlog_database.result @@ -17,6 +17,22 @@ master-bin.000001 # Query # # use `testing_1`; CREATE DEFINER=`root`@`localhost` master-bin.000001 # Query # # use `testing_1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`(a int) insert into t1 values(a) master-bin.000001 # Query # # drop database testing_1 +use test; +reset master; +create temporary table tt1 (a int); +create table t1 (a int); +insert into t1 values (1); +drop database if exists mysqltest1; +insert into t1 values (1); +drop table tt1, t1; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; create temporary table tt1 (a int) +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Query # # use `test`; insert into t1 values (1) +master-bin.000001 # Query # # drop database if exists mysqltest1 +master-bin.000001 # Query # # use `test`; insert into t1 values (1) +master-bin.000001 # Query # # use `test`; drop table tt1, t1 set binlog_format=mixed; reset master; create database testing_1; @@ -36,6 +52,22 @@ master-bin.000001 # Query # # use `testing_1`; CREATE DEFINER=`root`@`localhost` master-bin.000001 # Query # # use `testing_1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`(a int) insert into t1 values(a) master-bin.000001 # Query # # drop database testing_1 +use test; +reset master; +create temporary table tt1 (a int); +create table t1 (a int); +insert into t1 values (1); +drop database if exists mysqltest1; +insert into t1 values (1); +drop table tt1, t1; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; create temporary table tt1 (a int) +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Query # # use `test`; insert into t1 values (1) +master-bin.000001 # Query # # drop database if exists mysqltest1 +master-bin.000001 # Query # # use `test`; insert into t1 values (1) +master-bin.000001 # Query # # use `test`; drop table tt1, t1 set binlog_format=row; reset master; create database testing_1; @@ -55,6 +87,27 @@ master-bin.000001 # Query # # use `testing_1`; CREATE DEFINER=`root`@`localhost` master-bin.000001 # Query # # use `testing_1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`(a int) insert into t1 values(a) master-bin.000001 # Query # # drop database testing_1 +use test; +reset master; +create temporary table tt1 (a int); +create table t1 (a int); +insert into t1 values (1); +drop database if exists mysqltest1; +insert into t1 values (1); +drop table tt1, t1; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # drop database if exists mysqltest1 +master-bin.000001 # Query # # use `test`; BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; COMMIT +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ show databases; Database information_schema diff --git a/sql/sql_db.cc b/sql/sql_db.cc index bb55f5f7a4f..52d9e42bc82 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -883,13 +883,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); - /* - This statement will be replicated as a statement, even when using - row-based replication. The flag will be reset at the end of the - statement. - */ - thd->clear_current_stmt_binlog_row_based(); - length= build_table_filename(path, sizeof(path), db, "", "", 0); strmov(path+length, MY_DB_OPT_FILE); // Append db option file name del_dbopt(path); // Remove dboption hash entry @@ -914,8 +907,21 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) remove_db_from_cache(db); pthread_mutex_unlock(&LOCK_open); - error= -1; + /* + We temporarily disable the binary log while dropping the objects + in the database. Since the DROP DATABASE statement is always + replicated as a statement, execution of it will drop all objects + in the database on the slave as well, so there is no need to + replicate the removal of the individual objects in the database + as well. + + This is more of a safety precaution, since normally no objects + should be dropped while the database is being cleaned, but in + the event that a change in the code to remove other objects is + made, these drops should still not be logged. + */ + tmp_disable_binlog(thd); if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0, &dropped_tables)) >= 0) { @@ -927,6 +933,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) #endif error = 0; } + reenable_binlog(thd); } if (!silent && deleted>=0) {