MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:February 3 2010 2:09pm
Subject:bzr commit into mysql-5.5-next-mr branch (jon.hauglid:3067) Bug#50786
View as plain text  
#At file:///export/home/z/mysql-next-4284-bug50786/ based on revid:kostja@stripped

 3067 Jon Olav Hauglid	2010-02-03
      Bug #50786 Assertion `thd->mdl_context.trans_sentinel() == __null' 
                 failed in open_ltable()
      
      The problem was too restrictive asserts that enforced that 
      open_ltable() was called without any active HANDLERs, LOCK TABLES
      or global read locks. 
      
      However, this can happen in several cases when opening system
      tables. The assert would, for example, be triggered when drop
      function was called from a connection with active HANDLERs as
      this would cause open_ltable() to be called for mysql.proc.
      The assert could also be triggered when using table-based
      general log (mysql.general_log).
      
      This patch removes the asserts since they will be triggered in
      several legitimate cases and because the asserts are no longer
      relevant due to changes in how locks are released.
      
      The patch also fixes set_needs_thr_lock_abort() that before 
      ignored its parameter and always set the member variable to TRUE.
      
      Test case added to mdl_sync.test.
      Thanks to Dmitry Lenev for help with this bug!

    modified:
      mysql-test/r/mdl_sync.result
      mysql-test/t/mdl_sync.test
      sql/mdl.h
      sql/sql_base.cc
=== modified file 'mysql-test/r/mdl_sync.result'
--- a/mysql-test/r/mdl_sync.result	2010-02-01 11:43:06 +0000
+++ b/mysql-test/r/mdl_sync.result	2010-02-03 14:09:27 +0000
@@ -2244,3 +2244,51 @@ FLUSH TABLES WITH READ LOCK;
 UNLOCK TABLES;
 # Connection 1
 SET DEBUG_SYNC= 'RESET';
+#
+# Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null' 
+#           failed in open_ltable()
+#
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (i INT);
+CREATE TABLE t2 (i INT);
+SET @old_general_log= @@global.general_log;
+SET @@global.general_log= 1;
+SET @old_log_output= @@global.log_output;
+SET @@global.log_output= 'TABLE';
+SET @old_sql_log_off= @@session.sql_log_off;
+SET @@session.sql_log_off= 1;
+# connection: con1
+HANDLER t1 OPEN;
+# connection: con3
+SET @@session.sql_log_off= 1;
+# connection: con2
+SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+# Sending:
+SELECT 1;
+# connection: con3
+SET DEBUG_SYNC= 'now WAIT_FOR parked';
+# connection: con1
+# Sending:
+SELECT 1;
+# connection: con3
+# Sending:
+ALTER TABLE t1 ADD COLUMN j INT;
+# connection: default
+SET DEBUG_SYNC= 'now SIGNAL go';
+# connection: con1
+# Reaping SELECT 1
+1
+1
+HANDLER t1 CLOSE;
+# connection: con2
+# Reaping SELECT 1
+1
+1
+# connection: con3
+# Reaping ALTER TABLE t1 ADD COLUMN j INT
+# connection: default
+DROP TABLE t1, t2;
+SET DEBUG_SYNC= 'RESET';
+SET @@global.general_log= @old_general_log;
+SET @@global.log_output= @old_log_output;
+SET @@session.sql_log_off= @old_sql_log_off;

=== modified file 'mysql-test/t/mdl_sync.test'
--- a/mysql-test/t/mdl_sync.test	2010-02-01 17:59:59 +0000
+++ b/mysql-test/t/mdl_sync.test	2010-02-03 14:09:27 +0000
@@ -3212,6 +3212,109 @@ SET DEBUG_SYNC= 'RESET';
 disconnect con2;
 
 
