Bug #51355 handler stmt cause assertion in bool MDL_context::try_acquire_lock(MDL_request*)
Submitted: 20 Feb 2010 19:03 Modified: 13 Mar 2010 23:43
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Locking Severity:S1 (Critical)
Version:5.5.99-m3-debug OS:Linux
Assigned to: Jon Olav Hauglid CPU Architecture:Any
Tags: assertion, handler

[20 Feb 2010 19:03] Shane Bester
Description:
Version: '5.5.99-m3-debug-log'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution
mysqld: mdl.cc:1246: bool MDL_context::try_acquire_lock(MDL_request*): Assertion `mdl_request->ticket == __null' failed.
091204  1:59:55 - mysqld got signal 6 ;

Built using ./BUILD/compile-pentium-debug-max using sources:
revno: 2936
committer: Alexander Nozdrin <alik@sun.com>
branch nick: mysql-next-mr
timestamp: Sat 2010-02-20 12:27:30 +0300

Looks similar to bug #46748 and bug #50912
My build includes the fixes for both of them and this crash still happens.

How to repeat:
On a debug build, run the following sequence using two sessions.

#connection 1:
drop table if exists t1;
create table if not exists t1(a int,key a(a))engine=myisam;

#connection 2:
handler t1 open;

#connection 1:
drop table if exists t1;    #hangs 'waiting for table'
		    
#connection 2:
insert into t1 values (1);  #error, but releases the lock!
handler t1 read a next;     #error
handler t1 read a last;     #crash!
[21 Feb 2010 16:43] Valeriy Kravchuk
Verified just as described with recent next-mr from bzr on Linux.
[22 Feb 2010 14:20] Jon Olav Hauglid
Initial analysis:
1) DROP TABLE t1 blocks due to the open HANDLER on t1.
2) INSERT closes the open HANDLER table due to the pending exclusive lock from DROP. This releases the metadata lock on t1.
3) DROP is able to proceed since the open HANDLER table was closed and the conflicting metadata lock released.
4) INSERT fails since DROP has removed the table.
5) HANDLER NEXT fails since DROP has removed the table, but still acquires a metadata lock on t1...
6) HANDLER LAST causes an assert since HANDLER NEXT has already taken the metadata lock on t1. (The assert tests that the request hasn't already been granted.)
[22 Feb 2010 15: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/101098

3105 Jon Olav Hauglid	2010-02-22
      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 ticket representing the granted lock
      in 5) was not reset when the statement failed. The subsequent statement then
      tried to acquire a lock that was already granted, triggering the assert.
      
      This patch fixes the problem by assuring that the metadata ticket is reset
      when reopening of handler tables fails.
      
      Test case added to handler.inc
      
      ******
      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 ticket representing the granted lock
      in 5) was not reset when the statement failed. The subsequent statement then
      tried to acquire a lock that was already granted, triggering the assert.
      
      This patch fixes the problem by assuring that the metadata ticket is reset
      when reopening of handler tables fails.
      
      Test case added to handler.inc
[25 Feb 2010 10:17] 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/101423

3107 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. The subsequent statement 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
[25 Feb 2010 16:09] Dmitry Lenev
Approved with minor comment sent by e-mail.
[25 Feb 2010 17:09] 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/101509

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
[25 Feb 2010 17:10] Jon Olav Hauglid
Pushed to mysql-next-4284.
[6 Mar 2010 10:29] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100306102742-yw9zzgw9ac5r65m5) (version source revid:bar@mysql.com-20100305074327-h09o5lw290s04lcf) (merge vers: 6.0.14-alpha) (pib:16)
[6 Mar 2010 10:31] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100306102638-qna09hbjb5gm940h) (version source revid:alik@sun.com-20100304153932-9hajxhhyanqbckmu) (pib:16)
[6 Mar 2010 10:58] Bugs System
Pushed into 5.5.3-m3 (revid:alik@sun.com-20100306103849-hha31z2enhh7jwt3) (version source revid:alik@sun.com-20100304153932-9hajxhhyanqbckmu) (merge vers: 5.5.99-m3) (pib:16)
[13 Mar 2010 23:43] Paul DuBois
No changelog entry needed.