summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNayuta Yanagisawa <nayuta.yanagisawa@hey.com>2021-10-29 19:04:53 +0900
committerNayuta Yanagisawa <nayuta.yanagisawa@hey.com>2022-03-24 14:53:11 +0900
commitfe75fbd68e861eada772eff05f20945d824e18ce (patch)
tree7e1e1e4e4a9eaa398ceca10febf420b926722bac
parent6277e7df6b84f6d5931dab66d3edf8859d5b16d3 (diff)
downloadmariadb-git-bb-10.2-MDEV-26127.tar.gz
MDEV-26127 Assertion `err != DB_DUPLICATE_KEY' failed or InnoDB: Failing assertion: id != 0 on ALTER ... REBUILD PARTITIONbb-10.2-MDEV-26127
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.
-rw-r--r--mysql-test/suite/parts/inc/part_alter_values.inc14
-rw-r--r--mysql-test/suite/parts/r/partition_alter_innodb.result10
-rw-r--r--mysql-test/suite/parts/r/partition_alter_maria.result10
-rw-r--r--mysql-test/suite/parts/r/partition_alter_myisam.result10
-rw-r--r--sql/sql_partition.cc23
5 files changed, 60 insertions, 7 deletions
diff --git a/mysql-test/suite/parts/inc/part_alter_values.inc b/mysql-test/suite/parts/inc/part_alter_values.inc
index ac69169a9ca..20f3e063ba1 100644
--- a/mysql-test/suite/parts/inc/part_alter_values.inc
+++ b/mysql-test/suite/parts/inc/part_alter_values.inc
@@ -36,12 +36,20 @@ ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
);
DROP TABLE t1;
-#
-# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
-#
+--echo #
+--echo # MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
+--echo #
--eval create table t1 (i int) engine=$engine partition by range(i) (partition p0 values less than (10))
lock table t1 write;
--error ER_SAME_NAME_PARTITION
alter table t1 add partition (partition p0 values less than (20));
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
drop table t1;
+
+--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;
diff --git a/mysql-test/suite/parts/r/partition_alter_innodb.result b/mysql-test/suite/parts/r/partition_alter_innodb.result
index f3921a1db26..5d02ce4c00e 100644
--- a/mysql-test/suite/parts/r/partition_alter_innodb.result
+++ b/mysql-test/suite/parts/r/partition_alter_innodb.result
@@ -42,9 +42,19 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
+#
+# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
+#
create table t1 (i int) engine=InnoDB partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
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;
diff --git a/mysql-test/suite/parts/r/partition_alter_maria.result b/mysql-test/suite/parts/r/partition_alter_maria.result
index 77f511d9b3b..a49639482c0 100644
--- a/mysql-test/suite/parts/r/partition_alter_maria.result
+++ b/mysql-test/suite/parts/r/partition_alter_maria.result
@@ -69,9 +69,19 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
+#
+# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
+#
create table t1 (i int) engine=Aria partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
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=Aria PARTITION BY KEY(c) PARTITIONS 4;;
+LOCK TABLES t1 WRITE, t1 AS a READ;
+ALTER TABLE t1 REBUILD PARTITION p0;
+DROP TABLE t1;
diff --git a/mysql-test/suite/parts/r/partition_alter_myisam.result b/mysql-test/suite/parts/r/partition_alter_myisam.result
index ce3e04d6c97..afbb4c21353 100644
--- a/mysql-test/suite/parts/r/partition_alter_myisam.result
+++ b/mysql-test/suite/parts/r/partition_alter_myisam.result
@@ -42,12 +42,22 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
+#
+# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
+#
create table t1 (i int) engine=MyISAM partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
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=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'
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 2334286b039..2453e0da159 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2005, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2018, 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
@@ -6408,13 +6408,28 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
{
+ TABLE_SHARE *share= lpt->table->s;
+ char key[MAX_DBKEY_LENGTH];
+ size_t key_length= share->table_cache_key.length;
+ memcpy(key, share->table_cache_key.str, key_length);
+ int error= 0;
DBUG_ENTER("alter_close_table");
if (lpt->table->db_stat)
{
- mysql_lock_remove(lpt->thd, lpt->thd->lock, lpt->table);
- lpt->table->file->ha_close();
- lpt->table->db_stat= 0; // Mark file closed
+ for (TABLE *table= lpt->thd->open_tables; table; (table= table->next))
+ {
+ if (table->s->table_cache_key.length == key_length &&
+ !memcmp(table->s->table_cache_key.str, key, key_length))
+ {
+ mysql_lock_remove(lpt->thd, lpt->thd->lock, table);
+ if ((error= table->file->ha_close()))
+ {
+ DBUG_RETURN(error);
+ }
+ table->db_stat= 0; // Mark file closed
+ }
+ }
}
DBUG_RETURN(0);
}