Commit daf883f9 authored by Aleksey Midenkov's avatar Aleksey Midenkov

MDEV-14817 Server crashes in prep_alter_part_table() after table lock and...

MDEV-14817 Server crashes in prep_alter_part_table() after table lock and multiple add partition [fixes #440]

Cause: `table->part_info` is stale after `prep_alter_part_table()` while
`table->m_needs_reopen == true`.

Fix: restore `table->part_info` in case of error in `prep_alter_part_table()`.

Tested with main, parts, innodb suites.
parent dbf21ff3
......@@ -120,3 +120,10 @@ t1 CREATE TABLE `t1` (
PARTITION `p02` ENGINE = MyISAM,
PARTITION `p03` ENGINE = MyISAM)
drop table t1;
create or replace table t1 (x int) partition by hash (x) (partition p1, partition p2);
lock table t1 write;
alter table t1 add partition (partition p1);
ERROR HY000: Duplicate partition name p1
alter table t1 add partition (partition p1);
ERROR HY000: Duplicate partition name p1
drop table t1;
......@@ -114,3 +114,14 @@ insert into t1 values(0, 1, 1, NULL, now(), now());
alter online table t1 delay_key_write=1;
show create table t1;
drop table t1;
#
# MDEV-14817 Server crashes in prep_alter_part_table() after table lock and multiple add partition
#
create or replace table t1 (x int) partition by hash (x) (partition p1, partition p2);
lock table t1 write;
--error ER_SAME_NAME_PARTITION
alter table t1 add partition (partition p1);
--error ER_SAME_NAME_PARTITION
alter table t1 add partition (partition p1);
drop table t1;
......@@ -1797,8 +1797,9 @@ class MDL_deadlock_and_lock_abort_error_handler: public Internal_error_handler
class Locked_tables_list
{
private:
public:
MEM_ROOT m_locked_tables_root;
private:
TABLE_LIST *m_locked_tables;
TABLE_LIST **m_locked_tables_last;
/** An auxiliary array used only in reopen_tables(). */
......
......@@ -4573,6 +4573,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
/* ALTER_ADMIN_PARTITION is handled in mysql_admin_table */
DBUG_ASSERT(!(alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION));
partition_info *saved_part_info= NULL;
if (alter_info->flags &
(Alter_info::ALTER_ADD_PARTITION |
Alter_info::ALTER_DROP_PARTITION |
......@@ -4778,6 +4780,16 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
}
if (alter_info->flags & Alter_info::ALTER_ADD_PARTITION)
{
if (*fast_alter_table && thd->locked_tables_mode)
{
MEM_ROOT *old_root= thd->mem_root;
thd->mem_root= &thd->locked_tables_list.m_locked_tables_root;
saved_part_info= tab_part_info->get_clone(thd);
thd->mem_root= old_root;
saved_part_info->read_partitions= tab_part_info->read_partitions;
saved_part_info->lock_partitions= tab_part_info->lock_partitions;
saved_part_info->bitmaps_are_initialized= tab_part_info->bitmaps_are_initialized;
}
/*
We start by moving the new partitions to the list of temporary
partitions. We will then check that the new partitions fit in the
......@@ -5472,7 +5484,7 @@ the generated partition syntax in a correct manner.
goto err;
}
}
}
} // ADD, DROP, COALESCE, REORGANIZE, TABLE_REORG, REBUILD
else
{
/*
......@@ -5638,6 +5650,8 @@ the generated partition syntax in a correct manner.
DBUG_RETURN(FALSE);
err:
*fast_alter_table= false;
if (saved_part_info)
table->part_info= saved_part_info;
DBUG_RETURN(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