From: Date: November 11 2008 11:33pm Subject: bzr commit into mysql-6.0-falcon-team branch (cpowers:2908) Bug#38569 List-Archive: http://lists.mysql.com/commits/58507 X-Bug: 38569 Message-Id: <20081111223357.453C41DB0731@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/ 2908 Christopher Powers 2008-11-11 Bug#38569, "Falcon assertion in SRLUpdateIndex::thaw : type == srlUpdateIndex" The fix for Bug#39696, "Assertion in Table.cpp (dup->state == recDeleted)" exposed another problem with chill/thaw for deferred indexes. Changed SRLUpdateIndex::append() to advance past srlVersion records written at the top of each block within a window. Also removed a gap in mutex protection in the loop that reconstructs the DeferredIndex from multiple serial log records. modified: storage/falcon/SRLUpdateIndex.cpp storage/falcon/SerialLogControl.cpp storage/falcon/SerialLogRecord.cpp storage/falcon/SerialLogRecord.h per-file messages: storage/falcon/SRLUpdateIndex.cpp SRLUpdateIndex::append() now advances past srlVersion records written at the top of each block within a window. Removed a gap in mutex protection in the loop that reconstructs the DeferredIndex from multiple serial log records. Added comments. storage/falcon/SerialLogControl.cpp Added 'type' field storage/falcon/SerialLogRecord.cpp Added 'type' field storage/falcon/SerialLogRecord.h Added 'type' field === modified file 'storage/falcon/SRLUpdateIndex.cpp' --- a/storage/falcon/SRLUpdateIndex.cpp 2008-10-16 02:53:35 +0000 +++ b/storage/falcon/SRLUpdateIndex.cpp 2008-11-11 22:33:27 +0000 @@ -60,25 +60,37 @@ void SRLUpdateIndex::append(DeferredInde uint64 virtualOffset = 0; uint64 virtualOffsetAtEnd = 0; - // Remember where this is logged + // 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)"); + log->updateIndexUseVector(indexId, tableSpaceId, 1); SerialLogTransaction *srlTrans = log->getTransaction(transaction->transactionId); srlTrans->setTransaction(transaction); ASSERT(transaction->writePending); + + // Set the record header fields + putInt(tableSpaceId); putInt(transaction->transactionId); putInt(indexId); putInt(idxVersion); + + // Initialize the length field, adjust with correct length later. + // Use a fixed-length integer to accommodate a larger number. + UCHAR *lengthPtr = putFixedInt(0); UCHAR *start = log->writePtr; UCHAR *end = log->writeWarningTrack; + // Write the variable-length index node data. If the data length + // will extend past the end of the current window, start a new + // record. + for (; node; node = walker.next()) { if (log->writePtr + byteCount(node->recordNumber) + @@ -93,10 +105,18 @@ void SRLUpdateIndex::append(DeferredInde int len = (int) (log->writePtr - start); //printf("SRLUpdateIndex::append tid %d, index %d, length %d, ptr %x (%x)\n", transaction->transactionId, indexId, len, lengthPtr, org); ASSERT(len >= 0); - putFixedInt(len, lengthPtr); - const UCHAR *p = lengthPtr; - ASSERT(getInt(&p) == len); + + // Update the length field + + if (len > 0) + putFixedInt(len, lengthPtr); + + // Save the absolute offset of the end of the DeferredIndex record + virtualOffsetAtEnd = log->writeWindow->getNextVirtualOffset(); + + // End this serial log record and flush to disk. Force the creation of + // a new serial log window. log->endRecord(); if (node) @@ -235,21 +255,25 @@ void SRLUpdateIndex::thaw(DeferredIndex* if (window == NULL) { - Log::log("A window for DeferredIndex::virtualOffset=" I64FORMAT " could not be found.\n", - deferredIndex->virtualOffset); + Log::log("A window for DeferredIndex::virtualOffset=" I64FORMAT " could not be found.\n", deferredIndex->virtualOffset); log->printWindows(); - return; } - - // Find the correct block within the window and set the offset using that block. - SerialLogBlock *block = window->firstBlock(); - uint32 blockOffset = 0; - ASSERT( (UCHAR *) block == window->buffer); + // Location of the DeferredIndex within the window + uint32 windowOffset = (uint32) (virtualOffset - window->virtualOffset); - - while (windowOffset >= blockOffset + block->length) + + // Location of the block in which the DeferredIndex resides + + uint32 blockOffset = 0; + + // Find the block in which the DeferredIndex resides, starting with the first + // block in the window. Accumulate each block's offset in blockOffset. + + SerialLogBlock *block = window->firstBlock(); + + while (blockOffset + block->length <= windowOffset) { SerialLogBlock *prevBlock = block; block = window->nextBlock(block); @@ -257,21 +281,34 @@ void SRLUpdateIndex::thaw(DeferredIndex* blockOffset += thisBlockOffset; } + // Find the location of the DeferredIndex in the target block. Adjust for the + // offset of the data buffer within the block structure. + uint32 offsetWithinBlock = (windowOffset - blockOffset - OFFSET(SerialLogBlock*, data)); + + // Get the serial log version and set the input pointer to the specified offset within + // the target block. Activate the window, if necessary. + control->setWindow(window, block, offsetWithinBlock); ASSERT(control->input == window->buffer + windowOffset); ASSERT(control->inputEnd <= window->bufferEnd); - // Read the SerialLogRecord type and header + // Now we are pointing at a serial log record, so read the entire record. + // Version records are written at the top of each block. If necessary, + // advance past the version record and read the SRLUpdateIndex record. - UCHAR type = getInt(); - ASSERT(type == srlUpdateIndex); - read(); // this read() is also in control->nextRecord() below. - - while (virtualOffset < deferredIndex->virtualOffsetAtEnd) + SerialLogRecord* srlRecord = control->nextRecord(); + + if (srlRecord && srlRecord->type == srlVersion) + srlRecord = control->nextRecord(); + + ASSERT(srlRecord->type == srlUpdateIndex); + + // The DeferredIndex may reside in several serial log records. Read each record and + // rebuild the index from the nodes stored within the record. + + while (srlRecord && virtualOffset < deferredIndex->virtualOffsetAtEnd) { - sync.unlock(); - // Read the header of the deferredIndex and validate. ASSERT(transactionId == transId); @@ -283,7 +320,7 @@ void SRLUpdateIndex::thaw(DeferredIndex* IndexKey indexKey(deferredIndex->index); - // Read each IndexKey and add it to the deferredIndex. set ptr and end for nextKey() + // Read each IndexKey and add it to the deferredIndex. Set ptr and end for nextKey(). ptr = data; end = ptr + dataLength; @@ -291,13 +328,15 @@ void SRLUpdateIndex::thaw(DeferredIndex* for (recordNumber = nextKey(&indexKey); recordNumber >= 0; recordNumber = nextKey(&indexKey)) deferredIndex->addNode(&indexKey, recordNumber); - sync.lock(Exclusive); - for (;;) { // Quit if there are no more SerialLogRecords for this DeferredIndex. SerialLogWindow *inputWindow = control->inputWindow; + + if (!inputWindow) + break; + virtualOffset = inputWindow->virtualOffset + (control->input - inputWindow->buffer); if (virtualOffset >= deferredIndex->virtualOffsetAtEnd) @@ -305,9 +344,9 @@ void SRLUpdateIndex::thaw(DeferredIndex* // Find the next SerialLogRecord of this deferredIndex. - SerialLogRecord *record = control->nextRecord(); + srlRecord = control->nextRecord(); - if ((record == this) && (transactionId == transId) && (indexId == deferredIndex->index->indexId)) + if (srlRecord == this && transactionId == transId && indexId == deferredIndex->index->indexId) break; } } === modified file 'storage/falcon/SerialLogControl.cpp' --- a/storage/falcon/SerialLogControl.cpp 2008-03-11 16:15:47 +0000 +++ b/storage/falcon/SerialLogControl.cpp 2008-11-11 22:33:27 +0000 @@ -337,6 +337,7 @@ SerialLogRecord* SerialLogControl::nextR ASSERT(version > 0); ASSERT(type < srlMax); SerialLogRecord *record = records[type]; + record->type = type; record->read(); if (debug) === modified file 'storage/falcon/SerialLogRecord.cpp' --- a/storage/falcon/SerialLogRecord.cpp 2008-04-09 01:36:46 +0000 +++ b/storage/falcon/SerialLogRecord.cpp 2008-11-11 22:33:27 +0000 @@ -100,6 +100,7 @@ int init() SerialLogRecord::SerialLogRecord() { transactionId = 0; + type = 0; } SerialLogRecord::~SerialLogRecord() === modified file 'storage/falcon/SerialLogRecord.h' --- a/storage/falcon/SerialLogRecord.h 2008-02-14 21:06:10 +0000 +++ b/storage/falcon/SerialLogRecord.h 2008-11-11 22:33:27 +0000 @@ -111,6 +111,7 @@ public: SerialLog *log; SerialLogControl *control; TransId transactionId; + UCHAR type; };