1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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.
This commit is contained in:
Aleksey Midenkov
2018-01-03 19:47:01 +03:00
parent dbf21ff396
commit daf883f95c
4 changed files with 35 additions and 2 deletions

View File

@ -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;

View File

@ -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;

View File

@ -1797,8 +1797,9 @@ private:
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(). */

View File

@ -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);
}