Add MDL locks around rename and drop table in ddl_log.cc

This includes both normal tables and backup tables (as part of
atomic create and replace).

This is needed to ensure that InnoDB purge_coordinator_task and drop table
does not cause conflicts.
This commit is contained in:
Monty 2025-02-24 22:04:28 +02:00 committed by Sergei Golubchik
parent e62dc52420
commit 506f98cb59

View file

@ -1106,8 +1106,23 @@ static int execute_rename_table(THD *thd, DDL_LOG_ENTRY *ddl_log_entry,
{
uint to_length=0, fr_length=0;
int error= 0, err2;
MDL_request mdl_request[2];
DBUG_ENTER("execute_rename_table");
MDL_REQUEST_INIT(&mdl_request[0], MDL_key::TABLE,
from_db->str,
from_table->str,
MDL_EXCLUSIVE, MDL_EXPLICIT);
MDL_REQUEST_INIT(&mdl_request[1], MDL_key::TABLE,
to_db->str,
to_table->str,
MDL_EXCLUSIVE, MDL_EXPLICIT);
/* There should never be a conflict. The timeout is there for security */
err2= thd->mdl_context.acquire_lock(&mdl_request[0], 60);
err2|= thd->mdl_context.acquire_lock(&mdl_request[1], 60);
DBUG_ASSERT(err2 == 0);
thd->lex->part_info= 0;
if (file->needs_lower_case_filenames())
{
@ -1170,6 +1185,12 @@ static int execute_rename_table(THD *thd, DDL_LOG_ENTRY *ddl_log_entry,
if ((err2= mysql_file_rename(key_file_frm, from_path, to_path,
MYF(MY_WME))) && !error)
error= err2;
if (mdl_request[0].ticket)
thd->mdl_context.release_lock(mdl_request[0].ticket);
if (mdl_request[1].ticket)
thd->mdl_context.release_lock(mdl_request[1].ticket);
DBUG_RETURN(error);
}
@ -1179,8 +1200,16 @@ static int execute_drop_table(THD *thd, handlerton *hton, const LEX_CSTRING *db,
{
uint keys, total_keys;
int error, first_error= 0;
MDL_request mdl_request;
DBUG_ENTER("execute_drop_table");
MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLE,
db->str,
table->str,
MDL_EXCLUSIVE, MDL_EXPLICIT);
error= thd->mdl_context.acquire_lock(&mdl_request, 60);
DBUG_ASSERT(error == 0);
if (get_hlindex_keys_by_open(thd, db, table, path, &keys, &total_keys) == 0)
{
char idx_path[FN_REFLEN + 1];
@ -1200,6 +1229,8 @@ static int execute_drop_table(THD *thd, handlerton *hton, const LEX_CSTRING *db,
if (!non_existing_table_error(error))
first_error= error;
}
if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
DBUG_RETURN(first_error);
}
@ -1290,7 +1321,7 @@ static void rename_triggers(THD *thd, DDL_LOG_ENTRY *ddl_log_entry,
from_db.str,
from_converted_name.str,
MDL_EXCLUSIVE, MDL_EXPLICIT);
error= thd->mdl_context.acquire_lock(&mdl_request, 1);
error= thd->mdl_context.acquire_lock(&mdl_request, 60);
/* acquire_locks() should never fail during recovery */
DBUG_ASSERT(error == 0);
@ -1308,7 +1339,8 @@ static void rename_triggers(THD *thd, DDL_LOG_ENTRY *ddl_log_entry,
&from_converted_name,
&to_db,
&to_table);
thd->mdl_context.release_lock(mdl_request.ticket);
if (mdl_request.ticket)
thd->mdl_context.release_lock(mdl_request.ticket);
}
}