diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index af6ce9cd1e0..d65203e1b34 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -584,6 +584,7 @@ int ha_partition::drop_partitions(const char *path) uint no_subparts= m_part_info->no_subparts; uint i= 0; uint name_variant; + int ret_error; int error= 0; DBUG_ENTER("ha_partition::drop_partitions"); @@ -610,7 +611,8 @@ int ha_partition::drop_partitions(const char *path) sub_elem->partition_name, name_variant); file= m_file[part]; DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff)); - error+= file->delete_table((const char *) part_name_buff); + if ((ret_error= file->delete_table((const char *) part_name_buff))) + error= ret_error; } while (++j < no_subparts); } else @@ -620,7 +622,8 @@ int ha_partition::drop_partitions(const char *path) TRUE); file= m_file[i]; DBUG_PRINT("info", ("Drop partition %s", part_name_buff)); - error+= file->delete_table((const char *) part_name_buff); + if ((ret_error= file->delete_table((const char *) part_name_buff))) + error= ret_error; } if (part_elem->part_state == PART_IS_CHANGED) part_elem->part_state= PART_NORMAL; @@ -663,6 +666,7 @@ int ha_partition::rename_partitions(const char *path) uint i= 0; uint j= 0; int error= 0; + int ret_error; uint temp_partitions= m_part_info->temp_partitions.elements; handler *file; partition_element *part_elem, *sub_elem; @@ -693,8 +697,9 @@ int ha_partition::rename_partitions(const char *path) sub_elem->partition_name, NORMAL_PART_NAME); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); - if (file->delete_table((const char *) norm_name_buff) || - inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) + if ((ret_error= file->delete_table((const char *) norm_name_buff))) + error= ret_error; + else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= 1; else sub_elem->log_entry= NULL; /* Indicate success */ @@ -707,8 +712,9 @@ int ha_partition::rename_partitions(const char *path) part_elem->partition_name, NORMAL_PART_NAME, TRUE); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); - if (file->delete_table((const char *) norm_name_buff) || - inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) + if ((ret_error= file->delete_table((const char *) norm_name_buff))) + error= ret_error; + else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= 1; else sub_elem->log_entry= NULL; /* Indicate success */ @@ -761,8 +767,9 @@ int ha_partition::rename_partitions(const char *path) { file= m_reorged_file[part_count++]; DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); - if (file->delete_table((const char *) norm_name_buff) || - inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) + if ((ret_error= file->delete_table((const char *) norm_name_buff))) + error= ret_error; + else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= 1; VOID(sync_table_log()); } @@ -773,9 +780,10 @@ int ha_partition::rename_partitions(const char *path) TEMP_PART_NAME); DBUG_PRINT("info", ("Rename subpartition from %s to %s", part_name_buff, norm_name_buff)); - if (file->rename_table((const char *) norm_name_buff, - (const char *) part_name_buff) || - inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) + if ((ret_error= file->rename_table((const char *) norm_name_buff, + (const char *) part_name_buff))) + error= ret_error; + else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= 1; else sub_elem->log_entry= NULL; @@ -790,8 +798,9 @@ int ha_partition::rename_partitions(const char *path) { file= m_reorged_file[part_count++]; DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); - if (file->delete_table((const char *) norm_name_buff) || - inactivate_table_log_entry(part_elem->log_entry->entry_pos)) + if ((ret_error= file->delete_table((const char *) norm_name_buff))) + error= ret_error; + else if (inactivate_table_log_entry(part_elem->log_entry->entry_pos)) error= 1; VOID(sync_table_log()); } @@ -801,9 +810,10 @@ int ha_partition::rename_partitions(const char *path) TRUE); DBUG_PRINT("info", ("Rename partition from %s to %s", part_name_buff, norm_name_buff)); - if (file->rename_table((const char *) norm_name_buff, - (const char *) part_name_buff) || - inactivate_table_log_entry(part_elem->log_entry->entry_pos)) + if ((ret_error= file->rename_table((const char *) norm_name_buff, + (const char *) part_name_buff))) + error= ret_error; + else if (inactivate_table_log_entry(part_elem->log_entry->entry_pos)) error= 1; else part_elem->log_entry= NULL; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 56e64537fdf..6a34fcaadde 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -4975,14 +4975,17 @@ the generated partition syntax in a correct manner. static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) { char path[FN_REFLEN+1]; + int error; + handler *file= lpt->table->file; DBUG_ENTER("mysql_change_partitions"); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); - DBUG_RETURN(lpt->table->file->change_partitions(lpt->create_info, path, - &lpt->copied, - &lpt->deleted, - lpt->pack_frm_data, - lpt->pack_frm_len)); + DBUG_RETURN(file->change_partitions(lpt->create_info, + path, + &lpt->copied, + &lpt->deleted, + lpt->pack_frm_data, + lpt->pack_frm_len)); } @@ -5008,10 +5011,17 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) { char path[FN_REFLEN+1]; + int error; DBUG_ENTER("mysql_rename_partitions"); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); - DBUG_RETURN(lpt->table->file->rename_partitions(path)); + if ((error= lpt->table->file->rename_partitions(path))) + { + if (error != 1) + lpt->table->file->print_error(error, MYF(0)); + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); } @@ -5042,11 +5052,13 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) List_iterator part_it(part_info->partitions); uint i= 0; uint remove_count= 0; + int error; DBUG_ENTER("mysql_drop_partitions"); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); - if (lpt->table->file->drop_partitions(path)) + if ((error= lpt->table->file->drop_partitions(path))) { + lpt->table->file->print_error(error, MYF(0)); DBUG_RETURN(TRUE); } do @@ -5920,6 +5932,31 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, abort(); if (!not_completed) abort(); + if (!part_info->first_log_entry && + execute_table_log_entry(part_info->first_log_entry)) + { + /* + We couldn't recover from error + */ + } + else + { + if (not_completed) + { + /* + We hit an error before things were completed but managed + to recover from the error. + */ + } + else + { + /* + We hit an error after we had completed most of the operation + and were successful in a second attempt so the operation + actually is successful now. + */ + } + } fast_alter_partition_error_handler(lpt); DBUG_RETURN(TRUE); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b2bd7494709..8391a976679 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -320,7 +320,8 @@ read_table_log_file_entry(uint entry_no) uint io_size= global_table_log.io_size; DBUG_ENTER("read_table_log_file_entry"); - if (my_pread(file_id, file_entry, io_size, io_size * entry_no, MYF(0))) + if (my_pread(file_id, file_entry, io_size, io_size * entry_no, + MYF(MY_WME))) error= TRUE; DBUG_RETURN(error); } @@ -346,7 +347,7 @@ write_table_log_file_entry(uint entry_no) DBUG_ENTER("write_table_log_file_entry"); if (my_pwrite(file_id, file_entry, - IO_SIZE, IO_SIZE * entry_no, MYF(0)) != IO_SIZE) + IO_SIZE, IO_SIZE * entry_no, MYF(MY_WME)) != IO_SIZE) error= TRUE; DBUG_RETURN(error); } @@ -383,7 +384,7 @@ write_table_log_header() if (write_table_log_file_entry(0UL)) error= TRUE; if (!error) - error= sync_table_log(); + VOID(sync_table_log()); DBUG_RETURN(error); } @@ -430,7 +431,7 @@ read_table_log_header() bzero(file_entry, sizeof(global_table_log.file_entry)); create_table_log_file_name(file_name); - if (!(my_open(file_name, O_RDWR | O_TRUNC | O_BINARY, MYF(0)))) + if (!(my_open(file_name, O_RDWR | O_TRUNC | O_BINARY, MYF(MY_WME)))) { if (read_table_log_file_entry(0UL)) { @@ -517,7 +518,7 @@ init_table_log() if ((global_table_log.file_id= my_create(file_name, CREATE_MODE, O_RDWR | O_TRUNC | O_BINARY, - MYF(0))) < 0) + MYF(MY_WME))) < 0) { /* Couldn't create table log file, this is serious error */ abort(); @@ -564,6 +565,7 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) hton= ha_resolve_by_name(current_thd, handler_name); if (!hton) { + my_error(ER_ILLEGAL_HA, table_log_entry->handler_type); DBUG_RETURN(TRUE); } init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); @@ -573,7 +575,10 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) { file= get_new_handler(table_share, &mem_root, hton); if (!file) + { + mem_alloc_error(sizeof(handler)); goto error; + } } switch (table_log_entry->action_type) case TLOG_ACTION_DELETE_CODE: @@ -585,20 +590,24 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) if (frm_action) { strxmov(path, table_log_entry->name, reg_ext, NullS); - VOID(my_delete(path, MYF(0))); + if (my_delete(path, MYF(MY_WME))) + break; strxmov(path, table_log_entry->name, par_ext, NullS); - VOID(my_delete(path, MYF(0))); + if (my_delete(path, MYF(MY_WME))) + break; } else { if (file->delete_table(table_name)) break; } - if ((!inactivate_table_log_entry(table_log_entry->entry_pos)) && - (!sync_table_log())) + if ((!inactivate_table_log_entry(table_log_entry->entry_pos))) ; else + { + VOID(sync_table_log()); error= FALSE; + } break; } if (table_log_entry->action_type == TLOG_ACTION_DELETE_CODE) @@ -609,11 +618,11 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) { strxmov(path, table_log_entry->name, reg_ext, NullS); strxmov(from_path, table_log_entry->from_name, reg_ext, NullS); - if (my_rename(path, from_path, MYF(0))) + if (my_rename(path, from_path, MYF(MY_WME))) break; strxmov(path, table_log_entry->name, par_ext, NullS); strxmov(from_path, table_log_entry->from_name, par_ext, NullS); - if (my_rename(path, from_path, MYF(0))) + if (my_rename(path, from_path, MYF(MY_WME))) break; } else @@ -621,11 +630,13 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) if (file->rename_table(table_log_entry->name, table_log_entry->from_name)) break; - if ((!inactivate_table_log_entry(table_log_entry->entry_pos)) && - (!sync_table_log())) + if ((!inactivate_table_log_entry(table_log_entry->entry_pos))) ; else + { + VOID(sync_table_log()); error= FALSE; + } } break; default: @@ -662,7 +673,7 @@ get_free_table_log_entry(TABLE_LOG_MEMORY_ENTRY **active_entry, if (global_table_log.first_free == NULL) { if (!(used_entry= (TABLE_LOG_MEMORY_ENTRY*)my_malloc( - sizeof(TABLE_LOG_MEMORY_ENTRY), MYF(0)))) + sizeof(TABLE_LOG_MEMORY_ENTRY), MYF(MY_WME)))) { DBUG_RETURN(TRUE); } @@ -748,7 +759,8 @@ write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry, error= TRUE; if (write_header && !error) { - if (sync_table_log() || write_table_log_header()) + VOID(sync_table_log()); + if (write_table_log_header()) error= TRUE; } if (error) @@ -1232,7 +1244,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) VOID(pthread_mutex_lock(&LOCK_open)); if (my_delete(frm_name, MYF(MY_WME)) || inactivate_table_log_entry(part_info->frm_log_entry->entry_pos) || - sync_table_log() || + (sync_table_log(), FALSE) || my_rename(shadow_frm_name, frm_name, MYF(MY_WME)) || lpt->table->file->create_handler_files(path, shadow_path, TRUE)) {