mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +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 `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());
|
|||||||
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 @@ private:
|
|||||||
|
|
||||||
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,
|
|||||||
/* 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,
|
|||||||
}
|
}
|
||||||
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.
|
|||||||
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.
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user