diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2022-10-18 00:48:10 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2022-10-18 00:49:06 +0300 |
commit | b450eb4b385ceb572105e59efc07f72b44b220f0 (patch) | |
tree | 80e98229587bcfc58f6690ed1a057d27b3d91177 | |
parent | 0d2b41f698e442640b0dcffed0305d3b8195ecc1 (diff) | |
download | mariadb-git-bb-10.10-midenok-MDEV-27180.tar.gz |
ddl_log_link_chains() improvedbb-10.10-midenok-MDEV-27180
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.
-rw-r--r-- | sql/ddl_log.cc | 14 | ||||
-rw-r--r-- | sql/ddl_log.h | 2 | ||||
-rw-r--r-- | 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, |