Bug #39024 Crash in DeferredIndex::detachTransaction
Submitted: 25 Aug 2008 21:40 Modified: 9 Jan 2009 13:43
Reporter: Vladislav Vaintroub Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Falcon storage engine Severity:S3 (Non-critical)
Version: OS:Any
Assigned to: Vladislav Vaintroub CPU Architecture:Any

[25 Aug 2008 21:40] Vladislav Vaintroub
Description:
During  SystemQA tests, including DDL , falcon crashes at drop table 
with following callstack. The assertion checks the state of the SyncObject to be None.

Error::debugBreak()+0x12 
Error::error(char const*, ...)+0x7a 
Error::assertionFailed(char const*, char const*, int)
SyncObject::~SyncObject()+0x2f 
DeferredIndex::~DeferredIndex()+0x73 
DeferredIndex::releaseRef()+0x34 
DeferredIndex::detachTransaction()+0x90 
Transaction::releaseDeferredIndexes(Table*)+0x41 
Transaction::dropTable(Table*)+0x19
TransactionManager::dropTable(Table*, Transaction*)+0x59
Database::dropTable(Table*, Transaction*)+0xf6 

DeferredIndex::detachTransaction() looks like this
void DeferredIndex::detachTransaction(void)
{
    Sync sync(&syncObject, "DeferredIndex::detachTransaction");
    sync.lock(Exclusive);
    ..code..
    releaseRef();
}

it release reference to itself which eventually ends up in 
delete this;

while lock to this::SyncObject can still be held (it can be released as well, but not in all cases).

How to repeat:
Run systemQA tests on system QA machines.

Suggested fix:
sync.unlock() unconditionally before doing releaseRef()
[25 Aug 2008 21:46] Vladislav Vaintroub
Hmm, not sure analysis is correct. Seems like sync.unlock()  is always called, and eventually Index::detachDeferredIndex() locks and unlocks it again.
[27 Aug 2008 21:53] 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/52787

2805 Vladislav Vaintroub	2008-08-27
      Bug#39024 Crash in DeferredIndex::detachTransaction 
      
      DeferredIndex::syncObject is accessed even after 
      "this" object is destroyed in releaseRef().
      
      I put a block at the start of function and before releaseRef()
      to force the destructor of sync before  the object itself 
      is destroyed.
[6 Nov 2008 5:19] Kevin Lewis
The original fix for this bug stopped the assert, but introduced the following bugs.  See Bug#39711 for the final patch which fixed these also.
Bug#39711 "Running falcon_bug_34351_C shows increasing memory usage"
Bug#39795 "Falcon: Online add index does not support index with non-null columns"
Bug#39796 "Falcon: Reference count decrement not atomic"
[9 Jan 2009 13:43] MC Brown
Internal only. No documentation needed.