#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on revid:kevin.lewis@stripped
3043 Kevin Lewis 2009-02-25
Bug #41742 Falcon REPEATABLE READ does not return repeatable results
Suspecting that the recordBitmap gets out of sync with the Record tree,
I rearranged Table::insertIntoTree so that;
1) It gets and exclusive or shared lock up front.
2) When deleting a record from the tree, it clears recordBitmap first because
other threads doing fetchNext() will check the recordBitmap first.
We don't want them to find a set bit and then not find the record in the tree.
3) When inserting a record into the tree, it now sets the recordBitmap last,
after assuring that the store() succeeded.
4) If the store of a NULL failed, the recordBitmap is now re-set.
This may be the real cause of the inconsistency.
modified:
storage/falcon/Table.cpp
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2009-02-14 17:11:43 +0000
+++ b/storage/falcon/Table.cpp 2009-02-25 16:53:39 +0000
@@ -1956,40 +1956,19 @@ void Table::retireRecords(RecordScavenge
bool Table::insertIntoTree(Record * record, Record *prior, int recordNumber)
{
ageGroup = database->currentGeneration;
- Sync sync(&syncObject, "Table::insert");
- if (record)
- {
-#ifdef CHECK_RECORD_ACTIVITY
- record->active = true;
-#endif
- sync.lock(Shared);
-
- if (!recordBitmap->setSafe(recordNumber))
- {
- sync.unlock();
- sync.lock(Exclusive);
- recordBitmap->set(recordNumber);
- }
- }
- else
- {
+ Sync sync(&syncObject, "Table::insert");
+ if (!record || !records)
sync.lock(Exclusive);
+ else
+ sync.lock(Shared);
+
+ if (!record)
recordBitmap->clear(recordNumber);
- }
if (!records)
- {
- if (sync.state != Exclusive)
- {
- sync.unlock();
- sync.lock(Exclusive);
- }
-
- if (!records)
- records = NEW RecordLeaf;
- }
-
+ records = NEW RecordLeaf;
+
// Bump the record use count on the assumption that the
// store will succeed. Release it later if it fails.
@@ -2005,13 +1984,31 @@ bool Table::insertIntoTree(Record * reco
#endif
prior->release();
}
-
+
+ if (record)
+ {
+#ifdef CHECK_RECORD_ACTIVITY
+ prior->active = true;
+#endif
+
+ if (!recordBitmap->setSafe(recordNumber))
+ {
+ sync.unlock();
+ sync.lock(Exclusive);
+ recordBitmap->set(recordNumber);
+ }
+ }
+
return true;
}
-
+
+ // The store() failed.
+
if (record)
record->release();
-
+ else
+ recordBitmap->set(recordNumber); // Reset the bit
+
return false;
}