List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:November 11 2008 10:33pm
Subject:bzr commit into mysql-6.0-falcon-team branch (cpowers:2908) Bug#38569
View as plain text  
#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#38569Christopher Powers11 Nov