#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on revid:vvaintroub@stripped
3038 Kevin Lewis 2009-02-25
Bug#41742 - Since Table::fetchNext seems to do OK if a bit below the higWater mark
is set incorrectly, but does not do OK if a bit below highWater is cleared incorrectly,
I am changing Table::insertIntoTree so that it sets bits but does not clear them.
Bits are already not cleared by RecordLeaf::retireRecords.
So it will be the responsibility of Table::fetchRecords to clear bits below the highWater
mark if the record is not found in either the record tree or the database. This is done
under an exclusive lock of Table::syncObject. After the lock is made and before we clear
that bit, another fetch is attempted just in case another thread just added that record.
Since Table::insertIntoTree no longer clears bits in recordBitmap, we no longer need to
re-set the bit in Table::backlogRecord().
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2009-02-25 16:53:39 +0000
+++ b/storage/falcon/Table.cpp 2009-02-26 05:57:24 +0000
@@ -519,9 +519,9 @@ Record* Table::fetchNext(int32 start)
- recordNumber = highWater;
+ recordNumber = recordBitmapHighWater;
- else if (eof || bitNumber < highWater)
+ else if (eof || bitNumber < recordBitmapHighWater)
// Record should exist somewhere
@@ -569,12 +569,29 @@ Record* Table::fetchNext(int32 start)
ASSERT(n < 2);
+ // Table::databaseFetch returned NULL. That bit should no longer be set
+ // But Table::syncObject is not currently locked.
+ // While you are reading this, another thread may be adding this record
+ // and setting the bit. So get an exclusive lock and double check that it
+ // is not in the tree.
- // Record has gotten lost; no serious cause for concern
+ if ((record = records->fetch(bitNumber)))
+ // Woops, there it is!
+ return record;
+ // The record did not re-appear. Clear the bit and try the next bit.
recordNumber = bitNumber + 1;
@@ -594,7 +611,7 @@ Record* Table::fetchNext(int32 start)
- highWater = recNumber + 1;
+ recordBitmapHighWater = recNumber + 1;
// If we've got that record in memory, use it instead
@@ -863,7 +880,7 @@ void Table::init(int id, const char *sch
deleting = false;
foreignKeys = NULL;
records = NULL;
- highWater = 0;
+ recordBitmapHighWater = 0;
eof = false;
markedForDelete = false;
primaryKey = NULL;
@@ -1963,9 +1980,6 @@ bool Table::insertIntoTree(Record * reco
- if (!record)
records = NEW RecordLeaf;
@@ -2006,8 +2020,6 @@ bool Table::insertIntoTree(Record * reco
- recordBitmap->set(recordNumber); // Reset the bit
@@ -3809,10 +3821,13 @@ int32 Table::backlogRecord(RecordVersion
backlogId = database->backLog->save(record);
+ // InsertIntoTree does not clear bits in recordBitmap.
+ // We want the bit to remain set so this record can be found
+ // in fetchNext().
ASSERT(insertIntoTree(NULL, record, record->recordNumber));
=== modified file 'storage/falcon/Table.h'
--- a/storage/falcon/Table.h 2009-02-12 20:22:40 +0000
+++ b/storage/falcon/Table.h 2009-02-26 05:57:24 +0000
@@ -272,7 +272,7 @@ public:
bool deleting; // dropping or truncating.
- int32 highWater;
+ int32 recordBitmapHighWater;
|• bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:3038)Bug#41742||Kevin Lewis||26 Feb|