#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on
revid:john.embretsen@stripped
2722 Kevin Lewis 2009-06-10
Bug#36631 - Make sure that SerialLogControl::currentLength is always set correctly.
If it is too short and a buffer needs to be re-read, not enough of the serial log will be
read back inot the buffer. When it gets to the end of the current length and calls
SerialLogControl::nextRecord() it will hit an assert when it reads the previous contents
of that buffer, which is now junk. The problem is that the block length indicates a
larger window than the currentLength.
SerialLogControl::currentLength is now updated in each location that the current
writePtr is extended. This is three more places than before.
In addition, some comments and some just-in-case code is added to
SRLUpdateRecords::thaw(). Since this thaw is not calling setWindow(), but only doing a
subset of that function, the task of clearing anddeactivating the old inputWindow that is
done in setWindow() is repeated here.
modified:
storage/falcon/SRLUpdateRecords.cpp
storage/falcon/SerialLog.cpp
=== modified file 'storage/falcon/SRLUpdateRecords.cpp'
--- a/storage/falcon/SRLUpdateRecords.cpp 2009-06-03 18:15:32 +0000
+++ b/storage/falcon/SRLUpdateRecords.cpp 2009-06-10 07:36:02 +0000
@@ -73,7 +73,7 @@ char* SRLUpdateRecords::thaw(RecordVersi
// activate the window, reading from disk if necessary
SerialLogWindow *window = log->findWindowGivenOffset(record->getVirtualOffset());
-
+
// If the serial log window is no longer available, then this virtualOffset is
// no longer any good. Reset it and return.
@@ -85,9 +85,20 @@ char* SRLUpdateRecords::thaw(RecordVersi
Sync sync(&log->syncWrite, "SRLUpdateRecords::thaw");
sync.lock(Exclusive);
- // Return pointer to record data
+ // Instead of calling setWindow(), we only set input and inputEnd.
+ // Do not even assign our local 'window' to inputWindow because we will
+ // deactivate it here.
+
+ if (control->inputWindow && control->inputWindow != window)
+ {
+ control->inputWindow->deactivateWindow();
+ control->inputWindow = NULL;
+ }
+
+ // Set the input and inputEnd pointers to the record we are thawing.
- control->input = window->buffer + (record->getVirtualOffset() -
window->virtualOffset);
+ uint64 recordOffset = record->getVirtualOffset() - window->virtualOffset;
+ control->input = window->buffer + recordOffset;
control->inputEnd = window->bufferEnd;
// Get section id, record id and data length written. Input pointer will be at
=== modified file 'storage/falcon/SerialLog.cpp'
--- a/storage/falcon/SerialLog.cpp 2009-05-12 14:35:40 +0000
+++ b/storage/falcon/SerialLog.cpp 2009-06-10 07:36:02 +0000
@@ -373,7 +373,7 @@ void SerialLog::recover()
// probing the log files, open a window on the first block
// we're going to use for recovery. That should work, but
// if it doesn't, complain.
-
+
lastWindow->deactivateWindow();
SerialLogWindow *window = findWindowGivenBlock(readBlockNumber);
@@ -544,6 +544,8 @@ void SerialLog::overflowFlush(void)
// OK, we're going to do some writing. Start by locking the serial log
*writePtr++ = srlEnd | LOW_BYTE_FLAG;
+ if (writePtr > writeWindow->buffer + writeWindow->currentLength)
+ writeWindow->currentLength = (int) (writePtr - writeWindow->buffer);
writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
writeWindow->setLastBlock(writeBlock);
lastReadBlock = writeBlock->readBlockNumber = getReadBlock();
@@ -638,6 +640,8 @@ uint64 SerialLog::flush(bool forceNewWin
ASSERT(writer == NULL || writer == thread);
writer = thread;
*writePtr++ = srlEnd | LOW_BYTE_FLAG;
+ if (writePtr > writeWindow->buffer + writeWindow->currentLength)
+ writeWindow->currentLength = (int) (writePtr - writeWindow->buffer);
writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
lastReadBlock = writeBlock->readBlockNumber = getReadBlock();
@@ -795,6 +799,8 @@ void SerialLog::putData(uint32 length, c
UCHAR recordCode = *recordStart;
writeBlock->length = (int) (recordStart - (UCHAR*) writeBlock);
writePtr = recordStart;
+ if (writePtr > writeWindow->buffer + writeWindow->currentLength)
+ writeWindow->currentLength = (int) (writePtr - writeWindow->buffer);
overflowFlush();
while (writePtr + length + tailLength >= writeWarningTrack)
Attachment: [text/bzr-bundle] bzr/kevin.lewis@sun.com-20090610073602-wlfh2ajbgxeykcbg.bundle