Bug #54117 crash in thr_multi_unlock, temporary table

This crash occured after ALTER TABLE was used on a temporary
transactional table locked by LOCK TABLES. Any later attempts to
execute LOCK/UNLOCK TABLES, caused the server to crash.

The reason for the crash was the list of locked tables would
end up having a pointer to a free'd table instance. This happened
because ALTER TABLE deleted the table without also removing the
table reference from the locked tables list.

This patch fixes the problem by making sure ALTER TABLE also
removes the table from the locked tables list.

Test case added to innodb_mysql.test.
This commit is contained in:
Jon Olav Hauglid 2010-07-07 13:55:09 +02:00
parent 8411a720c8
commit 60edcf9475
3 changed files with 27 additions and 0 deletions

View File

@ -2499,4 +2499,12 @@ ORDER BY f1 DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range f2,f4 f4 1 NULL 11 Using where 1 SIMPLE t1 range f2,f4 f4 1 NULL 11 Using where
DROP TABLE t1; DROP TABLE t1;
#
# Bug#54117 crash in thr_multi_unlock, temporary table
#
CREATE TEMPORARY TABLE t1(a INT) ENGINE = InnoDB;
LOCK TABLES t1 READ;
ALTER TABLE t1 COMMENT 'test';
UNLOCK TABLES;
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests

View File

@ -737,4 +737,18 @@ ORDER BY f1 DESC LIMIT 5;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug#54117 crash in thr_multi_unlock, temporary table
--echo #
CREATE TEMPORARY TABLE t1(a INT) ENGINE = InnoDB;
LOCK TABLES t1 READ;
ALTER TABLE t1 COMMENT 'test';
UNLOCK TABLES;
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -7387,6 +7387,11 @@ view_err:
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
thd->lock=0; thd->lock=0;
} }
/*
If LOCK TABLES list is not empty and contains this table,
unlock the table and remove the table from this list.
*/
mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
/* Remove link to old table and rename the new one */ /* Remove link to old table and rename the new one */
close_temporary_table(thd, table, 1, 1); close_temporary_table(thd, table, 1, 1);
/* Should pass the 'new_name' as we store table name in the cache */ /* Should pass the 'new_name' as we store table name in the cache */