mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Bug#56172: Server crashes in ha_partition::reset on
REBUILD PARTITION under LOCK TABLE Collapsed patch including updates from the reviews. In case of failure in ALTER ... PARTITION under LOCK TABLE the server could crash, due to it had modified the locked table object, which was not reverted in case of failure, resulting in a bad table definition used after the failed command. Solved by instead of altering the locked table object and its partition_info struct, creating an internal temporary intermediate table object used for altering, just like the non partitioned mysql_alter_table. So if an error occur before the alter operation is complete, the original table is not modified at all. But if the alter operation have succeeded so far that it must be completed as whole, the table is properly closed and reopened. (The completion on failure is done by the ddl_log.)
This commit is contained in:
@@ -1725,8 +1725,6 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
||||
CHF_DELETE_FLAG, NULL) ||
|
||||
deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) ||
|
||||
(sync_ddl_log(), FALSE) ||
|
||||
#endif
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
mysql_file_rename(key_file_frm,
|
||||
shadow_frm_name, frm_name, MYF(MY_WME)) ||
|
||||
lpt->table->file->ha_create_handler_files(path, shadow_path,
|
||||
@@ -5599,7 +5597,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
handlerton *old_db_type, *new_db_type, *save_old_db_type;
|
||||
enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
uint fast_alter_partition= 0;
|
||||
TABLE *table_for_fast_alter_partition= NULL;
|
||||
bool partition_changed= FALSE;
|
||||
#endif
|
||||
bool need_lock_for_indexes= TRUE;
|
||||
@@ -5968,7 +5966,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type,
|
||||
&partition_changed, &fast_alter_partition))
|
||||
&partition_changed,
|
||||
db, table_name, path,
|
||||
&table_for_fast_alter_partition))
|
||||
goto err;
|
||||
#endif
|
||||
/*
|
||||
@@ -6201,12 +6201,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
create_info->frm_only= 1;
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (fast_alter_partition)
|
||||
if (table_for_fast_alter_partition)
|
||||
{
|
||||
DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
|
||||
create_info, table_list,
|
||||
db, table_name,
|
||||
fast_alter_partition));
|
||||
table_for_fast_alter_partition));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6686,6 +6686,11 @@ err_new_table_cleanup:
|
||||
create_info->frm_only ? FN_IS_TMP | FRM_ONLY : FN_IS_TMP);
|
||||
|
||||
err:
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/* If prep_alter_part_table created an intermediate table, destroy it. */
|
||||
if (table_for_fast_alter_partition)
|
||||
close_temporary(table_for_fast_alter_partition, 1, 0);
|
||||
#endif /* WITH_PARTITION_STORAGE_ENGINE */
|
||||
/*
|
||||
No default value was provided for a DATE/DATETIME field, the
|
||||
current sql_mode doesn't allow the '0000-00-00' value and
|
||||
|
||||
Reference in New Issue
Block a user