List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:August 27 2008 10:40am
Subject:bzr commit into mysql-5.1 branch (mats:2708) Bug#38773
View as plain text  
#At file:///home/bzr/bugs/b38773-5.1-rpl-merge/

 2708 Mats Kindahl	2008-08-27
      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.
modified:
  mysql-test/extra/binlog_tests/database.test
  mysql-test/suite/binlog/r/binlog_database.result
  sql/sql_db.cc

per-file messages:
  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.
=== modified file 'mysql-test/extra/binlog_tests/database.test'
--- a/mysql-test/extra/binlog_tests/database.test	2007-11-16 14:55:22 +0000
+++ b/mysql-test/extra/binlog_tests/database.test	2008-08-27 08:40:11 +0000
@@ -13,3 +13,18 @@ create trigger tr1 before insert on t1 f
 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;

=== modified file 'mysql-test/suite/binlog/r/binlog_database.result'
--- a/mysql-test/suite/binlog/r/binlog_database.result	2008-05-16 15:35:15 +0000
+++ b/mysql-test/suite/binlog/r/binlog_database.result	2008-08-27 08:40:11 +0000
@@ -17,6 +17,22 @@ master-bin.000001	#	Query	#	#	use `testi
 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 <binlog_start>;
+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 `testi
 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 <binlog_start>;
+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 `testi
 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 <binlog_start>;
+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

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2008-05-09 07:43:02 +0000
+++ b/sql/sql_db.cc	2008-08-27 08:40:11 +0000
@@ -883,13 +883,6 @@ bool mysql_rm_db(THD *thd,char *db,bool 
 
   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 
 
     
     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)

Thread
bzr commit into mysql-5.1 branch (mats:2708) Bug#38773Mats Kindahl27 Aug