1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +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:
Jon Olav Hauglid
2010-07-01 15:53:46 +02:00
parent 34e409fafa
commit 41a3dfe490
28 changed files with 1300 additions and 652 deletions

View File

@ -19,10 +19,10 @@
#include "sql_priv.h"
#include "unireg.h"
#include "sql_view.h"
#include "sql_base.h" // find_table_in_global_list
#include "sql_base.h" // find_table_in_global_list, lock_table_names
#include "sql_parse.h" // sql_parse
#include "sql_cache.h" // query_cache_*
#include "lock.h" // wait_if_global_read_lock, lock_table_names
#include "lock.h" // wait_if_global_read_lock
#include "sql_show.h" // append_identifier
#include "sql_table.h" // build_table_filename
#include "sql_db.h" // mysql_opt_change_db, mysql_change_db
@ -1652,7 +1652,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
DBUG_RETURN(TRUE);
}
if (lock_table_names(thd, views))
if (lock_table_names(thd, views, 0, thd->variables.lock_wait_timeout,
MYSQL_OPEN_SKIP_TEMPORARY))
DBUG_RETURN(TRUE);
mysql_mutex_lock(&LOCK_open);