summaryrefslogtreecommitdiff
path: root/sql/sql_partition.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r--sql/sql_partition.cc705
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;