diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 49e51631b91..3f1165fd069 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -210,3 +210,12 @@ select @tlwa < @tlwb; @tlwa < @tlwb 1 End of 5.1 tests +drop table if exists t1; +create table t1 (i int); +connection: default +lock tables t1 write; +connection: flush +flush tables with read lock;; +connection: default +flush tables; +drop table t1; diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index cd4d70bd99e..75ee6d07723 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -636,6 +636,41 @@ select @tlwa < @tlwb; --echo End of 5.1 tests +# +# Test that DROP TABLES does not wait for a impending FLUSH TABLES +# WITH READ LOCK +# + +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (i int); +connect (flush,localhost,root,,test,,); +connection default; +--echo connection: default +lock tables t1 write; +connection flush; +--echo connection: flush +--send flush tables with read lock; +connection default; +--echo connection: default +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +flush tables; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +drop table t1; +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where state = "Flushing tables"; +--source include/wait_condition.inc +connection flush; +--reap +connection default; +disconnect flush; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc - diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 63dc4e68fdf..150a896103c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1766,7 +1766,8 @@ void write_bin_log(THD *thd, bool clear_error, If a table is in use, we will wait for all users to free the table before dropping it - Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set. + Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set, but + not if under LOCK TABLES. RETURN FALSE OK. In this case ok packet is sent to user @@ -1777,7 +1778,7 @@ void write_bin_log(THD *thd, bool clear_error, bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, my_bool drop_temporary) { - bool error= FALSE, need_start_waiters= FALSE; + bool error= FALSE, need_start_waiting= FALSE; Drop_table_error_handler err_handler(thd->get_internal_handler()); DBUG_ENTER("mysql_rm_table"); @@ -1785,13 +1786,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, if (!drop_temporary) { - if ((error= wait_if_global_read_lock(thd, 0, 1))) - { - my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name); + if (!thd->locked_tables && + !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) DBUG_RETURN(TRUE); - } - else - need_start_waiters= TRUE; } /* @@ -1804,7 +1801,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, thd->pop_internal_handler(); - if (need_start_waiters) + if (need_start_waiting) start_waiting_global_read_lock(thd); if (error)