From 9180e8666b8e31239d2e2075b703fb8bc8effc13 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 19 Jul 2018 01:03:14 +0200 Subject: MDEV-16465 Invalid (old?) table or database name or hang in ha_innobase::delete_table and log semaphore wait upon concurrent DDL with foreign keys ALTER TABLE locks the table with TL_READ_NO_INSERT, to prevent the source table modifications while it's being copied. But there's an indirect way of modifying a table, via cascade FK actions. After previous commits, an attempt to modify an FK parent table will cause FK children to be prelocked, so the table-being-altered cannot be modified by a cascade FK action, because ALTER holds a lock and prelocking will wait. But if a new FK is being added by this very ALTER, then the target table is not locked yet (it's a temporary table). So, we have to lock FK parents explicitly. --- sql/table.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'sql/table.h') diff --git a/sql/table.h b/sql/table.h index 23f97ed18d0..4a1552f8c0d 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1695,6 +1695,14 @@ struct TABLE_LIST const char *alias_arg, enum thr_lock_type lock_type_arg) { + enum enum_mdl_type mdl_type; + if (lock_type_arg >= TL_WRITE_ALLOW_WRITE) + mdl_type= MDL_SHARED_WRITE; + else if (lock_type_arg == TL_READ_NO_INSERT) + mdl_type= MDL_SHARED_NO_WRITE; + else + mdl_type= MDL_SHARED_READ; + bzero((char*) this, sizeof(*this)); db= (char*) db_name_arg; db_length= db_length_arg; @@ -1702,10 +1710,7 @@ struct TABLE_LIST table_name_length= table_name_length_arg; alias= (char*) (alias_arg ? alias_arg : table_name_arg); lock_type= lock_type_arg; - mdl_request.init(MDL_key::TABLE, db, table_name, - (lock_type >= TL_WRITE_ALLOW_WRITE) ? - MDL_SHARED_WRITE : MDL_SHARED_READ, - MDL_TRANSACTION); + mdl_request.init(MDL_key::TABLE, db, table_name, mdl_type, MDL_TRANSACTION); } inline void init_one_table_for_prelocking(const char *db_name_arg, -- cgit v1.2.1