#At file:///home/anders/work/bzrwork/worktree3/mysql-5.1-rep%2B2/ based on revid:li-bing.song@stripped
3185 Li-Bing.Song@stripped 2010-05-06
Bug #48084 slave breaks if 'drop database' fails on master and mismatched tables on slave
'DROP TABLE <deleted tables>' was binlogged when 'DROP DATABASE' failed
and at least one table was deleted from the database. The log event would
lead slave SQL thread stop if some of the tables did not exist on slave.
After this patch, It is always binlogged with 'IF EXISTS' option.
modified:
mysql-test/extra/binlog_tests/database.test
mysql-test/suite/binlog/r/binlog_database.result
sql/sql_db.cc
=== modified file 'mysql-test/extra/binlog_tests/database.test'
--- a/mysql-test/extra/binlog_tests/database.test 2009-01-23 12:22:05 +0000
+++ b/mysql-test/extra/binlog_tests/database.test 2010-05-06 06:56:36 +0000
@@ -30,3 +30,32 @@ drop table tt1, t1;
source include/show_binlog_events.inc;
FLUSH STATUS;
+
+--echo
+--echo # 'DROP TABLE IF EXISTS <deleted tables>' is binlogged
+--echo # when 'DROP DATABASE' fails and at least one table is deleted
+--echo # from the database.
+RESET MASTER;
+CREATE DATABASE testing_1;
+USE testing_1;
+CREATE TABLE t1(c1 INT);
+CREATE TABLE t2(c1 INT);
+
+let $prefix= `SELECT UUID()`;
+--echo # Create a file in the database directory
+--replace_result $prefix FAKE_FILE
+eval SELECT 'hello' INTO OUTFILE 'fake_file.$prefix';
+
+--echo
+--echo # 'DROP DATABASE' will fail if there is any other file in the the
+--echo # database directory
+--error 1010
+DROP DATABASE testing_1;
+source include/show_binlog_events.inc;
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+
+--echo
+--echo # Remove the fake file.
+--remove_file $MYSQLD_DATADIR/testing_1/fake_file.$prefix
+--echo # Now we can drop the database.
+DROP DATABASE testing_1;
=== modified file 'mysql-test/suite/binlog/r/binlog_database.result'
--- a/mysql-test/suite/binlog/r/binlog_database.result 2009-11-03 19:02:56 +0000
+++ b/mysql-test/suite/binlog/r/binlog_database.result 2010-05-06 06:56:36 +0000
@@ -38,6 +38,32 @@ master-bin.000001 # Query # # use `test`
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; drop table tt1, t1
FLUSH STATUS;
+
+# 'DROP TABLE IF EXISTS <deleted tables>' is binlogged
+# when 'DROP DATABASE' fails and at least one table is deleted
+# from the database.
+RESET MASTER;
+CREATE DATABASE testing_1;
+USE testing_1;
+CREATE TABLE t1(c1 INT);
+CREATE TABLE t2(c1 INT);
+# Create a file in the database directory
+SELECT 'hello' INTO OUTFILE 'fake_file.FAKE_FILE';
+
+# 'DROP DATABASE' will fail if there is any other file in the the
+# database directory
+DROP DATABASE testing_1;
+ERROR HY000: Error dropping database (can't rmdir './testing_1/', errno: 17)
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE testing_1
+master-bin.000001 # Query # # use `testing_1`; CREATE TABLE t1(c1 INT)
+master-bin.000001 # Query # # use `testing_1`; CREATE TABLE t2(c1 INT)
+master-bin.000001 # Query # # use `testing_1`; DROP TABLE IF EXISTS `t2`,`t1`
+
+# Remove the fake file.
+# Now we can drop the database.
+DROP DATABASE testing_1;
set binlog_format=mixed;
reset master;
create database testing_1;
@@ -78,6 +104,32 @@ master-bin.000001 # Query # # use `test`
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; drop table tt1, t1
FLUSH STATUS;
+
+# 'DROP TABLE IF EXISTS <deleted tables>' is binlogged
+# when 'DROP DATABASE' fails and at least one table is deleted
+# from the database.
+RESET MASTER;
+CREATE DATABASE testing_1;
+USE testing_1;
+CREATE TABLE t1(c1 INT);
+CREATE TABLE t2(c1 INT);
+# Create a file in the database directory
+SELECT 'hello' INTO OUTFILE 'fake_file.FAKE_FILE';
+
+# 'DROP DATABASE' will fail if there is any other file in the the
+# database directory
+DROP DATABASE testing_1;
+ERROR HY000: Error dropping database (can't rmdir './testing_1/', errno: 17)
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE testing_1
+master-bin.000001 # Query # # use `testing_1`; CREATE TABLE t1(c1 INT)
+master-bin.000001 # Query # # use `testing_1`; CREATE TABLE t2(c1 INT)
+master-bin.000001 # Query # # use `testing_1`; DROP TABLE IF EXISTS `t2`,`t1`
+
+# Remove the fake file.
+# Now we can drop the database.
+DROP DATABASE testing_1;
set binlog_format=row;
reset master;
create database testing_1;
@@ -119,6 +171,32 @@ master-bin.000001 # Write_rows # # table
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */
FLUSH STATUS;
+
+# 'DROP TABLE IF EXISTS <deleted tables>' is binlogged
+# when 'DROP DATABASE' fails and at least one table is deleted
+# from the database.
+RESET MASTER;
+CREATE DATABASE testing_1;
+USE testing_1;
+CREATE TABLE t1(c1 INT);
+CREATE TABLE t2(c1 INT);
+# Create a file in the database directory
+SELECT 'hello' INTO OUTFILE 'fake_file.FAKE_FILE';
+
+# 'DROP DATABASE' will fail if there is any other file in the the
+# database directory
+DROP DATABASE testing_1;
+ERROR HY000: Error dropping database (can't rmdir './testing_1/', errno: 17)
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE testing_1
+master-bin.000001 # Query # # use `testing_1`; CREATE TABLE t1(c1 INT)
+master-bin.000001 # Query # # use `testing_1`; CREATE TABLE t2(c1 INT)
+master-bin.000001 # Query # # use `testing_1`; DROP TABLE IF EXISTS `t2`,`t1`
+
+# Remove the fake file.
+# Now we can drop the database.
+DROP DATABASE testing_1;
show databases;
Database
information_schema
=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc 2010-02-12 23:30:44 +0000
+++ b/sql/sql_db.cc 2010-05-06 06:56:36 +0000
@@ -998,7 +998,7 @@ bool mysql_rm_db(THD *thd,char *db,bool
if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
goto exit; /* not much else we can do */
- query_pos= query_data_start= strmov(query,"drop table ");
+ query_pos= query_data_start= strmov(query,"DROP TABLE IF EXISTS ");
query_end= query + MAX_DROP_TABLE_Q_LEN;
db_len= strlen(db);
Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20100506065636-vwcxbw7vybo3jhfb.bundle