Hi Kevin,
Patch looks good. OK to push.
BTW: Thanks for a very detailed commit message that explained why this
crash occurred.
Olav
Kevin Lewis wrote:
> #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)
>
>
> ------------------------------------------------------------------------
>
>