1
0
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:
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 `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;

View File

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

View File

@ -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(). */

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 */ /* 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);
} }