From: Jon Olav Hauglid Date: November 17 2010 12:41pm Subject: bzr commit into mysql-5.5-runtime branch (jon.hauglid:3187) Bug#57663 List-Archive: http://lists.mysql.com/commits/124153 X-Bug: 57663 Message-Id: <201011171241.oAH9OoDv023502@rcsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1286843235785392035==" --===============1286843235785392035== 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-refactor/ based on revid:jon.hauglid@stripped 3187 Jon Olav Hauglid 2010-11-17 Bug #57663 Concurrent statement using stored function and DROP DATABASE breaks SBR The problem was that DROP DATABASE ignores any metadata locks on stored functions and procedures held by other connections. This makes it possible for DROP DATABASE to drop functions/procedures that are in use by other connections and therefore break statement based replication. (DROP DATABASE can appear in the binlog before a statement using a dropped function/procedure.) This problem was an issue left unresolved by the patch for Bug#30977 where metadata locks for stored functions/procedures were introduced. This patch fixes the problem by making sure DROP DATABASE takes exclusive metadata locks on all stored functions/procedures to be dropped. Test case added to sp-lock.test. modified: mysql-test/r/sp-lock.result mysql-test/t/sp-lock.test sql/sp.cc sql/sp.h sql/sql_db.cc === modified file 'mysql-test/r/sp-lock.result' --- a/mysql-test/r/sp-lock.result 2010-08-06 11:29:37 +0000 +++ b/mysql-test/r/sp-lock.result 2010-11-17 12:41:11 +0000 @@ -735,5 +735,96 @@ END latin1 latin1_swedish_ci latin1_swed # Connection default; DROP PROCEDURE p1; # +# Bug#57663 Concurrent statement using stored function and DROP DATABASE +# breaks SBR +# +DROP DATABASE IF EXISTS db1; +DROP FUNCTION IF EXISTS f1; +# Test 1: Check that DROP DATABASE block if a function is used +# by an active transaction. +# Connection default +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); +db1.f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +# Waiting for DROP DATABASE to be blocked by the lock on f1() +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 2: Check that DROP DATABASE blocks if a procedure is +# used by an active transaction. +# Connection default +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() BEGIN END; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN +CALL db1.p1(); +RETURN 1; +END| +START TRANSACTION; +SELECT f1(); +f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +# Waiting for DROP DATABASE to be blocked by the lock on p1() +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 3: Check that DROP DATABASE is not selected as a victim if a +# deadlock is discovered with DML statements. +# Connection default +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); +db1.f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +# Waiting for DROP DATABASE to be blocked by the lock on f1() +SELECT * FROM db1.t1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 4: Check that active DROP DATABASE blocks stored routine DDL. +# Connection default +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 2; +START TRANSACTION; +SELECT db1.f2(); +db1.f2() +2 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection con2 +# Waiting for DROP DATABASE to be blocked by the lock on f2() +# Sending: +ALTER FUNCTION db1.f1 COMMENT "test"; +# Connection default +# Waiting for ALTER FUNCTION to be blocked by the schema lock on db1 +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Connection con2 +# Reaping: ALTER FUNCTION f1 COMMENT 'test' +ERROR 42000: FUNCTION db1.f1 does not exist +# Connection default +DROP FUNCTION f1; +# # End of 5.5 tests # === modified file 'mysql-test/t/sp-lock.test' --- a/mysql-test/t/sp-lock.test 2010-08-06 11:29:37 +0000 +++ b/mysql-test/t/sp-lock.test 2010-11-17 12:41:11 +0000 @@ -972,5 +972,170 @@ DROP PROCEDURE p1; --echo # +--echo # Bug#57663 Concurrent statement using stored function and DROP DATABASE +--echo # breaks SBR +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS db1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +connect(con1, localhost, root); +connect(con2, localhost, root); + +--echo # Test 1: Check that DROP DATABASE block if a function is used +--echo # by an active transaction. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +--echo # Waiting for DROP DATABASE to be blocked by the lock on f1() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 2: Check that DROP DATABASE blocks if a procedure is +--echo # used by an active transaction. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() BEGIN END; +delimiter |; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN + CALL db1.p1(); + RETURN 1; +END| +delimiter ;| +START TRANSACTION; +SELECT f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +--echo # Waiting for DROP DATABASE to be blocked by the lock on p1() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored procedure metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 3: Check that DROP DATABASE is not selected as a victim if a +--echo # deadlock is discovered with DML statements. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +# DROP DATABASE will lock tables (t1) before functions (f1) +SELECT db1.f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +--echo # Waiting for DROP DATABASE to be blocked by the lock on f1() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +--error ER_LOCK_DEADLOCK +SELECT * FROM db1.t1; +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 4: Check that active DROP DATABASE blocks stored routine DDL. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 2; +START TRANSACTION; +SELECT db1.f2(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection con2 +connection con2; +--echo # Waiting for DROP DATABASE to be blocked by the lock on f2() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +--echo # Sending: +--send ALTER FUNCTION db1.f1 COMMENT "test" + +--echo # Connection default +connection default; +--echo # Waiting for ALTER FUNCTION to be blocked by the schema lock on db1 +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for schema metadata lock' + AND info='ALTER FUNCTION db1.f1 COMMENT "test"'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo # Connection con2 +connection con2; +--echo # Reaping: ALTER FUNCTION f1 COMMENT 'test' +--error ER_SP_DOES_NOT_EXIST +--reap +disconnect con2; +--source include/wait_until_disconnected.inc + +--echo # Connection default +connection default; +DROP FUNCTION f1; + + +--echo # --echo # End of 5.5 tests --echo # === modified file 'sql/sp.cc' --- a/sql/sp.cc 2010-11-11 17:11:05 +0000 +++ b/sql/sp.cc 2010-11-17 12:41:11 +0000 @@ -1361,6 +1361,103 @@ err: /** + This internal handler is used to trap errors from opening mysql.proc. +*/ + +class Lock_db_routines_error_handler : public Internal_error_handler +{ +public: + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) + { + if (sql_errno == ER_NO_SUCH_TABLE || + sql_errno == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED) + return true; + return false; + } +}; + + +/** + Acquires exclusive metadata lock on all stored routines in the + given database. + + @note Will also return false (=success) if mysql.proc can't be opened. + Note that any ER_NO_SUCH_TABLE error will be supressed. + */ + +bool lock_db_routines(THD *thd, char *db) +{ + TABLE *table; + uint key_len; + int nxtres= 0; + Open_tables_backup open_tables_state_backup; + MDL_request_list mdl_requests; + Lock_db_routines_error_handler err_handler; + DBUG_ENTER("lock_db_routines"); + + /* + mysql.proc will be re-opened during deletion, so we can ignore + errors when opening the table here. + */ + thd->push_internal_handler(&err_handler); + table = open_proc_table_for_read(thd, &open_tables_state_backup); + thd->pop_internal_handler(); + if (!table) + { + /* + DROP DATABASE should not fail even if mysql.proc can't be opened. + We therefore return false allowing mysql_rm_db() to proceed. + */ + DBUG_RETURN(false); + } + + table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info); + key_len= table->key_info->key_part[0].store_length; + table->file->ha_index_init(0, 1); + + if (! table->file->index_read_map(table->record[0], + table->field[MYSQL_PROC_FIELD_DB]->ptr, + (key_part_map)1, HA_READ_KEY_EXACT)) + { + do + { + char *sp_name= get_field(thd->mem_root, + table->field[MYSQL_PROC_FIELD_NAME]); + longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int(); + MDL_request *mdl_request= new (thd->mem_root) MDL_request; + mdl_request->init(sp_type == TYPE_ENUM_FUNCTION ? + MDL_key::FUNCTION : MDL_key::PROCEDURE, + db, sp_name, MDL_EXCLUSIVE, MDL_TRANSACTION); + mdl_requests.push_front(mdl_request); + } while (! (nxtres= table->file->index_next_same(table->record[0], + table->field[MYSQL_PROC_FIELD_DB]->ptr, + key_len))); + } + table->file->ha_index_end(); + if (nxtres != 0 && nxtres != HA_ERR_END_OF_FILE) + { + table->file->print_error(nxtres, MYF(0)); + close_system_tables(thd, &open_tables_state_backup); + DBUG_RETURN(true); + } + close_system_tables(thd, &open_tables_state_backup); + + /* We should already hold a global IX lock and a schema X lock. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", + MDL_INTENTION_EXCLUSIVE) && + thd->mdl_context.is_lock_owner(MDL_key::SCHEMA, db, "", + MDL_EXCLUSIVE)); + DBUG_RETURN(thd->mdl_context.acquire_locks(&mdl_requests, + thd->variables.lock_wait_timeout)); +} + + +/** Drop all routines in database 'db' @note Close the thread tables, the calling code might want to === modified file 'sql/sp.h' --- a/sql/sp.h 2010-10-07 16:01:17 +0000 +++ b/sql/sp.h 2010-11-17 12:41:11 +0000 @@ -84,6 +84,18 @@ enum int sp_drop_db_routines(THD *thd, char *db); +/** + Acquires exclusive metadata lock on all stored routines in the + given database. + + @param thd Thread handler + @param db Database name + + @retval false Success + @retval true Failure + */ +bool lock_db_routines(THD *thd, char *db); + sp_head * sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, bool cache_only); === modified file 'sql/sql_db.cc' --- a/sql/sql_db.cc 2010-11-16 10:00:12 +0000 +++ b/sql/sql_db.cc 2010-11-17 12:41:11 +0000 @@ -46,10 +46,12 @@ const char *del_exts[]= {".frm", ".BAK", static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, - const char *db, const char *path, - TABLE_LIST **dropped_tables); - +static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, + const char *db, + const char *path, + TABLE_LIST **tables, + bool *found_other_files); + long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path); static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error); static void mysql_change_db_impl(THD *thd, @@ -738,36 +740,37 @@ exit: } -/* - Drop all tables in a database and the database itself +/** + Drop all tables, routines and events in a database and the database itself. - SYNOPSIS - mysql_rm_db() - thd Thread handle - db Database name in the case given by user - It's already validated and set to lower case - (if needed) when we come here - if_exists Don't give error if database doesn't exists - silent Don't generate errors - - RETURN - FALSE ok (Database dropped) - ERROR Error + @param thd Thread handle + @param db Database name in the case given by user + It's already validated and set to lower case + (if needed) when we come here + @param if_exists Don't give error if database doesn't exists + @param silent Don't write the statement to the binary log and don't + send ok packet to the client + + @retval false OK (Database dropped) + @retval true Error */ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { - long deleted=0; - int error= 0; + ulong deleted_tables= 0; + bool error= true; char path[FN_REFLEN+16]; MY_DIR *dirp; uint length; - TABLE_LIST* dropped_tables= 0; + bool found_other_files= false; + TABLE_LIST *tables= NULL; + TABLE_LIST *table; + Drop_table_error_handler err_handler; DBUG_ENTER("mysql_rm_db"); if (lock_schema_name(thd, db)) - DBUG_RETURN(TRUE); + DBUG_RETURN(true); length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0); strmov(path+length, MY_DB_OPT_FILE); // Append db option file name @@ -779,20 +782,72 @@ bool mysql_rm_db(THD *thd,char *db,bool { if (!if_exists) { - error= -1; my_error(ER_DB_DROP_EXISTS, MYF(0), db); - goto exit; + DBUG_RETURN(true); } else + { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db); + error= false; + goto update_binlog; + } } - else + + thd->push_internal_handler(&err_handler); + + if (find_db_tables_and_rm_known_files(thd, dirp, db, path, &tables, + &found_other_files)) { - Drop_table_error_handler err_handler; - thd->push_internal_handler(&err_handler); + thd->pop_internal_handler(); + goto exit; + } - error= -1; + /* + Disable drop of enabled log tables, must be done before name locking. + This check is only needed if we are dropping the "mysql" database. + */ + if ((my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0)) + { + 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"); + thd->pop_internal_handler(); + goto exit; + } + } + } + + /* Lock all tables and stored routines about to be dropped. */ + if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, + MYSQL_OPEN_SKIP_TEMPORARY) || + lock_db_routines(thd, db)) + { + thd->pop_internal_handler(); + goto exit; + } + + /* mysql_ha_rm_tables() requires a non-null TABLE_LIST. */ + if (tables) + mysql_ha_rm_tables(thd, tables); + + for (table= tables; table; table= table->next_local) + { + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, + false); + deleted_tables++; + } + + if (thd->killed || + (tables && mysql_rm_table_no_locks(thd, tables, true, false, true, true))) + { + tables= NULL; + } + else + { /* We temporarily disable the binary log while dropping the objects in the database. Since the DROP DATABASE statement is always @@ -810,23 +865,30 @@ bool mysql_rm_db(THD *thd,char *db,bool 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, - &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 */ + */ + + 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); + Events::drop_schema_events(thd, db); #endif - error = 0; - reenable_binlog(thd); - } - thd->pop_internal_handler(); + reenable_binlog(thd); + + /* + If the directory is a symbolic link, remove the link first, then + remove the directory the symbolic link pointed at + */ + if (found_other_files) + my_error(ER_DB_DROP_RMDIR, MYF(0), path, EEXIST); + else + error= rm_dir_w_symlink(path, true); } - if (!silent && deleted>=0) + thd->pop_internal_handler(); + +update_binlog: + if (!silent && !error) { const char *query; ulong query_length; @@ -861,13 +923,13 @@ bool mysql_rm_db(THD *thd,char *db,bool */ if (mysql_bin_log.write(&qinfo)) { - error= -1; + error= true; goto exit; } } thd->clear_error(); thd->server_status|= SERVER_STATUS_DB_DROPPED; - my_ok(thd, (ulong) deleted); + my_ok(thd, deleted_tables); } else if (mysql_bin_log.is_open()) { @@ -881,7 +943,7 @@ bool mysql_rm_db(THD *thd,char *db,bool query_end= query + MAX_DROP_TABLE_Q_LEN; db_len= strlen(db); - for (tbl= dropped_tables; tbl; tbl= tbl->next_local) + for (tbl= tables; tbl; tbl= tbl->next_local) { uint tbl_name_len; @@ -895,7 +957,7 @@ bool mysql_rm_db(THD *thd,char *db,bool */ if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len)) { - error= -1; + error= true; goto exit; } query_pos= query_data_start; @@ -915,7 +977,7 @@ bool mysql_rm_db(THD *thd,char *db,bool */ if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len)) { - error= -1; + error= true; goto exit; } } @@ -928,27 +990,23 @@ exit: SELECT DATABASE() in the future). For this we free() thd->db and set it to 0. */ - if (thd->db && !strcmp(thd->db, db) && error == 0) + if (thd->db && !strcmp(thd->db, db) && !error) mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); + my_dirend(dirp); DBUG_RETURN(error); } -/* - Removes files with known extensions. - thd MUST be set when calling this function! -*/ -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, - const char *org_path, - TABLE_LIST **dropped_tables) +static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, + const char *db, + const char *path, + TABLE_LIST **tables, + bool *found_other_files) { - long deleted=0; - 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)); + DBUG_ENTER("find_db_tables_and_rm_known_files"); + DBUG_PRINT("enter",("path: %s", path)); tot_list_next_local= tot_list_next_global= &tot_list; @@ -974,16 +1032,16 @@ static long mysql_rm_known_files(THD *th */ char newpath[FN_REFLEN]; MY_DIR *new_dirp; - strxmov(newpath, org_path, "/", "arc", NullS); + strxmov(newpath, path, "/", "arc", NullS); (void) unpack_filename(newpath, newpath); if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT)))) { DBUG_PRINT("my",("Archive subdir found: %s", newpath)); if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0) - goto err; + DBUG_RETURN(true); continue; } - found_other_files++; + *found_other_files= true; continue; } if (!(extension= strrchr(file->name, '.'))) @@ -991,7 +1049,7 @@ static long mysql_rm_known_files(THD *th if (find_type(extension, &deletable_extentions,1+2) <= 0) { if (find_type(extension, ha_known_exts(),1+2) <= 0) - found_other_files++; + *found_other_files= true; continue; } /* just for safety we use files_charset_info */ @@ -1007,7 +1065,7 @@ static long mysql_rm_known_files(THD *th strlen(file->name) + 1); if (!table_list) - goto err; + DBUG_RETURN(true); table_list->db= (char*) (table_list+1); table_list->db_length= strmov(table_list->db, db) - table_list->db; table_list->table_name= table_list->db + table_list->db_length + 1; @@ -1032,77 +1090,16 @@ static long mysql_rm_known_files(THD *th (*tot_list_next_global)= table_list; tot_list_next_local= &table_list->next_local; tot_list_next_global= &table_list->next_global; - deleted++; } else { - strxmov(filePath, org_path, "/", file->name, NullS); + strxmov(filePath, path, "/", file->name, NullS); if (mysql_file_delete_with_symlink(key_file_misc, filePath, MYF(MY_WME))) - { - goto err; - } - } - } - - /* - Disable drop of enabled log tables, must be done before name locking. - This check is only needed if we are dropping the "mysql" database. - */ - if ((my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0)) - { - 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; - } + DBUG_RETURN(true); } } - - /* mysql_ha_rm_tables() requires a non-null TABLE_LIST. */ - 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_no_locks(thd, tot_list, true, - false, true, true))) - goto err; - - my_dirend(dirp); - - if (dropped_tables) - *dropped_tables= tot_list; - - /* - If the directory is a symbolic link, remove the link first, then - remove the directory the symbolic link pointed at - */ - if (found_other_files) - { - my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST); - DBUG_RETURN(-1); - } - else - { - if (rm_dir_w_symlink(org_path, true)) - DBUG_RETURN(-1); - } - - DBUG_RETURN(deleted); - -err: - my_dirend(dirp); - DBUG_RETURN(-1); + *tables= tot_list; + DBUG_RETURN(false); } --===============1286843235785392035== 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-refactor/ # testament_sha1: f7de4f95ebdddff9a9182360ea68d740ac1f7022 # timestamp: 2010-11-17 13:41:15 +0100 # source_branch: file:///export/home/x/mysql-5.5-bugfixing/ # base_revision_id: jon.hauglid@stripped\ # kxep9txz2fxy3nmw # # Begin bundle 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 D34zlUA= --===============1286843235785392035==--