diff options
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r-- | sql/sql_partition.cc | 705 |
1 files changed, 487 insertions, 218 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 0547331e7cd..b75a318ab65 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -67,7 +67,6 @@ #include "opt_range.h" // store_key_image_to_rec #include "sql_alter.h" // Alter_table_ctx #include "sql_select.h" -#include "sql_tablespace.h" // check_tablespace_name #include "ddl_log.h" #include "tztime.h" // my_tz_OFFSET0 @@ -78,11 +77,6 @@ using std::min; #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" -#define ERROR_INJECT_CRASH(code) \ - DBUG_EVALUATE_IF(code, (DBUG_SUICIDE(), 0), 0) -#define ERROR_INJECT_ERROR(code) \ - DBUG_EVALUATE_IF(code, (my_error(ER_UNKNOWN_ERROR, MYF(0)), TRUE), 0) - /* Partition related functions declarations and some static constants; */ @@ -525,7 +519,7 @@ static bool create_full_part_field_array(THD *thd, TABLE *table, goto end; } if (unlikely(my_bitmap_init(&part_info->full_part_field_set, bitmap_buf, - table->s->fields, FALSE))) + table->s->fields))) { result= TRUE; goto end; @@ -1100,10 +1094,10 @@ static bool set_up_partition_bitmaps(THD *thd, partition_info *part_info) bitmap_bytes * 2)))) DBUG_RETURN(TRUE); - my_bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits, FALSE); + my_bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits); /* Use the second half of the allocated buffer for lock_partitions */ my_bitmap_init(&part_info->lock_partitions, bitmap_buf + (bitmap_bytes / 4), - bitmap_bits, FALSE); + bitmap_bits); part_info->bitmaps_are_initialized= TRUE; part_info->set_partition_bitmaps(NULL); DBUG_RETURN(FALSE); @@ -2215,8 +2209,6 @@ static int add_partition_options(String *str, partition_element *p_elem) { int err= 0; - if (p_elem->tablespace_name) - err+= add_keyword_string(str,"TABLESPACE", false, p_elem->tablespace_name); if (p_elem->nodegroup_id != UNDEF_NODEGROUP) err+= add_keyword_int(str,"NODEGROUP",(longlong)p_elem->nodegroup_id); if (p_elem->part_max_rows) @@ -4714,8 +4706,6 @@ bool compare_partition_options(HA_CREATE_INFO *table_create_info, Note that there are not yet any engine supporting tablespace together with partitioning. TODO: when there are, add compare. */ - if (part_elem->tablespace_name || table_create_info->tablespace) - option_diffs[errors++]= "TABLESPACE"; if (part_elem->part_max_rows != table_create_info->max_rows) option_diffs[errors++]= "MAX_ROWS"; if (part_elem->part_min_rows != table_create_info->min_rows) @@ -4876,10 +4866,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, if (alter_info->partition_flags & (ALTER_PARTITION_ADD | ALTER_PARTITION_DROP | + ALTER_PARTITION_CONVERT_OUT | ALTER_PARTITION_COALESCE | ALTER_PARTITION_REORGANIZE | ALTER_PARTITION_TABLE_REORG | - ALTER_PARTITION_REBUILD)) + ALTER_PARTITION_REBUILD | + ALTER_PARTITION_CONVERT_IN)) { /* You can't add column when we are doing alter related to partition @@ -5085,6 +5077,13 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, } if (alter_info->partition_flags & ALTER_PARTITION_ADD) { + if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN) && + !(tab_part_info->part_type == RANGE_PARTITION || + tab_part_info->part_type == LIST_PARTITION)) + { + my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "CONVERT TABLE TO"); + goto err; + } if (*fast_alter_table && thd->locked_tables_mode) { MEM_ROOT *old_root= thd->mem_root; @@ -5371,8 +5370,12 @@ that are reorganised. tab_part_info->is_auto_partitioned= FALSE; } } - else if (alter_info->partition_flags & ALTER_PARTITION_DROP) + else if ((alter_info->partition_flags & ALTER_PARTITION_DROP) | + (alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT)) { + const char * const cmd= + (alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) ? + "CONVERT" : "DROP"; /* Drop a partition from a range partition and list partitioning is always safe and can be made more or less immediate. It is necessary @@ -5401,7 +5404,7 @@ that are reorganised. if (!(tab_part_info->part_type == RANGE_PARTITION || tab_part_info->part_type == LIST_PARTITION)) { - my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "DROP"); + my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), cmd); goto err; } if (num_parts_dropped >= tab_part_info->num_parts) @@ -5443,7 +5446,7 @@ that are reorganised. } while (++part_count < tab_part_info->num_parts); if (num_parts_found != num_parts_dropped) { - my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "DROP"); + my_error(ER_PARTITION_DOES_NOT_EXIST, MYF(0)); goto err; } if (table->file->is_fk_defined_on_table_or_index(MAX_KEY)) @@ -5451,7 +5454,17 @@ that are reorganised. my_error(ER_ROW_IS_REFERENCED, MYF(0)); goto err; } + DBUG_ASSERT(!(alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) || + num_parts_dropped == 1); + /* NOTE: num_parts is used in generate_partition_syntax() */ tab_part_info->num_parts-= num_parts_dropped; + if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) && + tab_part_info->is_sub_partitioned()) + { + // TODO technically this can be converted to a *partitioned* table + my_error(ER_PARTITION_CONVERT_SUBPARTITIONED, MYF(0)); + goto err; + } } else if (alter_info->partition_flags & ALTER_PARTITION_REBUILD) { @@ -5459,7 +5472,7 @@ that are reorganised. tab_part_info->default_engine_type); if (set_part_state(alter_info, tab_part_info, PART_CHANGED)) { - my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REBUILD"); + my_error(ER_PARTITION_DOES_NOT_EXIST, MYF(0)); goto err; } if (!(*fast_alter_table)) @@ -5735,7 +5748,7 @@ the generated partition syntax in a correct manner. } while (++part_count < tab_part_info->num_parts); if (drop_count != num_parts_reorged) { - my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REORGANIZE"); + my_error(ER_PARTITION_DOES_NOT_EXIST, MYF(0)); goto err; } tab_part_info->num_parts= check_total_partitions; @@ -5795,7 +5808,7 @@ the generated partition syntax in a correct manner. goto err; } } - } // ADD, DROP, COALESCE, REORGANIZE, TABLE_REORG, REBUILD + } // ADD, DROP, COALESCE, REORGANIZE, TABLE_REORG, REBUILD, CONVERT else { /* @@ -6117,8 +6130,6 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) char path[FN_REFLEN+1]; partition_info *part_info= lpt->table->part_info; List_iterator<partition_element> part_it(part_info->partitions); - uint i= 0; - uint remove_count= 0; int error; DBUG_ENTER("mysql_drop_partitions"); @@ -6133,34 +6144,69 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) lpt->table->file->print_error(error, MYF(0)); DBUG_RETURN(TRUE); } - do - { - partition_element *part_elem= part_it++; - if (part_elem->part_state == PART_IS_DROPPED) - { - part_it.remove(); - remove_count++; - } - } while (++i < part_info->num_parts); - part_info->num_parts-= remove_count; DBUG_RETURN(FALSE); } /* - Insert log entry into list + Convert partition to a table in an ALTER TABLE of partitions + SYNOPSIS - insert_part_info_log_entry_list() - log_entry + alter_partition_convert_out() + lpt Struct containing parameters + RETURN VALUES - NONE + TRUE Failure + FALSE Success + + DESCRIPTION + Rename partition table marked with PART_TO_BE_DROPPED into a separate table + under the name lpt->alter_ctx->(new_db, new_name). + + This is ddl-logged by write_log_convert_out_partition(). */ -static void insert_part_info_log_entry_list(partition_info *part_info, - DDL_LOG_MEMORY_ENTRY *log_entry) +static bool alter_partition_convert_out(ALTER_PARTITION_PARAM_TYPE *lpt) { - log_entry->next_active_log_entry= part_info->first_log_entry; - part_info->first_log_entry= log_entry; + partition_info *part_info= lpt->table->part_info; + THD *thd= lpt->thd; + int error; + handler *file= get_new_handler(NULL, thd->mem_root, part_info->default_engine_type); + + DBUG_ASSERT(lpt->thd->mdl_context.is_lock_owner(MDL_key::TABLE, + lpt->table->s->db.str, + lpt->table->s->table_name.str, + MDL_EXCLUSIVE)); + + char from_name[FN_REFLEN + 1], to_name[FN_REFLEN + 1]; + const char *path= lpt->table->s->path.str; + + build_table_filename(to_name, sizeof(to_name) - 1, lpt->alter_ctx->new_db.str, + lpt->alter_ctx->new_name.str, "", 0); + + for (const partition_element &e: part_info->partitions) + { + if (e.part_state != PART_TO_BE_DROPPED) + continue; + + if (unlikely((error= create_partition_name(from_name, sizeof(from_name), + path, e.partition_name, + NORMAL_PART_NAME, FALSE)))) + { + DBUG_ASSERT(thd->is_error()); + return true; + } + if (DBUG_IF("error_convert_partition_00") || + unlikely(error= file->ha_rename_table(from_name, to_name))) + { + my_error(ER_ERROR_ON_RENAME, MYF(0), from_name, to_name, my_errno); + lpt->table->file->print_error(error, MYF(0)); + return true; + } + break; + } + + return false; } @@ -6188,50 +6234,44 @@ static void release_part_info_log_entries(DDL_LOG_MEMORY_ENTRY *log_entry) /* - Log an delete/rename frm file + Log an rename frm file SYNOPSIS - write_log_replace_delete_frm() + write_log_replace_frm() lpt Struct for parameters next_entry Next reference to use in log record from_path Name to rename from to_path Name to rename to - replace_flag TRUE if replace, else delete RETURN VALUES TRUE Error FALSE Success DESCRIPTION - Support routine that writes a replace or delete of an frm file into the + Support routine that writes a replace of an frm file into the ddl log. It also inserts an entry that keeps track of used space into the partition info object */ -static bool write_log_replace_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt, - uint next_entry, - const char *from_path, - const char *to_path, - bool replace_flag) +bool write_log_replace_frm(ALTER_PARTITION_PARAM_TYPE *lpt, + uint next_entry, + const char *from_path, + const char *to_path) { DDL_LOG_ENTRY ddl_log_entry; DDL_LOG_MEMORY_ENTRY *log_entry; - DBUG_ENTER("write_log_replace_delete_frm"); + DBUG_ENTER("write_log_replace_frm"); bzero(&ddl_log_entry, sizeof(ddl_log_entry)); - if (replace_flag) - ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION; - else - ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION; + ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION; ddl_log_entry.next_entry= next_entry; lex_string_set(&ddl_log_entry.handler_name, reg_ext); lex_string_set(&ddl_log_entry.name, to_path); + lex_string_set(&ddl_log_entry.from_name, from_path); - if (replace_flag) - lex_string_set(&ddl_log_entry.from_name, from_path); if (ddl_log_write_entry(&ddl_log_entry, &log_entry)) { - DBUG_RETURN(TRUE); + DBUG_RETURN(true); } - insert_part_info_log_entry_list(lpt->part_info, log_entry); - DBUG_RETURN(FALSE); + ddl_log_add_entry(lpt->part_info, log_entry); + DBUG_RETURN(false); } @@ -6310,7 +6350,7 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, *next_entry= log_entry->entry_pos; sub_elem->log_entry= log_entry; - insert_part_info_log_entry_list(part_info, log_entry); + ddl_log_add_entry(part_info, log_entry); } while (++j < num_subparts); } else @@ -6337,7 +6377,7 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, } *next_entry= log_entry->entry_pos; part_elem->log_entry= log_entry; - insert_part_info_log_entry_list(part_info, log_entry); + ddl_log_add_entry(part_info, log_entry); } } } while (++i < num_elements); @@ -6346,21 +6386,29 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, /* - Log dropped partitions + Log dropped or converted partitions SYNOPSIS - write_log_dropped_partitions() + log_drop_or_convert_action() lpt Struct containing parameters RETURN VALUES TRUE Error FALSE Success */ -static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, - uint *next_entry, - const char *path, - bool temp_list) +enum log_action_enum +{ + ACT_DROP = 0, + ACT_CONVERT_IN, + ACT_CONVERT_OUT +}; + +static bool log_drop_or_convert_action(ALTER_PARTITION_PARAM_TYPE *lpt, + uint *next_entry, const char *path, + const char *from_name, bool temp_list, + const log_action_enum convert_action) { DDL_LOG_ENTRY ddl_log_entry; + DBUG_ASSERT(convert_action == ACT_DROP || (from_name != NULL)); partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; char tmp_path[FN_REFLEN + 1]; @@ -6368,10 +6416,13 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, List_iterator<partition_element> temp_it(part_info->temp_partitions); uint num_temp_partitions= part_info->temp_partitions.elements; uint num_elements= part_info->partitions.elements; - DBUG_ENTER("write_log_dropped_partitions"); + DBUG_ENTER("log_drop_or_convert_action"); bzero(&ddl_log_entry, sizeof(ddl_log_entry)); - ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION; + + ddl_log_entry.action_type= convert_action ? + DDL_LOG_RENAME_ACTION : + DDL_LOG_DELETE_ACTION; if (temp_list) num_elements= num_temp_partitions; while (num_elements--) @@ -6392,8 +6443,13 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, name_variant= TEMP_PART_NAME; else name_variant= NORMAL_PART_NAME; + DBUG_ASSERT(convert_action != ACT_CONVERT_IN || + part_elem->part_state == PART_TO_BE_ADDED); + DBUG_ASSERT(convert_action != ACT_CONVERT_OUT || + part_elem->part_state == PART_TO_BE_DROPPED); if (part_info->is_sub_partitioned()) { + DBUG_ASSERT(!convert_action); List_iterator<partition_element> sub_it(part_elem->subpartitions); uint num_subparts= part_info->num_subparts; uint j= 0; @@ -6415,7 +6471,7 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, } *next_entry= log_entry->entry_pos; sub_elem->log_entry= log_entry; - insert_part_info_log_entry_list(part_info, log_entry); + ddl_log_add_entry(part_info, log_entry); } while (++j < num_subparts); } else @@ -6427,14 +6483,25 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, part_elem->partition_name, name_variant, TRUE)) DBUG_RETURN(TRUE); - lex_string_set(&ddl_log_entry.name, tmp_path); + switch (convert_action) + { + case ACT_CONVERT_OUT: + ddl_log_entry.from_name= { from_name, strlen(from_name) }; + /* fall through */ + case ACT_DROP: + ddl_log_entry.name= { tmp_path, strlen(tmp_path) }; + break; + case ACT_CONVERT_IN: + ddl_log_entry.name= { from_name, strlen(from_name) }; + ddl_log_entry.from_name= { tmp_path, strlen(tmp_path) }; + } if (ddl_log_write_entry(&ddl_log_entry, &log_entry)) { DBUG_RETURN(TRUE); } *next_entry= log_entry->entry_pos; part_elem->log_entry= log_entry; - insert_part_info_log_entry_list(part_info, log_entry); + ddl_log_add_entry(part_info, log_entry); } } } @@ -6442,21 +6509,37 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, } -/* - Set execute log entry in ddl log for this partitioned table - SYNOPSIS - set_part_info_exec_log_entry() - part_info Partition info object - exec_log_entry Log entry - RETURN VALUES - NONE -*/ - -static void set_part_info_exec_log_entry(partition_info *part_info, - DDL_LOG_MEMORY_ENTRY *exec_log_entry) +inline +static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt, + uint *next_entry, const char *path, + bool temp_list) { - part_info->exec_log_entry= exec_log_entry; - exec_log_entry->next_active_log_entry= NULL; + return log_drop_or_convert_action(lpt, next_entry, path, NULL, temp_list, + ACT_DROP); +} + +inline +static bool write_log_convert_partition(ALTER_PARTITION_PARAM_TYPE *lpt, + uint *next_entry, const char *path) +{ + char other_table[FN_REFLEN + 1]; + const ulong f= lpt->alter_info->partition_flags; + DBUG_ASSERT((f & ALTER_PARTITION_CONVERT_IN) || (f & ALTER_PARTITION_CONVERT_OUT)); + const log_action_enum convert_action= (f & ALTER_PARTITION_CONVERT_IN) + ? ACT_CONVERT_IN : ACT_CONVERT_OUT; + build_table_filename(other_table, sizeof(other_table) - 1, lpt->alter_ctx->new_db.str, + lpt->alter_ctx->new_name.str, "", 0); + DDL_LOG_MEMORY_ENTRY *main_entry= lpt->part_info->main_entry; + bool res= log_drop_or_convert_action(lpt, next_entry, path, other_table, + false, convert_action); + /* + NOTE: main_entry is "drop shadow frm", we have to keep it like this + because partitioning crash-safety disables it at install shadow FRM phase. + This is needed to avoid spurious drop action when the shadow frm is replaced + by the backup frm and there is nothing to drop. + */ + lpt->part_info->main_entry= main_entry; + return res; } @@ -6464,10 +6547,9 @@ static void set_part_info_exec_log_entry(partition_info *part_info, Write the log entry to ensure that the shadow frm file is removed at crash. SYNOPSIS - write_log_drop_shadow_frm() + write_log_drop_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 @@ -6476,36 +6558,53 @@ static void set_part_info_exec_log_entry(partition_info *part_info, file and its corresponding handler file. */ -static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt) +static bool write_log_drop_frm(ALTER_PARTITION_PARAM_TYPE *lpt, + DDL_LOG_STATE *drop_chain) { - partition_info *part_info= lpt->part_info; - DDL_LOG_MEMORY_ENTRY *log_entry; - DDL_LOG_MEMORY_ENTRY *exec_log_entry= NULL; - char shadow_path[FN_REFLEN + 1]; - DBUG_ENTER("write_log_drop_shadow_frm"); + char path[FN_REFLEN + 1]; + DBUG_ENTER("write_log_drop_frm"); + const DDL_LOG_STATE *main_chain= lpt->part_info; + const bool drop_backup= (drop_chain != main_chain); - build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); + build_table_shadow_filename(path, sizeof(path) - 1, lpt, drop_backup); mysql_mutex_lock(&LOCK_gdl); - if (write_log_replace_delete_frm(lpt, 0UL, NULL, - (const char*)shadow_path, FALSE)) + if (ddl_log_delete_frm(drop_chain, (const char*)path)) goto error; - log_entry= part_info->first_log_entry; - if (ddl_log_write_execute_entry(log_entry->entry_pos, - &exec_log_entry)) + + if (drop_backup && (lpt->alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN)) + { + TABLE_LIST *table_from= lpt->table_list->next_local; + build_table_filename(path, sizeof(path) - 1, table_from->db.str, + table_from->table_name.str, "", 0); + + if (ddl_log_delete_frm(drop_chain, (const char*) path)) + goto error; + } + + if (ddl_log_write_execute_entry(drop_chain->list->entry_pos, + drop_backup ? + main_chain->execute_entry->entry_pos : 0, + &drop_chain->execute_entry)) goto error; mysql_mutex_unlock(&LOCK_gdl); - set_part_info_exec_log_entry(part_info, exec_log_entry); DBUG_RETURN(FALSE); error: - release_part_info_log_entries(part_info->first_log_entry); + release_part_info_log_entries(drop_chain->list); mysql_mutex_unlock(&LOCK_gdl); - part_info->first_log_entry= NULL; + drop_chain->list= NULL; my_error(ER_DDL_LOG_ERROR, MYF(0)); DBUG_RETURN(TRUE); } +static inline +bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt) +{ + return write_log_drop_frm(lpt, lpt->part_info); +} + + /* Log renaming of shadow frm to real frm name and dropping of old frm SYNOPSIS @@ -6523,20 +6622,20 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt) { partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; - DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; + DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->execute_entry; char path[FN_REFLEN + 1]; char shadow_path[FN_REFLEN + 1]; - DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; + DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->list; DBUG_ENTER("write_log_rename_frm"); - part_info->first_log_entry= NULL; + part_info->list= NULL; build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); mysql_mutex_lock(&LOCK_gdl); - if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE)) + if (write_log_replace_frm(lpt, 0UL, shadow_path, path)) goto error; - log_entry= part_info->first_log_entry; - part_info->frm_log_entry= log_entry; + log_entry= part_info->list; + part_info->main_entry= log_entry; if (ddl_log_write_execute_entry(log_entry->entry_pos, &exec_log_entry)) goto error; @@ -6545,10 +6644,10 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_RETURN(FALSE); error: - release_part_info_log_entries(part_info->first_log_entry); + release_part_info_log_entries(part_info->list); mysql_mutex_unlock(&LOCK_gdl); - part_info->first_log_entry= old_first_log_entry; - part_info->frm_log_entry= NULL; + part_info->list= old_first_log_entry; + part_info->main_entry= NULL; my_error(ER_DDL_LOG_ERROR, MYF(0)); DBUG_RETURN(TRUE); } @@ -6573,25 +6672,25 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt) { partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; - DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; + DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->execute_entry; char tmp_path[FN_REFLEN + 1]; char path[FN_REFLEN + 1]; uint next_entry= 0; - DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; + DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->list; DBUG_ENTER("write_log_drop_partition"); - part_info->first_log_entry= NULL; + part_info->list= NULL; build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt); mysql_mutex_lock(&LOCK_gdl); if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, FALSE)) goto error; - if (write_log_replace_delete_frm(lpt, next_entry, (const char*)tmp_path, - (const char*)path, TRUE)) + if (write_log_replace_frm(lpt, next_entry, (const char*)tmp_path, + (const char*)path)) goto error; - log_entry= part_info->first_log_entry; - part_info->frm_log_entry= log_entry; + log_entry= part_info->list; + part_info->main_entry= log_entry; if (ddl_log_write_execute_entry(log_entry->entry_pos, &exec_log_entry)) goto error; @@ -6600,15 +6699,44 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_RETURN(FALSE); error: - release_part_info_log_entries(part_info->first_log_entry); + release_part_info_log_entries(part_info->list); mysql_mutex_unlock(&LOCK_gdl); - part_info->first_log_entry= old_first_log_entry; - part_info->frm_log_entry= NULL; + part_info->list= old_first_log_entry; + part_info->main_entry= NULL; my_error(ER_DDL_LOG_ERROR, MYF(0)); DBUG_RETURN(TRUE); } +static bool write_log_convert_partition(ALTER_PARTITION_PARAM_TYPE *lpt) +{ + partition_info *part_info= lpt->part_info; + char tmp_path[FN_REFLEN + 1]; + char path[FN_REFLEN + 1]; + uint next_entry= part_info->list ? part_info->list->entry_pos : 0; + + build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); + build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt); + + mysql_mutex_lock(&LOCK_gdl); + + if (write_log_convert_partition(lpt, &next_entry, (const char*)path)) + goto error; + DBUG_ASSERT(next_entry == part_info->list->entry_pos); + if (ddl_log_write_execute_entry(part_info->list->entry_pos, + &part_info->execute_entry)) + goto error; + mysql_mutex_unlock(&LOCK_gdl); + return false; + +error: + mysql_mutex_unlock(&LOCK_gdl); + part_info->main_entry= NULL; + my_error(ER_DDL_LOG_ERROR, MYF(0)); + return true; +} + + /* Write the log entries to ensure that the add partition command is not executed at all if a crash before it has completed @@ -6630,11 +6758,10 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) { partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; - DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; char tmp_path[FN_REFLEN + 1]; char path[FN_REFLEN + 1]; uint next_entry= 0; - DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; + DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->list; /* write_log_drop_shadow_frm(lpt) must have been run first */ DBUG_ASSERT(old_first_log_entry); DBUG_ENTER("write_log_add_change_partition"); @@ -6649,20 +6776,18 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, FALSE)) goto error; - log_entry= part_info->first_log_entry; + log_entry= part_info->list; if (ddl_log_write_execute_entry(log_entry->entry_pos, - /* Reuse the old execute ddl_log_entry */ - &exec_log_entry)) + &part_info->execute_entry)) goto error; mysql_mutex_unlock(&LOCK_gdl); - set_part_info_exec_log_entry(part_info, exec_log_entry); DBUG_RETURN(FALSE); error: - release_part_info_log_entries(part_info->first_log_entry); + release_part_info_log_entries(part_info->list); mysql_mutex_unlock(&LOCK_gdl); - part_info->first_log_entry= old_first_log_entry; + part_info->list= old_first_log_entry; my_error(ER_DDL_LOG_ERROR, MYF(0)); DBUG_RETURN(TRUE); } @@ -6694,10 +6819,10 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) { partition_info *part_info= lpt->part_info; DDL_LOG_MEMORY_ENTRY *log_entry; - DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; + DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->execute_entry; char path[FN_REFLEN + 1]; char shadow_path[FN_REFLEN + 1]; - DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; + DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->list; uint next_entry= 0; DBUG_ENTER("write_log_final_change_partition"); @@ -6705,7 +6830,7 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) Do not link any previous log entry. Replace the revert operations with forced retry operations. */ - part_info->first_log_entry= NULL; + part_info->list= NULL; build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt); mysql_mutex_lock(&LOCK_gdl); @@ -6715,10 +6840,10 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) lpt->alter_info->partition_flags & ALTER_PARTITION_REORGANIZE)) goto error; - if (write_log_replace_delete_frm(lpt, next_entry, shadow_path, path, TRUE)) + if (write_log_replace_frm(lpt, next_entry, shadow_path, path)) goto error; - log_entry= part_info->first_log_entry; - part_info->frm_log_entry= log_entry; + log_entry= part_info->list; + part_info->main_entry= log_entry; /* Overwrite the revert execute log entry with this retry execute entry */ if (ddl_log_write_execute_entry(log_entry->entry_pos, &exec_log_entry)) @@ -6728,10 +6853,10 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_RETURN(FALSE); error: - release_part_info_log_entries(part_info->first_log_entry); + release_part_info_log_entries(part_info->list); mysql_mutex_unlock(&LOCK_gdl); - part_info->first_log_entry= old_first_log_entry; - part_info->frm_log_entry= NULL; + part_info->list= old_first_log_entry; + part_info->main_entry= NULL; my_error(ER_DDL_LOG_ERROR, MYF(0)); DBUG_RETURN(TRUE); } @@ -6748,11 +6873,15 @@ error: FALSE Success */ +/* + TODO: Partitioning atomic DDL refactoring: this should be replaced with + ddl_log_complete(). +*/ static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, bool dont_crash) { partition_info *part_info= lpt->part_info; - DDL_LOG_MEMORY_ENTRY *log_entry= part_info->exec_log_entry; + DDL_LOG_MEMORY_ENTRY *log_entry= part_info->execute_entry; DBUG_ENTER("write_log_completed"); DBUG_ASSERT(log_entry); @@ -6768,11 +6897,11 @@ static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, */ ; } - release_part_info_log_entries(part_info->first_log_entry); - release_part_info_log_entries(part_info->exec_log_entry); + release_part_info_log_entries(part_info->list); + release_part_info_log_entries(part_info->execute_entry); mysql_mutex_unlock(&LOCK_gdl); - part_info->exec_log_entry= NULL; - part_info->first_log_entry= NULL; + part_info->execute_entry= NULL; + part_info->list= NULL; DBUG_VOID_RETURN; } @@ -6786,14 +6915,18 @@ static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, NONE */ +/* + TODO: Partitioning atomic DDL refactoring: this should be replaced with + ddl_log_release_entries(). +*/ static void release_log_entries(partition_info *part_info) { mysql_mutex_lock(&LOCK_gdl); - release_part_info_log_entries(part_info->first_log_entry); - release_part_info_log_entries(part_info->exec_log_entry); + release_part_info_log_entries(part_info->list); + release_part_info_log_entries(part_info->execute_entry); mysql_mutex_unlock(&LOCK_gdl); - part_info->first_log_entry= NULL; - part_info->exec_log_entry= NULL; + part_info->list= NULL; + part_info->execute_entry= NULL; } @@ -6859,6 +6992,10 @@ static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt) @param close_table Table is still open, close it before reverting */ +/* + TODO: Partitioning atomic DDL refactoring: this should be replaced with + correct combination of ddl_log_revert() / ddl_log_complete() +*/ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, bool action_completed, bool drop_partition, @@ -6906,8 +7043,8 @@ static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED, NULL); } - if (part_info->first_log_entry && - ddl_log_execute_entry(thd, part_info->first_log_entry->entry_pos)) + if (part_info->list && + ddl_log_execute_entry(thd, part_info->list->entry_pos)) { /* We couldn't recover from error, most likely manual interaction @@ -7069,6 +7206,64 @@ bool log_partition_alter_to_ddl_log(ALTER_PARTITION_PARAM_TYPE *lpt) } +extern bool alter_partition_convert_in(ALTER_PARTITION_PARAM_TYPE *lpt); + +/** + Check that definition of source table fits definition of partition being + added and every row stored in the table conforms partition's expression. + + @param lpt Structure containing parameters required for checking + @param[in,out] part_file_name_buf Buffer for storing a partition name + @param part_file_name_buf_sz Size of buffer for storing a partition name + @param part_file_name_len Length of partition prefix stored in the buffer + on invocation of function + + @return false on success, true on error +*/ + +static bool check_table_data(ALTER_PARTITION_PARAM_TYPE *lpt) +{ + /* + TODO: if destination is partitioned by range(X) and source is indexed by X + then just get min(X) and max(X) from index. + */ + THD *thd= lpt->thd; + TABLE *table_to= lpt->table_list->table; + TABLE *table_from= lpt->table_list->next_local->table; + + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, + table_to->s->db.str, + table_to->s->table_name.str, + MDL_EXCLUSIVE)); + + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, + table_from->s->db.str, + table_from->s->table_name.str, + MDL_EXCLUSIVE)); + + uint32 new_part_id; + partition_element *part_elem; + const char* partition_name= thd->lex->part_info->curr_part_elem->partition_name; + part_elem= table_to->part_info->get_part_elem(partition_name, + nullptr, 0, &new_part_id); + if (unlikely(!part_elem)) + return true; + + if (unlikely(new_part_id == NOT_A_PARTITION_ID)) + { + DBUG_ASSERT(table_to->part_info->is_sub_partitioned()); + my_error(ER_PARTITION_INSTEAD_OF_SUBPARTITION, MYF(0)); + return true; + } + + if (verify_data_with_partition(table_from, table_to, new_part_id)) + { + return true; + } + + return false; +} + /** Actually perform the change requested by ALTER TABLE of partitions @@ -7093,11 +7288,23 @@ bool log_partition_alter_to_ddl_log(ALTER_PARTITION_PARAM_TYPE *lpt) uint fast_alter_partition_table(THD *thd, TABLE *table, Alter_info *alter_info, + Alter_table_ctx *alter_ctx, HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - const LEX_CSTRING *db, - const LEX_CSTRING *table_name) + TABLE_LIST *table_list) { + /* + TODO: Partitioning atomic DDL refactoring. + + DDL log chain state is stored in partition_info: + + struct st_ddl_log_memory_entry *first_log_entry; + struct st_ddl_log_memory_entry *exec_log_entry; + struct st_ddl_log_memory_entry *frm_log_entry; + + Make it stored and used in DDL_LOG_STATE like it was done in MDEV-17567. + This requires mysql_write_frm() refactoring (see comment there). + */ + /* Set-up struct used to write frm files */ partition_info *part_info; ALTER_PARTITION_PARAM_TYPE lpt_obj; @@ -7115,13 +7322,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, lpt->table_list= table_list; lpt->part_info= part_info; lpt->alter_info= alter_info; + lpt->alter_ctx= alter_ctx; lpt->create_info= create_info; lpt->db_options= create_info->table_options_with_row_type(); lpt->table= table; lpt->key_info_buffer= 0; lpt->key_count= 0; - lpt->db= *db; - lpt->table_name= *table_name; + lpt->db= alter_ctx->db; + lpt->table_name= alter_ctx->table_name; lpt->org_tabledef_version= table->s->tabledef_version; lpt->copied= 0; lpt->deleted= 0; @@ -7241,38 +7449,29 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, to test if recovery is properly done. */ if (write_log_drop_shadow_frm(lpt) || - ERROR_INJECT_CRASH("crash_drop_partition_1") || - ERROR_INJECT_ERROR("fail_drop_partition_1") || + ERROR_INJECT("drop_partition_1") || mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || - ERROR_INJECT_CRASH("crash_drop_partition_2") || - ERROR_INJECT_ERROR("fail_drop_partition_2") || + ERROR_INJECT("drop_partition_2") || wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) || - ERROR_INJECT_CRASH("crash_drop_partition_3") || - ERROR_INJECT_ERROR("fail_drop_partition_3") || + ERROR_INJECT("drop_partition_3") || write_log_drop_partition(lpt) || (action_completed= TRUE, FALSE) || - ERROR_INJECT_CRASH("crash_drop_partition_4") || - ERROR_INJECT_ERROR("fail_drop_partition_4") || + ERROR_INJECT("drop_partition_4") || alter_close_table(lpt) || - ERROR_INJECT_CRASH("crash_drop_partition_5") || - ERROR_INJECT_ERROR("fail_drop_partition_5") || - ERROR_INJECT_CRASH("crash_drop_partition_6") || - ERROR_INJECT_ERROR("fail_drop_partition_6") || + ERROR_INJECT("drop_partition_5") || + ERROR_INJECT("drop_partition_6") || (frm_install= TRUE, FALSE) || mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || log_partition_alter_to_ddl_log(lpt) || (frm_install= FALSE, FALSE) || - ERROR_INJECT_CRASH("crash_drop_partition_7") || - ERROR_INJECT_ERROR("fail_drop_partition_7") || + ERROR_INJECT("drop_partition_7") || mysql_drop_partitions(lpt) || - ERROR_INJECT_CRASH("crash_drop_partition_8") || - ERROR_INJECT_ERROR("fail_drop_partition_8") || + ERROR_INJECT("drop_partition_8") || (write_log_completed(lpt, FALSE), FALSE) || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query(), thd->query_length()), FALSE)) || - ERROR_INJECT_CRASH("crash_drop_partition_9") || - ERROR_INJECT_ERROR("fail_drop_partition_9")) + ERROR_INJECT("drop_partition_9")) { handle_alter_part_error(lpt, action_completed, TRUE, frm_install); goto err; @@ -7280,10 +7479,102 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, if (alter_partition_lock_handling(lpt)) goto err; } + else if (alter_info->partition_flags & ALTER_PARTITION_CONVERT_OUT) + { + DDL_LOG_STATE chain_drop_backup; + bzero(&chain_drop_backup, sizeof(chain_drop_backup)); + + if (mysql_write_frm(lpt, WFRM_WRITE_CONVERTED_TO) || + ERROR_INJECT("convert_partition_1") || + write_log_drop_shadow_frm(lpt) || + ERROR_INJECT("convert_partition_2") || + mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || + ERROR_INJECT("convert_partition_3") || + wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) || + ERROR_INJECT("convert_partition_4") || + write_log_convert_partition(lpt) || + ERROR_INJECT("convert_partition_5") || + alter_close_table(lpt) || + ERROR_INJECT("convert_partition_6") || + alter_partition_convert_out(lpt) || + ERROR_INJECT("convert_partition_7") || + write_log_drop_frm(lpt, &chain_drop_backup) || + mysql_write_frm(lpt, WFRM_INSTALL_SHADOW|WFRM_BACKUP_ORIGINAL) || + log_partition_alter_to_ddl_log(lpt) || + ERROR_INJECT("convert_partition_8") || + ((!thd->lex->no_write_to_binlog) && + ((thd->binlog_xid= thd->query_id), + ddl_log_update_xid(lpt->part_info, thd->binlog_xid), + write_bin_log(thd, false, thd->query(), thd->query_length()), + (thd->binlog_xid= 0))) || + ERROR_INJECT("convert_partition_9")) + { + ddl_log_complete(&chain_drop_backup); + (void) ddl_log_revert(thd, lpt->part_info); + handle_alter_part_error(lpt, true, true, false); + goto err; + } + ddl_log_complete(lpt->part_info); + ERROR_INJECT("convert_partition_10"); + (void) ddl_log_revert(thd, &chain_drop_backup); + if (alter_partition_lock_handling(lpt) || + ERROR_INJECT("convert_partition_11")) + goto err; + } + else if ((alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN)) + { + DDL_LOG_STATE chain_drop_backup; + bzero(&chain_drop_backup, sizeof(chain_drop_backup)); + TABLE *table_from= table_list->next_local->table; + + if (wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) || + wait_while_table_is_used(thd, table_from, HA_EXTRA_PREPARE_FOR_RENAME) || + ERROR_INJECT("convert_partition_1") || + compare_table_with_partition(thd, table_from, table, NULL, 0) || + ERROR_INJECT("convert_partition_2") || + check_table_data(lpt)) + goto err; + + if (write_log_drop_shadow_frm(lpt) || + ERROR_INJECT("convert_partition_3") || + mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || + ERROR_INJECT("convert_partition_4") || + alter_close_table(lpt) || + ERROR_INJECT("convert_partition_5") || + write_log_convert_partition(lpt) || + ERROR_INJECT("convert_partition_6") || + alter_partition_convert_in(lpt) || + ERROR_INJECT("convert_partition_7") || + (frm_install= true, false) || + write_log_drop_frm(lpt, &chain_drop_backup) || + mysql_write_frm(lpt, WFRM_INSTALL_SHADOW|WFRM_BACKUP_ORIGINAL) || + log_partition_alter_to_ddl_log(lpt) || + (frm_install= false, false) || + ERROR_INJECT("convert_partition_8") || + ((!thd->lex->no_write_to_binlog) && + ((thd->binlog_xid= thd->query_id), + ddl_log_update_xid(lpt->part_info, thd->binlog_xid), + write_bin_log(thd, false, thd->query(), thd->query_length()), + (thd->binlog_xid= 0))) || + ERROR_INJECT("convert_partition_9")) + { + ddl_log_complete(&chain_drop_backup); + (void) ddl_log_revert(thd, lpt->part_info); + handle_alter_part_error(lpt, true, true, false); + goto err; + } + ddl_log_complete(lpt->part_info); + ERROR_INJECT("convert_partition_10"); + (void) ddl_log_revert(thd, &chain_drop_backup); + if (alter_partition_lock_handling(lpt) || + ERROR_INJECT("convert_partition_11")) + goto err; + } else if ((alter_info->partition_flags & ALTER_PARTITION_ADD) && (part_info->part_type == RANGE_PARTITION || part_info->part_type == LIST_PARTITION)) { + DBUG_ASSERT(!(alter_info->partition_flags & ALTER_PARTITION_CONVERT_IN)); /* ADD RANGE/LIST PARTITIONS In this case there are no tuples removed and no tuples are added. @@ -7315,41 +7606,31 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, 12)Complete query */ if (write_log_drop_shadow_frm(lpt) || - ERROR_INJECT_CRASH("crash_add_partition_1") || - ERROR_INJECT_ERROR("fail_add_partition_1") || + ERROR_INJECT("add_partition_1") || mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || - ERROR_INJECT_CRASH("crash_add_partition_2") || - ERROR_INJECT_ERROR("fail_add_partition_2") || + ERROR_INJECT("add_partition_2") || wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) || - ERROR_INJECT_CRASH("crash_add_partition_3") || - ERROR_INJECT_ERROR("fail_add_partition_3") || + ERROR_INJECT("add_partition_3") || write_log_add_change_partition(lpt) || - ERROR_INJECT_CRASH("crash_add_partition_4") || - ERROR_INJECT_ERROR("fail_add_partition_4") || + ERROR_INJECT("add_partition_4") || mysql_change_partitions(lpt) || - ERROR_INJECT_CRASH("crash_add_partition_5") || - ERROR_INJECT_ERROR("fail_add_partition_5") || + ERROR_INJECT("add_partition_5") || alter_close_table(lpt) || - ERROR_INJECT_CRASH("crash_add_partition_6") || - ERROR_INJECT_ERROR("fail_add_partition_6") || - ERROR_INJECT_CRASH("crash_add_partition_7") || - ERROR_INJECT_ERROR("fail_add_partition_7") || + ERROR_INJECT("add_partition_6") || + ERROR_INJECT("add_partition_7") || write_log_rename_frm(lpt) || (action_completed= TRUE, FALSE) || - ERROR_INJECT_CRASH("crash_add_partition_8") || - ERROR_INJECT_ERROR("fail_add_partition_8") || + ERROR_INJECT("add_partition_8") || (frm_install= TRUE, FALSE) || mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || log_partition_alter_to_ddl_log(lpt) || (frm_install= FALSE, FALSE) || - ERROR_INJECT_CRASH("crash_add_partition_9") || - ERROR_INJECT_ERROR("fail_add_partition_9") || + ERROR_INJECT("add_partition_9") || (write_log_completed(lpt, FALSE), FALSE) || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query(), thd->query_length()), FALSE)) || - ERROR_INJECT_CRASH("crash_add_partition_10") || - ERROR_INJECT_ERROR("fail_add_partition_10")) + ERROR_INJECT("add_partition_10")) { handle_alter_part_error(lpt, action_completed, FALSE, frm_install); goto err; @@ -7414,47 +7695,35 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, 13) Complete query. */ if (write_log_drop_shadow_frm(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_1") || - ERROR_INJECT_ERROR("fail_change_partition_1") || + ERROR_INJECT("change_partition_1") || mysql_write_frm(lpt, WFRM_WRITE_SHADOW) || - ERROR_INJECT_CRASH("crash_change_partition_2") || - ERROR_INJECT_ERROR("fail_change_partition_2") || + ERROR_INJECT("change_partition_2") || write_log_add_change_partition(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_3") || - ERROR_INJECT_ERROR("fail_change_partition_3") || + ERROR_INJECT("change_partition_3") || mysql_change_partitions(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_4") || - ERROR_INJECT_ERROR("fail_change_partition_4") || + ERROR_INJECT("change_partition_4") || wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) || - ERROR_INJECT_CRASH("crash_change_partition_5") || - ERROR_INJECT_ERROR("fail_change_partition_5") || + ERROR_INJECT("change_partition_5") || alter_close_table(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_6") || - ERROR_INJECT_ERROR("fail_change_partition_6") || + ERROR_INJECT("change_partition_6") || write_log_final_change_partition(lpt) || (action_completed= TRUE, FALSE) || - ERROR_INJECT_CRASH("crash_change_partition_7") || - ERROR_INJECT_ERROR("fail_change_partition_7") || - ERROR_INJECT_CRASH("crash_change_partition_8") || - ERROR_INJECT_ERROR("fail_change_partition_8") || + ERROR_INJECT("change_partition_7") || + ERROR_INJECT("change_partition_8") || ((frm_install= TRUE), FALSE) || mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || log_partition_alter_to_ddl_log(lpt) || (frm_install= FALSE, FALSE) || - ERROR_INJECT_CRASH("crash_change_partition_9") || - ERROR_INJECT_ERROR("fail_change_partition_9") || + ERROR_INJECT("change_partition_9") || mysql_drop_partitions(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_10") || - ERROR_INJECT_ERROR("fail_change_partition_10") || + ERROR_INJECT("change_partition_10") || mysql_rename_partitions(lpt) || - ERROR_INJECT_CRASH("crash_change_partition_11") || - ERROR_INJECT_ERROR("fail_change_partition_11") || + ERROR_INJECT("change_partition_11") || (write_log_completed(lpt, FALSE), FALSE) || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query(), thd->query_length()), FALSE)) || - ERROR_INJECT_CRASH("crash_change_partition_12") || - ERROR_INJECT_ERROR("fail_change_partition_12")) + ERROR_INJECT("change_partition_12")) { handle_alter_part_error(lpt, action_completed, FALSE, frm_install); goto err; |