From: Jon Olav Hauglid Date: November 15 2010 1:00pm Subject: bzr commit into mysql-5.5-runtime branch (jon.hauglid:3185) Bug#57663 List-Archive: http://lists.mysql.com/commits/123898 X-Bug: 57663 Message-Id: <201011151300.oAFD0ws6015603@rcsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6867337138506396656==" --===============6867337138506396656== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/x/mysql-5.5-runtime-prereq/ based on revid:jon.hauglid@stripped 3185 Jon Olav Hauglid 2010-11-15 Bug #57663 Concurrent statement using stored function and DROP DATABASE breaks SBR This pre-requisite patch refactors the code for dropping tables, used by DROP TABLE and DROP DATABASE. The patch moves the code for acquiring metadata locks out of mysql_rm_table_part2() and makes it the responsibility of the caller. This in preparation of changing the DROP DATABASE implementation to acquire all metadata locks before any changes are made. mysql_rm_table_part2() is renamed mysql_rm_table_no_locks() to reflect the change. modified: mysql-test/r/partition_debug_sync.result mysql-test/t/partition_debug_sync.test sql/sql_db.cc sql/sql_table.cc sql/sql_table.h === modified file 'mysql-test/r/partition_debug_sync.result' --- a/mysql-test/r/partition_debug_sync.result 2010-07-01 13:53:46 +0000 +++ b/mysql-test/r/partition_debug_sync.result 2010-11-15 13:00:04 +0000 @@ -25,7 +25,7 @@ ALTER TABLE t1 REMOVE PARTITIONING; # Con default SET DEBUG_SYNC= 'now WAIT_FOR removing_partitioning'; SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL waiting_for_alter'; -SET DEBUG_SYNC= 'rm_table_part2_before_delete_table WAIT_FOR partitioning_removed'; +SET DEBUG_SYNC= 'rm_table_no_locks_before_delete_table WAIT_FOR partitioning_removed'; DROP TABLE IF EXISTS t1; # Con 1 SET SESSION debug= "-d,sleep_before_create_table_no_lock"; @@ -51,12 +51,12 @@ SET DEBUG_SYNC= 'alter_table_before_open SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done'; ALTER TABLE t2 REMOVE PARTITIONING; # Con default -SET SESSION debug= "+d,sleep_before_part2_delete_table"; +SET SESSION debug= "+d,sleep_before_no_locks_delete_table"; SET DEBUG_SYNC= 'now WAIT_FOR removing_partitions'; -SET DEBUG_SYNC= 'rm_table_part2_before_delete_table SIGNAL waiting_for_alter'; -SET DEBUG_SYNC= 'rm_table_part2_before_binlog SIGNAL delete_done'; +SET DEBUG_SYNC= 'rm_table_no_locks_before_delete_table SIGNAL waiting_for_alter'; +SET DEBUG_SYNC= 'rm_table_no_locks_before_binlog SIGNAL delete_done'; DROP TABLE IF EXISTS t2; -SET SESSION debug= "-d,sleep_before_part2_delete_table"; +SET SESSION debug= "-d,sleep_before_no_locks_delete_table"; # Con 1 ERROR 42S02: Table 'test.t2' doesn't exist SET DEBUG_SYNC= 'RESET'; === modified file 'mysql-test/t/partition_debug_sync.test' --- a/mysql-test/t/partition_debug_sync.test 2010-07-01 13:53:46 +0000 +++ b/mysql-test/t/partition_debug_sync.test 2010-11-15 13:00:04 +0000 @@ -38,7 +38,7 @@ connection default; --echo # Con default SET DEBUG_SYNC= 'now WAIT_FOR removing_partitioning'; SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL waiting_for_alter'; -SET DEBUG_SYNC= 'rm_table_part2_before_delete_table WAIT_FOR partitioning_removed'; +SET DEBUG_SYNC= 'rm_table_no_locks_before_delete_table WAIT_FOR partitioning_removed'; DROP TABLE IF EXISTS t1; --echo # Con 1 connection con1; @@ -70,12 +70,12 @@ SET DEBUG_SYNC= 'alter_table_before_rena --send ALTER TABLE t2 REMOVE PARTITIONING connection default; --echo # Con default -SET SESSION debug= "+d,sleep_before_part2_delete_table"; +SET SESSION debug= "+d,sleep_before_no_locks_delete_table"; SET DEBUG_SYNC= 'now WAIT_FOR removing_partitions'; -SET DEBUG_SYNC= 'rm_table_part2_before_delete_table SIGNAL waiting_for_alter'; -SET DEBUG_SYNC= 'rm_table_part2_before_binlog SIGNAL delete_done'; +SET DEBUG_SYNC= 'rm_table_no_locks_before_delete_table SIGNAL waiting_for_alter'; +SET DEBUG_SYNC= 'rm_table_no_locks_before_binlog SIGNAL delete_done'; DROP TABLE IF EXISTS t2; -SET SESSION debug= "-d,sleep_before_part2_delete_table"; +SET SESSION debug= "-d,sleep_before_no_locks_delete_table"; --echo # Con 1 connection con1; --error ER_NO_SUCH_TABLE === modified file 'sql/sql_db.cc' --- a/sql/sql_db.cc 2010-11-15 11:32:49 +0000 +++ b/sql/sql_db.cc 2010-11-15 13:00:04 +0000 @@ -28,6 +28,8 @@ #include "sql_acl.h" // SELECT_ACL, DB_ACLS, // acl_get, check_grant_db #include "log_event.h" // Query_log_event +#include "sql_base.h" // lock_table_names, tdc_remove_table +#include "sql_handler.h" // mysql_ha_rm_tables #include #include "sp.h" #include "events.h" @@ -944,6 +946,7 @@ static long mysql_rm_known_files(THD *th ulong found_other_files=0; char filePath[FN_REFLEN]; TABLE_LIST *tot_list=0, **tot_list_next_local, **tot_list_next_global; + TABLE_LIST *table; DBUG_ENTER("mysql_rm_known_files"); DBUG_PRINT("enter",("path: %s", org_path)); @@ -1040,8 +1043,32 @@ static long mysql_rm_known_files(THD *th } } } + + /* Disable drop of enabled log tables, must be done before name locking */ + for (table= tot_list; table; table= table->next_local) + { + if (check_if_log_table(table->db_length, table->db, + table->table_name_length, table->table_name, true)) + { + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); + goto err; + } + } + + if (tot_list) + mysql_ha_rm_tables(thd, tot_list); + + if (lock_table_names(thd, tot_list, NULL, thd->variables.lock_wait_timeout, + MYSQL_OPEN_SKIP_TEMPORARY)) + goto err; + + for (table= tot_list; table; table= table->next_local) + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, + false); + if (thd->killed || - (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1))) + (tot_list && mysql_rm_table_no_locks(thd, tot_list, true, + false, true, true))) goto err; my_dirend(dirp); === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2010-11-12 11:23:17 +0000 +++ b/sql/sql_table.cc 2010-11-15 13:00:04 +0000 @@ -1849,12 +1849,77 @@ bool mysql_rm_table(THD *thd,TABLE_LIST { bool error; Drop_table_error_handler err_handler; + TABLE_LIST *table; DBUG_ENTER("mysql_rm_table"); + /* Disable drop of enabled log tables, must be done before name locking */ + for (table= tables; table; table= table->next_local) + { + if (check_if_log_table(table->db_length, table->db, + table->table_name_length, table->table_name, true)) + { + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); + DBUG_RETURN(true); + } + } + + mysql_ha_rm_tables(thd, tables); + + if (!drop_temporary) + { + if (!thd->locked_tables_mode) + { + if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, + MYSQL_OPEN_SKIP_TEMPORARY)) + DBUG_RETURN(true); + for (table= tables; table; table= table->next_local) + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, + false); + } + else + { + for (table= tables; table; table= table->next_local) + if (table->open_type != OT_BASE_ONLY && + find_temporary_table(thd, table)) + { + /* + A temporary table. + + Don't try to find a corresponding MDL lock or assign it + to table->mdl_request.ticket. There can't be metadata + locks for temporary tables: they are local to the session. + + Later in this function we release the MDL lock only if + table->mdl_requeset.ticket is not NULL. Thus here we + ensure that we won't release the metadata lock on the base + table locked with LOCK TABLES as a side effect of temporary + table drop. + */ + DBUG_ASSERT(table->mdl_request.ticket == NULL); + } + else + { + /* + Not a temporary table. + + Since 'tables' list can't contain duplicates (this is ensured + by parser) it is safe to cache pointer to the TABLE instances + in its elements. + */ + table->table= find_table_for_mdl_upgrade(thd->open_tables, table->db, + table->table_name, false); + if (!table->table) + DBUG_RETURN(true); + table->mdl_request.ticket= table->table->mdl_ticket; + } + } + } + /* mark for close and remove all cached entries */ thd->push_internal_handler(&err_handler); - error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0); + error= mysql_rm_table_no_locks(thd, tables, if_exists, drop_temporary, + false, false); thd->pop_internal_handler(); if (error) @@ -1865,9 +1930,10 @@ bool mysql_rm_table(THD *thd,TABLE_LIST /* Execute the drop of a normal or temporary table + This function assumes that metadata locks have already been taken. SYNOPSIS - mysql_rm_table_part2() + mysql_rm_table_no_locks() thd Thread handler tables Tables to drop if_exists If set, don't give an error if table doesn't exists. @@ -1893,9 +1959,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST -1 Thread was killed */ -int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, - bool drop_temporary, bool drop_view, - bool dont_log_query) +int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, + bool drop_temporary, bool drop_view, + bool dont_log_query) { TABLE_LIST *table; char path[FN_REFLEN + 1], *alias= NULL; @@ -1909,7 +1975,7 @@ int mysql_rm_table_part2(THD *thd, TABLE bool non_tmp_table_deleted= 0; String built_query; String built_trans_tmp_query, built_non_trans_tmp_query; - DBUG_ENTER("mysql_rm_table_part2"); + DBUG_ENTER("mysql_rm_table_no_locks"); /* Prepares the drop statements that will be written into the binary @@ -1963,71 +2029,6 @@ int mysql_rm_table_part2(THD *thd, TABLE } } - mysql_ha_rm_tables(thd, tables); - - /* Disable drop of enabled log tables, must be done before name locking */ - for (table= tables; table; table= table->next_local) - { - if (check_if_log_table(table->db_length, table->db, - table->table_name_length, table->table_name, 1)) - { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); - DBUG_RETURN(1); - } - } - - if (!drop_temporary) - { - if (!thd->locked_tables_mode) - { - if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, - MYSQL_OPEN_SKIP_TEMPORARY)) - DBUG_RETURN(1); - for (table= tables; table; table= table->next_local) - { - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, - FALSE); - } - } - else - { - for (table= tables; table; table= table->next_local) - if (table->open_type != OT_BASE_ONLY && - find_temporary_table(thd, table)) - { - /* - A temporary table. - - Don't try to find a corresponding MDL lock or assign it - to table->mdl_request.ticket. There can't be metadata - locks for temporary tables: they are local to the session. - - Later in this function we release the MDL lock only if - table->mdl_requeset.ticket is not NULL. Thus here we - ensure that we won't release the metadata lock on the base - table locked with LOCK TABLES as a side effect of temporary - table drop. - */ - DBUG_ASSERT(table->mdl_request.ticket == NULL); - } - else - { - /* - Not a temporary table. - - Since 'tables' list can't contain duplicates (this is ensured - by parser) it is safe to cache pointer to the TABLE instances - in its elements. - */ - table->table= find_table_for_mdl_upgrade(thd->open_tables, table->db, - table->table_name, FALSE); - if (!table->table) - DBUG_RETURN(1); - table->mdl_request.ticket= table->table->mdl_ticket; - } - } - } - for (table= tables; table; table= table->next_local) { bool is_trans; @@ -2156,8 +2157,8 @@ int mysql_rm_table_part2(THD *thd, TABLE built_query.append("`,"); } } - DEBUG_SYNC(thd, "rm_table_part2_before_delete_table"); - DBUG_EXECUTE_IF("sleep_before_part2_delete_table", + DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); + DBUG_EXECUTE_IF("sleep_before_no_locks_delete_table", my_sleep(100000);); error= 0; if (drop_temporary || @@ -2244,7 +2245,7 @@ int mysql_rm_table_part2(THD *thd, TABLE ER(ER_BAD_TABLE_ERROR), MYF(0), table->table_name);); } - DEBUG_SYNC(thd, "rm_table_part2_before_binlog"); + DEBUG_SYNC(thd, "rm_table_no_locks_before_binlog"); thd->thread_specific_used|= (trans_tmp_table_deleted || non_trans_tmp_table_deleted); error= 0; === modified file 'sql/sql_table.h' --- a/sql/sql_table.h 2010-08-20 17:15:48 +0000 +++ b/sql/sql_table.h 2010-11-15 13:00:04 +0000 @@ -174,8 +174,9 @@ bool mysql_checksum_table(THD* thd, TABL HA_CHECK_OPT* check_opt); bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, my_bool drop_temporary); -int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, - bool drop_temporary, bool drop_view, bool log_query); +int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, + bool drop_temporary, bool drop_view, + bool log_query); bool quick_rm_table(handlerton *base,const char *db, const char *table_name, uint flags); void close_cached_table(THD *thd, TABLE *table); --===============6867337138506396656== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jon.hauglid@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jon.hauglid@stripped # target_branch: file:///export/home/x/mysql-5.5-runtime-prereq/ # testament_sha1: b748ee9bebc12534677ec19fe8970b0548b26246 # timestamp: 2010-11-15 14:00:09 +0100 # source_branch: file:///export/home/x/mysql-5.5-bugfixing/ # base_revision_id: jon.hauglid@stripped\ # aw1yt3qa07qz09r2 # # Begin bundle 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 --===============6867337138506396656==--