Bug #45665 chill_thaw fails Table::checkUniqueRecordVersion() with ASSERT(dup->isDeleted())
Submitted: 22 Jun 2009 21:00 Modified: 26 May 2010 17:48
Reporter: Olav Sandstå Email Updates:
Status: Unsupported Impact on me:
None 
Category:MySQL Server: Falcon storage engine Severity:S2 (Serious)
Version:6.0.12-alpha OS:Microsoft Windows
Assigned to: Kevin Lewis CPU Architecture:Any
Tags: F_RECORD TREE
Triage: Triaged: D1 (Critical)

[22 Jun 2009 21:00] Olav Sandstå
Description:
falcon_chill_thaw test fails with the following error:

[Falcon] Error: assertion (dup->isDeleted()) failed at line 2598 in file .\Table.cpp

The code in Table::checkUniqueRecordVersion() is:

// Check for a deleted record or a record lock

if (!dup->hasRecord())
	{
	// A record without a data buffer is either a lock record or a deleted record.

	if (dup->isALock() || dup->isRecordDataFreed())
		continue;	// Next record version.

	ASSERT(dup->isDeleted());  // Deleted records require special actions.

The call stack from the crash:

005CE3B0    mysqld.exe!Error::debugBreak()[error.cpp:90]
005CE47E    mysqld.exe!Error::error()[error.cpp:73]
005CE4C9    mysqld.exe!Error::assertionFailed()[error.cpp:78]
005D7F34    mysqld.exe!Table::checkUniqueRecordVersion()[table.cpp:2598]
005DA2A5    mysqld.exe!Table::checkUniqueIndex()[table.cpp:2543]
005DAB4C    mysqld.exe!Table::insertIndexes()[table.cpp:1319]
005DB0F7    mysqld.exe!Table::insert()[table.cpp:3090]
005D0A13    mysqld.exe!StorageDatabase::insert()[storagedatabase.cpp:269]
005CD352    mysqld.exe!StorageTable::insert()[storagetable.cpp:113]
005C229F    mysqld.exe!StorageInterface::write_row()[ha_falcon.cpp:1184]
0049338E    mysqld.exe!handler::ha_write_row()[handler.cc:5517]
0054A83D    mysqld.exe!write_record()[sql_insert.cc:1596]
0054F0F3    mysqld.exe!mysql_insert()[sql_insert.cc:836]
004F5D61    mysqld.exe!wait_if_global_read_lock()[lock.cc:1323]
7C82C60E    ntdll.dll!RtlDetermineDosPathNameType_U()

How to repeat:
Seen once when running the RQG test falcon_chill_thaw on a verson from mysql-6.0-falcon-team on June 18.
[23 Jun 2009 18:39] Kevin Lewis
I am pretty sure that what is happening here is that the dup record gets thawed and immediately re-chilled.  I have made a bunch of changes recently to pass and/or return a pointer to a data buffer in order to make continued checks on that pointer instead of the Record::data.record pointer which can be chilled again almost immediately.  So I need to do that here also.  And I should take a closer look at each place where hasRecord() is called to see if an immediate re-chill after it will make a difference.
[23 Jun 2009 21: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/76971

2739 Kevin Lewis	2009-06-23
      Bug#45665 - Change the tests so that the Record::data.record is read once 
      and tested multiple times instead of calling Record functions to test it
      multiple times in Table::checkUniqueRecordVersion().  
     @ storage/falcon/Record.cpp
        Bug#45665 - findRecordData is simplified to an inline.
        isAllocated(void)  and isRecordDataFreed() are not used.
     @ storage/falcon/Record.h
        Bug#45665 - findRecordData is simplified to an inline.
        isAllocated(void)  and isRecordDataFreed() are not used.
     @ storage/falcon/RecordVersion.cpp
        Bug#45665 - findRecordData is simplified to an inline.
     @ storage/falcon/RecordVersion.h
        Bug#45665 - findRecordData is simplified to an inline.
     @ storage/falcon/SRLUpdateRecords.cpp
        Bug#45665 - Rename dataRecord to RecordData for consistency.
        SRLUpdateRecords::thaw() uses Record::findRecordData() to get
        Record::data.record.  But it needs to return null if the record
        is not thawed.  Record::findRecordData() is simplified to return
        exactly what is there so converting 'special' pointer values to
        null is not done here.
     @ storage/falcon/Table.cpp
        Bug#45665 - Change the tests so that the Record::data.record is read once 
        and tested multiple times instead of calling Record functions to test it
        multiple times in Table::checkUniqueRecordVersion().
     @ storage/falcon/Transaction.cpp
        Bug#45665 - Use isRolledBack() in an assert at the bottom of
        Transaction::getRelativeState().
        At this point, the transaction can be no other.
     @ storage/falcon/TransactionState.h
        Use isRolledBack() in an assert at the bottom of Transaction::getRelativeState().