MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:November 18 2009 9:02am
Subject:bzr commit into mysql-5.1-bugteam branch (jon.hauglid:3203) Bug#47682
View as plain text  
#At file:///export/home/z/mysql-5.1-bugteam-bug47682/ based on revid:kent.boortz@stripped

 3203 Jon Olav Hauglid	2009-11-18
      Bug #47682 strange behaviour of INSERT DELAYED
      
      The problem was a "self-deadlock" if the connection issuing INSERT DELAYED
      had both the global read lock (FLUSH TABLES WITH READ LOCK) and LOCK TABLES
      mode active. The table being inserted into had to be different from the 
      table(s) locked by LOCK TABLES.
      
      For INSERT DELAYED, the connection thread waits until the handler thread has
      opened and locked its table before returning. But since the global read lock
      was active, the handler thread would be unable to lock and would wait for the
      global read lock to go away.
      
      So the handler thread would be waiting for the connection thread to release
      the global read lock while the connection thread was waiting for the handler
      thread to lock the table. This gave a "self-deadlock" (same connection,
      different threads).
      
      The deadlock would only happen if we also had LOCK TABLES mode since the
      INSERT otherwise will try to get protection against global read lock before
      starting the handler thread. It will then notice that the global read lock
      is owned by the same connection and report ER_CANT_UPDATE_WITH_READLOCK.
      
      This patch removes the deadlock by reporting ER_CANT_UPDATE_WITH_READLOCK
      also if we are inside LOCK TABLES mode.
      
      Test case added to delayed.test.

    modified:
      mysql-test/r/delayed.result
      mysql-test/t/delayed.test
      sql/sql_insert.cc
=== modified file 'mysql-test/r/delayed.result'
--- a/mysql-test/r/delayed.result	2009-02-03 17:16:24 +0000
+++ b/mysql-test/r/delayed.result	2009-11-18 09:02:21 +0000
@@ -310,4 +310,16 @@ a	b
 2	2
 drop table t1;
 set global low_priority_updates = @old_delayed_updates;
+#
+# Bug #47682 strange behaviour of INSERT DELAYED
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (f1 integer);
+CREATE TABLE t2 (f1 integer);
+FLUSH TABLES WITH READ LOCK;
+LOCK TABLES t1 READ;
+INSERT DELAYED INTO t2 VALUES (1);
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+UNLOCK TABLES;
+DROP TABLE t1, t2;
 End of 5.1 tests

=== modified file 'mysql-test/t/delayed.test'
--- a/mysql-test/t/delayed.test	2009-02-03 17:16:24 +0000
+++ b/mysql-test/t/delayed.test	2009-11-18 09:02:21 +0000
@@ -328,4 +328,26 @@ drop table t1;
 
 set global low_priority_updates = @old_delayed_updates;
 
+
+--echo #
+--echo # Bug #47682 strange behaviour of INSERT DELAYED
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (f1 integer);
+CREATE TABLE t2 (f1 integer);
+
+FLUSH TABLES WITH READ LOCK;
+LOCK TABLES t1 READ;
+
+--error ER_CANT_UPDATE_WITH_READLOCK
+INSERT DELAYED INTO t2 VALUES (1);
+
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+
+
 --echo End of 5.1 tests

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-10-16 10:29:42 +0000
+++ b/sql/sql_insert.cc	2009-11-18 09:02:21 +0000
@@ -500,6 +500,22 @@ bool open_and_lock_for_insert_delayed(TH
   DBUG_ENTER("open_and_lock_for_insert_delayed");
 
 #ifndef EMBEDDED_LIBRARY
+  if (thd->locked_tables && thd->global_read_lock)
+  {
+    /*
+      If this connection has the global read lock, the handler thread
+      will not be able to lock the table. It will wait for the global
+      read lock to go away, but this will never happen since the
+      connection thread will be stuck waiting for the handler thread
+      to open and lock the table.
+      If we are not in locked tables mode, INSERT will seek protection
+      against the global read lock (and fail), thus we will only get
+      to this point in locked tables mode.
+    */
+    my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
+    DBUG_RETURN(TRUE);
+  }
+
   if (delayed_get_table(thd, table_list))
     DBUG_RETURN(TRUE);
 


Attachment: [text/bzr-bundle] bzr/jon.hauglid@sun.com-20091118090221-om5450z83g75ktzb.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (jon.hauglid:3203) Bug#47682Jon Olav Hauglid18 Nov