+--echo #
+--echo # Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null' 
+--echo #           failed in open_ltable()
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+connect (con1,localhost,root);
+connect (con2,localhost,root);
+connect (con3,localhost,root);
+connection default;
+
+CREATE TABLE t1 (i INT);
+CREATE TABLE t2 (i INT);
+
+SET @old_general_log= @@global.general_log;
+SET @@global.general_log= 1;
+
+SET @old_log_output= @@global.log_output;
+SET @@global.log_output= 'TABLE';
+
+SET @old_sql_log_off= @@session.sql_log_off;
+SET @@session.sql_log_off= 1;
+
+--echo # connection: con1
+connection con1;
+HANDLER t1 OPEN;
+
+--echo # connection: con3
+connection con3;
+SET @@session.sql_log_off= 1;
+
+--echo # connection: con2
+connection con2;
+SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+
+# The below statement will block on the debug sync point
+# after it gets write lock on mysql.general_log table.
+--echo # Sending:
+--send SELECT 1
+
+--echo # connection: con3
+connection con3;
+SET DEBUG_SYNC= 'now WAIT_FOR parked';
+
+--echo # connection: con1
+connection con1;
+# This statement will block in open_ltable() when
+# trying to write into mysql.general_log.
+--echo # Sending:
+--send SELECT 1
+
+--echo # connection: con3
+connection con3;
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM information_schema.processlist
+  WHERE state = "Table lock" and info = "SELECT 1";
+--source include/wait_condition.inc
+# The ALTER below will try to abort the statement in connection con1,
+# since the latter waits on a table-level lock while having a HANDLER
+# open. This will cause mysql_lock_tables() in con1 fail which before
+# triggered the assert.
+--echo # Sending:
+--send ALTER TABLE t1 ADD COLUMN j INT
+
+--echo # connection: default
+connection default;
+let $wait_condition=
+  SELECT COUNT(*) = 1 FROM information_schema.processlist
+  WHERE state = "Waiting for table" 
+  AND info = "ALTER TABLE t1 ADD COLUMN j INT";
+--source include/wait_condition.inc
+SET DEBUG_SYNC= 'now SIGNAL go';
+
+--echo # connection: con1
+connection con1;
+--echo # Reaping SELECT 1
+--reap
+HANDLER t1 CLOSE;
+
+--echo # connection: con2
+connection con2;
+--echo # Reaping SELECT 1
+--reap
+
+--echo # connection: con3
+connection con3;
+--echo # Reaping ALTER TABLE t1 ADD COLUMN j INT
+--reap
+
+--echo # connection: default
+connection default;
+DROP TABLE t1, t2;
+SET DEBUG_SYNC= 'RESET';
+disconnect con1;
+disconnect con2;
+disconnect con3;
+SET @@global.general_log= @old_general_log;
+SET @@global.log_output= @old_log_output;
+SET @@session.sql_log_off= @old_sql_log_off;
+
 # 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/mdl.h'
--- a/sql/mdl.h	2010-02-01 23:22:16 +0000
+++ b/sql/mdl.h	2010-02-03 14:09:27 +0000
@@ -540,7 +540,7 @@ public:
             always re-try reading it after small timeout and therefore
             will see the new value eventually.
     */
-    m_needs_thr_lock_abort= TRUE;
+    m_needs_thr_lock_abort= needs_thr_lock_abort;
   }
   bool get_needs_thr_lock_abort() const
   {

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-02-03 13:43:03 +0000
+++ b/sql/sql_base.cc	2010-02-03 14:09:27 +0000
@@ -4996,8 +4996,6 @@ retry:
   while ((error= open_table(thd, table_list, thd->mem_root, &ot_ctx, 0)) &&
          ot_ctx.can_recover_from_failed_open())
   {
-    /* We never have an open HANDLER, LOCK TABLES or GRL here. */
-    DBUG_ASSERT(thd->mdl_context.trans_sentinel() == NULL);
     /*
       Even though we have failed to open table we still need to
       call release_transactional_locks() to release metadata locks which
@@ -5048,8 +5046,6 @@ retry:
             close_thread_tables(thd);
             table_list->table= NULL;
             table_list->mdl_request.ticket= NULL;
-            /* We never have an open HANDLER, LOCK TABLES or GRL here. */
-            DBUG_ASSERT(thd->mdl_context.trans_sentinel() == NULL);
             thd->mdl_context.rollback_to_savepoint(ot_ctx.start_of_statement_svp());
             goto retry;
           }


Attachment: [text/bzr-bundle] bzr/jon.hauglid@sun.com-20100203140927-l6melmrm40kuztr9.bundle
Thread
bzr commit into mysql-5.5-next-mr branch (jon.hauglid:3067) Bug#50786Jon Olav Hauglid3 Feb