summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/partition_innodb_plugin.result73
-rw-r--r--mysql-test/t/partition_innodb_plugin.test66
-rw-r--r--sql/sql_partition.cc21
3 files changed, 159 insertions, 1 deletions
diff --git a/mysql-test/r/partition_innodb_plugin.result b/mysql-test/r/partition_innodb_plugin.result
index dd91eee316a..f6b5ce84338 100644
--- a/mysql-test/r/partition_innodb_plugin.result
+++ b/mysql-test/r/partition_innodb_plugin.result
@@ -1,3 +1,76 @@
+call mtr.add_suppression("nnoDB: Error: table `test`.`t1` .* Partition.* InnoDB internal");
+#
+# Bug#55091: Server crashes on ADD PARTITION after a failed attempt
+#
+SET @old_innodb_file_format_check = @@global.innodb_file_format_check;
+SET @old_innodb_file_format = @@global.innodb_file_format;
+SET @old_innodb_file_per_table = @@global.innodb_file_per_table;
+SET @old_innodb_strict_mode = @@global.innodb_strict_mode;
+SET @@global.innodb_file_format = Barracuda,
+@@global.innodb_file_per_table = ON,
+@@global.innodb_strict_mode = ON;
+# Connection con1
+CREATE TABLE t1 (id INT NOT NULL
+PRIMARY KEY,
+user_num CHAR(10)
+) ENGINE = InnoDB
+KEY_BLOCK_SIZE=4
+PARTITION BY HASH(id) PARTITIONS 1;
+t1#P#p0.ibd
+t1.frm
+t1.par
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `user_num` char(10) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=4
+/*!50100 PARTITION BY HASH (id)
+PARTITIONS 1 */
+SET GLOBAL innodb_file_per_table = OFF;
+# Connection con2
+LOCK TABLE t1 WRITE;
+# ALTER fails because COMPRESSED/KEY_BLOCK_SIZE
+# are incompatible with innodb_file_per_table = OFF;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 1;
+ERROR HY000: Got error 1478 from storage engine
+t1#P#p0.ibd
+t1.frm
+t1.par
+# This SET is not needed to reproduce the bug,
+# it is here just to make the test case more realistic
+SET innodb_strict_mode = OFF;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+Warnings:
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4.
+t1.frm
+t1.par
+ALTER TABLE t1 REBUILD PARTITION p0;
+Warnings:
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=4.
+UNLOCK TABLES;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `user_num` char(10) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=4
+/*!50100 PARTITION BY HASH (id)
+PARTITIONS 3 */
+DROP TABLE t1;
+# Connection default
+SET @@global.innodb_strict_mode = @old_innodb_strict_mode;
+SET @@global.innodb_file_format = @old_innodb_file_format;
+SET @@global.innodb_file_per_table = @old_innodb_file_per_table;
+SET @@global.innodb_file_format_check = @old_innodb_file_format_check;
SET NAMES utf8;
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
ENGINE=InnoDB
diff --git a/mysql-test/t/partition_innodb_plugin.test b/mysql-test/t/partition_innodb_plugin.test
index eeb990c0d81..114adf67180 100644
--- a/mysql-test/t/partition_innodb_plugin.test
+++ b/mysql-test/t/partition_innodb_plugin.test
@@ -1,5 +1,71 @@
--source include/have_partition.inc
--source include/have_innodb_plugin.inc
+# Remove the line below when bug#53307 is solved.
+--source include/not_valgrind.inc
+
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+
+call mtr.add_suppression("nnoDB: Error: table `test`.`t1` .* Partition.* InnoDB internal");
+--echo #
+--echo # Bug#55091: Server crashes on ADD PARTITION after a failed attempt
+--echo #
+SET @old_innodb_file_format_check = @@global.innodb_file_format_check;
+SET @old_innodb_file_format = @@global.innodb_file_format;
+SET @old_innodb_file_per_table = @@global.innodb_file_per_table;
+SET @old_innodb_strict_mode = @@global.innodb_strict_mode;
+SET @@global.innodb_file_format = Barracuda,
+@@global.innodb_file_per_table = ON,
+@@global.innodb_strict_mode = ON;
+
+--echo # Connection con1
+--connect(con1,localhost,root,,)
+
+CREATE TABLE t1 (id INT NOT NULL
+PRIMARY KEY,
+user_num CHAR(10)
+) ENGINE = InnoDB
+KEY_BLOCK_SIZE=4
+PARTITION BY HASH(id) PARTITIONS 1;
+
+--list_files $MYSQLD_DATADIR/test
+SHOW CREATE TABLE t1;
+
+SET GLOBAL innodb_file_per_table = OFF;
+
+--disconnect con1
+--connect(con2,localhost,root,,)
+--echo # Connection con2
+
+LOCK TABLE t1 WRITE;
+
+--echo # ALTER fails because COMPRESSED/KEY_BLOCK_SIZE
+--echo # are incompatible with innodb_file_per_table = OFF;
+
+--error ER_GET_ERRNO
+ALTER TABLE t1 ADD PARTITION PARTITIONS 1;
+
+--list_files $MYSQLD_DATADIR/test
+--echo # This SET is not needed to reproduce the bug,
+--echo # it is here just to make the test case more realistic
+SET innodb_strict_mode = OFF;
+
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+--list_files $MYSQLD_DATADIR/test
+
+# really bug#56172
+ALTER TABLE t1 REBUILD PARTITION p0;
+
+UNLOCK TABLES;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--disconnect con2
+--connection default
+--echo # Connection default
+SET @@global.innodb_strict_mode = @old_innodb_strict_mode;
+SET @@global.innodb_file_format = @old_innodb_file_format;
+SET @@global.innodb_file_per_table = @old_innodb_file_per_table;
+SET @@global.innodb_file_format_check = @old_innodb_file_format_check;
#
# Bug#32430 - show engine innodb status causes errors
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 702c3d99fda..d6f05bf5407 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -5935,6 +5935,12 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
if (lpt->thd->locked_tables)
{
/*
+ Close the table if open, to remove/destroy the already altered
+ table->part_info object, so that it is not reused.
+ */
+ if (lpt->table->db_stat)
+ abort_and_upgrade_lock_and_close_table(lpt);
+ /*
When we have the table locked, it is necessary to reopen the table
since all table objects were closed and removed as part of the
ALTER TABLE of partitioning structure.
@@ -6436,7 +6442,20 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
table, table_list, FALSE, NULL,
written_bin_log));
err:
- close_thread_tables(thd);
+ if (thd->locked_tables)
+ {
+ /*
+ table->part_info was altered in prep_alter_part_table and must be
+ destroyed and recreated, since otherwise it will be reused, since
+ we are under LOCK TABLE.
+ */
+ alter_partition_lock_handling(lpt);
+ }
+ else
+ {
+ /* Force the table to be closed to avoid reuse of the table->part_info */
+ close_thread_tables(thd);
+ }
DBUG_RETURN(TRUE);
}
#endif