#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on revid:john.embretsen@stripped
2753 Kevin Lewis 2009-07-08
Bug#45746 - Gopher thread gets error 305.
Transaction::thawAll was added for 44946 but it was too intrusive.
It required a full thaw of all records in the transaction. This
patch limits thawAll to only those records that have already been
superceded by a newer change at 'complete time' when thawAll is
called.
Also, RecordVersion::superceded is converted to
RecordVersion::base and made more reliable by updating it in
RecordLeaf::store.
@ storage/falcon/Record.cpp
Bug#45746 - Convert 'superceded' to 'base'
The value of 'base does not matter for a Record object
since it is not assocviated with any transaction.
@ storage/falcon/Record.h
Bug#45746 - Convert 'superceded' to 'base'
@ storage/falcon/RecordLeaf.cpp
Bug#45746 - Set RecordVersion::base in RecordLeaf::store()
so that it reliably reflects whether a record is currently
the base record.
@ storage/falcon/RecordVersion.cpp
Bug#45746 - Convert 'superceded' to 'base'.
Delete old places where superceded is set since 'base'
is set in RecordLeaf::store().
@ storage/falcon/RecordVersion.h
Bug#45746 - Convert 'superceded' to 'base'.
@ storage/falcon/Table.cpp
Bug#45746 - Convert 'superceded' to 'base'.
Delete old places where superceded is set since 'base'
is set in RecordLeaf::store().
@ storage/falcon/Transaction.cpp
Bug#45746 - Convert 'superceded' to 'base'.
Use RecordVersion::isBase() to limit the number of records
thawed at complete time.
modified:
storage/falcon/Record.cpp
storage/falcon/Record.h
storage/falcon/RecordLeaf.cpp
storage/falcon/RecordVersion.cpp
storage/falcon/RecordVersion.h
storage/falcon/Table.cpp
storage/falcon/Transaction.cpp
=== modified file 'storage/falcon/Record.cpp'
--- a/storage/falcon/Record.cpp 2009-06-23 21:16:25 +0000
+++ b/storage/falcon/Record.cpp 2009-07-08 20:05:22 +0000
@@ -514,7 +514,7 @@ Record* Record::getPriorVersion()
return NULL;
}
-void Record::setSuperceded(bool flag)
+void Record::setBase(bool flag)
{
}
@@ -531,7 +531,7 @@ TransactionState* Record::getTransaction
return NULL;
}
-bool Record::isSuperceded()
+bool Record::isBase()
{
return false;
}
=== modified file 'storage/falcon/Record.h'
--- a/storage/falcon/Record.h 2009-06-23 21:16:25 +0000
+++ b/storage/falcon/Record.h 2009-07-08 20:05:22 +0000
@@ -116,7 +116,7 @@ public:
virtual TransactionState* getTransactionState() const;
virtual TransId getTransactionId();
virtual int getSavePointId();
- virtual void setSuperceded (bool flag);
+ virtual void setBase (bool flag);
virtual Record* fetchVersion (Transaction * transaction);
virtual void retire(void);
virtual void scavenge(TransId targetTransactionId, int oldestActiveSavePointId);
@@ -138,7 +138,7 @@ public:
virtual bool isChilled();
virtual bool isALock();
virtual bool isDeleted();
- virtual bool isSuperceded();
+ virtual bool isBase();
virtual bool isVersion();
virtual bool isNull(int fieldId);
=== modified file 'storage/falcon/RecordLeaf.cpp'
--- a/storage/falcon/RecordLeaf.cpp 2009-04-16 12:09:15 +0000
+++ b/storage/falcon/RecordLeaf.cpp 2009-07-08 20:05:22 +0000
@@ -54,7 +54,7 @@ RecordLeaf::~RecordLeaf()
for (Record *rec = records[n]; rec; rec = rec->getPriorVersion())
rec->active = false;
#endif
-
+ records[n]->setBase(false);
records[n]->release(REC_HISTORY);
}
}
@@ -94,8 +94,9 @@ bool RecordLeaf::store(Record *record, R
return (*parentPtr)->store(record, prior, id, parentPtr);
}
- // If we're adding a new version, don't bother with a lock. Otherwise we need to lock out
- // simultaneous fetches to avoid a potential race between addRef() and release().
+ // If we're adding a new version, don't bother with a lock.
+ // Otherwise we need to lock out simultaneous fetches to avoid
+ // a potential race between addRef() and release().
if (record && record->getPriorVersion() == prior)
{
@@ -111,6 +112,17 @@ bool RecordLeaf::store(Record *record, R
return false;
}
+ // Set the base boolean for these 2 Records.
+ // This can be done after a successful CAS because the only thread
+ // interested in this boolean is the one working on the pending transaction
+ // of the new base record, which it this thread.
+
+ if (prior)
+ prior->setBase(false);
+
+ if (record)
+ record->setBase(true);
+
return true;
}
@@ -207,6 +219,7 @@ void RecordLeaf::retireRecords (Table *t
{
++recordScavenge->recordsRetired;
recordScavenge->spaceRetired += record->getMemUsage();
+ record->setBase(false);
record->retire();
}
else
=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp 2009-06-23 21:16:25 +0000
+++ b/storage/falcon/RecordVersion.cpp 2009-07-08 20:05:22 +0000
@@ -65,7 +65,7 @@ RecordVersion::RecordVersion(Table *tbl,
setTransactionState(transaction->transactionState);
savePointId = transaction->curSavePointId;
- superceded = false;
+ base = false;
// Add a use count on the transaction state to ensure it lives
// as long as the record version object
@@ -77,10 +77,7 @@ RecordVersion::RecordVersion(Table *tbl,
// Be sure the priorVersion is thawed.
- priorVersion->hasRecord();
-
- if (transactionState == priorVersion->getTransactionState())
- oldVersion->setSuperceded (true);
+ priorVersion->getRecordData();
}
else
recordNumber = -1;
@@ -94,18 +91,13 @@ RecordVersion::RecordVersion(Database* d
virtualOffset = stream->getInt64();
TransId transactionId = stream->getInt();
int priorType = stream->getInt();
- superceded = false;
+ base = false;
transactionState = NULL;
if (priorType == 0)
priorVersion = new Record(database, stream);
else if (priorType == 1)
- {
priorVersion = new RecordVersion(database, stream);
-
- if (priorVersion->getTransactionId() == transactionId)
- superceded = true;
- }
else
priorVersion = NULL;
@@ -208,7 +200,7 @@ Record* RecordVersion::fetchVersion(Tran
void RecordVersion::rollback(Transaction *transaction)
{
- if (!superceded)
+ if (isBase())
format->table->rollbackRecord (this, transaction);
}
@@ -318,9 +310,9 @@ Record* RecordVersion::getGCPriorVersion
return (state == recEndChain) ? NULL : priorVersion;
}
-void RecordVersion::setSuperceded(bool flag)
+void RecordVersion::setBase(bool flag)
{
- superceded = flag;
+ base = flag;
}
/***
@@ -335,9 +327,9 @@ TransactionState* RecordVersion::getTran
return transactionState;
}
-bool RecordVersion::isSuperceded()
+bool RecordVersion::isBase()
{
- return superceded;
+ return base;
}
// Set the priorVersion to NULL and return its pointer.
@@ -545,7 +537,7 @@ bool RecordVersion::hasRecord(void)
if (hasNoData(recordData))
return false;
- if (isChilled())
+ if (recordData == recordIsChilled)
{
recordData = thaw();
ASSERT(recordData != recordIsChilled);
=== modified file 'storage/falcon/RecordVersion.h'
--- a/storage/falcon/RecordVersion.h 2009-06-23 21:16:25 +0000
+++ b/storage/falcon/RecordVersion.h 2009-07-08 20:05:22 +0000
@@ -40,7 +40,7 @@ public:
virtual TransactionState* getTransactionState() const;
virtual TransId getTransactionId();
virtual int getSavePointId();
- virtual void setSuperceded (bool flag);
+ virtual void setBase (bool flag);
virtual Record* getPriorVersion();
virtual Record* getGCPriorVersion(void);
virtual void retire(void);
@@ -62,7 +62,7 @@ public:
virtual bool isChilled();
virtual bool isALock();
virtual bool isDeleted();
- virtual bool isSuperceded();
+ virtual bool isBase();
virtual bool isVersion();
void commit();
@@ -82,7 +82,7 @@ public:
RecordVersion *prevInTrans;
//TransId transactionId;
int savePointId;
- bool superceded;
+ bool base; // The record tree currently points to this revord version.
//private:
TransactionState *transactionState;
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2009-06-25 22:48:40 +0000
+++ b/storage/falcon/Table.cpp 2009-07-08 20:05:22 +0000
@@ -1066,23 +1066,15 @@ void Table::rollbackRecord(RecordVersion
Record *priorRecord = recordToRollback->getPriorVersion();
if (priorRecord)
- {
priorRecord->addRef(REC_HISTORY);
- priorRecord->setSuperceded(false);
- }
// Replace the current version of this record.
if (!insertIntoTree(priorRecord, recordToRollback, recordToRollback->recordNumber))
{
- // If a transaction inserts a record and then deletes it,
- // the deleted record version will have no priorRecord.
+ // Deleted record versions must always have a prior version.
- if (priorRecord == NULL && recordToRollback->isDeleted())
- {
- ASSERT(!(priorRecord == NULL && recordToRollback->isDeleted()));
- return; // This should not be an excuse to keep going.
- }
+ ASSERT(!(recordToRollback->isDeleted() && priorRecord == NULL));
// The store of this record into the record leaf failed. No way to recover.
// While the base record is uncommitted, only that transaction can change it.
@@ -1427,10 +1419,6 @@ void Table::update(Transaction * transac
if (record)
{
- Record *prior = record->getPriorVersion();
- if (prior)
- prior->setSuperceded(false);
-
ASSERT(!record->isALock());
record->deleteData();
@@ -3253,10 +3241,6 @@ void Table::update(Transaction * transac
}
else
{
- Record* prior = record->getPriorVersion();
- if (prior)
- prior->setSuperceded(false);
-
char* recordData = record->exchangeData((char*) recordDataIsFreed);
record->deleteData(recordData, false);
@@ -3458,9 +3442,10 @@ void Table::unlockRecord(RecordVersion*
if (!record->isALock())
return;
- // A lock record that has superceded=true is already unlocked
+ // A lock record that has base=false is either already unlocked,
+ // or it has been superceded by an updated version.
- if (record->isSuperceded())
+ if (!record->isBase())
return;
// Only unlock records at the current savepoint
@@ -3469,9 +3454,7 @@ void Table::unlockRecord(RecordVersion*
return;
Record *prior = record->getPriorVersion();
- if (insertIntoTree(prior, record, record->recordNumber))
- record->setSuperceded(true);
- else
+ if (!insertIntoTree(prior, record, record->recordNumber))
Log::debug("Table::unlockRecord: record lock not in record tree\n");
}
=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp 2009-06-23 21:16:25 +0000
+++ b/storage/falcon/Transaction.cpp 2009-07-08 20:05:22 +0000
@@ -249,7 +249,7 @@ void Transaction::commit()
RECORD_HISTORY(record);
Table * table = record->format->table;
- if (!record->isSuperceded() && !record->isALock())
+ if (record->isBase() && !record->isALock())
{
table->updateRecord (record);
@@ -385,6 +385,8 @@ void Transaction::rollback()
Sync syncRec(&syncRecords, "Transaction::rollback(records)");
syncRec.lock(Exclusive);
+ // firstRecord is the oldest, remove and add to stack.
+
while (firstRecord)
{
record = firstRecord;
@@ -397,6 +399,8 @@ void Transaction::rollback()
lastRecord = NULL;
+ // Stack is newest to oldest.
+
while (stack)
{
record = stack;
@@ -1543,7 +1547,7 @@ void Transaction::backlogRecords(void)
// Be sure this is the base record. Backlog all chilled records
// and deleted records, but not lock records
- if ( !record->isSuperceded()
+ if ( record->isBase()
&& ( record->isChilled()
|| record->isDeleted() ))
{
@@ -1596,6 +1600,10 @@ bool Transaction::committedBefore(TransI
return (transactionState->commitId && transactionState->commitId < transactionId);
}
+// Called at 'transaction complete' time to thaw any records
+// that are already updated to a newer version. At this time,
+// the record can still be found in the serial log.
+
void Transaction::thawAll(void)
{
Sync syncRec(&syncRecords,"Transaction::thawAll");
@@ -1607,7 +1615,7 @@ void Transaction::thawAll(void)
for (RecordVersion *record = firstRecord; record && record->nextInTrans; record = record->nextInTrans)
{
totalRecords++;
- if (record->isChilled())
+ if (record->isChilled()&& !record->isBase())
{
totalThawed++;
record->getRecordData();
Attachment: [text/bzr-bundle] bzr/kevin.lewis@sun.com-20090708200522-1nd2ln8e335fxfi0.bundle
| Thread |
|---|
| • bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2753)Bug#45746 | Kevin Lewis | 8 Jul |