diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2021-09-27 15:53:52 +0300 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-10-26 17:07:46 +0200 |
commit | 7da721be314c7355a549681dc93a782f89c99981 (patch) | |
tree | 3a1ed3eeaab621cd674e87d6d55a3ec44d46e467 /sql/ddl_log.cc | |
parent | 428024524cc8979b55c510f3d4685eb86767bfda (diff) | |
download | mariadb-git-7da721be314c7355a549681dc93a782f89c99981.tar.gz |
Review and crash-safety fix
Diffstat (limited to 'sql/ddl_log.cc')
-rw-r--r-- | sql/ddl_log.cc | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc index ea33f075938..47b0077588f 100644 --- a/sql/ddl_log.cc +++ b/sql/ddl_log.cc @@ -77,6 +77,8 @@ #define DDL_LOG_MAGIC_LENGTH 4 /* How many times to try to execute a ddl log entry that causes crashes */ #define DDL_LOG_MAX_RETRY 3 +#define DDL_LOG_RETRY_MASK 0xFF +#define DDL_LOG_RETRY_BITS 8 uchar ddl_log_file_magic[]= { (uchar) 254, (uchar) 254, (uchar) 11, (uchar) 2 }; @@ -155,7 +157,7 @@ mysql_mutex_t LOCK_gdl; #define DDL_LOG_XID_POS 10 /* Used to store unique uuid from the .frm file */ #define DDL_LOG_UUID_POS 18 -/* ID_POS can be used to store something unique, like file size (4 bytes) */ +/* ID_POS can be used to store something unique, like file size (8 bytes) */ #define DDL_LOG_ID_POS DDL_LOG_UUID_POS + MY_UUID_SIZE #define DDL_LOG_END_POS DDL_LOG_ID_POS + 8 @@ -2515,6 +2517,7 @@ bool ddl_log_write_entry(DDL_LOG_ENTRY *ddl_log_entry, @param first_entry First entry in linked list of entries to execute. + @param cond_entry Check and don't execute if cond_entry is active @param[in,out] active_entry Entry to execute, 0 = NULL if the entry is written first time and needs to be returned. In this case the entry written @@ -2525,6 +2528,7 @@ bool ddl_log_write_entry(DDL_LOG_ENTRY *ddl_log_entry, */ bool ddl_log_write_execute_entry(uint first_entry, + uint cond_entry, DDL_LOG_MEMORY_ENTRY **active_entry) { uchar *file_entry_buf= global_ddl_log.file_entry_buf; @@ -2541,6 +2545,7 @@ bool ddl_log_write_execute_entry(uint first_entry, file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (uchar)DDL_LOG_EXECUTE_CODE; int4store(file_entry_buf + DDL_LOG_NEXT_ENTRY_POS, first_entry); + int8store(file_entry_buf + DDL_LOG_ID_POS, (cond_entry << DDL_LOG_RETRY_BITS)); if (!(*active_entry)) { @@ -2763,13 +2768,13 @@ int ddl_log_execute_recovery() recovery_state.xid= ddl_log_entry.xid; /* purecov: begin tested */ - if (ddl_log_entry.unique_id > DDL_LOG_MAX_RETRY) + if ((ddl_log_entry.unique_id & DDL_LOG_RETRY_MASK) > DDL_LOG_MAX_RETRY) { error= -1; continue; } update_unique_id(i, ++ddl_log_entry.unique_id); - if (ddl_log_entry.unique_id > DDL_LOG_MAX_RETRY) + if ((ddl_log_entry.unique_id & DDL_LOG_RETRY_MASK) > DDL_LOG_MAX_RETRY) { sql_print_error("DDL_LOG: Aborting executing entry %u after %llu " "retries", i, ddl_log_entry.unique_id); @@ -2778,6 +2783,15 @@ int ddl_log_execute_recovery() } /* purecov: end tested */ + uint cond_entry= (uint)(ddl_log_entry.unique_id >> DDL_LOG_RETRY_BITS); + + if (cond_entry && is_execute_entry_active(cond_entry)) + { + if (disable_execute_entry(i)) + error= -1; + continue; + } + if (ddl_log_execute_entry_no_lock(thd, ddl_log_entry.next_entry)) { /* Real unpleasant scenario but we have to continue anyway */ @@ -3534,3 +3548,32 @@ err: mysql_mutex_unlock(&LOCK_gdl); DBUG_RETURN(1); } + + +/* + Log an delete frm file +*/ + +/* + TODO: Partitioning atomic DDL refactoring: this should be replaced with + ddl_log_create_table(). +*/ +bool ddl_log_delete_frm(DDL_LOG_STATE *ddl_state, const char *to_path) +{ + DDL_LOG_ENTRY ddl_log_entry; + DDL_LOG_MEMORY_ENTRY *log_entry; + DBUG_ENTER("ddl_log_delete_frm"); + bzero(&ddl_log_entry, sizeof(ddl_log_entry)); + ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION; + ddl_log_entry.next_entry= ddl_state->list ? ddl_state->list->entry_pos : 0; + + lex_string_set(&ddl_log_entry.handler_name, reg_ext); + lex_string_set(&ddl_log_entry.name, to_path); + + mysql_mutex_assert_owner(&LOCK_gdl); + if (ddl_log_write_entry(&ddl_log_entry, &log_entry)) + DBUG_RETURN(1); + + ddl_log_add_entry(ddl_state, log_entry); + DBUG_RETURN(0); +} |