WL 2826: Error handling of ALTER TABLE for partitioning

First step for handling errors in ALTER TABLE for partitioning
parent 5b99026a
...@@ -584,6 +584,7 @@ int ha_partition::drop_partitions(const char *path) ...@@ -584,6 +584,7 @@ int ha_partition::drop_partitions(const char *path)
uint no_subparts= m_part_info->no_subparts; uint no_subparts= m_part_info->no_subparts;
uint i= 0; uint i= 0;
uint name_variant; uint name_variant;
int ret_error;
int error= 0; int error= 0;
DBUG_ENTER("ha_partition::drop_partitions"); DBUG_ENTER("ha_partition::drop_partitions");
...@@ -610,7 +611,8 @@ int ha_partition::drop_partitions(const char *path) ...@@ -610,7 +611,8 @@ int ha_partition::drop_partitions(const char *path)
sub_elem->partition_name, name_variant); sub_elem->partition_name, name_variant);
file= m_file[part]; file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff)); 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); } while (++j < no_subparts);
} }
else else
...@@ -620,7 +622,8 @@ int ha_partition::drop_partitions(const char *path) ...@@ -620,7 +622,8 @@ int ha_partition::drop_partitions(const char *path)
TRUE); TRUE);
file= m_file[i]; file= m_file[i];
DBUG_PRINT("info", ("Drop partition %s", part_name_buff)); 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) if (part_elem->part_state == PART_IS_CHANGED)
part_elem->part_state= PART_NORMAL; part_elem->part_state= PART_NORMAL;
...@@ -663,6 +666,7 @@ int ha_partition::rename_partitions(const char *path) ...@@ -663,6 +666,7 @@ int ha_partition::rename_partitions(const char *path)
uint i= 0; uint i= 0;
uint j= 0; uint j= 0;
int error= 0; int error= 0;
int ret_error;
uint temp_partitions= m_part_info->temp_partitions.elements; uint temp_partitions= m_part_info->temp_partitions.elements;
handler *file; handler *file;
partition_element *part_elem, *sub_elem; partition_element *part_elem, *sub_elem;
...@@ -693,8 +697,9 @@ int ha_partition::rename_partitions(const char *path) ...@@ -693,8 +697,9 @@ int ha_partition::rename_partitions(const char *path)
sub_elem->partition_name, sub_elem->partition_name,
NORMAL_PART_NAME); NORMAL_PART_NAME);
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if (file->delete_table((const char *) norm_name_buff) || if ((ret_error= file->delete_table((const char *) norm_name_buff)))
inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= ret_error;
else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
sub_elem->log_entry= NULL; /* Indicate success */ sub_elem->log_entry= NULL; /* Indicate success */
...@@ -707,8 +712,9 @@ int ha_partition::rename_partitions(const char *path) ...@@ -707,8 +712,9 @@ int ha_partition::rename_partitions(const char *path)
part_elem->partition_name, NORMAL_PART_NAME, part_elem->partition_name, NORMAL_PART_NAME,
TRUE); TRUE);
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if (file->delete_table((const char *) norm_name_buff) || if ((ret_error= file->delete_table((const char *) norm_name_buff)))
inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= ret_error;
else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
sub_elem->log_entry= NULL; /* Indicate success */ sub_elem->log_entry= NULL; /* Indicate success */
...@@ -761,8 +767,9 @@ int ha_partition::rename_partitions(const char *path) ...@@ -761,8 +767,9 @@ int ha_partition::rename_partitions(const char *path)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if (file->delete_table((const char *) norm_name_buff) || if ((ret_error= file->delete_table((const char *) norm_name_buff)))
inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= ret_error;
else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
VOID(sync_table_log()); VOID(sync_table_log());
} }
...@@ -773,9 +780,10 @@ int ha_partition::rename_partitions(const char *path) ...@@ -773,9 +780,10 @@ int ha_partition::rename_partitions(const char *path)
TEMP_PART_NAME); TEMP_PART_NAME);
DBUG_PRINT("info", ("Rename subpartition from %s to %s", DBUG_PRINT("info", ("Rename subpartition from %s to %s",
part_name_buff, norm_name_buff)); part_name_buff, norm_name_buff));
if (file->rename_table((const char *) norm_name_buff, if ((ret_error= file->rename_table((const char *) norm_name_buff,
(const char *) part_name_buff) || (const char *) part_name_buff)))
inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) error= ret_error;
else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
sub_elem->log_entry= NULL; sub_elem->log_entry= NULL;
...@@ -790,8 +798,9 @@ int ha_partition::rename_partitions(const char *path) ...@@ -790,8 +798,9 @@ int ha_partition::rename_partitions(const char *path)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if (file->delete_table((const char *) norm_name_buff) || if ((ret_error= file->delete_table((const char *) norm_name_buff)))
inactivate_table_log_entry(part_elem->log_entry->entry_pos)) error= ret_error;
else if (inactivate_table_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
VOID(sync_table_log()); VOID(sync_table_log());
} }
...@@ -801,9 +810,10 @@ int ha_partition::rename_partitions(const char *path) ...@@ -801,9 +810,10 @@ int ha_partition::rename_partitions(const char *path)
TRUE); TRUE);
DBUG_PRINT("info", ("Rename partition from %s to %s", DBUG_PRINT("info", ("Rename partition from %s to %s",
part_name_buff, norm_name_buff)); part_name_buff, norm_name_buff));
if (file->rename_table((const char *) norm_name_buff, if ((ret_error= file->rename_table((const char *) norm_name_buff,
(const char *) part_name_buff) || (const char *) part_name_buff)))
inactivate_table_log_entry(part_elem->log_entry->entry_pos)) error= ret_error;
else if (inactivate_table_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
part_elem->log_entry= NULL; part_elem->log_entry= NULL;
......
...@@ -4975,10 +4975,13 @@ the generated partition syntax in a correct manner. ...@@ -4975,10 +4975,13 @@ the generated partition syntax in a correct manner.
static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
char path[FN_REFLEN+1]; char path[FN_REFLEN+1];
int error;
handler *file= lpt->table->file;
DBUG_ENTER("mysql_change_partitions"); DBUG_ENTER("mysql_change_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "");
DBUG_RETURN(lpt->table->file->change_partitions(lpt->create_info, path, DBUG_RETURN(file->change_partitions(lpt->create_info,
path,
&lpt->copied, &lpt->copied,
&lpt->deleted, &lpt->deleted,
lpt->pack_frm_data, lpt->pack_frm_data,
...@@ -5008,10 +5011,17 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) ...@@ -5008,10 +5011,17 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
char path[FN_REFLEN+1]; char path[FN_REFLEN+1];
int error;
DBUG_ENTER("mysql_rename_partitions"); DBUG_ENTER("mysql_rename_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); 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) ...@@ -5042,11 +5052,13 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
List_iterator<partition_element> part_it(part_info->partitions); List_iterator<partition_element> part_it(part_info->partitions);
uint i= 0; uint i= 0;
uint remove_count= 0; uint remove_count= 0;
int error;
DBUG_ENTER("mysql_drop_partitions"); DBUG_ENTER("mysql_drop_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, ""); 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); DBUG_RETURN(TRUE);
} }
do do
...@@ -5920,6 +5932,31 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ...@@ -5920,6 +5932,31 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
abort(); abort();
if (!not_completed) if (!not_completed)
abort(); 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); fast_alter_partition_error_handler(lpt);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
......
...@@ -320,7 +320,8 @@ read_table_log_file_entry(uint entry_no) ...@@ -320,7 +320,8 @@ read_table_log_file_entry(uint entry_no)
uint io_size= global_table_log.io_size; uint io_size= global_table_log.io_size;
DBUG_ENTER("read_table_log_file_entry"); 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; error= TRUE;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -346,7 +347,7 @@ write_table_log_file_entry(uint entry_no) ...@@ -346,7 +347,7 @@ write_table_log_file_entry(uint entry_no)
DBUG_ENTER("write_table_log_file_entry"); DBUG_ENTER("write_table_log_file_entry");
if (my_pwrite(file_id, 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; error= TRUE;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -383,7 +384,7 @@ write_table_log_header() ...@@ -383,7 +384,7 @@ write_table_log_header()
if (write_table_log_file_entry(0UL)) if (write_table_log_file_entry(0UL))
error= TRUE; error= TRUE;
if (!error) if (!error)
error= sync_table_log(); VOID(sync_table_log());
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -430,7 +431,7 @@ read_table_log_header() ...@@ -430,7 +431,7 @@ read_table_log_header()
bzero(file_entry, sizeof(global_table_log.file_entry)); bzero(file_entry, sizeof(global_table_log.file_entry));
create_table_log_file_name(file_name); 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)) if (read_table_log_file_entry(0UL))
{ {
...@@ -517,7 +518,7 @@ init_table_log() ...@@ -517,7 +518,7 @@ init_table_log()
if ((global_table_log.file_id= my_create(file_name, if ((global_table_log.file_id= my_create(file_name,
CREATE_MODE, CREATE_MODE,
O_RDWR | O_TRUNC | O_BINARY, O_RDWR | O_TRUNC | O_BINARY,
MYF(0))) < 0) MYF(MY_WME))) < 0)
{ {
/* Couldn't create table log file, this is serious error */ /* Couldn't create table log file, this is serious error */
abort(); abort();
...@@ -564,6 +565,7 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) ...@@ -564,6 +565,7 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
hton= ha_resolve_by_name(current_thd, handler_name); hton= ha_resolve_by_name(current_thd, handler_name);
if (!hton) if (!hton)
{ {
my_error(ER_ILLEGAL_HA, table_log_entry->handler_type);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
...@@ -573,8 +575,11 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) ...@@ -573,8 +575,11 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
{ {
file= get_new_handler(table_share, &mem_root, hton); file= get_new_handler(table_share, &mem_root, hton);
if (!file) if (!file)
{
mem_alloc_error(sizeof(handler));
goto error; goto error;
} }
}
switch (table_log_entry->action_type) switch (table_log_entry->action_type)
case TLOG_ACTION_DELETE_CODE: case TLOG_ACTION_DELETE_CODE:
case TLOG_ACTION_REPLACE_CODE: case TLOG_ACTION_REPLACE_CODE:
...@@ -585,20 +590,24 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) ...@@ -585,20 +590,24 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
if (frm_action) if (frm_action)
{ {
strxmov(path, table_log_entry->name, reg_ext, NullS); 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); strxmov(path, table_log_entry->name, par_ext, NullS);
VOID(my_delete(path, MYF(0))); if (my_delete(path, MYF(MY_WME)))
break;
} }
else else
{ {
if (file->delete_table(table_name)) if (file->delete_table(table_name))
break; break;
} }
if ((!inactivate_table_log_entry(table_log_entry->entry_pos)) && if ((!inactivate_table_log_entry(table_log_entry->entry_pos)))
(!sync_table_log()))
; ;
else else
{
VOID(sync_table_log());
error= FALSE; error= FALSE;
}
break; break;
} }
if (table_log_entry->action_type == TLOG_ACTION_DELETE_CODE) if (table_log_entry->action_type == TLOG_ACTION_DELETE_CODE)
...@@ -609,11 +618,11 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) ...@@ -609,11 +618,11 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
{ {
strxmov(path, table_log_entry->name, reg_ext, NullS); strxmov(path, table_log_entry->name, reg_ext, NullS);
strxmov(from_path, table_log_entry->from_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; break;
strxmov(path, table_log_entry->name, par_ext, NullS); strxmov(path, table_log_entry->name, par_ext, NullS);
strxmov(from_path, table_log_entry->from_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; break;
} }
else else
...@@ -621,12 +630,14 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) ...@@ -621,12 +630,14 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
if (file->rename_table(table_log_entry->name, if (file->rename_table(table_log_entry->name,
table_log_entry->from_name)) table_log_entry->from_name))
break; break;
if ((!inactivate_table_log_entry(table_log_entry->entry_pos)) && if ((!inactivate_table_log_entry(table_log_entry->entry_pos)))
(!sync_table_log()))
; ;
else else
{
VOID(sync_table_log());
error= FALSE; error= FALSE;
} }
}
break; break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
...@@ -662,7 +673,7 @@ get_free_table_log_entry(TABLE_LOG_MEMORY_ENTRY **active_entry, ...@@ -662,7 +673,7 @@ get_free_table_log_entry(TABLE_LOG_MEMORY_ENTRY **active_entry,
if (global_table_log.first_free == NULL) if (global_table_log.first_free == NULL)
{ {
if (!(used_entry= (TABLE_LOG_MEMORY_ENTRY*)my_malloc( 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); DBUG_RETURN(TRUE);
} }
...@@ -748,7 +759,8 @@ write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry, ...@@ -748,7 +759,8 @@ write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry,
error= TRUE; error= TRUE;
if (write_header && !error) if (write_header && !error)
{ {
if (sync_table_log() || write_table_log_header()) VOID(sync_table_log());
if (write_table_log_header())
error= TRUE; error= TRUE;
} }
if (error) if (error)
...@@ -1232,7 +1244,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) ...@@ -1232,7 +1244,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (my_delete(frm_name, MYF(MY_WME)) || if (my_delete(frm_name, MYF(MY_WME)) ||
inactivate_table_log_entry(part_info->frm_log_entry->entry_pos) || 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)) || my_rename(shadow_frm_name, frm_name, MYF(MY_WME)) ||
lpt->table->file->create_handler_files(path, shadow_path, TRUE)) lpt->table->file->create_handler_files(path, shadow_path, TRUE))
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment