mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#23713 LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
This bug is actually two bugs in one, one of which is CREATE TRIGGER under LOCK TABLES and the other is CREATE TRIGGER under LOCK TABLES simultaneous to a FLUSH TABLES WITH READ LOCK (global read lock). Both situations could lead to a server crash or deadlock. The first problem arises from the fact that when under LOCK TABLES, if the table is in the set of locked tables, the table is already open and it doesn't need to be reopened (not a placeholder). Also in this case, if the table is not write locked, a exclusive lock can't be acquired because of a possible deadlock with another thread also holding a (read) lock on the table. The second issue arises from the fact that one should never wait for a global read lock if it's holding any locked tables, because the global read lock is waiting for these tables and this leads to a circular wait deadlock. The solution for the first case is to check if the table is write locked and upgraded the write lock to a exclusive lock and fail otherwise for non write locked tables. Grabbin the exclusive lock in this case also means to ensure that the table is opened only by the calling thread. The second issue is partly fixed by not waiting for the global read lock if the thread is holding any locked tables. The second issue is only partly addressed in this patch because it turned out to be much wider and also affects other DDL statements. Reported as Bug#32395
This commit is contained in:
@ -978,7 +978,8 @@ bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
|
||||
bool compare_record(TABLE *table);
|
||||
bool append_file_to_dir(THD *thd, const char **filename_ptr,
|
||||
const char *table_name);
|
||||
|
||||
void wait_while_table_is_used(THD *thd, TABLE *table,
|
||||
enum ha_extra_function function);
|
||||
bool table_cache_init(void);
|
||||
void table_cache_free(void);
|
||||
bool table_def_init(void);
|
||||
@ -1141,6 +1142,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
|
||||
uint lock_flags);
|
||||
TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem,
|
||||
bool *refresh, uint flags);
|
||||
bool name_lock_locked_table(THD *thd, TABLE_LIST *tables);
|
||||
bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in);
|
||||
TABLE *table_cache_insert_placeholder(THD *thd, const char *key,
|
||||
uint key_length);
|
||||
@ -1292,7 +1294,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
|
||||
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
|
||||
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
|
||||
void mysql_ha_flush(THD *thd);
|
||||
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables);
|
||||
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables, bool is_locked);
|
||||
void mysql_ha_cleanup(THD *thd);
|
||||
|
||||
/* sql_base.cc */
|
||||
|
Reference in New Issue
Block a user