List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:March 24 2011 1:47pm
Subject:bzr commit into mysql-5.1 branch (jon.hauglid:3628) Bug#11763784
View as plain text  
#At file:///export/home/x/mysql-5.1-bug11763784/ based on revid:bjorn.munch@stripped

 3628 Jon Olav Hauglid	2011-03-24
      Bug# 11763784 (former 56541)
      ASSERTION TABLE->DB_STAT FAILED IN
      SQL_BASE.CC::OPEN_TABLE() DURING I_S Q
      
      This assert could be triggered if a statement requiring a name
      lock on a table (e.g. DROP TRIGGER) executed concurrently
      with an I_S query which also used the table.
      
      One connection first started an I_S query that opened a given table.
      Then another connection started a statement requiring a name lock
      on the same table. This statement was blocked since the table was
      in use by the I_S query. When the I_S query resumed and tried to
      open the table again as part of get_all_tables(), it would encounter
      a table instance with an old version number representing the pending
      name lock. Since I_S queries ignore version checks and thus pending
      name locks, it would try to continue. This caused it to encounter
      the assert. The assert checked that the TABLE instance found with a
      different version, was a real, open table. However, since this TABLE
      instance instead represented a pending name lock, the check would
      fail and trigger the assert.
      
      This patch fixes the problem by removing the assert. It is ok for
      TABLE::db_stat to be 0 in this case since the TABLE instance can
      represent a pending name lock.
      
      Test case added to lock_sync.test.

    modified:
      mysql-test/r/lock_sync.result
      mysql-test/t/lock_sync.test
      sql/sql_base.cc
=== modified file 'mysql-test/r/lock_sync.result'
--- a/mysql-test/r/lock_sync.result	2010-05-27 20:07:40 +0000
+++ b/mysql-test/r/lock_sync.result	2011-03-24 13:47:49 +0000
@@ -629,3 +629,30 @@ drop procedure p1;
 drop procedure p2;
 drop table t1, t2, t3, t4, t5, te;
 set @@global.concurrent_insert= @old_concurrent_insert;
+#
+# Bug#11763784 56541: ASSERTION TABLE->DB_STAT FAILED IN
+#                     SQL_BASE.CC::OPEN_TABLE() DURING I_S Q
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
+# Connection con2
+SET DEBUG_SYNC= 'before_open_in_get_all_tables SIGNAL is_waits WAIT_FOR is_cont';
+# Sending:
+SELECT * FROM information_schema.table_constraints JOIN t1 ON table_name = a;
+# Connection con1
+SET DEBUG_SYNC= 'now WAIT_FOR is_waits';
+# Sending:
+DROP TRIGGER t1_bi;
+# Connection default
+# Wait until DROP TRIGGER is blocked, waiting for t1
+SET DEBUG_SYNC= 'now SIGNAL is_cont';
+# Connection con2
+# Reaping SELECT * FROM information_schema.table_constraints JOIN t1...
+CONSTRAINT_CATALOG	CONSTRAINT_SCHEMA	CONSTRAINT_NAME	TABLE_SCHEMA	TABLE_NAME	CONSTRAINT_TYPE	a
+# Connection con1
+# Reaping DROP TRIGGER t1_bi
+# Connection default
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';

=== modified file 'mysql-test/t/lock_sync.test'
--- a/mysql-test/t/lock_sync.test	2010-05-27 20:07:40 +0000
+++ b/mysql-test/t/lock_sync.test	2011-03-24 13:47:49 +0000
@@ -862,6 +862,60 @@ disconnect con2;
 set @@global.concurrent_insert= @old_concurrent_insert;
 
 
+--echo #
+--echo # Bug#11763784 56541: ASSERTION TABLE->DB_STAT FAILED IN
+--echo #                     SQL_BASE.CC::OPEN_TABLE() DURING I_S Q
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
+
+connect (con1, localhost, root);
+--echo # Connection con2
+connect (con2, localhost, root);
+SET DEBUG_SYNC= 'before_open_in_get_all_tables SIGNAL is_waits WAIT_FOR is_cont';
+--echo # Sending:
+--send SELECT * FROM information_schema.table_constraints JOIN t1 ON table_name = a
+
+--echo # Connection con1
+connection con1;
+SET DEBUG_SYNC= 'now WAIT_FOR is_waits';
+--echo # Sending:
+--send DROP TRIGGER t1_bi
+
+--echo # Connection default
+connection default;
+--echo # Wait until DROP TRIGGER is blocked, waiting for t1
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM information_schema.processlist
+  WHERE state = "Waiting for table" AND
+        info = "DROP TRIGGER t1_bi";
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL is_cont';
+
+--echo # Connection con2
+connection con2;
+--echo # Reaping SELECT * FROM information_schema.table_constraints JOIN t1...
+--reap
+
+--echo # Connection con1
+connection con1;
+--echo # Reaping DROP TRIGGER t1_bi
+--reap
+
+--echo # Connection default
+connection default;
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';
+disconnect con1;
+disconnect con2;
+
+
 # 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_base.cc'
--- a/sql/sql_base.cc	2011-01-25 14:42:40 +0000
+++ b/sql/sql_base.cc	2011-03-24 13:47:49 +0000
@@ -2798,10 +2798,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *
                  ("Found table '%s.%s' with different refresh version",
                   table_list->db, table_list->table_name));
 
-      /* Ignore FLUSH, but not name locks! */
+      /* Ignore FLUSH and pending name locks, but not acquired name locks! */
       if (flags & MYSQL_LOCK_IGNORE_FLUSH && !table->open_placeholder)
       {
-        DBUG_ASSERT(table->db_stat);
         /* Force close at once after usage */
         thd->version= table->s->version;
         continue;


Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20110324134749-jaymwq8z9dmpaf8z.bundle
Thread
bzr commit into mysql-5.1 branch (jon.hauglid:3628) Bug#11763784Jon Olav Hauglid24 Mar
  • Re: bzr commit into mysql-5.1 branch (jon.hauglid:3628) Bug#11763784Davi Arnaut28 Mar