diff options
author | Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> | 2021-10-29 19:04:53 +0900 |
---|---|---|
committer | Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> | 2022-03-24 14:53:11 +0900 |
commit | fe75fbd68e861eada772eff05f20945d824e18ce (patch) | |
tree | 7e1e1e4e4a9eaa398ceca10febf420b926722bac | |
parent | 6277e7df6b84f6d5931dab66d3edf8859d5b16d3 (diff) | |
download | mariadb-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.inc | 14 | ||||
-rw-r--r-- | mysql-test/suite/parts/r/partition_alter_innodb.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/parts/r/partition_alter_maria.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/parts/r/partition_alter_myisam.result | 10 | ||||
-rw-r--r-- | sql/sql_partition.cc | 23 |
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); } |