List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:September 3 2010 1:49pm
Subject:bzr commit into mysql-5.5-runtime branch (jon.hauglid:3133) Bug#56494
View as plain text  
#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#56494Jon Olav Hauglid3 Sep