Bug #50784 MDL: Assertion `m_tickets.is_empty() || m_tickets.front() == m_trans_sentinel'
Submitted: 1 Feb 2010 9:01 Modified: 7 Mar 2010 1:06
Reporter: Philip Stoev Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Locking Severity:S1 (Critical)
Version:mysql-next-4284-stage OS:Any
Assigned to: Dmitry Lenev CPU Architecture:Any

[1 Feb 2010 9:01] Philip Stoev
Description:
When executing the usual MDL RQG workload, the mysql-next-4284-stage tree crashed almost immediately with the following backtrace:

mysqld: mdl.cc:1556: bool MDL_context::acquire_locks(MDL_request_list*): Assertion `m_tickets.is_empty() || m_tickets.front() == m_trans_sentinel' failed.

# 10:57:02 #6  0x000000315a42bec9 in __assert_fail () from /lib64/libc.so.6
# 10:57:02 #7  0x0000000000842a60 in MDL_context::acquire_locks (this=0x308d8e8, mdl_requests=0x7f6c2949a680) at mdl.cc:1556
# 10:57:02 #8  0x0000000000692a49 in open_tables_acquire_upgradable_mdl (thd=0x308d818, tables_start=0x31ecf90, tables_end=0x0, ot_ctx=0x7f6c2949a750)
# 10:57:02     at sql_base.cc:4370
# 10:57:02 #9  0x00000000006996b9 in open_tables (thd=0x308d818, start=0x7f6c2949a820, counter=0x7f6c2949a85c, flags=32, prelocking_strategy=0x7f6c2949a8a0)
# 10:57:02     at sql_base.cc:4475
# 10:57:02 #10 0x0000000000699c6a in open_and_lock_tables_derived (thd=0x308d818, tables=0x31ecf90, derived=true, flags=32, prelocking_strategy=0x7f6c2949a8a0)
# 10:57:02     at sql_base.cc:5106
# 10:57:02 #11 0x00000000006505d2 in open_and_lock_tables_derived (thd=0x308d818, tables=0x31ecf90, derived=true, flags=32) at mysql_priv.h:1500
# 10:57:02 #12 0x00000000007a0f9d in mysql_admin_table (thd=0x308d818, tables=0x31eca50, check_opt=0x308fd80, operator_name=0xb4645d "repair", lock_type=TL_WRITE,
# 10:57:02     open_for_modify=true, no_warnings_for_error=false, extra_open_options=32, prepare_func=0x792c24 <prepare_for_repair>,
# 10:57:02     operator_func=0x777306 <handler::ha_repair(THD*, st_ha_check_opt*)>, view_operator_func=0) at sql_table.cc:4597
# 10:57:02 #13 0x00000000007a2ed0 in mysql_repair_table (thd=0x308d818, tables=0x31eca50, check_opt=0x308fd80) at sql_table.cc:5071
# 10:57:02 #14 0x000000000064789c in mysql_execute_command (thd=0x308d818) at sql_parse.cc:2778
# 10:57:02 #15 0x000000000064d541 in mysql_parse (thd=0x308d818, inBuf=0x31ec8e8 "REPAIR NO_WRITE_TO_BINLOG TABLE testdb_S . t1_merge1_N  , testdb_S . t1_temp1_S",
# 10:57:02     length=79, found_semicolon=0x7f6c2949cf10) at sql_parse.cc:5592
# 10:57:02 #16 0x000000000064e191 in dispatch_command (command=COM_QUERY, thd=0x308d818, packet=0x2f97319 "", packet_length=82) at sql_parse.cc:1011
# 10:57:02 #17 0x000000000064f662 in do_command (thd=0x308d818) at sql_parse.cc:695
# 10:57:02 #18 0x000000000063de31 in handle_one_connection (arg=0x308d818) at sql_connect.cc:1163
# 10:57:02 #19 0x000000315b0073da in start_thread () from /lib64/libpthread.so.0
# 10:57:02 #20 0x000000315a4e627d in clone () from /lib64/libc.so.6

How to repeat:
Test case, core, binary will be provided shortly.
[1 Feb 2010 9:07] Philip Stoev
Core and binary:

http://mysql-systemqa.s3.amazonaws.com/var-bug50784.zip

Source:

revision-id: kostja@sun.com-20100129154650-wmq5gczzj868s66r
date: 2010-01-29 18:46:50 +0300
build-date: 2010-02-01 11:07:16 +0200
revno: 3084
branch-nick: mysql-next-4284-stage
[1 Feb 2010 9:28] Philip Stoev
Non-concurrent test case

SET AUTOCOMMIT = 0;
OPTIMIZE LOCAL TABLE t1, t2;

So, the issue happens when trying to perform a housekeeping operation on several tables at once in autocommit=off mode.
[2 Feb 2010 11:24] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/98931

3059 Dmitry Lenev	2010-02-02
      Fix for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
      m_tickets.front() == m_trans_sentinel'".
      
      Debug build of server crashed due to assert failure in MDL
      subsystem when one tried to execute multi-table REPAIR or
      OPTIMIZE in autocommit=0 mode.
      
      The assert failure occured when multi-table REPAIR or OPTIMIZE
      started processing of second table from its table list and
      tried to acquire upgradable metadata lock on this table.
      The cause of the assert failure were MDL locks left over from
      processing of previous table. It turned out that in autocommit=0
      mode close_thread_tables() which happens at the end of table
      processing doesn't release metadata locks.
      
      This fix solves problem by releasing locks explicitly using
      MDL_context::release_trans_locks() call.
     @ mysql-test/r/repair.result
        Added test for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
        m_tickets.front() == m_trans_sentinel'".
     @ mysql-test/t/repair.test
        Added test for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
        m_tickets.front() == m_trans_sentinel'".
     @ sql/sql_table.cc
        Ensure that metadata locks are released after multi-table REPAIR/
        OPTIMIZE/... processes each table. close_thread_tables() which is
        called after processing each table doesn't release metadata locks
        if we are in autocommit=0 mode. So this have to be done
        explicitly by calling MDL_context::release_trans_locks().
[3 Feb 2010 5:34] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/99002

3063 Dmitry Lenev	2010-02-03
      Fix for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
      m_tickets.front() == m_trans_sentinel'".
      
      Debug build of server crashed due to assert failure in MDL
      subsystem when one tried to execute multi-table REPAIR or
      OPTIMIZE in autocommit=0 mode.
      
      The assert failure occured when multi-table REPAIR or OPTIMIZE
      started processing of second table from its table list and
      tried to acquire upgradable metadata lock on this table.
      The cause of the assert failure were MDL locks left over from
      processing of previous table. It turned out that in autocommit=0
      mode close_thread_tables() which happens at the end of table
      processing doesn't release metadata locks.
      
      This fix solves problem by releasing locks explicitly using
      MDL_context::release_trans_locks() call.
     @ mysql-test/r/repair.result
        Added test for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
        m_tickets.front() == m_trans_sentinel'".
     @ mysql-test/t/repair.test
        Added test for bug #50784 "MDL: Assertion `m_tickets.is_empty() ||
        m_tickets.front() == m_trans_sentinel'".
     @ sql/sql_table.cc
        Ensure that metadata locks are released after multi-table REPAIR/
        OPTIMIZE/... processes each table. close_thread_tables() which is
        called after processing each table doesn't release metadata locks
        if we are in autocommit=0 mode. So this have to be done
        explicitly by calling MDL_context::release_trans_locks().
[3 Feb 2010 5:36] Dmitry Lenev
Fix for this bug was pushed into mysql-next-4284 tree.

Since this problem was reported against tree which is
not publicly available yet there is nothing to document.
So I am simply closing this bug.
[16 Feb 2010 16:51] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100216101445-2ofzkh48aq2e0e8o) (version source revid:kostja@sun.com-20100210211106-nq8ztcq2z9o4csit) (merge vers: 6.0.14-alpha) (pib:16)
[16 Feb 2010 17:00] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100216101208-33qkfwdr0tep3pf2) (version source revid:kostja@sun.com-20100203111037-ajk1r65ssvwn8dio) (pib:16)
[6 Mar 2010 11:07] Bugs System
Pushed into 5.5.3-m3 (revid:alik@sun.com-20100306103849-hha31z2enhh7jwt3) (version source revid:vvaintroub@mysql.com-20100216221947-luyhph0txl2c5tc8) (merge vers: 5.5.99-m3) (pib:16)
[7 Mar 2010 1:06] Paul DuBois
No changelog entry needed.