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:
@ -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 @@ 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(). */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user