2881 Christopher Powers 2008-10-24
Bug#36631,"Assertion in SerialLogControl::nextRecord"
Bug#38541,"Falcon RecordVersion::thaw assertion """"bytesRestored > 0 || data.record == NULL"""
Bug#38567,"Falcon crash in Record::getEncodedRecord at Record.cpp:743"
Bug#38569,"Falcon assertion in SRLUpdateIndex::thaw : type == srlUpdateIndex"
Bug#39694,"Crash in StorageTable::setRecord during falcon_chill_thaw test"
Bug#39695,"Crash in SRLUpdateRecords::thaw during falcon_chill_thaw test"
Bug#39696,"Assertion in Table.cpp (dup->state == recDeleted) fails during falcon_chill_thaw"
Fix 2 of 3 for chill/thaw bugs.
Synchronized record thaw operations using a pool of sync objects in the associated table.
Record chill operations do not need to be synchronized because chills are performed in one place, and only by the active Transaction.
modified:
storage/falcon/Record.cpp
storage/falcon/Record.h
storage/falcon/RecordVersion.cpp
storage/falcon/Table.cpp
storage/falcon/Table.h
2880 Christopher Powers 2008-10-24
Bug#36631,"Assertion in SerialLogControl::nextRecord"
Bug#38541,"Falcon RecordVersion::thaw assertion """"bytesRestored > 0 || data.record == NULL"""
Bug#38567,"Falcon crash in Record::getEncodedRecord at Record.cpp:743"
Bug#38569,"Falcon assertion in SRLUpdateIndex::thaw : type == srlUpdateIndex"
Bug#39694,"Crash in StorageTable::setRecord during falcon_chill_thaw test"
Bug#39695,"Crash in SRLUpdateRecords::thaw during falcon_chill_thaw test"
Bug#39696,"Assertion in Table.cpp (dup->state == recDeleted) fails during falcon_chill_thaw"
Fix 1 of 3 for chill/thaw bugs.
Modified Record::hasRecord() to thaw if necessary, removed redundant record thaws, added exception handling
modified:
storage/falcon/Record.cpp
storage/falcon/Record.h
storage/falcon/RecordScavenge.cpp
storage/falcon/RecordVersion.cpp
storage/falcon/RecordVersion.h
storage/falcon/SRLUpdateRecords.cpp
storage/falcon/Table.cpp
storage/falcon/Transaction.cpp
2879 Christopher Powers 2008-10-23 [merge]
(no message)
modified:
storage/falcon/Bitmap.cpp
storage/falcon/Cache.cpp
storage/falcon/Database.cpp
storage/falcon/StorageConnection.cpp
storage/falcon/StorageConnection.h
storage/falcon/ha_falcon.cpp
=== modified file 'storage/falcon/Record.cpp'
--- a/storage/falcon/Record.cpp 2008-05-09 19:58:50 +0000
+++ b/storage/falcon/Record.cpp 2008-10-24 05:35:38 +0000
@@ -586,22 +586,27 @@ int Record::getSavePointId()
return 0;
}
-void Record::getRecord(Stream *stream)
+bool Record::getRecord(Stream *stream)
{
- switch (encoding)
+ if (data.record != NULL)
{
- case traditional:
- stream->compress (format->length, data.record);
- break;
+ switch (encoding)
+ {
+ case traditional:
+ stream->compress (format->length, data.record);
+ break;
- case shortVector:
- stream->putSegment(getEncodedSize(),
- data.record + ((USHORT*) data.record)[0] - sizeof(short), false);
- break;
+ case shortVector:
+ stream->putSegment(getEncodedSize(),
+ data.record + ((USHORT*) data.record)[0] - sizeof(short), false);
+ break;
- default:
- NOT_YET_IMPLEMENTED;
+ default:
+ NOT_YET_IMPLEMENTED;
+ }
}
+
+ return (data.record != NULL);
}
int Record::getEncodedSize()
@@ -626,11 +631,8 @@ int Record::getEncodedSize()
void Record::getEncodedValue(int fieldId, Value *value)
{
- // If chilled, restore the record data from the serial log
-
- if (state == recChilled)
- thaw();
-
+ try
+ {
switch (encoding)
{
case shortVector:
@@ -663,6 +665,11 @@ void Record::getEncodedValue(int fieldId
NOT_YET_IMPLEMENTED;
}
}
+ catch (SQLException& exception)
+ {
+ int code = exception.getSqlcode();
+ }
+}
void Record::finalize(Transaction *transaction)
{
@@ -849,7 +856,7 @@ void Record::setPriorVersion(Record* rec
ASSERT(false);
}
-int Record::thaw()
+int Record::thaw(bool force)
{
return 0;
}
@@ -964,3 +971,8 @@ SyncObject* Record::getSyncPrior(void)
{
return format->table->getSyncPrior(this);
}
+
+SyncObject* Record::getSyncThaw(void)
+{
+ return format->table->getSyncThaw(this);
+}
=== modified file 'storage/falcon/Record.h'
--- a/storage/falcon/Record.h 2008-05-09 19:58:50 +0000
+++ b/storage/falcon/Record.h 2008-10-24 05:35:38 +0000
@@ -88,12 +88,13 @@ public:
virtual Record* getPriorVersion();
virtual Record* getGCPriorVersion(void);
virtual void print(void);
- virtual int thaw();
+ virtual int thaw(bool force = false);
virtual const char* getEncodedRecord();
virtual int setRecordData(const UCHAR *dataIn, int dataLength);
virtual void serialize(Serialize* stream);
virtual int getSize(void);
virtual SyncObject* getSyncPrior(void);
+ virtual SyncObject* getSyncThaw(void);
const UCHAR* getEncoding (int index);
int setEncodedRecord(Stream *stream, bool interlocked);
@@ -107,7 +108,7 @@ public:
int getBlobId(int fieldId);
void finalize(Transaction *transaction);
void getEncodedValue (int fieldId, Value *value);
- void getRecord (Stream *stream);
+ bool getRecord (Stream *stream);
int getEncodedSize();
void deleteData(void);
void printRecord(const char* header);
@@ -119,10 +120,13 @@ public:
Record (Table *table, int32 recordNumber, Stream *stream);
Record (Database *database, Serialize* stream);
- inline int hasRecord()
+ inline int hasRecord(bool forceThaw = true)
{
- return data.record != NULL;
- };
+ if (state == recChilled && forceThaw)
+ thaw();
+
+ return (data.record != NULL);
+ }
inline char* getRecordData()
{
@@ -142,7 +146,6 @@ protected:
public:
volatile INTERLOCK_TYPE useCount;
- //Table *table;
Format *format;
int recordNumber;
int size;
=== modified file 'storage/falcon/RecordScavenge.cpp'
--- a/storage/falcon/RecordScavenge.cpp 2008-05-09 19:58:50 +0000
+++ b/storage/falcon/RecordScavenge.cpp 2008-10-24 05:06:52 +0000
@@ -56,7 +56,7 @@ void RecordScavenge::inventoryRecord(Rec
uint64 age = baseGeneration - record->generation;
int size = record->size + sizeof(MemBigHeader);
- if (record->hasRecord() || (record->state == recChilled))
+ if (record->hasRecord(false) || record->state == recChilled)
size += sizeof(MemBigHeader);
if (age != UNDEFINED && age < AGE_GROUPS)
=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp 2008-10-16 02:57:10 +0000
+++ b/storage/falcon/RecordVersion.cpp 2008-10-24 05:35:38 +0000
@@ -194,7 +194,7 @@ bool RecordVersion::scavenge(RecordScave
if ( useCount == 1
&& !transaction
&& transactionId < recordScavenge->transactionId
- && (!hasRecord()
+ && (!hasRecord(false)
|| generation <= recordScavenge->scavengeGeneration
|| recordScavenge->forced))
{
@@ -231,7 +231,7 @@ bool RecordVersion::scavenge(RecordScave
if ( rec->useCount == 1
&& !rec->getTransaction()
&& rec->getTransactionId() < recordScavenge->transactionId
- && (!rec->hasRecord()
+ && (!rec->hasRecord(false)
|| rec->generation <= recordScavenge->scavengeGeneration))
return true;
}
@@ -353,8 +353,11 @@ uint64 RecordVersion::getVirtualOffset()
return (virtualOffset);
}
-int RecordVersion::thaw()
+int RecordVersion::thaw(bool force)
{
+ Sync syncThaw(format->table->getSyncThaw(this), "RecordVersion::thaw");
+ syncThaw.lock(Exclusive);
+
int bytesRestored = 0;
Transaction *trans = transaction;
@@ -367,7 +370,7 @@ int RecordVersion::thaw()
// true, then the record data can be restored from the serial log. If writePending
// is false, then the record data has been written to the data pages.
- if (trans && trans->writePending)
+ if (trans && (trans->writePending || force))
{
trans->addRef();
bytesRestored = trans->thaw(this);
@@ -381,9 +384,6 @@ int RecordVersion::thaw()
// The record data is no longer available in the serial log, so zap the
// virtual offset and restore from the data page.
- if (state != recChilled)
- return size;
-
bool recordFetched = false;
if (bytesRestored == 0)
@@ -414,9 +414,10 @@ int RecordVersion::thaw()
}
if (state == recChilled)
- ASSERT(bytesRestored > 0 || data.record == NULL);
-
- state = recData;
+ {
+ if (data.record != NULL)
+ state = recData;
+ }
return bytesRestored;
}
=== modified file 'storage/falcon/RecordVersion.h'
--- a/storage/falcon/RecordVersion.h 2008-04-25 04:25:18 +0000
+++ b/storage/falcon/RecordVersion.h 2008-10-24 05:06:52 +0000
@@ -53,7 +53,7 @@ public:
virtual void setPriorVersion (Record *oldVersion);
virtual void setVirtualOffset(uint64 offset);
virtual uint64 getVirtualOffset();
- virtual int thaw();
+ virtual int thaw(bool force = false);
virtual void print(void);
virtual int getSize(void);
virtual void serialize(Serialize* stream);
=== modified file 'storage/falcon/SRLUpdateRecords.cpp'
--- a/storage/falcon/SRLUpdateRecords.cpp 2008-10-16 02:53:35 +0000
+++ b/storage/falcon/SRLUpdateRecords.cpp 2008-10-24 05:06:52 +0000
@@ -198,8 +198,11 @@ void SRLUpdateRecords::append(Transactio
// Load the record data into a stream
- if (record->hasRecord())
- record->getRecord(&stream);
+ if (record->hasRecord(false))
+ {
+ if (!record->getRecord(&stream))
+ continue;
+ }
else
ASSERT(record->state == recDeleted);
@@ -247,7 +250,6 @@ void SRLUpdateRecords::append(Transactio
log->chilledRecords += chilledRecordsWindow;
log->chilledBytes += chilledBytesWindow;
transaction->chilledRecords += chilledRecordsWindow;
- transaction->chilledBytes += chilledBytesWindow;
windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE;
}
} // next window
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2008-10-21 20:51:43 +0000
+++ b/storage/falcon/Table.cpp 2008-10-24 05:35:38 +0000
@@ -859,8 +859,12 @@ void Table::init(int id, const char *sch
syncTriggers.setName("Table::syncTriggers");
syncScavenge.setName("Table::syncScavenge");
syncAlter.setName("Table::syncAlter");
+
for (int n = 0; n < SYNC_VERSIONS_SIZE; n++)
syncPriorVersions[n].setName("Table::syncPriorVersions");
+
+ for (int n = 0; n < SYNC_THAW_SIZE; n++)
+ syncThaw[n].setName("Table::syncThaw");
}
Record* Table::fetch(int32 recordNumber)
@@ -2545,9 +2549,6 @@ bool Table::checkUniqueRecordVersion(int
state = transaction->getRelativeState(dup, DO_NOT_WAIT);
- if (dup->state == recChilled)
- dup->getRecordData();
-
// Check for a deleted record or a record lock
if (!dup->hasRecord())
@@ -3548,6 +3549,13 @@ Record* Table::fetchForUpdate(Transactio
return NULL;
}
+ if (record->state == recChilled && !record->thaw())
+ {
+ record->release();
+
+ return NULL;
+ }
+
// Lock the record
if (dbb->debug & DEBUG_RECORD_LOCKS)
@@ -3562,9 +3570,6 @@ Record* Table::fetchForUpdate(Transactio
transaction->addRecord(recordVersion);
recordVersion->release();
- if (record->state == recChilled)
- record->thaw();
-
ASSERT(record->useCount >= 2);
return record;
@@ -3818,6 +3823,18 @@ SyncObject* Table::getSyncPrior(int reco
return syncPriorVersions + lockNumber;
}
+SyncObject* Table::getSyncThaw(Record* record)
+{
+ int lockNumber = record->recordNumber % SYNC_THAW_SIZE;
+ return syncThaw + lockNumber;
+}
+
+SyncObject* Table::getSyncThaw(int recordNumber)
+{
+ int lockNumber = recordNumber % SYNC_THAW_SIZE;
+ return syncThaw + lockNumber;
+}
+
static bool needUniqueCheck(Index *index, Record *record)
{
Record *oldRecord = record->getPriorVersion();
=== modified file 'storage/falcon/Table.h'
--- a/storage/falcon/Table.h 2008-10-16 02:53:35 +0000
+++ b/storage/falcon/Table.h 2008-10-24 05:35:38 +0000
@@ -43,6 +43,7 @@ static const int PostCommit = 128;
static const int BL_SIZE = 128;
static const int FORMAT_HASH_SIZE = 20;
static const int SYNC_VERSIONS_SIZE = 16;
+static const int SYNC_THAW_SIZE = 16;
#define FOR_FIELDS(field,table) {for (Field *field=table->fields; field; field = field->next){
#define FOR_INDEXES(index,table) {for (Index *index=table->indexes; index; index = index->next){
@@ -224,7 +225,8 @@ public:
SyncObject* getSyncPrior(Record* record);
SyncObject* getSyncPrior(int recordNumber);
-
+ SyncObject* getSyncThaw(Record* record);
+ SyncObject* getSyncThaw(int recordNumber);
Dbb *dbb;
SyncObject syncObject;
@@ -232,6 +234,7 @@ public:
SyncObject syncScavenge;
SyncObject syncAlter; // prevent concurrent Alter statements.
SyncObject syncPriorVersions[SYNC_VERSIONS_SIZE];
+ SyncObject syncThaw[SYNC_THAW_SIZE];
Table *collision; // Hash collision in database
Table *idCollision; // mod(id) collision in database
Table *next; // next in database linked list
=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp 2008-10-16 02:53:35 +0000
+++ b/storage/falcon/Transaction.cpp 2008-10-24 05:06:52 +0000
@@ -1526,7 +1526,7 @@ void Transaction::backlogRecords(void)
{
prior = record->prevInTrans;
- if (!record->hasRecord())
+ if (!record->hasRecord(false))
{
if (savePoints)
for (; savePoint && record->savePointId < savePoint->id; savePoint = savePoint->next)
| Thread |
|---|
| • bzr push into mysql-6.0-falcon-team branch (cpowers:2879 to 2881) Bug#36631Bug#38541 Bug#38567 Bug#38569 Bug#39694 Bug#39695 Bug#39696 | Christopher Powers | 24 Oct |