#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;
};
Thread |
---|
• bzr commit into mysql-6.0-falcon-team branch (cpowers:2908) Bug#38569 | Christopher Powers | 11 Nov |