diff options
author | unknown <mikron@c-d10be253.1238-1-64736c10.cust.bredbandsbolaget.se> | 2006-02-09 20:20:22 +0100 |
---|---|---|
committer | unknown <mikron@c-d10be253.1238-1-64736c10.cust.bredbandsbolaget.se> | 2006-02-09 20:20:22 +0100 |
commit | ddb14e0f238d92cd55dcd594815ae6bfa8f3577e (patch) | |
tree | a38ff42302b8fb796463b332745a5dd3da7cb5b7 /sql/sql_partition.cc | |
parent | 392b82a10a0ce5ef960d079db84233d626e6a7f3 (diff) | |
download | mariadb-git-ddb14e0f238d92cd55dcd594815ae6bfa8f3577e.tar.gz |
WL 2826: Error handling of ALTER TABLE for partitioning
More work on table logging of ALTER TABLE for partitioning
sql/mysql_priv.h:
More work on table logging of ALTER TABLE for partitioning
sql/sql_partition.cc:
More work on table logging of ALTER TABLE for partitioning
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r-- | sql/sql_partition.cc | 354 |
1 files changed, 229 insertions, 125 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index f0f22b4d927..ea358154b1c 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5107,56 +5107,48 @@ release_part_info_log_entries(TABLE_LOG_MEMORY_ENTRY *log_entry) /* - Write the log entry to ensure that the shadow frm file is removed at - crash. + Log an delete/rename frm file SYNOPSIS - write_log_shadow_frm() - lpt Struct containing parameters - install_frm Should we log action to install shadow frm or should - the action be to remove the shadow frm file. + write_log_rename_delete_frm() + lpt Struct for parameters + next_entry Next reference to use in log record + path Name to rename from + rename_flag TRUE if rename, else delete RETURN VALUES - TRUE Error - FALSE Success + TRUE Error + FALSE Success DESCRIPTION - Prepare an entry to the table log indicating a drop/install of the shadow frm - file and its corresponding handler file. + Support routine that writes a rename or delete of an frm file into the + table log. It also inserts an entry that keeps track of used space into + the partition info object */ bool -write_log_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool install_frm) +write_log_rename_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt, + uint next_entry, + const char *from_path + const char *to_path, + bool rename_flag) { TABLE_LOG_ENTRY table_log_entry; - partition_info *part_info= lpt->part_info; TABLE_LOG_MEMORY_ENTRY *log_entry; - TABLE_LOG_MEMORY_ENTRY *exec_log_entry= NULL; - char shadow_path[FN_LEN]; - DBUG_ENTER("write_log_shadow_frm"); + DBUG_ENTER("write_log_rename_frm"); - lock_global_table_log(); - do - { - build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, - lpt->table_name, "#"); + if (rename_flag) + table_log_entry.action_type= 'r'; + else table_log_entry.action_type= 'd'; - table_log_entry.next_entry= 0; - table_log_entry.handler_type= "frm"; - table_log_entry.name= shadow_path; - - if (write_table_log_entry(&table_log_entry, &log_entry)) - break; - insert_part_info_log_entry_list(part_info, log_entry); - if (write_execute_table_log_entry(log_entry->entry_pos, - FALSE, &exec_log_entry)) - break; - part_info->exec_log_entry= exec_log_entry; - unlock_global_table_log(); - DBUG_RETURN(FALSE); - } while (TRUE); - release_part_info_log_entries(part_info->first_log_entry); - part_info->first_log_entry= NULL; - unlock_global_table_log(); - my_error(ER_TABLE_LOG_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + table_log_entry.next_entry= next_entry; + table_log_entry.handler_type= "frm"; + if (rename_flag) + table_log_entry.name= to_path; + table_log_entry.from_name= from_path; + if (write_table_log_entry(&table_log_entry, &log_entry)) + { + DBUG_RETURN(TRUE); + } + insert_part_info_log_entry_list(part_info, log_entry); + DBUG_RETURN(FALSE); } @@ -5174,24 +5166,41 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, uint *next_entry, - const char *path) + const char *path, + bool temp_list) { TABLE_LOG_ENTRY table_log_entry; partition_info *part_info= lpt->part_info; TABLE_LOG_MEMORY_ENTRY *log_entry; char tmp_path[FN_LEN]; List_iterator<partition_element> part_it(part_info->partitions); + List_iterator<partition_element> temp_it(part_info->temp_partitions); + uint no_temp_partitions= part_info->temp_partitions.elements; uint no_elements= part_info->partitions.elements; uint i= 0; DBUG_ENTER("write_log_dropped_partitions"); table_log_entry.action_type= 'd'; - do + if (temp_list) + no_elements= no_temp_partitions; + while (no_elements--) { - partition_element *part_elem= part_it++; + partition_element *part_elem; + if (temp_list) + part_elem= temp_it++; + else + part_elem= part_it++; if (part_elem->part_state == PART_TO_BE_DROPPED || - part_elem->part_state == PART_TO_BE_ADDED) + part_elem->part_state == PART_TO_BE_ADDED || + part_elem->part_state == PART_CHANGED) { + uint name_variant; + if (part_elem->part_state == PART_CHANGED || + (part_elem->part_state == PART_TO_BE_ADDED && + no_temp_partitions)) + name_variant= TEMP_PART_NAME; + else + name_variant= NORMAL_PART_NAME; if (is_sub_partitioned(part_info)) { List_iterator<partition_element> sub_it(part_elem->subpartitions); @@ -5202,11 +5211,11 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, partition_element *sub_elem= sub_it++; table_log_entry.next_entry= *next_entry; table_log_entry.handler_type= - ha_resolve_storage_engine_name(sub_elem->engine_type); + ha_resolve_storage_engine_name(sub_elem->engine_type); create_subpartition_name(tmp_path, path, part_elem->partition_name, sub_elem->partition_name, - NORMAL_PART_NAME); + name_variant); table_log_entry.name= tmp_path; if (write_table_log_entry(&table_log_entry, &log_entry)) { @@ -5223,7 +5232,7 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, ha_resolve_storage_engine_name(part_elem->engine_type); create_partition_name(tmp_path, path, part_elem->partition_name, - NORMAL_PART_NAME, TRUE); + name_variant, TRUE); table_log_entry.name= tmp_path; if (write_table_log_entry(&table_log_entry, &log_entry)) { @@ -5233,66 +5242,103 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, insert_part_info_log_entry_list(part_info, log_entry); } } - } while (++i < no_elements); + } DBUG_RETURN(FALSE); } /* - Write the log entries to ensure that the drop partition command is completed - even in the presence of a crash. + Write the log entry to ensure that the shadow frm file is removed at + crash. + SYNOPSIS + write_log_drop_shadow_frm() + lpt Struct containing parameters + install_frm Should we log action to install shadow frm or should + the action be to remove the shadow frm file. + RETURN VALUES + TRUE Error + FALSE Success + DESCRIPTION + Prepare an entry to the table log indicating a drop/install of the shadow frm + file and its corresponding handler file. +*/ + +static +bool +write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt) +{ + TABLE_LOG_ENTRY table_log_entry; + partition_info *part_info= lpt->part_info; + TABLE_LOG_MEMORY_ENTRY *log_entry; + TABLE_LOG_MEMORY_ENTRY *exec_log_entry= NULL; + char shadow_path[FN_LEN]; + DBUG_ENTER("write_log_drop_shadow_frm"); + lock_global_table_log(); + do + { + build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, + lpt->table_name, "#"); + if (write_log_rename_delete_frm(lpt, 0UL, NULL, + (const char*)shadow_path, FALSE)) + break; + log_entry= part_info->first_log_entry; + if (write_execute_table_log_entry(log_entry->entry_pos, + FALSE, &exec_log_entry)) + break; + part_info->exec_log_entry= exec_log_entry; + unlock_global_table_log(); + DBUG_RETURN(FALSE); + } while (TRUE); + release_part_info_log_entries(part_info->first_log_entry); + part_info->first_log_entry= NULL; + unlock_global_table_log(); + my_error(ER_TABLE_LOG_ERROR, MYF(0)); + DBUG_RETURN(TRUE); +} + + +/* + Log renaming of shadow frm to real frm name and dropping of old frm SYNOPSIS - write_log_drop_partition() + write_log_rename_frm() lpt Struct containing parameters RETURN VALUES TRUE Error FALSE Success DESCRIPTION - Prepare entries to the table log indicating all partitions to drop and to - install the shadow frm file and remove the old frm file. + Prepare an entry to ensure that we complete the renaming of the frm + file if failure occurs in the middle of the rename process. */ +static bool -write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt) +write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt) { TABLE_LOG_ENTRY table_log_entry; partition_info *part_info= lpt->part_info; TABLE_LOG_MEMORY_ENTRY *log_entry; TABLE_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; - char tmp_path[FN_LEN]; - char path[FN_LEN]; - uint next_entry= 0; + char shadow_path[FN_LEN]; TABLE_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; - DBUG_ENTER("write_log_drop_partition"); + DBUG_ENTER("write_log_drop_shadow_frm"); - part_info->first_log_entry= NULL; - build_table_filename(path, sizeof(path), lpt->db, - lpt->table_name, ""); lock_global_table_log(); do { - if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path)) - break; - /* - At first we write an entry that installs the new frm file - */ - build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, + build_table_filename(path, sizeof(path), lpt->db, + lpt->table_name, ""); + build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, lpt->table_name, "#"); - table_log_entry.action_type= 'r'; - table_log_entry.next_entry= next_entry; - table_log_entry.handler_type= "frm"; - table_log_entry.name= path; - table_log_entry.from_name= tmp_path; - if (write_table_log_entry(&table_log_entry, &log_entry)) + if (write_log_rename_delete_frm(lpt, 0UL, path, shadow_path, FALSE)) break; - insert_part_info_log_entry_list(part_info, log_entry); + log_entry= part_info->first_log_entry; if (write_execute_table_log_entry(log_entry->entry_pos, FALSE, &exec_log_entry)) break; release_part_info_log_entries(old_first_log_entry); unlock_global_table_log(); - DBUG_RETURN(FALSE); + DBUG_RETURN(FALSE); } while (TRUE); release_part_info_log_entries(part_info->first_log_entry); part_info->first_log_entry= old_first_log_entry; @@ -5303,50 +5349,49 @@ write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt) /* - Write the log entries to ensure that the add partition command is not - executed at all if a crash before it has completed + Write the log entries to ensure that the drop partition command is completed + even in the presence of a crash. SYNOPSIS - write_log_add_partition() + write_log_drop_partition() lpt Struct containing parameters RETURN VALUES TRUE Error FALSE Success DESCRIPTION Prepare entries to the table log indicating all partitions to drop and to - remove the shadow frm file. - The removal of the shadow frm file is already in the log file so we only - need to link the new entries to the existing and carefully ensure that - the new linked list has first the dropped partitions and then the - drop of the shadow frm file. - We always inject entries backwards in the list in the table log since we - don't know the entry position until we have written it. + install the shadow frm file and remove the old frm file. */ +static bool -write_log_add_partition(ALTER_PARTITION_PARAM_TYPE *lpt) +write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt) { TABLE_LOG_ENTRY table_log_entry; partition_info *part_info= lpt->part_info; TABLE_LOG_MEMORY_ENTRY *log_entry; + TABLE_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; char tmp_path[FN_LEN]; char path[FN_LEN]; - TABLE_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; + uint next_entry= 0; TABLE_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; - uint next_entry= old_first_log_entry->entry_pos; - /* Ensure we linked the existing entries at the back */ - DBUG_ENTER("write_log_add_partition"); + DBUG_ENTER("write_log_drop_partition"); part_info->first_log_entry= NULL; build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); + build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, + lpt->table_name, "#"); lock_global_table_log(); do { - if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path)) + if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path), + FALSE) + break; + if (write_log_rename_delete_frm(lpt, next_entry, (const char*)path, + (const char*)tmp_path, TRUE)) break; log_entry= part_info->first_log_entry; - /* Ensure first entry is the last dropped partition */ if (write_execute_table_log_entry(log_entry->entry_pos, FALSE, &exec_log_entry)) break; @@ -5363,28 +5408,58 @@ write_log_add_partition(ALTER_PARTITION_PARAM_TYPE *lpt) /* - Write indicator of how to abort in first phase of change partitions + Write the log entries to ensure that the add partition command is not + executed at all if a crash before it has completed + SYNOPSIS - write_log_ph1_change_partition() + write_log_add_change_partition() lpt Struct containing parameters RETURN VALUES TRUE Error FALSE Success DESCRIPTION - Write the log entries to remove partitions in creation when changing - partitions in an ADD/REORGANIZE/COALESCE command. These commands will - abort the entire operation if the system crashes before the next phase - is done. + Prepare entries to the table log indicating all partitions to drop and to + remove the shadow frm file. + We always inject entries backwards in the list in the table log since we + don't know the entry position until we have written it. */ +static bool -write_log_ph1_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) +write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) { - DBUG_ENTER("write_log_ph1_change_partition"); + partition_info *part_info= lpt->part_info; + TABLE_LOG_MEMORY_ENTRY *log_entry, *exec_log_entry; + char tmp_path[FN_LEN]; + char path[FN_LEN]; + uint next_entry= 0; + DBUG_ENTER("write_log_add_change_partition"); + build_table_filename(path, sizeof(path), lpt->db, + lpt->table_name, ""); lock_global_table_log(); + do + { + if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path), + FALSE) + break; + build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, + lpt->table_name, "#"); + if (write_log_rename_delete_frm(lpt, next_entry, tmp_path, + NULL, FALSE)) + break; + log_entry= part_info->first_log_entry; + if (write_execute_table_log_entry(log_entry->entry_pos, + FALSE, &exec_log_entry)) + break; + unlock_global_table_log(); + DBUG_RETURN(FALSE); + } while (TRUE); + release_part_info_log_entries(part_info->first_log_entry); + part_info->first_log_entry= NULL; unlock_global_table_log(); - DBUG_RETURN(FALSE); + my_error(ER_TABLE_LOG_ERROR, MYF(0)); + DBUG_RETURN(TRUE); } @@ -5393,7 +5468,7 @@ write_log_ph1_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) change partitions. SYNOPSIS - write_log_ph2_change_partition() + write_log_final_change_partition() lpt Struct containing parameters RETURN VALUES TRUE Error @@ -5404,14 +5479,46 @@ write_log_ph1_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) frm file. */ +static bool -write_log_ph2_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) +write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) { - DBUG_ENTER("write_log_ph2_change_partition"); + TABLE_LOG_ENTRY table_log_entry; + partition_info *part_info= lpt->part_info; + TABLE_LOG_MEMORY_ENTRY *log_entry; + TABLE_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; + char shadow_path[FN_LEN]; + TABLE_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; + uint next_entry= 0; + DBUG_ENTER("write_log_final_change_partition"); lock_global_table_log(); + do + { + if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path), + TRUE) + break; + if (write_log_changed_partitions(lpt, &next_entry, (const char*)path)) + break; + build_table_filename(path, sizeof(path), lpt->db, + lpt->table_name, ""); + build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, + lpt->table_name, "#"); + if (write_log_rename_delete_frm(lpt, 0UL, path, shadow_path, FALSE)) + break; + log_entry= part_info->first_log_entry; + if (write_execute_table_log_entry(log_entry->entry_pos, + FALSE, &exec_log_entry)) + break; + release_part_info_log_entries(old_first_log_entry); + unlock_global_table_log(); + DBUG_RETURN(FALSE); + } while (TRUE); + release_part_info_log_entries(part_info->first_log_entry); + part_info->first_log_entry= old_first_log_entry; unlock_global_table_log(); - DBUG_RETURN(FALSE); + my_error(ER_TABLE_LOG_ERROR, MYF(0)); + DBUG_RETURN(TRUE); } @@ -5425,6 +5532,7 @@ write_log_ph2_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) TRUE Error FALSE Success */ + static bool write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt) @@ -5641,7 +5749,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, We insert Error injections at all places where it could be interesting to test if recovery is properly done. */ - if (write_log_shadow_frm(lpt, FALSE) || + if (write_log_drop_shadow_frm(lpt) || ERROR_INJECT_CRASH("crash_drop_partition_1") || mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || ERROR_INJECT_CRASH("crash_drop_partition_2") || @@ -5697,26 +5805,24 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, 8) Remove entries from table log 9) Complete query */ - if (write_log_shadow_frm(lpt, FALSE) || + if (write_log_add_change_partition(lpt) || ERROR_INJECT_CRASH("crash_add_partition_1") || mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || ERROR_INJECT_CRASH("crash_add_partition_2") || - write_log_add_partition(lpt) || - ERROR_INJECT_CRASH("crash_add_partition_3") || mysql_change_partitions(lpt) || - ERROR_INJECT_CRASH("crash_add_partition_4") || + ERROR_INJECT_CRASH("crash_add_partition_3") || abort_and_upgrade_lock(lpt) || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query, thd->query_length), FALSE)) || + ERROR_INJECT_CRASH("crash_add_partition_4") || + write_log_rename_frm(lpt) || ERROR_INJECT_CRASH("crash_add_partition_5") || - write_log_shadow_frm(lpt, TRUE) || - ERROR_INJECT_CRASH("crash_add_partition_6") || mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || - ERROR_INJECT_CRASH("crash_add_partition_7") || + ERROR_INJECT_CRASH("crash_add_partition_6") || (close_open_tables_and_downgrade(lpt), FALSE) || write_log_completed(lpt) || - ERROR_INJECT_CRASH("crash_add_partition_8")) + ERROR_INJECT_CRASH("crash_add_partition_7")) { fast_alter_partition_error_handler(lpt); DBUG_RETURN(TRUE); @@ -5778,33 +5884,31 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, 14)Complete query */ - if (write_log_shadow_frm(lpt, FALSE) || + if (write_log_add_change_partition(lpt) || ERROR_INJECT_CRASH("crash_change_partition_1") || mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || ERROR_INJECT_CRASH("crash_change_partition_2") || - write_log_ph1_change_partition(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_3") || mysql_change_partitions(lpt) || + ERROR_INJECT_CRASH("crash_change_partition_3") || + write_log_final_change_partition(lpt) || ERROR_INJECT_CRASH("crash_change_partition_4") || - write_log_ph2_change_partition(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_5") || abort_and_upgrade_lock(lpt) || table->file->extra(HA_EXTRA_PREPARE_FOR_DELETE) || - ERROR_INJECT_CRASH("crash_change_partition_6") || + ERROR_INJECT_CRASH("crash_change_partition_5") || mysql_rename_partitions(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_7") || + ERROR_INJECT_CRASH("crash_change_partition_6") || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query, thd->query_length), FALSE)) || - ERROR_INJECT_CRASH("crash_change_partition_8") || + ERROR_INJECT_CRASH("crash_change_partition_7") || mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || - ERROR_INJECT_CRASH("crash_change_partition_9") || + ERROR_INJECT_CRASH("crash_change_partition_8") || (close_open_tables_and_downgrade(lpt), FALSE) || - ERROR_INJECT_CRASH("crash_change_partition_10") || + ERROR_INJECT_CRASH("crash_change_partition_9") || mysql_drop_partitions(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_11") || + ERROR_INJECT_CRASH("crash_change_partition_10") || write_log_completed(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_12") || + ERROR_INJECT_CRASH("crash_change_partition_11") || (mysql_wait_completed_table(lpt, table), FALSE)) { fast_alter_partition_error_handler(lpt); |