From 0203409175ce8f68111c296c3fc9a7306f04cca5 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Wed, 27 Aug 2008 10:40:11 +0200 Subject: Bug #38773: DROP DATABASE cause switch to stmt-mode when there are temporary tables open When executing a DROP DATABASE statement in ROW mode and having temporary tables open at the same time, the existance of temporary tables prevent the server from switching back to row mode after temporarily switching to statement mode to handle the logging of the statement. Fixed the problem by removing the code to switch to statement mode and added code to temporarily disable the binary log while dropping the objects in the database. mysql-test/extra/binlog_tests/database.test: Added test to ensure that DROP DATABASE does not affect the replication mode. sql/sql_db.cc: Removed code that clears the current_stmt_binlog_row_based flag. Added code to disable the binary log while dropping the objects in a database. --- sql/sql_db.cc | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'sql/sql_db.cc') diff --git a/sql/sql_db.cc b/sql/sql_db.cc index bb55f5f7a4f..e1bff5e435b 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 @@ -916,16 +909,36 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) 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. + + Notice that the binary log have to be enabled over the call to + ha_drop_database(), since NDB otherwise detects the binary log + as disabled and will not log the drop database statement on any + other connected server. + */ if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0, &dropped_tables)) >= 0) { ha_drop_database(path); + tmp_disable_binlog(thd); query_cache_invalidate1(db); (void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */ #ifdef HAVE_EVENT_SCHEDULER Events::drop_schema_events(thd, db); #endif error = 0; + reenable_binlog(thd); } } if (!silent && deleted>=0) -- cgit v1.2.1