From: Date: November 9 2008 2:45am Subject: bzr commit into mysql-6.0-falcon-team branch (cpowers:2906) Bug#39696 List-Archive: http://lists.mysql.com/commits/58261 X-Bug: 39696 Message-Id: <20081109014514.31D7A1DB0730@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-11/mysql/ 2906 Christopher Powers 2008-11-08 Bug#39696, "Assertion in Table.cpp (dup->state == recDeleted) fails during falcon_chill_thaw" The record chill operation sometimes generates SRLUpdateRecord entries in the serial log that have zero data length. This causes a corruption of the serial log. The total data length of the chilled records is known only after all of the records have been processed in SRLUpdateRecords::append(). If none of the record versions within a given savepoint are eligible to be chilled, the total data length of the serial log record will be zero. Even when there are zero bytes of data to commit to disk, SRLUpdateRecords::append() issues a serial log flush and forces the creation of a new serial log window. This creates a one-byte offset error in the serial log that ultimately results in a fatal assertion during gopher thread processing. To prevent this error, SRLUpdateRecords::append() now only flushes serial log records with a non-zero data length. modified: storage/falcon/SRLUpdateRecords.cpp per-file messages: storage/falcon/SRLUpdateRecords.cpp Don't flush serial log records having zero data length. === modified file 'storage/falcon/SRLUpdateRecords.cpp' --- a/storage/falcon/SRLUpdateRecords.cpp 2008-11-07 01:09:04 +0000 +++ b/storage/falcon/SRLUpdateRecords.cpp 2008-11-09 01:44:58 +0000 @@ -124,12 +124,11 @@ void SRLUpdateRecords::append(Transactio { uint32 chilledRecordsWindow = 0; uint32 chilledBytesWindow = 0; - uint32 windowNumber = 0; SerialLogTransaction *srlTrans = NULL; int savepointId; // Generate one serial log record per write window. To ensure that - // record updates are grouped by savepoint, start a new serial + // chilled records are grouped by savepoint, start a new serial // log record for each savepoint. Several serial log records may // be generated for one savepoint. @@ -165,7 +164,6 @@ void SRLUpdateRecords::append(Transactio if (record->state == recChilled) { transaction->chillPoint = &record->nextInTrans; - continue; } @@ -235,11 +233,11 @@ void SRLUpdateRecords::append(Transactio byteCount(stream.totalLength) + stream.totalLength >= end) break; - // Set the virtual offset of the record in the serial log - ASSERT(record->recordNumber >= 0); ASSERT(log->writePtr > (UCHAR *)log->writeWindow->buffer); + // Set the virtual offset of the record in the serial log + record->setVirtualOffset(log->writeWindow->currentLength + log->writeWindow->virtualOffset); uint32 sectionId = table->dataSectionId; log->updateSectionUseVector(sectionId, tableSpaceId, 1); @@ -259,10 +257,14 @@ void SRLUpdateRecords::append(Transactio int len = (int) (log->writePtr - start); + // The length field is 0, update if necessary + if (len > 0) putFixedInt(len, lengthPtr); - if (record) + // Flush record data, if any, and force the creation of a new serial log window + + if (record && len > 0) log->flush(true, 0, &sync); else sync.unlock(); @@ -273,7 +275,7 @@ void SRLUpdateRecords::append(Transactio log->chilledBytes += chilledBytesWindow; transaction->chilledRecords += chilledRecordsWindow; transaction->chilledBytes += chilledBytesWindow; - windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE; +// uint32 windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE; } } // next serial log record and write window }