#At file:///home/cpowers/work/dev/dev-11/mysql/
2909 Christopher Powers 2008-11-13
Bug#40690, "Falcon: Deferred index thaw crashes in addNode()"
Bug#40691, "Falcon: Chill/thaw operations do not lock SerialLog::syncWrite"
modified:
storage/falcon/DeferredIndex.cpp
storage/falcon/SRLUpdateIndex.cpp
storage/falcon/SRLUpdateRecords.cpp
storage/falcon/SerialLog.cpp
storage/falcon/SerialLog.h
per-file messages:
storage/falcon/DeferredIndex.cpp
Clear min/max values in DeferredIndex::chill(). These will be reset during ::thaw()
storage/falcon/SRLUpdateIndex.cpp
Set DeferredIndex::virtualOffset inside of the SerialLog::syncWrite lock to
ensure it will remain unchanged
Added error messages
storage/falcon/SRLUpdateRecords.cpp
Lock SerialLog::syncWrite before thawing a record from the serial log
storage/falcon/SerialLog.cpp
Set SerialLog::startRecordVirtualOffset after syncWrite is locked and
before the first write into the serial log
storage/falcon/SerialLog.h
Added SerialLog::startRecordVirtualOffset
=== modified file 'storage/falcon/DeferredIndex.cpp'
--- a/storage/falcon/DeferredIndex.cpp 2008-10-16 02:53:35 +0000
+++ b/storage/falcon/DeferredIndex.cpp 2008-11-13 09:04:22 +0000
@@ -862,6 +862,10 @@ void DeferredIndex::chill(Dbb *dbb)
leaf->count = 0;
root = leaf;
count = 0;
+ minValue = NULL;
+ maxValue = NULL;
+ haveMinValue = true;
+ haveMaxValue = true;
Log::log(LogInfo, "%d: Index chill: transaction %ld, index %ld, %ld bytes, address %p,
vofs %llx\n",
dbb->database->deltaTime, transaction->transactionId, index->indexId,
sizeEstimate, this, virtualOffset);
=== modified file 'storage/falcon/SRLUpdateIndex.cpp'
--- a/storage/falcon/SRLUpdateIndex.cpp 2008-11-11 22:33:27 +0000
+++ b/storage/falcon/SRLUpdateIndex.cpp 2008-11-13 09:04:22 +0000
@@ -60,14 +60,16 @@ void SRLUpdateIndex::append(DeferredInde
uint64 virtualOffset = 0;
uint64 virtualOffsetAtEnd = 0;
- // 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)");
+ // Save the absolute offset of the DeferredIndex record within the serial log.
+ // This must be done inside the SerialLog::syncWrite lock set by START_RECORD().
+
+ if (virtualOffset == 0)
+ virtualOffset = log->startRecordVirtualOffset;
+
log->updateIndexUseVector(indexId, tableSpaceId, 1);
SerialLogTransaction *srlTrans = log->getTransaction(transaction->transactionId);
srlTrans->setTransaction(transaction);
@@ -238,9 +240,9 @@ void SRLUpdateIndex::thaw(DeferredIndex*
{
Sync sync(&log->syncWrite, "SRLUpdateIndex::thaw");
sync.lock(Exclusive);
+
uint64 virtualOffset = deferredIndex->virtualOffset;
int recordNumber = 0; // a valid record number to get into the loop.
- ASSERT(deferredIndex->virtualOffset);
Transaction *trans = deferredIndex->transaction;
TransId transId = trans->transactionId;
indexId = deferredIndex->index->indexId;
@@ -255,7 +257,7 @@ void SRLUpdateIndex::thaw(DeferredIndex*
if (window == NULL)
{
- Log::log("A window for DeferredIndex::virtualOffset=" I64FORMAT " could not be
found.\n", deferredIndex->virtualOffset);
+ Log::log("Index thaw FAIL: A window for DeferredIndex::virtualOffset=" I64FORMAT "
could not be found.\n", deferredIndex->virtualOffset);
log->printWindows();
return;
}
@@ -302,7 +304,10 @@ void SRLUpdateIndex::thaw(DeferredIndex*
if (srlRecord && srlRecord->type == srlVersion)
srlRecord = control->nextRecord();
- ASSERT(srlRecord->type == srlUpdateIndex);
+ if (srlRecord)
+ ASSERT(srlRecord->type == srlUpdateIndex);
+ else
+ Log::log("Index thaw FAIL: SRLUpdateIndex record not found.
DeferredIndex::virtualOffset=" I64FORMAT "\n", deferredIndex->virtualOffset);
// The DeferredIndex may reside in several serial log records. Read each record and
// rebuild the index from the nodes stored within the record.
=== modified file 'storage/falcon/SRLUpdateRecords.cpp'
--- a/storage/falcon/SRLUpdateRecords.cpp 2008-11-09 01:44:58 +0000
+++ b/storage/falcon/SRLUpdateRecords.cpp 2008-11-13 09:04:22 +0000
@@ -76,6 +76,9 @@ int SRLUpdateRecords::thaw(RecordVersion
if (!window)
return 0;
+ Sync sync(&log->syncWrite, "SRLUpdateRecords::thaw");
+ sync.lock(Exclusive);
+
// Return pointer to record data
control->input = window->buffer + (record->getVirtualOffset() -
window->virtualOffset);
@@ -94,14 +97,15 @@ int SRLUpdateRecords::thaw(RecordVersion
int dataLength = control->getInt();
int bytesReallocated = 0;
+ window->deactivateWindow();
+ sync.unlock();
+
// setRecordData() handles race conditions with an interlocked compare and exchange,
// but check the state and record number anyway
if (record->state == recChilled && recordNumber == record->recordNumber)
bytesReallocated = record->setRecordData(control->input, dataLength);
- window->deactivateWindow();
-
if (bytesReallocated > 0)
{
ASSERT(recordNumber == record->recordNumber);
=== modified file 'storage/falcon/SerialLog.cpp'
--- a/storage/falcon/SerialLog.cpp 2008-10-30 00:22:54 +0000
+++ b/storage/falcon/SerialLog.cpp 2008-11-13 09:04:22 +0000
@@ -131,6 +131,7 @@ SerialLog::SerialLog(Database *db, JStri
gophers = NULL;
wantToSerializeGophers = 0;
serializeGophers = 0;
+ startRecordVirtualOffset = 0;
for (uint n = 0; n < falcon_gopher_threads; ++n)
{
@@ -711,6 +712,8 @@ void SerialLog::startRecord()
if (writeError)
throw SQLError(IO_ERROR_SERIALLOG, "Previous I/O error on serial log prevents further
processing");
+ startRecordVirtualOffset = writeWindow->getNextVirtualOffset();
+
if (writePtr == writeBlock->data)
putVersion();
=== modified file 'storage/falcon/SerialLog.h'
--- a/storage/falcon/SerialLog.h 2008-10-20 21:28:11 +0000
+++ b/storage/falcon/SerialLog.h 2008-11-13 09:04:22 +0000
@@ -224,6 +224,7 @@ public:
uint64 chilledBytes;
int32 wantToSerializeGophers;
int32 serializeGophers;
+ uint64 startRecordVirtualOffset;
TableSpaceInfo *tableSpaces[SLT_HASH_SIZE];
TableSpaceInfo *tableSpaceInfo;
| Thread |
|---|
| • bzr commit into mysql-6.0-falcon-team branch (cpowers:2909) Bug#40690Bug#40691 | Christopher Powers | 13 Nov |