Bug#55091: Server crashes on ADD PARTITION after a failed attempt
In case of failure in ALTER ... PARTITION under LOCK TABLE the server could crash, due to it had modified the locked table object, which was not reverted in case of failure, resulting in a bad table definition used after the failed command. Solved by always closing the LOCKED TABLE, even in case of error. Note: this is a 5.1-only fix, bug#56172 fixed it in 5.5+ mysql-test/r/partition_innodb_plugin.result: updated result mysql-test/t/disabled.def: Only disabled valgrind instead. mysql-test/t/partition_innodb_plugin.test: Added test sql/sql_partition.cc: close_thread_tables do not close LOCKED TABLEs and destroys the table object (including part_info), so to avoid it to be reused, always close the table regardless of any previous failure.
This commit is contained in:
parent
bd09e49843
commit
dd1d7ff161
@ -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
|
||||
|
@ -11,6 +11,5 @@
|
||||
##############################################################################
|
||||
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
|
||||
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
|
||||
partition_innodb_plugin : Bug#53307 2010-04-30 VasilDimov valgrind warnings
|
||||
main.mysqlhotcopy_myisam : bug#54129 2010-06-04 Horst
|
||||
main.mysqlhotcopy_archive: bug#54129 2010-06-04 Horst
|
||||
|
@ -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
|
||||
|
@ -5934,6 +5934,12 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
int err;
|
||||
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
|
||||
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user