mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
A 5.5 version of the fix for Bug #54360 "Deadlock DROP/ALTER/CREATE
DATABASE with open HANDLER" Remove LOCK_create_db, database name locks, and use metadata locks instead. This exposes CREATE/DROP/ALTER DATABASE statements to the graph-based deadlock detector in MDL, and paves the way for a safe, deadlock-free implementation of RENAME DATABASE. Database DDL statements will now take exclusive metadata locks on the database name, while table/view/routine DDL statements take intention exclusive locks on the database name. This prevents race conditions between database DDL and table/view/routine DDL. (e.g. DROP DATABASE with concurrent CREATE/ALTER/DROP TABLE) By adding database name locks, this patch implements WL#4450 "DDL locking: CREATE/DROP DATABASE must use database locks" and WL#4985 "DDL locking: namespace/hierarchical locks". The patch also changes code to use init_one_table() where appropriate. The new lock_table_names() function requires TABLE_LIST::db_length to be set correctly, and this is taken care of by init_one_table(). This patch also adds a simple template to help work with the mysys HASH data structure. Most of the patch was written by Konstantin Osipov.
This commit is contained in:
@ -24,10 +24,9 @@
|
||||
#include "sql_table.h" // build_table_filename
|
||||
#include "sql_view.h" // mysql_frm_type, mysql_rename_view
|
||||
#include "sql_trigger.h"
|
||||
#include "lock.h" // wait_if_global_read_lock, lock_table_names,
|
||||
// unlock_table_names,
|
||||
#include "lock.h" // wait_if_global_read_lock
|
||||
// start_waiting_global_read_lock
|
||||
#include "sql_base.h" // tdc_remove_table
|
||||
#include "sql_base.h" // tdc_remove_table, lock_table_names,
|
||||
#include "sql_handler.h" // mysql_ha_rm_tables
|
||||
#include "datadict.h"
|
||||
|
||||
@ -144,7 +143,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
||||
}
|
||||
}
|
||||
|
||||
if (lock_table_names(thd, table_list))
|
||||
if (lock_table_names(thd, table_list, 0, thd->variables.lock_wait_timeout,
|
||||
MYSQL_OPEN_SKIP_TEMPORARY))
|
||||
goto err;
|
||||
|
||||
mysql_mutex_lock(&LOCK_open);
|
||||
@ -197,7 +197,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
||||
if (!error)
|
||||
query_cache_invalidate3(thd, table_list, 0);
|
||||
|
||||
unlock_table_names(thd);
|
||||
thd->mdl_context.release_transactional_locks();
|
||||
|
||||
err:
|
||||
thd->global_read_lock.start_waiting_global_read_lock(thd);
|
||||
|
Reference in New Issue
Block a user