diff options
author | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2010-11-16 11:00:12 +0100 |
---|---|---|
committer | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2010-11-16 11:00:12 +0100 |
commit | a84d7503008e0bb7d1b4dca72eaf42016ed1a5d9 (patch) | |
tree | 51b238d7f54d17bf3bd843bab00120cc801d8b9c /sql/sql_db.cc | |
parent | 2ef19bdcc420d090d0bed822a884eef40cd347a9 (diff) | |
download | mariadb-git-a84d7503008e0bb7d1b4dca72eaf42016ed1a5d9.tar.gz |
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.
Diffstat (limited to 'sql/sql_db.cc')
-rw-r--r-- | sql/sql_db.cc | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 2abe4d8d072..1391b2c4d72 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -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 <mysys_err.h> #include "sp.h" #include "events.h" @@ -944,6 +946,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, 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,39 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, } } } + + /* + 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; + } + } + } + + /* 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_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); |