MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:February 25 2010 5:08pm
Subject:bzr commit into mysql-next-mr-bugfixing branch (jon.hauglid:3108) Bug#51355
View as plain text  
#At file:///export/home/z/mysql-next-4284-bug51355/ based on revid:jon.hauglid@stripped

 3108 Jon Olav Hauglid	2010-02-25
      Bug #51355 handler stmt cause assertion in 
                 bool MDL_context::try_acquire_lock(MDL_request*)
      
      This assert was triggered in the following way:
      1) HANDLER OPEN t1 from connection 1
      2) DROP TABLE t1 from connection 2. This will block due to the metadata lock
      held by the open handler in connection 1.
      3) DML statement (e.g. INSERT) from connection 1. This will close the table
      opened by the HANDLER in 1) and release its metadata lock. This is done due
      to the pending exclusive metadata lock from 2). 
      4) DROP TABLE t1 from connection 2 now completes and removes table t1.
      5) HANDLER READ from connection 1. Since the handler table was closed in 3),
      the handler code will try to reopen the table. First a new metadata lock on
      t1 will be granted before the command fails since the table was removed in 4).
      6) HANDLER READ from connection 1. This caused the assert.
      
      The reason for the assert was that the MDL_request's pointer to the lock
      ticket was not reset when the statement failed. HANDLER READ then tried to
      acquire a lock using the same MDL_request object, triggering the assert.
      This bug was only noticeable on debug builds and did not cause any problems
      on release builds.
      
      This patch fixes the problem by assuring that the pointer to the metadata 
      lock ticket is reset when reopening of handler tables fails.
      
      Test case added to handler.inc

    modified:
      mysql-test/include/handler.inc
      mysql-test/r/handler_innodb.result
      mysql-test/r/handler_myisam.result
      sql/sql_handler.cc
=== modified file 'mysql-test/include/handler.inc'
--- a/mysql-test/include/handler.inc	2010-02-16 19:26:44 +0000
+++ b/mysql-test/include/handler.inc	2010-02-25 17:08:12 +0000
@@ -1704,3 +1704,56 @@ unlock tables;
 --echo # already released by commit.
 handler t1 close;
 drop tables t1, t2;
+
+
+--echo #
+--echo # Bug#51355 handler stmt cause assertion in
+--echo #           bool MDL_context::try_acquire_lock(MDL_request*)
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+connect(con51355, localhost, root);
+
+--echo # Connection default
+connection default;
+CREATE TABLE t1(id INT, KEY id(id));
+HANDLER t1 OPEN;
+
+--echo # Connection con51355
+connection con51355;
+--echo # Sending:
+--send DROP TABLE t1
+
+--echo # Connection default
+connection default;
+--echo # This I_S query will cause the handler table to be closed and
+--echo # the metadata lock to be released. This will allow DROP TABLE
+--echo # to proceed. Waiting for the table to be removed.
+let $wait_condition=
+  SELECT COUNT(*) = 0 FROM information_schema.tables WHERE table_name = "t1";
+--source include/wait_condition.inc
+
+--echo # Connection con51355
+connection con51355;
+--echo # Reaping: DROP TABLE t1
+--reap
+
+--echo # Connection default
+connection default;
+--error ER_NO_SUCH_TABLE
+HANDLER t1 READ id NEXT;
+# This caused an assertion
+--error ER_NO_SUCH_TABLE
+HANDLER t1 READ id NEXT;
+
+HANDLER t1 CLOSE;
+--echo # Connection con51355
+connection con51355;
+disconnect con51355;
+--source include/wait_until_disconnected.inc
+--echo # Connection default
+connection default;
+

=== modified file 'mysql-test/r/handler_innodb.result'
--- a/mysql-test/r/handler_innodb.result	2010-02-15 11:23:36 +0000
+++ b/mysql-test/r/handler_innodb.result	2010-02-25 17:08:12 +0000
@@ -1685,3 +1685,28 @@ unlock tables;
 # already released by commit.
 handler t1 close;
 drop tables t1, t2;
+#
+# Bug#51355 handler stmt cause assertion in
+#           bool MDL_context::try_acquire_lock(MDL_request*)
+#
+DROP TABLE IF EXISTS t1;
+# Connection default
+CREATE TABLE t1(id INT, KEY id(id));
+HANDLER t1 OPEN;
+# Connection con51355
+# Sending:
+DROP TABLE t1;
+# Connection default
+# This I_S query will cause the handler table to be closed and
+# the metadata lock to be released. This will allow DROP TABLE
+# to proceed. Waiting for the table to be removed.
+# Connection con51355
+# Reaping: DROP TABLE t1
+# Connection default
+HANDLER t1 READ id NEXT;
+ERROR 42S02: Table 'test.t1' doesn't exist
+HANDLER t1 READ id NEXT;
+ERROR 42S02: Table 'test.t1' doesn't exist
+HANDLER t1 CLOSE;
+# Connection con51355
+# Connection default

=== modified file 'mysql-test/r/handler_myisam.result'
--- a/mysql-test/r/handler_myisam.result	2010-02-15 11:23:36 +0000
+++ b/mysql-test/r/handler_myisam.result	2010-02-25 17:08:12 +0000
@@ -1682,6 +1682,31 @@ unlock tables;
 handler t1 close;
 drop tables t1, t2;
 #
+# Bug#51355 handler stmt cause assertion in
+#           bool MDL_context::try_acquire_lock(MDL_request*)
+#
+DROP TABLE IF EXISTS t1;
+# Connection default
+CREATE TABLE t1(id INT, KEY id(id));
+HANDLER t1 OPEN;
+# Connection con51355
+# Sending:
+DROP TABLE t1;
+# Connection default
+# This I_S query will cause the handler table to be closed and
+# the metadata lock to be released. This will allow DROP TABLE
+# to proceed. Waiting for the table to be removed.
+# Connection con51355
+# Reaping: DROP TABLE t1
+# Connection default
+HANDLER t1 READ id NEXT;
+ERROR 42S02: Table 'test.t1' doesn't exist
+HANDLER t1 READ id NEXT;
+ERROR 42S02: Table 'test.t1' doesn't exist
+HANDLER t1 CLOSE;
+# Connection con51355
+# Connection default
+#
 # BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash 
 #
 CREATE TABLE t1 AS SELECT 1 AS f1;

=== modified file 'sql/sql_handler.cc'
--- a/sql/sql_handler.cc	2010-02-12 07:05:43 +0000
+++ b/sql/sql_handler.cc	2010-02-25 17:08:12 +0000
@@ -311,7 +311,11 @@ bool mysql_ha_open(THD *thd, TABLE_LIST 
     if (!reopen)
       my_hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables);
     else
+    {
       hash_tables->table= NULL;
+      /* Safety, cleanup the pointer to satisfy MDL assertions. */
+      hash_tables->mdl_request.ticket= NULL;
+    }
     DBUG_PRINT("exit",("ERROR"));
     DBUG_RETURN(TRUE);
   }


Attachment: [text/bzr-bundle] bzr/jon.hauglid@sun.com-20100225170812-yxtyed2bmc7247tg.bundle
Thread
bzr commit into mysql-next-mr-bugfixing branch (jon.hauglid:3108) Bug#51355Jon Olav Hauglid25 Feb