From b450eb4b385ceb572105e59efc07f72b44b220f0 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 18 Oct 2022 00:48:10 +0300 Subject: ddl_log_link_chains() improved ddl_log_link_chains() now can operate on empty master chain. If the master chain is empty it first writes empty execute entry to it. Usable when you need to link the chains before start filling the master chain. ddl_log_execute_recovery() now can skip empty execute entries. --- sql/ddl_log.cc | 14 +++++++++++++- sql/ddl_log.h | 2 +- sql/sql_table.cc | 9 +++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc index 60d28d0e6ec..37d8900e974 100644 --- a/sql/ddl_log.cc +++ b/sql/ddl_log.cc @@ -3800,8 +3800,20 @@ bool ddl_log_rename_frm(DDL_LOG_STATE *ddl_state, CREATE OR REPLACE ... is used. */ -void ddl_log_link_chains(DDL_LOG_STATE *state, DDL_LOG_STATE *master_state) +bool ddl_log_link_chains(DDL_LOG_STATE *state, DDL_LOG_STATE *master_state) { + if (!master_state->execute_entry) + { + mysql_mutex_lock(&LOCK_gdl); + if (ddl_log_write_execute_entry(0, master_state->master_chain_pos, + &master_state->execute_entry)) + { + mysql_mutex_unlock(&LOCK_gdl); + return true; + } + mysql_mutex_unlock(&LOCK_gdl); + } DBUG_ASSERT(master_state->execute_entry); state->master_chain_pos= master_state->execute_entry->entry_pos; + return false; } diff --git a/sql/ddl_log.h b/sql/ddl_log.h index c166f1da06e..f0e05412824 100644 --- a/sql/ddl_log.h +++ b/sql/ddl_log.h @@ -369,6 +369,6 @@ bool ddl_log_store_query(THD *thd, DDL_LOG_STATE *ddl_log_state, bool ddl_log_delete_frm(DDL_LOG_STATE *ddl_state, const char *to_path); bool ddl_log_rename_frm(DDL_LOG_STATE *ddl_state, const char *from_path, const char *to_path); -void ddl_log_link_chains(DDL_LOG_STATE *state, DDL_LOG_STATE *master_state); +bool ddl_log_link_chains(DDL_LOG_STATE *state, DDL_LOG_STATE *master_state); extern mysql_mutex_t LOCK_gdl; #endif /* DDL_LOG_INCLUDED */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ef1cfcd2171..c7ff17e229b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4399,10 +4399,15 @@ bool HA_CREATE_INFO::finalize_atomic_replace(THD *thd, TABLE_LIST *orig_table) DBUG_ASSERT(is_atomic_replace()); debug_crash_here("ddl_log_create_before_install_new"); + /* If old table exists, rename it to backup_name */ if (old_hton) { - /* Old table exists, rename it to backup_name */ - ddl_log_link_chains(ddl_log_state_rm, ddl_log_state_create); + /* + Cleanup chain (ddl_log_state_rm) will not be executed unless + rollback chain (ddl_log_state_create) is active. + */ + if (ddl_log_link_chains(ddl_log_state_rm, ddl_log_state_create)) + return true; cpath.length= build_table_filename(path, sizeof(path) - 1, backup_name.db.str, -- cgit v1.2.1