#At file:///export/home/x/mysql-5.5-runtime-bug56494/ based on revid:jon.hauglid@stripped
3133 Jon Olav Hauglid 2010-09-03
Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for
REPAIR of merge table
This crash happened if a table maintenance statement (ANALYZE TABLE,
REPAIR TABLE, etc.) was executed on a MERGE table and a metadata
lock on the MERGE table could not be acquired due to a conflicting
metadata lock on a child table.
During processing of maintenance statments, the metadata lock on
the table is upgraded. If the lock was not acquired in the first
place, this would cause a segfault.
This patch fixes the problem by checking that we in fact have a
metadata lock on the table before lock upgrade is attempted.
Test case added to mdl_sync.test.
modified:
mysql-test/r/mdl_sync.result
mysql-test/t/mdl_sync.test
sql/sql_admin.cc
=== modified file 'mysql-test/r/mdl_sync.result'
--- a/mysql-test/r/mdl_sync.result 2010-08-12 13:50:23 +0000
+++ b/mysql-test/r/mdl_sync.result 2010-09-03 13:49:36 +0000
@@ -2913,3 +2913,27 @@ UNLOCK TABLES;
# Connection default
UNLOCK TABLES;
DROP DATABASE db1;
+#
+# Bug#56494 Segfault in upgrade_shared_lock_to_exclusive() for
+# REPAIR of merge table
+#
+DROP TABLE IF EXISTS t1, t2, m1;
+CREATE TABLE t1 (a INT) engine=MyISAM;
+CREATE TABLE t2 (a INT) engine=MyISAM;
+CREATE TABLE m1 (a INT) engine=MERGE UNION=(t1, t2);
+# Connection default
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL waiting WAIT_FOR repaired';
+# Sending:
+CREATE TABLE IF NOT EXISTS t1 (a INT);
+# Connection con1
+# Waiting for CREATE TABLE to acquire a lock
+SET DEBUG_SYNC= 'now WAIT_FOR waiting';
+SET SESSION lock_wait_timeout= 1;
+REPAIR TABLE m1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SET DEBUG_SYNC= 'now SIGNAL repaired';
+# Connection default
+# Reaping: CREATE TABLE IF NOT EXISTS t1 (a INT)
+Warnings:
+Note 1050 Table 't1' already exists
+DROP TABLE m1, t1, t2;
=== modified file 'mysql-test/t/mdl_sync.test'
--- a/mysql-test/t/mdl_sync.test 2010-08-12 13:50:23 +0000
+++ b/mysql-test/t/mdl_sync.test 2010-09-03 13:49:36 +0000
@@ -4532,6 +4532,45 @@ disconnect con2;
disconnect con3;
+--echo #
+--echo # Bug#56494 Segfault in upgrade_shared_lock_to_exclusive() for
+--echo # REPAIR of merge table
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, m1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT) engine=MyISAM;
+CREATE TABLE t2 (a INT) engine=MyISAM;
+CREATE TABLE m1 (a INT) engine=MERGE UNION=(t1, t2);
+
+connect (con1, localhost, root);
+
+--echo # Connection default
+connection default;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL waiting WAIT_FOR repaired';
+--echo # Sending:
+--send CREATE TABLE IF NOT EXISTS t1 (a INT)
+
+--echo # Connection con1
+connection con1;
+--echo # Waiting for CREATE TABLE to acquire a lock
+SET DEBUG_SYNC= 'now WAIT_FOR waiting';
+SET SESSION lock_wait_timeout= 1;
+# This caused the segfault
+--error ER_LOCK_WAIT_TIMEOUT
+REPAIR TABLE m1;
+SET DEBUG_SYNC= 'now SIGNAL repaired';
+
+--echo # Connection default
+connection default;
+--echo # Reaping: CREATE TABLE IF NOT EXISTS t1 (a INT)
+--reap
+DROP TABLE m1, t1, t2;
+disconnect con1;
+
+
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc 2010-08-18 11:29:04 +0000
+++ b/sql/sql_admin.cc 2010-09-03 13:49:36 +0000
@@ -488,7 +488,8 @@ static bool mysql_admin_table(THD* thd,
*/
if (lock_type == TL_WRITE && !table->table->s->tmp_table)
{
- if (wait_while_table_is_used(thd, table->table,
+ if (!table->table->mdl_ticket ||
+ wait_while_table_is_used(thd, table->table,
HA_EXTRA_PREPARE_FOR_RENAME))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20100903134936-bjx0t4uns27i219g.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5-runtime branch (jon.hauglid:3133) Bug#56494 | Jon Olav Hauglid | 3 Sep |