From: Date: November 13 2008 10:04am Subject: bzr commit into mysql-6.0-falcon-team branch (cpowers:2909) Bug#40690 Bug#40691 List-Archive: http://lists.mysql.com/commits/58610 X-Bug: 40690,40691 Message-Id: <20081113090439.279191DB0732@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/ 2909 Christopher Powers 2008-11-13 Bug#40690, "Falcon: Deferred index thaw crashes in addNode()" Bug#40691, "Falcon: Chill/thaw operations do not lock SerialLog::syncWrite" modified: storage/falcon/DeferredIndex.cpp storage/falcon/SRLUpdateIndex.cpp storage/falcon/SRLUpdateRecords.cpp storage/falcon/SerialLog.cpp storage/falcon/SerialLog.h per-file messages: storage/falcon/DeferredIndex.cpp Clear min/max values in DeferredIndex::chill(). These will be reset during ::thaw() storage/falcon/SRLUpdateIndex.cpp Set DeferredIndex::virtualOffset inside of the SerialLog::syncWrite lock to ensure it will remain unchanged Added error messages storage/falcon/SRLUpdateRecords.cpp Lock SerialLog::syncWrite before thawing a record from the serial log storage/falcon/SerialLog.cpp Set SerialLog::startRecordVirtualOffset after syncWrite is locked and before the first write into the serial log storage/falcon/SerialLog.h Added SerialLog::startRecordVirtualOffset === modified file 'storage/falcon/DeferredIndex.cpp' --- a/storage/falcon/DeferredIndex.cpp 2008-10-16 02:53:35 +0000 +++ b/storage/falcon/DeferredIndex.cpp 2008-11-13 09:04:22 +0000 @@ -862,6 +862,10 @@ void DeferredIndex::chill(Dbb *dbb) leaf->count = 0; root = leaf; count = 0; + minValue = NULL; + maxValue = NULL; + haveMinValue = true; + haveMaxValue = true; Log::log(LogInfo, "%d: Index chill: transaction %ld, index %ld, %ld bytes, address %p, vofs %llx\n", dbb->database->deltaTime, transaction->transactionId, index->indexId, sizeEstimate, this, virtualOffset); === modified file 'storage/falcon/SRLUpdateIndex.cpp' --- a/storage/falcon/SRLUpdateIndex.cpp 2008-11-11 22:33:27 +0000 +++ b/storage/falcon/SRLUpdateIndex.cpp 2008-11-13 09:04:22 +0000 @@ -60,14 +60,16 @@ void SRLUpdateIndex::append(DeferredInde uint64 virtualOffset = 0; uint64 virtualOffsetAtEnd = 0; - // Save the absolute offset of the DeferredIndex record within the serial log - - virtualOffset = log->writeWindow->getNextVirtualOffset(); - for (DINode *node = walker.next(); node;) { START_RECORD(srlUpdateIndex, "SRLUpdateIndex::append(2)"); + // Save the absolute offset of the DeferredIndex record within the serial log. + // This must be done inside the SerialLog::syncWrite lock set by START_RECORD(). + + if (virtualOffset == 0) + virtualOffset = log->startRecordVirtualOffset; + log->updateIndexUseVector(indexId, tableSpaceId, 1); SerialLogTransaction *srlTrans = log->getTransaction(transaction->transactionId); srlTrans->setTransaction(transaction); @@ -238,9 +240,9 @@ void SRLUpdateIndex::thaw(DeferredIndex* { Sync sync(&log->syncWrite, "SRLUpdateIndex::thaw"); sync.lock(Exclusive); + uint64 virtualOffset = deferredIndex->virtualOffset; int recordNumber = 0; // a valid record number to get into the loop. - ASSERT(deferredIndex->virtualOffset); Transaction *trans = deferredIndex->transaction; TransId transId = trans->transactionId; indexId = deferredIndex->index->indexId; @@ -255,7 +257,7 @@ void SRLUpdateIndex::thaw(DeferredIndex* if (window == NULL) { - Log::log("A window for DeferredIndex::virtualOffset=" I64FORMAT " could not be found.\n", deferredIndex->virtualOffset); + Log::log("Index thaw FAIL: A window for DeferredIndex::virtualOffset=" I64FORMAT " could not be found.\n", deferredIndex->virtualOffset); log->printWindows(); return; } @@ -302,7 +304,10 @@ void SRLUpdateIndex::thaw(DeferredIndex* if (srlRecord && srlRecord->type == srlVersion) srlRecord = control->nextRecord(); - ASSERT(srlRecord->type == srlUpdateIndex); + if (srlRecord) + ASSERT(srlRecord->type == srlUpdateIndex); + else + Log::log("Index thaw FAIL: SRLUpdateIndex record not found. DeferredIndex::virtualOffset=" I64FORMAT "\n", deferredIndex->virtualOffset); // The DeferredIndex may reside in several serial log records. Read each record and // rebuild the index from the nodes stored within the record. === modified file 'storage/falcon/SRLUpdateRecords.cpp' --- a/storage/falcon/SRLUpdateRecords.cpp 2008-11-09 01:44:58 +0000 +++ b/storage/falcon/SRLUpdateRecords.cpp 2008-11-13 09:04:22 +0000 @@ -76,6 +76,9 @@ int SRLUpdateRecords::thaw(RecordVersion if (!window) return 0; + Sync sync(&log->syncWrite, "SRLUpdateRecords::thaw"); + sync.lock(Exclusive); + // Return pointer to record data control->input = window->buffer + (record->getVirtualOffset() - window->virtualOffset); @@ -94,14 +97,15 @@ int SRLUpdateRecords::thaw(RecordVersion int dataLength = control->getInt(); int bytesReallocated = 0; + window->deactivateWindow(); + sync.unlock(); + // setRecordData() handles race conditions with an interlocked compare and exchange, // but check the state and record number anyway if (record->state == recChilled && recordNumber == record->recordNumber) bytesReallocated = record->setRecordData(control->input, dataLength); - window->deactivateWindow(); - if (bytesReallocated > 0) { ASSERT(recordNumber == record->recordNumber); === modified file 'storage/falcon/SerialLog.cpp' --- a/storage/falcon/SerialLog.cpp 2008-10-30 00:22:54 +0000 +++ b/storage/falcon/SerialLog.cpp 2008-11-13 09:04:22 +0000 @@ -131,6 +131,7 @@ SerialLog::SerialLog(Database *db, JStri gophers = NULL; wantToSerializeGophers = 0; serializeGophers = 0; + startRecordVirtualOffset = 0; for (uint n = 0; n < falcon_gopher_threads; ++n) { @@ -711,6 +712,8 @@ void SerialLog::startRecord() if (writeError) throw SQLError(IO_ERROR_SERIALLOG, "Previous I/O error on serial log prevents further processing"); + startRecordVirtualOffset = writeWindow->getNextVirtualOffset(); + if (writePtr == writeBlock->data) putVersion(); === modified file 'storage/falcon/SerialLog.h' --- a/storage/falcon/SerialLog.h 2008-10-20 21:28:11 +0000 +++ b/storage/falcon/SerialLog.h 2008-11-13 09:04:22 +0000 @@ -224,6 +224,7 @@ public: uint64 chilledBytes; int32 wantToSerializeGophers; int32 serializeGophers; + uint64 startRecordVirtualOffset; TableSpaceInfo *tableSpaces[SLT_HASH_SIZE]; TableSpaceInfo *tableSpaceInfo;