#At file:///home/cpowers/work/dev/dev-06/mysql/
2801 Christopher Powers 2008-08-27
Bug #38566 Falcon crash in RecordVersion::thaw at RecordVersion.cpp:421
Removed unnecessary log messages
Modified assertions to accommodate race condition where two threads thaw the same record
modified:
storage/falcon/RecordVersion.cpp
storage/falcon/SRLUpdateRecords.cpp
per-file messages:
storage/falcon/RecordVersion.cpp
RecordVersion::thaw()
- Removed unnecessary log debug messages
- Check record state before asserting on number of bytes restored
storage/falcon/SRLUpdateRecords.cpp
SRLUpdateRecords::thaw()
- Only assert on record number if record was actually thawed
- Update chill/thaw byte counts if record was actualy thawed
- setRecordData() checks for race condition using compare and exchange pointer, so no need to assert if record wasn't thawed by current thread
=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp 2008-07-15 18:57:27 +0000
+++ b/storage/falcon/RecordVersion.cpp 2008-08-27 07:08:18 +0000
@@ -416,11 +416,9 @@ int RecordVersion::thaw()
}
}
- if (bytesRestored <= 0)
- Log::debug("RecordVersion::thaw: writePending %d, was %d, recordFetched %d, data %p\n",
- trans->writePending, wasWritePending, recordFetched, data.record);
-
- ASSERT(bytesRestored > 0 || data.record == NULL);
+ if (state == recChilled)
+ ASSERT(bytesRestored > 0 || data.record == NULL);
+
state = recData;
return bytesRestored;
=== modified file 'storage/falcon/SRLUpdateRecords.cpp'
--- a/storage/falcon/SRLUpdateRecords.cpp 2008-04-09 08:23:51 +0000
+++ b/storage/falcon/SRLUpdateRecords.cpp 2008-08-27 07:08:18 +0000
@@ -84,34 +84,39 @@ int SRLUpdateRecords::thaw(RecordVersion
// Get section id, record id and data length written. Input pointer will be at
// beginning of record data.
- int tableSpaceId;
+ int tableSpaceId = 0;
if (control->version >= srlVersion8)
tableSpaceId = control->getInt();
- else
- tableSpaceId = 0;
control->getInt(); // sectionId
int recordNumber = control->getInt();
int dataLength = control->getInt();
- ASSERT(recordNumber == record->recordNumber);
- int bytesReallocated = record->setRecordData(control->input, dataLength);
+ int bytesReallocated = 0;
+
+ // setRecordData() handles race conditions with an interlocked compare and exchange,
+ // but check the state and record number anyway
- if (bytesReallocated > 0)
- bytesReallocated = record->getEncodedSize();
+ if (record->state == recChilled && recordNumber == record->recordNumber)
+ bytesReallocated = record->setRecordData(control->input, dataLength);
window->deactivateWindow();
- if (log->chilledRecords > 0)
- log->chilledRecords--;
+ if (bytesReallocated > 0)
+ {
+ ASSERT(recordNumber == record->recordNumber);
+ bytesReallocated = record->getEncodedSize();
+ *thawed = true;
+
+ if (log->chilledRecords > 0)
+ log->chilledRecords--;
- if (log->chilledBytes > uint64(bytesReallocated))
- log->chilledBytes -= bytesReallocated;
- else
- log->chilledBytes = 0;
-
- *thawed = true;
-
+ if (log->chilledBytes > uint64(bytesReallocated))
+ log->chilledBytes -= bytesReallocated;
+ else
+ log->chilledBytes = 0;
+ }
+
return bytesReallocated;
}