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-06-13 23:43:48 +0900
commite077ce2a68a418d0f4cbe32f9311cf235ee1578c (patch)
tree216d75915d16238ec5db9f479f4ea72ca433df49
parentb59bc629c8cef1e3e07529007dca2948b812e8fb (diff)
downloadmariadb-git-e077ce2a68a418d0f4cbe32f9311cf235ee1578c.tar.gz
MDEV-26127 Assertion `err != DB_DUPLICATE_KEY' failed or InnoDB: Failing 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.
-rw-r--r--mysql-test/suite/parts/inc/part_alter_values.inc8
-rw-r--r--mysql-test/suite/parts/r/partition_alter_innodb.result7
-rw-r--r--mysql-test/suite/parts/r/partition_alter_maria.result7
-rw-r--r--mysql-test/suite/parts/r/partition_alter_myisam.result7
-rw-r--r--sql/sql_partition.cc29
5 files changed, 51 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 ca18faa5758..d3b63a4610f 100644
--- a/mysql-test/suite/parts/inc/part_alter_values.inc
+++ b/mysql-test/suite/parts/inc/part_alter_values.inc
@@ -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;
diff --git a/mysql-test/suite/parts/r/partition_alter_innodb.result b/mysql-test/suite/parts/r/partition_alter_innodb.result
index ae3caaa4981..6afa133f989 100644
--- a/mysql-test/suite/parts/r/partition_alter_innodb.result
+++ b/mysql-test/suite/parts/r/partition_alter_innodb.result
@@ -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;
diff --git a/mysql-test/suite/parts/r/partition_alter_maria.result b/mysql-test/suite/parts/r/partition_alter_maria.result
index 358ffbdfbe7..eca8378430f 100644
--- a/mysql-test/suite/parts/r/partition_alter_maria.result
+++ b/mysql-test/suite/parts/r/partition_alter_maria.result
@@ -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;
diff --git a/mysql-test/suite/parts/r/partition_alter_myisam.result b/mysql-test/suite/parts/r/partition_alter_myisam.result
index 9d76881fdfa..ba1a0fe05c4 100644
--- a/mysql-test/suite/parts/r/partition_alter_myisam.result
+++ b/mysql-test/suite/parts/r/partition_alter_myisam.result
@@ -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'
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 778a3177360..4a0a55f8178 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
@@ -6929,14 +6929,29 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
{
+ THD *thd= lpt->thd;
+ TABLE_SHARE *share= lpt->table->s;
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
- }
+ 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)
+ {
+ mysql_lock_remove(thd, thd->lock, table);
+ if (int error= table->file->ha_close())
+ {
+ DBUG_RETURN(error);
+ }
+ table->db_stat= 0; // Mark file closed
+ }
+ } while ((table= table->next));
+
DBUG_RETURN(0);
}