diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 577 |
1 files changed, 295 insertions, 282 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 626344ef93d..01e62d70151 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -109,7 +109,8 @@ static char* add_identifier(THD* thd, char *to_p, const char * end_p, tmp_name[name_len]= 0; conv_name= tmp_name; } - res= strconvert(&my_charset_filename, conv_name, system_charset_info, + res= strconvert(&my_charset_filename, conv_name, name_len, + system_charset_info, conv_string, FN_REFLEN, &errors); if (!res || errors) { @@ -407,7 +408,7 @@ uint filename_to_tablename(const char *from, char *to, uint to_length } else { - res= strconvert(&my_charset_filename, from, + res= strconvert(&my_charset_filename, from, FN_REFLEN, system_charset_info, to, to_length, &errors); if (errors) // Old 5.0 name { @@ -508,7 +509,7 @@ uint tablename_to_filename(const char *from, char *to, uint to_length) } DBUG_RETURN(length); } - length= strconvert(system_charset_info, from, + length= strconvert(system_charset_info, from, FN_REFLEN, &my_charset_filename, to, to_length, &errors); if (check_if_legal_tablename(to) && length + 4 < to_length) @@ -564,7 +565,7 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db, db, table_name, ext, flags)); if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP - strnmov(tbbuff, table_name, sizeof(tbbuff)); + strmake(tbbuff, table_name, sizeof(tbbuff)-1); else (void) tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)); @@ -579,8 +580,11 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db, pos= strnmov(pos, FN_ROOTDIR, end - pos); pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS); #ifdef USE_SYMDIR - unpack_dirname(buff, buff); - pos= strend(buff); + if (!(flags & SKIP_SYMDIR_ACCESS)) + { + unpack_dirname(buff, buff); + pos= strend(buff); + } #endif pos= strxnmov(pos, end - pos, tbbuff, ext, NullS); @@ -687,14 +691,14 @@ mysql_mutex_t LOCK_gdl; #define DDL_LOG_NAME_LEN_POS 4 #define DDL_LOG_IO_SIZE_POS 8 -/* - Read one entry from ddl log file - SYNOPSIS - read_ddl_log_file_entry() - entry_no Entry number to read - RETURN VALUES - TRUE Error - FALSE Success +/** + Read one entry from ddl log file. + + @param entry_no Entry number to read + + @return Operation status + @retval true Error + @retval false Success */ static bool read_ddl_log_file_entry(uint entry_no) @@ -713,14 +717,14 @@ static bool read_ddl_log_file_entry(uint entry_no) } -/* - Write one entry from ddl log file - SYNOPSIS - write_ddl_log_file_entry() - entry_no Entry number to write - RETURN VALUES - TRUE Error - FALSE Success +/** + Write one entry to ddl log file. + + @param entry_no Entry number to write + + @return Operation status + @retval true Error + @retval false Success */ static bool write_ddl_log_file_entry(uint entry_no) @@ -731,7 +735,7 @@ static bool write_ddl_log_file_entry(uint entry_no) DBUG_ENTER("write_ddl_log_file_entry"); mysql_mutex_assert_owner(&LOCK_gdl); - if (mysql_file_pwrite(file_id, (uchar*)file_entry_buf, + if (mysql_file_pwrite(file_id, file_entry_buf, IO_SIZE, IO_SIZE * entry_no, MYF(MY_WME)) != IO_SIZE) error= TRUE; DBUG_RETURN(error); @@ -769,7 +773,7 @@ static bool write_ddl_log_header() int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS], global_ddl_log.num_entries); - const_var= FN_LEN; + const_var= FN_REFLEN; int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS], (ulong) const_var); const_var= IO_SIZE; @@ -784,13 +788,9 @@ static bool write_ddl_log_header() } -/* - Create ddl log file name - SYNOPSIS - create_ddl_log_file_name() - file_name Filename setup - RETURN VALUES - NONE +/** + Create ddl log file name. + @param file_name Filename setup */ static inline void create_ddl_log_file_name(char *file_name) @@ -799,17 +799,14 @@ static inline void create_ddl_log_file_name(char *file_name) } -/* - Read header of ddl log file - SYNOPSIS - read_ddl_log_header() - RETURN VALUES - > 0 Last entry in ddl log - 0 No entries in ddl log - DESCRIPTION - When we read the ddl log header we get information about maximum sizes - of names in the ddl log and we also get information about the number - of entries in the ddl log. +/** + Read header of ddl log file. + + When we read the ddl log header we get information about maximum sizes + of names in the ddl log and we also get information about the number + of entries in the ddl log. + + @return Last entry in ddl log (0 if no entries) */ static uint read_ddl_log_header() @@ -820,6 +817,8 @@ static uint read_ddl_log_header() bool successful_open= FALSE; DBUG_ENTER("read_ddl_log_header"); + mysql_mutex_init(key_LOCK_gdl, &LOCK_gdl, MY_MUTEX_INIT_SLOW); + mysql_mutex_lock(&LOCK_gdl); create_ddl_log_file_name(file_name); if ((global_ddl_log.file_id= mysql_file_open(key_file_global_ddl_log, file_name, @@ -848,36 +847,72 @@ static uint read_ddl_log_header() global_ddl_log.first_free= NULL; global_ddl_log.first_used= NULL; global_ddl_log.num_entries= 0; - mysql_mutex_init(key_LOCK_gdl, &LOCK_gdl, MY_MUTEX_INIT_FAST); global_ddl_log.do_release= true; + mysql_mutex_unlock(&LOCK_gdl); DBUG_RETURN(entry_no); } -/* - Read a ddl log entry - SYNOPSIS - read_ddl_log_entry() - read_entry Number of entry to read - out:entry_info Information from entry - RETURN VALUES - TRUE Error - FALSE Success - DESCRIPTION - Read a specified entry in the ddl log +/** + Convert from ddl_log_entry struct to file_entry_buf binary blob. + + @param ddl_log_entry filled in ddl_log_entry struct. */ -bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry) +static void set_global_from_ddl_log_entry(const DDL_LOG_ENTRY *ddl_log_entry) { - char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf; + mysql_mutex_assert_owner(&LOCK_gdl); + global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= + (char)DDL_LOG_ENTRY_CODE; + global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= + (char)ddl_log_entry->action_type; + global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0; + int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], + ddl_log_entry->next_entry); + DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_REFLEN); + strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS], + ddl_log_entry->name, FN_REFLEN - 1); + if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION || + ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION || + ddl_log_entry->action_type == DDL_LOG_EXCHANGE_ACTION) + { + DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_REFLEN); + strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_REFLEN], + ddl_log_entry->from_name, FN_REFLEN - 1); + } + else + global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_REFLEN]= 0; + DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_REFLEN); + strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_REFLEN)], + ddl_log_entry->handler_name, FN_REFLEN - 1); + if (ddl_log_entry->action_type == DDL_LOG_EXCHANGE_ACTION) + { + DBUG_ASSERT(strlen(ddl_log_entry->tmp_name) < FN_REFLEN); + strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (3*FN_REFLEN)], + ddl_log_entry->tmp_name, FN_REFLEN - 1); + } + else + global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (3*FN_REFLEN)]= 0; +} + + +/** + Convert from file_entry_buf binary blob to ddl_log_entry struct. + + @param[out] ddl_log_entry struct to fill in. + + @note Strings (names) are pointing to the global_ddl_log structure, + so LOCK_gdl needs to be hold until they are read or copied. +*/ + +static void set_ddl_log_entry_from_global(DDL_LOG_ENTRY *ddl_log_entry, + const uint read_entry) +{ + char *file_entry_buf= (char*) global_ddl_log.file_entry_buf; uint inx; uchar single_char; - DBUG_ENTER("read_ddl_log_entry"); - if (read_ddl_log_file_entry(read_entry)) - { - DBUG_RETURN(TRUE); - } + mysql_mutex_assert_owner(&LOCK_gdl); ddl_log_entry->entry_pos= read_entry; single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]; ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char; @@ -890,22 +925,51 @@ bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry) ddl_log_entry->from_name= &file_entry_buf[inx]; inx+= global_ddl_log.name_len; ddl_log_entry->handler_name= &file_entry_buf[inx]; + if (ddl_log_entry->action_type == DDL_LOG_EXCHANGE_ACTION) + { + inx+= global_ddl_log.name_len; + ddl_log_entry->tmp_name= &file_entry_buf[inx]; + } + else + ddl_log_entry->tmp_name= NULL; +} + + +/** + Read a ddl log entry. + + Read a specified entry in the ddl log. + + @param read_entry Number of entry to read + @param[out] entry_info Information from entry + + @return Operation status + @retval TRUE Error + @retval FALSE Success +*/ + +static bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry) +{ + DBUG_ENTER("read_ddl_log_entry"); + + if (read_ddl_log_file_entry(read_entry)) + { + DBUG_RETURN(TRUE); + } + set_ddl_log_entry_from_global(ddl_log_entry, read_entry); DBUG_RETURN(FALSE); } -/* - Initialise ddl log - SYNOPSIS - init_ddl_log() +/** + Initialise ddl log. - DESCRIPTION - Write the header of the ddl log file and length of names. Also set - number of entries to zero. + Write the header of the ddl log file and length of names. Also set + number of entries to zero. - RETURN VALUES - TRUE Error - FALSE Success + @return Operation status + @retval TRUE Error + @retval FALSE Success */ static bool init_ddl_log() @@ -917,7 +981,7 @@ static bool init_ddl_log() goto end; global_ddl_log.io_size= IO_SIZE; - global_ddl_log.name_len= FN_LEN; + global_ddl_log.name_len= FN_REFLEN; create_ddl_log_file_name(file_name); if ((global_ddl_log.file_id= mysql_file_create(key_file_global_ddl_log, file_name, CREATE_MODE, @@ -1043,14 +1107,14 @@ static bool deactivate_ddl_log_entry_no_lock(uint entry_no) } -/* +/** Execute one action in a ddl log entry - SYNOPSIS - execute_ddl_log_action() - ddl_log_entry Information in action entry to execute - RETURN VALUES - TRUE Error - FALSE Success + + @param ddl_log_entry Information in action entry to execute + + @return Operation status + @retval TRUE Error + @retval FALSE Success */ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) @@ -1068,6 +1132,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) handlerton *hton; DBUG_ENTER("execute_ddl_log_action"); + mysql_mutex_assert_owner(&LOCK_gdl); if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE) { DBUG_RETURN(FALSE); @@ -1132,7 +1197,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) } if ((deactivate_ddl_log_entry_no_lock(ddl_log_entry->entry_pos))) break; - (void) sync_ddl_log(); + (void) sync_ddl_log_no_lock(); error= FALSE; if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION) break; @@ -1165,9 +1230,9 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) ddl_log_entry->name)) break; } - if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos))) + if ((deactivate_ddl_log_entry_no_lock(ddl_log_entry->entry_pos))) break; - (void) sync_ddl_log(); + (void) sync_ddl_log_no_lock(); error= FALSE; break; } @@ -1234,14 +1299,14 @@ error: } -/* +/** Get a free entry in the ddl log - SYNOPSIS - get_free_ddl_log_entry() - out:active_entry A ddl log memory entry returned - RETURN VALUES - TRUE Error - FALSE Success + + @param[out] active_entry A ddl log memory entry returned + + @return Operation status + @retval TRUE Error + @retval FALSE Success */ static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry, @@ -1284,24 +1349,67 @@ static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry, } +/** + Execute one entry in the ddl log. + + Executing an entry means executing a linked list of actions. + + @param first_entry Reference to first action in entry + + @return Operation status + @retval TRUE Error + @retval FALSE Success +*/ + +static bool execute_ddl_log_entry_no_lock(THD *thd, uint first_entry) +{ + DDL_LOG_ENTRY ddl_log_entry; + uint read_entry= first_entry; + DBUG_ENTER("execute_ddl_log_entry_no_lock"); + + mysql_mutex_assert_owner(&LOCK_gdl); + do + { + if (read_ddl_log_entry(read_entry, &ddl_log_entry)) + { + /* Write to error log and continue with next log entry */ + sql_print_error("Failed to read entry = %u from ddl log", + read_entry); + break; + } + DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE || + ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE); + + if (execute_ddl_log_action(thd, &ddl_log_entry)) + { + /* Write to error log and continue with next log entry */ + sql_print_error("Failed to execute action for entry = %u from ddl log", + read_entry); + break; + } + read_entry= ddl_log_entry.next_entry; + } while (read_entry); + DBUG_RETURN(FALSE); +} + + /* External interface methods for the DDL log Module --------------------------------------------------- */ -/* - SYNOPSIS - write_ddl_log_entry() - ddl_log_entry Information about log entry - out:entry_written Entry information written into +/** + Write a ddl log entry. - RETURN VALUES - TRUE Error - FALSE Success + A careful write of the ddl log is performed to ensure that we can + handle crashes occurring during CREATE and ALTER TABLE processing. - DESCRIPTION - A careful write of the ddl log is performed to ensure that we can - handle crashes occurring during CREATE and ALTER TABLE processing. + @param ddl_log_entry Information about log entry + @param[out] entry_written Entry information written into + + @return Operation status + @retval TRUE Error + @retval FALSE Success */ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, @@ -1310,46 +1418,29 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, bool error, write_header; DBUG_ENTER("write_ddl_log_entry"); + mysql_mutex_assert_owner(&LOCK_gdl); if (init_ddl_log()) { DBUG_RETURN(TRUE); } - global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= - (char)DDL_LOG_ENTRY_CODE; - global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= - (char)ddl_log_entry->action_type; - global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0; - int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], - ddl_log_entry->next_entry); - DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_LEN); - strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS], - ddl_log_entry->name, FN_LEN - 1); - if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION || - ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION) - { - DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_LEN); - strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN], - ddl_log_entry->from_name, FN_LEN - 1); - } - else - global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0; - DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_LEN); - strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)], - ddl_log_entry->handler_name, FN_LEN - 1); + set_global_from_ddl_log_entry(ddl_log_entry); if (get_free_ddl_log_entry(active_entry, &write_header)) { DBUG_RETURN(TRUE); } error= FALSE; DBUG_PRINT("ddl_log", - ("write type %c next %u name '%s' from_name '%s' handler '%s'", + ("write type %c next %u name '%s' from_name '%s' handler '%s'" + " tmp_name '%s'", (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS], ddl_log_entry->next_entry, (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS], (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS - + FN_LEN], + + FN_REFLEN], (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS - + (2*FN_LEN)])); + + (2*FN_REFLEN)], + (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + + (3*FN_REFLEN)])); if (write_ddl_log_file_entry((*active_entry)->entry_pos)) { error= TRUE; @@ -1358,7 +1449,7 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, } if (write_header && !error) { - (void) sync_ddl_log(); + (void) sync_ddl_log_no_lock(); if (write_ddl_log_header()) error= TRUE; } @@ -1368,31 +1459,30 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, } -/* - Write final entry in the ddl log - SYNOPSIS - write_execute_ddl_log_entry() - first_entry First entry in linked list of entries +/** + @brief Write final entry in the ddl log. + + @details This is the last write in the ddl log. The previous log entries + have already been written but not yet synched to disk. + We write a couple of log entries that describes action to perform. + This entries are set-up in a linked list, however only when a first + execute entry is put as the first entry these will be executed. + This routine writes this first. + + @param first_entry First entry in linked list of entries to execute, if 0 = NULL it means that the entry is removed and the entries are put into the free list. - complete Flag indicating we are simply writing + @param complete Flag indicating we are simply writing info about that entry has been completed - in:out:active_entry Entry to execute, 0 = NULL if the entry + @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 is returned in this parameter - RETURN VALUES - TRUE Error - FALSE Success - DESCRIPTION - This is the last write in the ddl log. The previous log entries have - already been written but not yet synched to disk. - We write a couple of log entries that describes action to perform. - This entries are set-up in a linked list, however only when a first - execute entry is put as the first entry these will be executed. - This routine writes this first + @return Operation status + @retval TRUE Error + @retval FALSE Success */ bool write_execute_ddl_log_entry(uint first_entry, @@ -1403,6 +1493,7 @@ bool write_execute_ddl_log_entry(uint first_entry, char *file_entry_buf= (char*)global_ddl_log.file_entry_buf; DBUG_ENTER("write_execute_ddl_log_entry"); + mysql_mutex_assert_owner(&LOCK_gdl); if (init_ddl_log()) { DBUG_RETURN(TRUE); @@ -1415,7 +1506,7 @@ bool write_execute_ddl_log_entry(uint first_entry, any log entries before, we are only here to write the execute entry to indicate it is done. */ - (void) sync_ddl_log(); + (void) sync_ddl_log_no_lock(); file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE; } else @@ -1424,14 +1515,15 @@ bool write_execute_ddl_log_entry(uint first_entry, file_entry_buf[DDL_LOG_PHASE_POS]= 0; int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry); file_entry_buf[DDL_LOG_NAME_POS]= 0; - file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0; - file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0; + file_entry_buf[DDL_LOG_NAME_POS + FN_REFLEN]= 0; + file_entry_buf[DDL_LOG_NAME_POS + 2*FN_REFLEN]= 0; if (!(*active_entry)) { if (get_free_ddl_log_entry(active_entry, &write_header)) { DBUG_RETURN(TRUE); } + write_header= TRUE; } if (write_ddl_log_file_entry((*active_entry)->entry_pos)) { @@ -1439,7 +1531,7 @@ bool write_execute_ddl_log_entry(uint first_entry, release_ddl_log_memory_entry(*active_entry); DBUG_RETURN(TRUE); } - (void) sync_ddl_log(); + (void) sync_ddl_log_no_lock(); if (write_header) { if (write_ddl_log_header()) @@ -1452,106 +1544,54 @@ bool write_execute_ddl_log_entry(uint first_entry, } -/* - For complex rename operations we need to deactivate individual entries. - SYNOPSIS - deactivate_ddl_log_entry() - entry_no Entry position of record to change - RETURN VALUES - TRUE Error - FALSE Success - DESCRIPTION - During replace operations where we start with an existing table called - t1 and a replacement table called t1#temp or something else and where - we want to delete t1 and rename t1#temp to t1 this is not possible to - do in a safe manner unless the ddl log is informed of the phases in - the change. - - Delete actions are 1-phase actions that can be ignored immediately after - being executed. - Rename actions from x to y is also a 1-phase action since there is no - interaction with any other handlers named x and y. - Replace action where drop y and x -> y happens needs to be a two-phase - action. Thus the first phase will drop y and the second phase will - rename x -> y. +/** + Deactivate an individual entry. + + @details see deactivate_ddl_log_entry_no_lock. + + @param entry_no Entry position of record to change + + @return Operation status + @retval TRUE Error + @retval FALSE Success */ bool deactivate_ddl_log_entry(uint entry_no) { - char *file_entry_buf= (char*)global_ddl_log.file_entry_buf; + bool error; DBUG_ENTER("deactivate_ddl_log_entry"); - if (!read_ddl_log_file_entry(entry_no)) - { - if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE) - { - if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION || - file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION || - (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION && - file_entry_buf[DDL_LOG_PHASE_POS] == 1)) - file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE; - else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION) - { - DBUG_ASSERT(file_entry_buf[DDL_LOG_PHASE_POS] == 0); - file_entry_buf[DDL_LOG_PHASE_POS]= 1; - } - else - { - DBUG_ASSERT(0); - } - if (write_ddl_log_file_entry(entry_no)) - { - sql_print_error("Error in deactivating log entry. Position = %u", - entry_no); - DBUG_RETURN(TRUE); - } - } - } - else - { - sql_print_error("Failed in reading entry before deactivating it"); - DBUG_RETURN(TRUE); - } - DBUG_RETURN(FALSE); + mysql_mutex_lock(&LOCK_gdl); + error= deactivate_ddl_log_entry_no_lock(entry_no); + mysql_mutex_unlock(&LOCK_gdl); + DBUG_RETURN(error); } -/* - Sync ddl log file - SYNOPSIS - sync_ddl_log() - RETURN VALUES - TRUE Error - FALSE Success +/** + Sync ddl log file. + + @return Operation status + @retval TRUE Error + @retval FALSE Success */ bool sync_ddl_log() { - bool error= FALSE; + bool error; DBUG_ENTER("sync_ddl_log"); - if ((!global_ddl_log.recovery_phase) && - init_ddl_log()) - { - DBUG_RETURN(TRUE); - } - if (mysql_file_sync(global_ddl_log.file_id, MYF(0))) - { - /* Write to error log */ - sql_print_error("Failed to sync ddl log"); - error= TRUE; - } + mysql_mutex_lock(&LOCK_gdl); + error= sync_ddl_log_no_lock(); + mysql_mutex_unlock(&LOCK_gdl); + DBUG_RETURN(error); } -/* - Release a log memory entry - SYNOPSIS - release_ddl_log_memory_entry() - log_memory_entry Log memory entry to release - RETURN VALUES - NONE +/** + Release a log memory entry. + @param log_memory_entry Log memory entry to release */ void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry) @@ -1561,6 +1601,7 @@ void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry) DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry; DBUG_ENTER("release_ddl_log_memory_entry"); + mysql_mutex_assert_owner(&LOCK_gdl); global_ddl_log.first_free= log_entry; log_entry->next_log_entry= first_free; @@ -1574,56 +1615,32 @@ void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry) } -/* - Execute one entry in the ddl log. Executing an entry means executing - a linked list of actions. - SYNOPSIS - execute_ddl_log_entry() - first_entry Reference to first action in entry - RETURN VALUES - TRUE Error - FALSE Success +/** + Execute one entry in the ddl log. + + Executing an entry means executing a linked list of actions. + + @param first_entry Reference to first action in entry + + @return Operation status + @retval TRUE Error + @retval FALSE Success */ bool execute_ddl_log_entry(THD *thd, uint first_entry) { - DDL_LOG_ENTRY ddl_log_entry; - uint read_entry= first_entry; + bool error; DBUG_ENTER("execute_ddl_log_entry"); mysql_mutex_lock(&LOCK_gdl); - do - { - if (read_ddl_log_entry(read_entry, &ddl_log_entry)) - { - /* Write to error log and continue with next log entry */ - sql_print_error("Failed to read entry = %u from ddl log", - read_entry); - break; - } - DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE || - ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE); - - if (execute_ddl_log_action(thd, &ddl_log_entry)) - { - /* Write to error log and continue with next log entry */ - sql_print_error("Failed to execute action for entry = %u from ddl log", - read_entry); - break; - } - read_entry= ddl_log_entry.next_entry; - } while (read_entry); + error= execute_ddl_log_entry_no_lock(thd, first_entry); mysql_mutex_unlock(&LOCK_gdl); - DBUG_RETURN(FALSE); + DBUG_RETURN(error); } -/* - Close the ddl log - SYNOPSIS - close_ddl_log() - RETURN VALUES - NONE +/** + Close the ddl log. */ static void close_ddl_log() @@ -1638,12 +1655,8 @@ static void close_ddl_log() } -/* - Execute the ddl log at recovery of MySQL Server - SYNOPSIS - execute_ddl_log_recovery() - RETURN VALUES - NONE +/** + Execute the ddl log at recovery of MySQL Server. */ void execute_ddl_log_recovery() @@ -1676,6 +1689,7 @@ void execute_ddl_log_recovery() /* this also initialize LOCK_gdl */ num_entries= read_ddl_log_header(); + mysql_mutex_lock(&LOCK_gdl); for (i= 1; i < num_entries + 1; i++) { if (read_ddl_log_entry(i, &ddl_log_entry)) @@ -1686,7 +1700,7 @@ void execute_ddl_log_recovery() } if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE) { - if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry)) + if (execute_ddl_log_entry_no_lock(thd, ddl_log_entry.next_entry)) { /* Real unpleasant scenario but we continue anyways. */ continue; @@ -1697,6 +1711,7 @@ void execute_ddl_log_recovery() create_ddl_log_file_name(file_name); (void) mysql_file_delete(key_file_global_ddl_log, file_name, MYF(0)); global_ddl_log.recovery_phase= FALSE; + mysql_mutex_unlock(&LOCK_gdl); delete thd; /* Remember that we don't have a THD */ set_current_thd(0); @@ -1704,24 +1719,22 @@ void execute_ddl_log_recovery() } -/* - Release all memory allocated to the ddl log - SYNOPSIS - release_ddl_log() - RETURN VALUES - NONE +/** + Release all memory allocated to the ddl log. */ void release_ddl_log() { - DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free; - DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used; + DDL_LOG_MEMORY_ENTRY *free_list; + DDL_LOG_MEMORY_ENTRY *used_list; DBUG_ENTER("release_ddl_log"); if (!global_ddl_log.do_release) DBUG_VOID_RETURN; mysql_mutex_lock(&LOCK_gdl); + free_list= global_ddl_log.first_free; + used_list= global_ddl_log.first_used; while (used_list) { DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry; |