From: Date: August 27 2008 9:08am Subject: bzr commit into mysql-6.0-falcon branch (cpowers:2801) Bug#38566 List-Archive: http://lists.mysql.com/commits/52651 X-Bug: 38566 Message-Id: <20080827070831.817991DB0729@xeno.mysql.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/cpowers/work/dev/dev-06/mysql/ 2801 Christopher Powers 2008-08-27 Bug #38566 Falcon crash in RecordVersion::thaw at RecordVersion.cpp:421 Removed unnecessary log messages Modified assertions to accommodate race condition where two threads thaw the same record modified: storage/falcon/RecordVersion.cpp storage/falcon/SRLUpdateRecords.cpp per-file messages: storage/falcon/RecordVersion.cpp RecordVersion::thaw() - Removed unnecessary log debug messages - Check record state before asserting on number of bytes restored storage/falcon/SRLUpdateRecords.cpp SRLUpdateRecords::thaw() - Only assert on record number if record was actually thawed - Update chill/thaw byte counts if record was actualy thawed - setRecordData() checks for race condition using compare and exchange pointer, so no need to assert if record wasn't thawed by current thread === modified file 'storage/falcon/RecordVersion.cpp' --- a/storage/falcon/RecordVersion.cpp 2008-07-15 18:57:27 +0000 +++ b/storage/falcon/RecordVersion.cpp 2008-08-27 07:08:18 +0000 @@ -416,11 +416,9 @@ int RecordVersion::thaw() } } - if (bytesRestored <= 0) - Log::debug("RecordVersion::thaw: writePending %d, was %d, recordFetched %d, data %p\n", - trans->writePending, wasWritePending, recordFetched, data.record); - - ASSERT(bytesRestored > 0 || data.record == NULL); + if (state == recChilled) + ASSERT(bytesRestored > 0 || data.record == NULL); + state = recData; return bytesRestored; === modified file 'storage/falcon/SRLUpdateRecords.cpp' --- a/storage/falcon/SRLUpdateRecords.cpp 2008-04-09 08:23:51 +0000 +++ b/storage/falcon/SRLUpdateRecords.cpp 2008-08-27 07:08:18 +0000 @@ -84,34 +84,39 @@ int SRLUpdateRecords::thaw(RecordVersion // Get section id, record id and data length written. Input pointer will be at // beginning of record data. - int tableSpaceId; + int tableSpaceId = 0; if (control->version >= srlVersion8) tableSpaceId = control->getInt(); - else - tableSpaceId = 0; control->getInt(); // sectionId int recordNumber = control->getInt(); int dataLength = control->getInt(); - ASSERT(recordNumber == record->recordNumber); - int bytesReallocated = record->setRecordData(control->input, dataLength); + int bytesReallocated = 0; + + // setRecordData() handles race conditions with an interlocked compare and exchange, + // but check the state and record number anyway - if (bytesReallocated > 0) - bytesReallocated = record->getEncodedSize(); + if (record->state == recChilled && recordNumber == record->recordNumber) + bytesReallocated = record->setRecordData(control->input, dataLength); window->deactivateWindow(); - if (log->chilledRecords > 0) - log->chilledRecords--; + if (bytesReallocated > 0) + { + ASSERT(recordNumber == record->recordNumber); + bytesReallocated = record->getEncodedSize(); + *thawed = true; + + if (log->chilledRecords > 0) + log->chilledRecords--; - if (log->chilledBytes > uint64(bytesReallocated)) - log->chilledBytes -= bytesReallocated; - else - log->chilledBytes = 0; - - *thawed = true; - + if (log->chilledBytes > uint64(bytesReallocated)) + log->chilledBytes -= bytesReallocated; + else + log->chilledBytes = 0; + } + return bytesReallocated; }