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` ( ...@@ -120,3 +120,10 @@ t1 CREATE TABLE `t1` (
PARTITION `p02` ENGINE = MyISAM, PARTITION `p02` ENGINE = MyISAM,
PARTITION `p03` ENGINE = MyISAM) PARTITION `p03` ENGINE = MyISAM)
drop table t1; 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()); ...@@ -114,3 +114,14 @@ insert into t1 values(0, 1, 1, NULL, now(), now());
alter online table t1 delay_key_write=1; alter online table t1 delay_key_write=1;
show create table t1; show create table t1;
drop 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 ...@@ -1797,8 +1797,9 @@ class MDL_deadlock_and_lock_abort_error_handler: public Internal_error_handler
class Locked_tables_list class Locked_tables_list
{ {
private: public:
MEM_ROOT m_locked_tables_root; MEM_ROOT m_locked_tables_root;
private:
TABLE_LIST *m_locked_tables; TABLE_LIST *m_locked_tables;
TABLE_LIST **m_locked_tables_last; TABLE_LIST **m_locked_tables_last;
/** An auxiliary array used only in reopen_tables(). */ /** 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, ...@@ -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 */ /* ALTER_ADMIN_PARTITION is handled in mysql_admin_table */
DBUG_ASSERT(!(alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION)); DBUG_ASSERT(!(alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION));
partition_info *saved_part_info= NULL;
if (alter_info->flags & if (alter_info->flags &
(Alter_info::ALTER_ADD_PARTITION | (Alter_info::ALTER_ADD_PARTITION |
Alter_info::ALTER_DROP_PARTITION | Alter_info::ALTER_DROP_PARTITION |
...@@ -4778,6 +4780,16 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, ...@@ -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 (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 We start by moving the new partitions to the list of temporary
partitions. We will then check that the new partitions fit in the partitions. We will then check that the new partitions fit in the
...@@ -5472,7 +5484,7 @@ the generated partition syntax in a correct manner. ...@@ -5472,7 +5484,7 @@ the generated partition syntax in a correct manner.
goto err; goto err;
} }
} }
} } // ADD, DROP, COALESCE, REORGANIZE, TABLE_REORG, REBUILD
else else
{ {
/* /*
...@@ -5638,6 +5650,8 @@ the generated partition syntax in a correct manner. ...@@ -5638,6 +5650,8 @@ the generated partition syntax in a correct manner.
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
err: err:
*fast_alter_table= false; *fast_alter_table= false;
if (saved_part_info)
table->part_info= saved_part_info;
DBUG_RETURN(TRUE); 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