List:Commits« Previous MessageNext Message »
From:Kevin Lewis Date:June 2 2009 2:40pm
Subject:bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2713)
Bug#44911
View as plain text  
#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on revid:lars-erik.bjork@stripped

 2713 Kevin Lewis	2009-06-02
      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 from transactions during the commit in the call to Transaction::releaseRecordLocks().  So if a lock record is the base record and the transaction turns out to be committed, then the transaction must have been committed after the fetch.  And it would only be CommittedVisible if the isolation was ReadCommitted or WriteCommitted.  It would not happen with ConsistentRead.

    modified:
      storage/falcon/Table.cpp
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp	2009-05-20 16:58:14 +0000
+++ b/storage/falcon/Table.cpp	2009-06-02 14:40:14 +0000
@@ -3527,6 +3527,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);
@@ -3534,18 +3537,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
 
@@ -3553,6 +3544,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-20090602144014-mdtpf9fmu4vreicg.bundle
Thread
bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2713)Bug#44911Kevin Lewis2 Jun