#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on revid:kevin.lewis@stripped
2713 Kevin Lewis 2009-05-26
Bug#44911 - Suppose a call to fetchForUpdate is called for a base lockRecord returned from Table::fetch, but before it is evaluated, the lockRecord is superceded by an update record and the transaction is committed. FetchForUpdate will need to re-fetch the new committed record as if getRelativeState() had returned WasActive. But getRelativeState() returned CommittedVisible. That would have caused this FATAL condition that a "Committed non-deleted record has no data buffer". So a check for (source->state == recLock) needs to be done in order to re-fetch the base record. A lockRecord can still be linked to a transaction after the commit if it was updated at a higher savepoint. But they are always superceded with newer records. Regular lockRecords are unlinked fro transaction during the commit in the call to Transaction::releaseRecordLocks().
modified:
storage/falcon/Table.cpp
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2009-05-26 18:11:13 +0000
+++ b/storage/falcon/Table.cpp 2009-05-26 18:32:05 +0000
@@ -3502,7 +3502,7 @@ Record* Table::fetchForUpdate(Transactio
return prior;
}
- // The record number is not currently locked.
+ // The record number is not currently locked by us.
for (;;)
{
@@ -3532,6 +3532,9 @@ Record* Table::fetchForUpdate(Transactio
case CommittedVisible:
{
+ if (source->state == recLock)
+ break; // need to re-fetch the base record
+
if (source->state == recDeleted)
{
source->release(REC_HISTORY);
@@ -3539,18 +3542,6 @@ Record* Table::fetchForUpdate(Transactio
return NULL;
}
- if (!source->hasRecord())
- {
- if (source->isVersion())
- {
- RecordVersion *rv = (RecordVersion *) source;
- FATAL("Committed non-deleted record has no data buffer. state=%d, useCount=%d, virtualOffset=" I64FORMAT "\n",
- rv->state, rv->useCount, rv->virtualOffset);
- }
- else
- FATAL("Committed non-deleted record has no data buffer. state=%d, useCount=%d" I64FORMAT "\n",
- source->state, source->useCount);
- }
// Lock the record
@@ -3558,6 +3549,10 @@ Record* Table::fetchForUpdate(Transactio
Log::debug("Table::fetchForUpdate: TransactionId=%d, isolationLevel=%d, recordNumber=%d\n",
transaction->transactionId, transaction->isolationLevel, recordNumber);
+ if (!source->hasRecord())
+ FATAL("Committed non-deleted record has no data buffer. state=%d, useCount=%d\n",
+ source->state, source->useCount);
+
RecordVersion *lockRecord = allocRecordVersion(NULL, transaction, source);
lockRecord->state = recLock;
Attachment: [text/bzr-bundle] bzr/kevin.lewis@sun.com-20090526183205-h8ps8u0t8pm7y22a.bundle
| Thread |
|---|
| • bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2713)Bug#44911 | Kevin Lewis | 26 May |