Skip to content

Commit

Permalink
MDEV-26127 Assertion `err != DB_DUPLICATE_KEY' failed or InnoDB: Fail…
Browse files Browse the repository at this point in the history
…ing assertion: id != 0 on ALTER ... REBUILD PARTITION

During rebuild of partition, the partitioning engine calls
alter_close_table(), which does not unlock and close some table
instances of the target table.
Then, the engine fails to rename partitions because there are table
instances that are still locked.

Closing all the table instance of the target table fixes the bug.
  • Loading branch information
nayuta-yanagisawa committed Jun 13, 2022
1 parent d4760d8 commit 06e9ce7
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 9 deletions.
8 changes: 8 additions & 0 deletions mysql-test/suite/parts/inc/part_alter_values.inc
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,11 @@ if (`SELECT IF('$engine' != 'InnoDB', 1, 0)`)

--remove_files_wildcard $MYSQLTEST_VARDIR/tmp/mdev_27065 *
--rmdir $MYSQLTEST_VARDIR/tmp/mdev_27065

--echo #
--echo # MDEV-26127 Assertion `err != DB_DUPLICATE_KEY' failed or InnoDB: Failing assertion: id != 0 on ALTER ... REBUILD PARTITION
--echo #
--eval CREATE TABLE t1 (c INT) ENGINE=$engine PARTITION BY KEY(c) PARTITIONS 4;
LOCK TABLES t1 WRITE, t1 AS a READ;
ALTER TABLE t1 REBUILD PARTITION p0;
DROP TABLE t1;
7 changes: 7 additions & 0 deletions mysql-test/suite/parts/r/partition_alter_innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,10 @@ PARTITION p1 VALUES LESS THAN MAXVALUE
Warnings:
Warning 1618 <DATA DIRECTORY> table option of old schema is ignored
DROP TABLE t1;
#
# MDEV-26127 Assertion `err != DB_DUPLICATE_KEY' failed or InnoDB: Failing assertion: id != 0 on ALTER ... REBUILD PARTITION
#
CREATE TABLE t1 (c INT) ENGINE=InnoDB PARTITION BY KEY(c) PARTITIONS 4;;
LOCK TABLES t1 WRITE, t1 AS a READ;
ALTER TABLE t1 REBUILD PARTITION p0;
DROP TABLE t1;
7 changes: 7 additions & 0 deletions mysql-test/suite/parts/r/partition_alter_maria.result
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,10 @@ PARTITION p1 VALUES LESS THAN MAXVALUE
Warnings:
Warning 1618 <INDEX DIRECTORY> table option of old schema is ignored
DROP TABLE t2;
#
# MDEV-26127 Assertion `err != DB_DUPLICATE_KEY' failed or InnoDB: Failing assertion: id != 0 on ALTER ... REBUILD PARTITION
#
CREATE TABLE t1 (c INT) ENGINE=Aria PARTITION BY KEY(c) PARTITIONS 4;;
LOCK TABLES t1 WRITE, t1 AS a READ;
ALTER TABLE t1 REBUILD PARTITION p0;
DROP TABLE t1;
7 changes: 7 additions & 0 deletions mysql-test/suite/parts/r/partition_alter_myisam.result
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ PARTITION p1 VALUES LESS THAN MAXVALUE
Warnings:
Warning 1618 <INDEX DIRECTORY> table option of old schema is ignored
DROP TABLE t2;
#
# MDEV-26127 Assertion `err != DB_DUPLICATE_KEY' failed or InnoDB: Failing assertion: id != 0 on ALTER ... REBUILD PARTITION
#
CREATE TABLE t1 (c INT) ENGINE=MyISAM PARTITION BY KEY(c) PARTITIONS 4;;
LOCK TABLES t1 WRITE, t1 AS a READ;
ALTER TABLE t1 REBUILD PARTITION p0;
DROP TABLE t1;
create table t1 ( c1 int, c2 int, c3 varchar(100)) delay_key_write=1
partition by key(c1) (
partition p01 data directory = 'MYSQL_TMP_DIR'
Expand Down
35 changes: 26 additions & 9 deletions sql/sql_partition.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (c) 2005, 2017, Oracle and/or its affiliates.
Copyright (c) 2009, 2020, MariaDB
Copyright (c) 2009, 2022, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -6817,16 +6817,33 @@ static bool alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)

static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
{
int error= 0;
THD *thd= lpt->thd;
TABLE_SHARE *share= lpt->table->s;
DBUG_ENTER("alter_close_table");

if (lpt->table->db_stat)
{
error= mysql_lock_remove(lpt->thd, lpt->thd->lock, lpt->table);
error= lpt->table->file->ha_close();
lpt->table->db_stat= 0; // Mark file closed
}
DBUG_RETURN(error);
TABLE *table= thd->open_tables;
do {
table= find_locked_table(table, share->db.str, share->table_name.str);
if (!table)
{
DBUG_RETURN(0);
}

if (table->db_stat)
{
if (int error= mysql_lock_remove(thd, thd->lock, table))
{
DBUG_RETURN(error);
}
if (int error= table->file->ha_close())
{
DBUG_RETURN(error);
}
table->db_stat= 0; // Mark file closed
}
} while ((table= table->next));

DBUG_RETURN(0);
}


Expand Down

0 comments on commit 06e9ce7

Please sign in to comment.