2869 Kevin Lewis 2008-10-15
Latest updates to the Deadlock Predictor.
Adds the type of lock and better reporting and analysis.
modified:
storage/falcon/SyncHandler.cpp
storage/falcon/SyncHandler.h
storage/falcon/SyncObject.cpp
2868 Kevin Lewis 2008-10-15
This call to poke() is not needed when a RecordVersion
is committed. It only delays the ability of the scavenger
to reclaim the memory for this record.
No bug. No testcase. Most likely, not measurable.
modified:
storage/falcon/RecordVersion.cpp
2867 Kevin Lewis 2008-10-15
Various code cleanup changes.
modified:
storage/falcon/Dbb.cpp
storage/falcon/DeferredIndex.cpp
storage/falcon/DeferredIndex.h
storage/falcon/DeferredIndexWalker.cpp
storage/falcon/Index.cpp
storage/falcon/SRLUpdateIndex.cpp
storage/falcon/SRLUpdateRecords.cpp
storage/falcon/Scavenger.cpp
storage/falcon/Scavenger.h
storage/falcon/SerialLogFile.cpp
storage/falcon/StorageDatabase.cpp
storage/falcon/StorageDatabase.h
storage/falcon/Table.cpp
storage/falcon/Table.h
storage/falcon/Transaction.cpp
storage/falcon/TransactionManager.cpp
storage/falcon/WalkDeferred.cpp
storage/falcon/ha_falcon.cpp
storage/falcon/ha_falcon.h
2866 Kevin Lewis 2008-10-15
Bug#39672 - Using BitMap::nextSet does not work correctly
when you clear the previous set bit. This was fixed by
the other changeset for this bug. This caused half of
the RecordLeafs to remain in memory. In order to process
the bitmap more reliably and make this loop like others
in the Falcon code, we use nextSet(0).
Also, do not spread out the numbers in the emptySections
bitmap by setting record numbers. Use section numbers
for a tighter bitmap.
Also, add some reporting features to analyze the RecordLeaf
objects and their contents.
Also, use RecordSection::anyActiveRecords() instead of
RecordSection::countActiveRecords() when the count is not
important. This will improve speed.
modified:
storage/falcon/Bitmap.h
storage/falcon/Connection.h
storage/falcon/Database.cpp
storage/falcon/RecordGroup.cpp
storage/falcon/RecordGroup.h
storage/falcon/RecordLeaf.cpp
storage/falcon/RecordLeaf.h
storage/falcon/RecordSection.h
storage/falcon/Table.cpp
storage/falcon/Table.h
2865 Kevin Lewis 2008-10-15
Bug#39672 - Using Bitmap::nextSet() failed after searching
from last bit cleard and crossing multiples of 1024.
To show the problem, I added a unit test that can be
activated by "SET GLOBAL FALCON_DEBUG_TRACE=64". The unit
test contains 4 different tests that print "** Error" when
something goes wrong.
modified:
storage/falcon/Bitmap.cpp
storage/falcon/Database.cpp
storage/falcon/Database.h
=== modified file 'storage/falcon/Bitmap.cpp'
--- a/storage/falcon/Bitmap.cpp 2008-06-19 15:09:45 +0000
+++ b/storage/falcon/Bitmap.cpp 2008-10-16 01:04:03 +0000
@@ -19,6 +19,7 @@
#include <memory.h>
#include "Engine.h"
+#include "Log.h"
#include "Bitmap.h"
#ifndef FALCONDB
@@ -207,7 +208,7 @@ int32 Bitmap::nextSet(int32 start)
uint indexes[6];
decompose (start, indexes);
- void **vectors [5];
+ void **vectors [5];
vectors [level] = vector;
int index;
@@ -244,7 +245,8 @@ int32 Bitmap::nextSet(int32 start)
void **vec = vectors [lvl];
for (index = indexes[lvl]; index < BITMAP_VECTOR_SIZE && !vec [index]; ++index)
- ;
+ for (int n = 0; n < lvl; ++n)
+ indexes[n] = 0;
if (index < BITMAP_VECTOR_SIZE)
{
@@ -702,3 +704,116 @@ bool Bitmap::setSafe(int32 bitNumber)
return true;
}
+
+void Bitmap::unitTest(void)
+{
+ int bitNumber;
+ Bitmap *tester = new Bitmap;
+
+ // Set numbers incremented by random amounts.
+ // Check that what is set is set.
+ // Clear sequentially searching from zero.
+ // Check that what was cleared is not still set.
+ Log::log("\nBitmap Test #1\n");
+
+ for (bitNumber = 0; bitNumber < 20000; bitNumber += rand() % 200)
+ {
+ Log::log("Setting bit %d\n", bitNumber);
+ tester->set(bitNumber);
+ }
+
+ for (int bitNumber = 0; (bitNumber = tester->nextSet(0)) >= 0;)
+ {
+ if (!tester->isSet(bitNumber))
+ Log::log("** Error - %d should be set\n", bitNumber);
+
+ Log::log("Clearing bit %d\n", bitNumber);
+ tester->clear(bitNumber);
+
+ if (tester->isSet(bitNumber))
+ Log::log("** Error - %d is still set\n", bitNumber);
+ }
+
+ for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+ Log::log("** Error - bit %d is still set\n", bitNumber);
+
+ tester->clear();
+
+ // Set numbers incremented by large random amounts.
+ // Clear bits after searching from last bit cleard.
+ // Check that all bits are cleared.
+ Log::log("\nBitmap Test #2\n");
+
+ for (bitNumber = 0; bitNumber < 2000000; bitNumber += rand() % 20000)
+ {
+ Log::log("Setting bit %d\n", bitNumber);
+ tester->set(bitNumber);
+ }
+
+ for (int bitNumber = 0; (bitNumber = tester->nextSet(bitNumber)) >= 0;)
+ {
+ Log::log("Clearing bit %d\n", bitNumber);
+ tester->clear(bitNumber);
+ }
+
+ for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+ Log::log("** Error - bit %d is still set\n", bitNumber);
+
+ tester->clear();
+
+ // Set numbers incremented by larger random amounts.
+ // Clear bits after searching from random locations.
+ // Finish clearing after searching from zero.
+ // Check that all bits are cleared.
+ Log::log("\nBitmap Test #3\n");
+
+ for (bitNumber = 0; bitNumber < 2000000; bitNumber += rand() % 20000)
+ {
+ Log::log("Setting bit %d\n", bitNumber);
+ tester->set(bitNumber);
+ }
+
+ for (int bitNumber = 0; (bitNumber = tester->nextSet( ((int32) rand() * (int32) rand()) % 1800000)) >= 0;)
+ {
+ Log::log("Clearing bit %d\n", bitNumber);
+ tester->clear(bitNumber);
+ }
+
+ for (int bitNumber = 0; (bitNumber = tester->nextSet(0)) >= 0;)
+ {
+ Log::log("Clearing bit %d\n", bitNumber);
+ tester->clear(bitNumber);
+ }
+
+ for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+ Log::log("** Error - bit %d is still set\n", bitNumber);
+
+ tester->clear();
+
+ // Set specific numbers around 1024 and 2048.
+ // Clear bits after searching from last bit cleared.
+ // Check that all bits are cleared.
+ Log::log("\nBitmap Test #4\n");
+ for (bitNumber = 1020; bitNumber <= 1040; bitNumber += 1)
+ {
+ Log::log("Setting bit %d\n", bitNumber);
+ tester->set(bitNumber);
+ }
+
+ for (bitNumber = 2040; bitNumber <= 2060; bitNumber += 1) // rand() % 1000)
+ {
+ Log::log("Setting bit %d\n", bitNumber);
+ tester->set(bitNumber);
+ }
+
+ for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber)) >= 0;)
+ {
+ Log::log("Clearing bit %d\n", bitNumber);
+ tester->clear(bitNumber);
+ }
+
+ for (bitNumber = 0; (bitNumber = tester->nextSet(bitNumber + 1)) >= 0;)
+ Log::log("** Error - bit %d is still set \n", bitNumber);
+
+ tester->clear();
+}
=== modified file 'storage/falcon/Bitmap.h'
--- a/storage/falcon/Bitmap.h 2007-09-20 15:44:25 +0000
+++ b/storage/falcon/Bitmap.h 2008-10-16 02:40:08 +0000
@@ -64,6 +64,8 @@ public:
void addRef();
INTERLOCK_TYPE count;
+
+ static void unitTest(void);
protected:
void decompose (int32 number, uint *indexes);
=== modified file 'storage/falcon/Connection.h'
--- a/storage/falcon/Connection.h 2008-02-25 12:17:55 +0000
+++ b/storage/falcon/Connection.h 2008-10-16 02:40:08 +0000
@@ -72,6 +72,7 @@ const int analyzeObjects = 64;
const int analyzeSpace = 128;
const int analyzeSync = 256;
const int analyzeIO = 512;
+const int analyzeRecordLeafs = 1024;
const int traceBooleans = 1;
const int traceTriggers = 2;
=== modified file 'storage/falcon/Database.cpp'
--- a/storage/falcon/Database.cpp 2008-10-13 21:02:24 +0000
+++ b/storage/falcon/Database.cpp 2008-10-16 02:40:08 +0000
@@ -73,12 +73,14 @@
#include "MemoryManager.h"
#include "MemMgr.h"
#include "RecordScavenge.h"
+#include "RecordSection.h"
#include "LogStream.h"
#include "SyncTest.h"
#include "SyncHandler.h"
#include "PriorityScheduler.h"
#include "Sequence.h"
#include "BackLog.h"
+#include "Bitmap.h"
#ifdef _WIN32
#define PATH_MAX _MAX_PATH
@@ -1825,7 +1827,7 @@ void Database::retireRecords(bool forced
catch (SQLException &exception)
{
//syncTbl.unlock();
- Log::debug ("Exception during scavenger of table %s.%s: %s\n",
+ Log::debug ("Exception during scavenge of table %s.%s: %s\n",
table->schemaName, table->name, exception.getText());
}
}
@@ -2049,6 +2051,30 @@ JString Database::analyze(int mask)
stream.putCharacter ('\n');
}
+ if (mask & analyzeRecordLeafs)
+ {
+ int *chart = new int [RECORD_SLOTS + 1];
+ stream.putSegment ("\nRecordLeafs\n");
+
+ for (Table *table = tableList; table; table = table->next)
+ {
+ memset(chart, 0, sizeof(int) * (RECORD_SLOTS + 1));
+ int count = table->chartActiveRecords(chart);
+
+ if (count)
+ {
+ stream.format ("%s.%s\t%d\t", table->schemaName, table->name, count);
+ for (int a = 0; a < RECORD_SLOTS + 1; a++)
+ if (chart[a])
+ stream.format ("[%d]%d ", a, chart[a]);
+
+ stream.format ("\n");
+ }
+ }
+
+ stream.putCharacter ('\n');
+ }
+
if (mask & analyzeStatements)
{
stream.putSegment ("\nStatements\n");
@@ -2501,6 +2527,9 @@ void Database::debugTrace(void)
if (falcon_debug_trace & FALC0N_FREEZE)
Synchronize::freezeSystem();
+ if (falcon_debug_trace & FALC0N_TEST_BITMAP)
+ Bitmap::unitTest();
+
falcon_debug_trace = 0;
#endif
}
=== modified file 'storage/falcon/Database.h'
--- a/storage/falcon/Database.h 2008-09-03 21:49:18 +0000
+++ b/storage/falcon/Database.h 2008-10-16 01:04:03 +0000
@@ -46,6 +46,7 @@ static const int FALC0N_SYNC_OBJECTS =
static const int FALC0N_FREEZE = 8;
static const int FALC0N_REPORT_WRITES = 16;
static const int FALC0N_SYNC_HANDLER = 32;
+static const int FALC0N_TEST_BITMAP = 64;
#define TABLE_HASH_SIZE 101
@@ -305,7 +306,7 @@ public:
int noSchedule;
int pendingIOErrorCode;
uint32 serialLogBlockSize;
-
+
volatile INTERLOCK_TYPE currentGeneration;
uint64 recordMemoryMax;
uint64 recordScavengeThreshold;
=== modified file 'storage/falcon/Dbb.cpp'
--- a/storage/falcon/Dbb.cpp 2008-08-07 21:11:55 +0000
+++ b/storage/falcon/Dbb.cpp 2008-10-16 02:53:35 +0000
@@ -668,10 +668,10 @@ void Dbb::validate(int optionMask)
Validation validation (this, optionMask);
validation.inUse ((int32) HEADER_PAGE, "HeaderPage");
PageInventoryPage::validate (this, &validation);
-
+
if (inversion)
inversion->validate (&validation);
-
+
Section::validateIndexes (this, &validation);
Section::validateSections (this, &validation);
PageInventoryPage::validateInventory (this, &validation);
=== modified file 'storage/falcon/DeferredIndex.cpp'
--- a/storage/falcon/DeferredIndex.cpp 2008-10-04 00:10:34 +0000
+++ b/storage/falcon/DeferredIndex.cpp 2008-10-16 02:53:35 +0000
@@ -819,7 +819,7 @@ void DeferredIndex::scanIndex(IndexKey *
void DeferredIndex::detachIndex(void)
{
Sync sync(&syncObject, "DeferredIndex::detachIndex");
- sync.lock(Exclusive); // was Shared
+ sync.lock(Exclusive); // Do not change while index is in use.
index = NULL;
}
@@ -882,8 +882,10 @@ void DeferredIndex::addRef()
INTERLOCKED_INCREMENT (useCount);
}
-void DeferredIndex::releaseRef()
+void DeferredIndex::release()
{
+ ASSERT(useCount > 0);
+
if (INTERLOCKED_DECREMENT(useCount) == 0)
delete this;
}
=== modified file 'storage/falcon/DeferredIndex.h'
--- a/storage/falcon/DeferredIndex.h 2008-07-25 18:07:24 +0000
+++ b/storage/falcon/DeferredIndex.h 2008-10-16 02:53:35 +0000
@@ -100,6 +100,8 @@ public:
void initializeSpace(void);
DINode* findMaxValue(void);
DINode* findMinValue(void);
+ void addRef();
+ void release();
SyncObject syncObject;
volatile INTERLOCK_TYPE useCount;
@@ -124,8 +126,6 @@ public:
uint64 virtualOffset; // virtual offset into the serial log where this DI was flushed.
uint64 virtualOffsetAtEnd;
SerialLogWindow *window;
- void addRef();
- void releaseRef();
};
#endif
=== modified file 'storage/falcon/DeferredIndexWalker.cpp'
--- a/storage/falcon/DeferredIndexWalker.cpp 2008-09-10 19:51:03 +0000
+++ b/storage/falcon/DeferredIndexWalker.cpp 2008-10-16 02:53:35 +0000
@@ -96,7 +96,7 @@ void DeferredIndexWalker::initialize(Def
DeferredIndexWalker::~DeferredIndexWalker(void)
{
if (deferredIndex)
- deferredIndex->releaseRef();
+ deferredIndex->release();
}
DINode* DeferredIndexWalker::next(void)
=== modified file 'storage/falcon/Index.cpp'
--- a/storage/falcon/Index.cpp 2008-08-19 03:33:01 +0000
+++ b/storage/falcon/Index.cpp 2008-10-16 02:53:35 +0000
@@ -123,6 +123,7 @@ Index::~Index()
{
ASSERT(deferredIndex->index == this);
deferredIndex->detachIndex();
+// deferredIndex->release(); not currently refCounted;
}
}
@@ -277,6 +278,7 @@ DeferredIndex *Index::getDeferredIndex(T
deferredIndex = new DeferredIndex(this, transaction);
sync.lock(Exclusive);
deferredIndexes.append(deferredIndex);
+// deferredIndex->addRef() not currently refCounted;
sync.unlock();
transaction->add(deferredIndex);
@@ -843,6 +845,7 @@ void Index::detachDeferredIndex(Deferred
Sync sync(&deferredIndexes.syncObject, "Index::detachDeferredIndex(1)");
sync.lock(Exclusive);
deferredIndexes.remove(deferredIndex);
+// deferredIndex->release(); not currently refCounted;
sync.unlock();
if ( (database->configuration->useDeferredIndexHash)
=== modified file 'storage/falcon/RecordGroup.cpp'
--- a/storage/falcon/RecordGroup.cpp 2008-03-11 16:15:47 +0000
+++ b/storage/falcon/RecordGroup.cpp 2008-10-16 02:40:08 +0000
@@ -154,6 +154,35 @@ int RecordGroup::countActiveRecords()
return count;
}
+bool RecordGroup::anyActiveRecords()
+{
+ for (RecordSection **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+ {
+ RecordSection *section = *ptr;
+
+ if (section)
+ if (section->anyActiveRecords())
+ return true;
+ }
+
+ return false;
+}
+
+int RecordGroup::chartActiveRecords(int *chart)
+{
+ int count = 0;
+
+ for (RecordSection **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+ {
+ RecordSection *section = *ptr;
+
+ if (section)
+ count += section->chartActiveRecords(chart);
+ }
+
+ return count;
+}
+
bool RecordGroup::inactive()
{
for (int slot = 0; slot < RECORD_SLOTS; slot++)
=== modified file 'storage/falcon/RecordGroup.h'
--- a/storage/falcon/RecordGroup.h 2007-10-26 21:42:32 +0000
+++ b/storage/falcon/RecordGroup.h 2008-10-16 02:40:08 +0000
@@ -33,16 +33,17 @@ public:
RecordGroup(int32 base);
virtual ~RecordGroup();
- virtual int countActiveRecords();
- virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
- virtual void inventoryRecords(RecordScavenge* recordScavenge);
+ virtual int countActiveRecords();
+ virtual bool anyActiveRecords();
+ virtual int chartActiveRecords(int *chart);
+ virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
+ virtual void inventoryRecords(RecordScavenge* recordScavenge);
virtual Record* fetch (int32 id);
- virtual int retireRecords(Table *table, int base, RecordScavenge *recordScavenge);
- virtual bool retireSections(Table * table, int id);
- virtual bool inactive();
+ virtual int retireRecords(Table *table, int base, RecordScavenge *recordScavenge);
+ virtual bool retireSections(Table * table, int id);
+ virtual bool inactive();
- RecordSection *records [RECORD_SLOTS];
- //int32 base;
+ RecordSection *records [RECORD_SLOTS];
};
#endif // !defined(AFX_RECORDGROUP_H__02AD6A55_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
=== modified file 'storage/falcon/RecordLeaf.cpp'
--- a/storage/falcon/RecordLeaf.cpp 2008-07-15 18:57:27 +0000
+++ b/storage/falcon/RecordLeaf.cpp 2008-10-16 02:40:08 +0000
@@ -118,7 +118,7 @@ int RecordLeaf::retireRecords (Table *ta
{
int count = 0;
Record **ptr, **end;
- Sync sync(&syncObject, "RecordLeaf::retireRecords(1)");
+ Sync sync(&syncObject, "RecordLeaf::retireRecords(syncObject)");
sync.lock(Shared);
// Get a shared lock to find at least one record to scavenge
@@ -134,7 +134,7 @@ int RecordLeaf::retireRecords (Table *ta
++count;
else if (record->isVersion())
{
- Sync syncPrior(record->getSyncPrior(), "RecordLeaf::retireRecords(2)");
+ Sync syncPrior(record->getSyncPrior(), "RecordLeaf::retireRecords(prior)");
syncPrior.lock(Shared);
if (record->scavenge(recordScavenge, Shared))
@@ -220,7 +220,7 @@ int RecordLeaf::retireRecords (Table *ta
// identifier when the leaf node is scavenged later.
if (!count && table->emptySections)
- table->emptySections->set(base * RECORD_SLOTS);
+ table->emptySections->set(base);
return count;
}
@@ -232,7 +232,7 @@ bool RecordLeaf::retireSections(Table *
bool RecordLeaf::inactive()
{
- return countActiveRecords() == 0;
+ return (!anyActiveRecords());
}
int RecordLeaf::countActiveRecords()
@@ -246,6 +246,23 @@ int RecordLeaf::countActiveRecords()
return count;
}
+bool RecordLeaf::anyActiveRecords()
+{
+ for (Record **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+ if (*ptr)
+ return true;
+
+ return false;
+}
+
+int RecordLeaf::chartActiveRecords(int *chart)
+{
+ int count = countActiveRecords();
+ chart[count]++;
+
+ return count;
+}
+
void RecordLeaf::inventoryRecords(RecordScavenge* recordScavenge)
{
Sync sync(&syncObject, "RecordLeaf::inventoryRecords");
=== modified file 'storage/falcon/RecordLeaf.h'
--- a/storage/falcon/RecordLeaf.h 2007-09-25 05:14:45 +0000
+++ b/storage/falcon/RecordLeaf.h 2008-10-16 02:40:08 +0000
@@ -31,8 +31,10 @@
class RecordLeaf : public RecordSection
{
public:
- virtual int countActiveRecords();
- virtual int retireRecords(Table *table, int id, RecordScavenge *recordScavenge);
+ virtual int countActiveRecords();
+ virtual bool anyActiveRecords();
+ virtual int chartActiveRecords(int *chart);
+ virtual int retireRecords(Table *table, int id, RecordScavenge *recordScavenge);
virtual bool retireSections(Table * table, int id);
virtual bool inactive();
virtual bool store(Record *record, Record *prior, int32 id,RecordSection **parentPtr);
=== modified file 'storage/falcon/RecordSection.h'
--- a/storage/falcon/RecordSection.h 2007-10-26 21:42:32 +0000
+++ b/storage/falcon/RecordSection.h 2008-10-16 02:40:08 +0000
@@ -38,11 +38,13 @@ public:
virtual bool inactive() = 0;
virtual ~RecordSection();
- virtual Record* fetch (int32 id) = 0;
- virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr) = 0;
- virtual int retireRecords(Table *table, int base, RecordScavenge *recordScavenge) = 0;
- virtual void inventoryRecords(RecordScavenge* recordScavenge) = 0;
- virtual int countActiveRecords() = 0;
+ virtual Record* fetch (int32 id) = 0;
+ virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr) = 0;
+ virtual int retireRecords(Table *table, int base, RecordScavenge *recordScavenge) = 0;
+ virtual void inventoryRecords(RecordScavenge* recordScavenge) = 0;
+ virtual int countActiveRecords() = 0;
+ virtual bool anyActiveRecords() = false;
+ virtual int chartActiveRecords(int *chart) = 0;
int32 base;
};
=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp 2008-08-27 12:55:46 +0000
+++ b/storage/falcon/RecordVersion.cpp 2008-10-16 02:57:10 +0000
@@ -175,7 +175,6 @@ bool RecordVersion::isVersion()
void RecordVersion::commit()
{
transaction = NULL;
- poke();
}
// Scavenge record versions by the scavenger thread. Return true if the
=== modified file 'storage/falcon/SRLUpdateIndex.cpp'
--- a/storage/falcon/SRLUpdateIndex.cpp 2008-10-04 00:10:34 +0000
+++ b/storage/falcon/SRLUpdateIndex.cpp 2008-10-16 02:53:35 +0000
@@ -40,25 +40,19 @@ SRLUpdateIndex::~SRLUpdateIndex(void)
void SRLUpdateIndex::append(DeferredIndex* deferredIndex)
{
- uint indexId;
- int idxVersion;
- int tableSpaceId;
-
- Sync syncDI(&deferredIndex->syncObject, "SRLUpdateIndex::append");
+ Sync syncDI(&deferredIndex->syncObject, "SRLUpdateIndex::append(DI)");
syncDI.lock(Shared);
if (!deferredIndex->index)
return;
- else
- {
- indexId = deferredIndex->index->indexId;
- idxVersion = deferredIndex->index->indexVersion;
- tableSpaceId = deferredIndex->index->dbb->tableSpaceId;
- }
+
+ uint indexId = deferredIndex->index->indexId;
+ int idxVersion = deferredIndex->index->indexVersion;
+ int tableSpaceId = deferredIndex->index->dbb->tableSpaceId;
syncDI.unlock();
- Sync syncIndexes(&log->syncIndexes, "SRLUpdateIndex::append(1)");
+ Sync syncIndexes(&log->syncIndexes, "SRLUpdateIndex::append(Indexes)");
syncIndexes.lock(Shared);
Transaction *transaction = deferredIndex->transaction;
=== modified file 'storage/falcon/SRLUpdateRecords.cpp'
--- a/storage/falcon/SRLUpdateRecords.cpp 2008-08-27 07:08:18 +0000
+++ b/storage/falcon/SRLUpdateRecords.cpp 2008-10-16 02:53:35 +0000
@@ -247,6 +247,7 @@ void SRLUpdateRecords::append(Transactio
log->chilledRecords += chilledRecordsWindow;
log->chilledBytes += chilledBytesWindow;
transaction->chilledRecords += chilledRecordsWindow;
+ transaction->chilledBytes += chilledBytesWindow;
windowNumber = (uint32)log->writeWindow->virtualOffset / SRL_WINDOW_SIZE;
}
} // next window
=== modified file 'storage/falcon/Scavenger.cpp'
--- a/storage/falcon/Scavenger.cpp 2007-09-20 15:44:25 +0000
+++ b/storage/falcon/Scavenger.cpp 2008-10-16 02:53:35 +0000
@@ -32,10 +32,10 @@
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-Scavenger::Scavenger (Database *db, ScavengeType scavengeType, const char *schedule) : Schedule (schedule)
+Scavenger::Scavenger (Database *db, ScavengerType scavengerType, const char *schedule) : Schedule (schedule)
{
database = db;
- type = scavengeType;
+ type = scavengerType;
}
Scavenger::~Scavenger()
=== modified file 'storage/falcon/Scavenger.h'
--- a/storage/falcon/Scavenger.h 2007-09-20 15:44:25 +0000
+++ b/storage/falcon/Scavenger.h 2008-10-16 02:53:35 +0000
@@ -26,7 +26,7 @@
#include "Schedule.h"
-enum ScavengeType {
+enum ScavengerType {
scvRecords,
scvJava,
};
@@ -38,13 +38,13 @@ class Scavenger : public Schedule
public:
virtual void execute (Scheduler *scheduler);
void scavenge();
- Scavenger(Database *db, ScavengeType scavengeType, const char *schedule);
+ Scavenger(Database *db, ScavengerType scavengerType, const char *schedule);
protected:
virtual ~Scavenger();
Database *database;
- ScavengeType type;
+ ScavengerType type;
};
#endif // !defined(AFX_SCAVENGER_H__9E139FC3_1F3E_11D3_AB74_0000C01D2301__INCLUDED_)
=== modified file 'storage/falcon/SerialLogFile.cpp'
--- a/storage/falcon/SerialLogFile.cpp 2008-10-14 13:00:31 +0000
+++ b/storage/falcon/SerialLogFile.cpp 2008-10-16 02:53:35 +0000
@@ -128,7 +128,7 @@ void SerialLogFile::open(JString filenam
if (create)
- handle = ::open(filename, O_RDWR | O_BINARY | O_CREAT|O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ handle = ::open(filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
else
handle = ::open(filename, O_RDWR | O_BINARY);
=== modified file 'storage/falcon/StorageDatabase.cpp'
--- a/storage/falcon/StorageDatabase.cpp 2008-08-18 20:17:15 +0000
+++ b/storage/falcon/StorageDatabase.cpp 2008-10-16 02:53:35 +0000
@@ -491,7 +491,7 @@ int StorageDatabase::nextIndexed(Storage
return record->recordNumber;
}
-
+/*
RecordVersion* StorageDatabase::lockRecord(StorageConnection* storageConnection, Table *table, Record* record)
{
try
@@ -505,7 +505,7 @@ RecordVersion* StorageDatabase::lockReco
return NULL;
}
}
-
+*/
int StorageDatabase::savepointSet(Connection* connection)
{
Transaction *transaction = connection->getTransaction();
=== modified file 'storage/falcon/StorageDatabase.h'
--- a/storage/falcon/StorageDatabase.h 2008-08-18 05:45:29 +0000
+++ b/storage/falcon/StorageDatabase.h 2008-10-16 02:53:35 +0000
@@ -81,7 +81,7 @@ public:
int nextIndexed(StorageTable *storageTable, void* recordBitmap, int recordNumber, bool lockForUpdate);
int nextIndexed(StorageTable* storageTable, IndexWalker* indexWalker, bool lockForUpdate);
int fetch(StorageConnection* storageConnection, StorageTable* storageTable, int recordNumber, bool lockForUpdate);
- RecordVersion* lockRecord(StorageConnection* storageConnection, Table *table, Record* record);
+// RecordVersion* lockRecord(StorageConnection* storageConnection, Table *table, Record* record);
int updateRow(StorageConnection* storageConnection, Table* table, Record *oldRecord, Stream* stream);
int getSegmentValue(StorageSegment* segment, const UCHAR* ptr, Value* value, Field *field);
=== modified file 'storage/falcon/SyncHandler.cpp'
--- a/storage/falcon/SyncHandler.cpp 2008-09-03 21:49:18 +0000
+++ b/storage/falcon/SyncHandler.cpp 2008-10-16 02:59:09 +0000
@@ -143,7 +143,7 @@ SyncHandler::~SyncHandler(void)
#endif
}
-void SyncHandler::addLock(SyncObject *syncObj, const char* locationName)
+void SyncHandler::addLock(SyncObject *syncObj, const char* locationName, LockType type)
{
#ifdef USE_FALCON_SYNC_HANDLER
if (syncObj == &syncObject)
@@ -158,7 +158,7 @@ void SyncHandler::addLock(SyncObject *sy
SyncThreadInfo *thd = addThread(thread->threadId);
SyncObjectInfo *soi = addSyncObject(syncObj->getName());
- SyncLocationInfo *loc = addLocation(locationName, soi);
+ SyncLocationInfo *loc = addLocation(locationName, soi, type);
addToThread(thd, loc);
#endif
@@ -297,29 +297,31 @@ void SyncHandler::showSyncObjects(void)
Log::debug(" %s\n", soi->name);
}
-SyncLocationInfo *SyncHandler::findLocation(const char* locationName, int slot)
+SyncLocationInfo *SyncHandler::findLocation(const char* locationName, LockType type, int slot)
{
for (SyncLocationInfo *loc = locations[slot]; loc; loc = loc->collision)
{
- if (loc->name == locationName)
+ if ((loc->name == locationName) && (loc->type == type))
return loc;
}
return NULL;
}
-SyncLocationInfo *SyncHandler::addLocation(const char* locationName, SyncObjectInfo *soi)
+
+SyncLocationInfo *SyncHandler::addLocation(const char* locationName, SyncObjectInfo *soi, LockType type)
{
ASSERT(locationName != NULL);
ASSERT(strlen(locationName) != 0);
int slot = JString::hash(locationName, locationHashSize);
- SyncLocationInfo *loc = findLocation(locationName, slot);
+ SyncLocationInfo *loc = findLocation(locationName, type, slot);
if (!loc)
{
loc = new SyncLocationInfo;
loc->name = locationName;
loc->soi = soi;
+ loc->type = type;
loc->collision = locations[slot];
locations[slot] = loc;
if ((++locationCount % 100) == 0)
@@ -339,10 +341,9 @@ void SyncHandler::showLocations(void)
for (int slot = 0; slot < locationHashSize; slot++)
for (SyncLocationInfo *loc = locations[slot]; loc; loc = loc->collision)
- Log::debug(" %s\t%s\n", loc->name, loc->soi->name);
+ Log::debug(" %s\t%s\t%s\n", loc->name, loc->soi->name, (loc->type == Exclusive ? "Exclusive" : "Shared"));
}
-
void SyncHandler::addToThread(SyncThreadInfo* thd, SyncLocationInfo *loc)
{
// Be sure this soi is only recorded once.
@@ -476,19 +477,34 @@ void SyncHandler::showLocationStacks(voi
for (int slot = 0; slot < stackHashSize; slot++)
for (LocationStackInfo *lsi = locationStacks[slot]; lsi; lsi = lsi->collision)
- {
- int stackHeight = 0;
- stackCount++;
- for (int n = 0; n < lsi->height - 1; n++)
- Log::debug(" %4d-%03d; %s (%s) ->\n",
- stackCount, ++stackHeight,
- lsi->loc[n]->name, lsi->loc[n]->soi->name);
-
- Log::debug(" %4d-%03d; %s (%s)\n\n",
- stackCount, ++stackHeight,
- lsi->loc[lsi->height - 1]->name,
- lsi->loc[lsi->height - 1]->soi->name);
- }
+ showLocationStack(lsi);
+}
+
+void SyncHandler::showLocationStack(int stackNum)
+{
+ for (int slot = 0; slot < stackHashSize; slot++)
+ for (LocationStackInfo *lsi = locationStacks[slot]; lsi; lsi = lsi->collision)
+ if (lsi->count == stackNum)
+ {
+ showLocationStack(lsi);
+ return;
+ }
+}
+
+void SyncHandler::showLocationStack(LocationStackInfo *lsi)
+{
+ int stackHeight = 0;
+ for (int n = 0; n < lsi->height - 1; n++)
+ Log::debug(" %4d-%03d; %s (%s) - %s ->\n",
+ lsi->count, ++stackHeight,
+ lsi->loc[n]->name, lsi->loc[n]->soi->name,
+ (lsi->loc[n]->type == Exclusive ? "Exclusive" : "Shared"));
+
+ Log::debug(" %4d-%03d; %s (%s) - %s\n\n",
+ lsi->count, ++stackHeight,
+ lsi->loc[lsi->height - 1]->name,
+ lsi->loc[lsi->height - 1]->soi->name,
+ (lsi->loc[lsi->height - 1]->type == Exclusive ? "Exclusive" : "Shared"));
}
DeadlockInfo* SyncHandler::findDeadlock(DeadlockInfo* dli, int slot)
@@ -527,12 +543,10 @@ void SyncHandler::validate(void)
{
// Make a list of all SyncObjects that must occur before and after and this.
- SyncObjectInfo *before[1000];
- memset(before, 0, sizeof(before));
+ memset(soi->beforeList, 0, sizeof(soi->beforeList));
int beforeCount = 0;
- SyncObjectInfo *after[1000];
- memset(after, 0, sizeof(after));
+ memset(soi->afterList, 0, sizeof(soi->afterList));
int afterCount = 0;
// search each location stack for this soi, make a list of
@@ -544,29 +558,35 @@ void SyncHandler::validate(void)
for (c = 0; c < lsi->height; c++)
if (soi == lsi->loc[c]->soi)
{
+
+ // Record the SyncObjects that occur before this
+
for (d = 0; d < c; d++)
{
for (e = 0; e < beforeCount; e++)
- if (before[e] == lsi->loc[d]->soi)
+ if (soi->beforeList[e] == lsi->loc[d]->soi)
break;
if (e == beforeCount)
- before[beforeCount++] = lsi->loc[d]->soi;
+ soi->beforeList[beforeCount++] = lsi->loc[d]->soi;
ASSERT(lsi->loc[d]->soi);
- ASSERT(beforeCount < 1000);
+ ASSERT(beforeCount < beforeAfterSize);
}
+
+ // Record the SyncObjects that occur after this
+
for (d = c + 1; d < lsi->height; d++)
{
for (e = 0; e < afterCount; e++)
- if (after[e] == lsi->loc[d]->soi)
+ if (soi->afterList[e] == lsi->loc[d]->soi)
break;
if (e == afterCount)
- after[afterCount++] = lsi->loc[d]->soi;
+ soi->afterList[afterCount++] = lsi->loc[d]->soi;
ASSERT(lsi->loc[d]->soi);
- ASSERT(afterCount < 1000);
+ ASSERT(afterCount < beforeAfterSize);
}
}
}
@@ -574,10 +594,85 @@ void SyncHandler::validate(void)
// Make sure none of the SyncObjects in before are also in after.
for (b = 0; b < beforeCount; b++)
- if (soi != before[b])
+ if (soi != soi->beforeList[b])
for (c = 0; c < afterCount; c++)
- if (before[b] == after[c])
- addPossibleDeadlock(soi, after[c]);
+ if (soi->beforeList[b] == soi->afterList[c])
+ addPossibleDeadlock(soi, soi->afterList[c]);
+ }
+
+ // Refine the list of possible deadlocks
+ // The second SOI was found before and after the first.
+ // But if that happened on the same stack, it is OK as long as
+ // the two calls do not go from shared up to exclusive.
+ for (a = 0; a < deadlockHashSize; a++)
+ for (DeadlockInfo *dli = possibleDeadlocks[a]; dli; dli = dli->collision)
+ {
+ bool foundBothInOneStack = false;
+ bool foundOneBeforeTwo = false;
+ bool foundTwoBeforeOne = false;
+ bool foundRisingLock = false;
+
+ for (b = 0; b < stackHashSize; b++)
+ for (LocationStackInfo *lsi = locationStacks[b]; lsi; lsi = lsi->collision)
+ {
+ int firstOneNum = 0;
+ int lastOneNum = 0;
+ int firstTwoNum = 0;
+ int lastTwoNum = 0;
+
+ for (c = 0; c < lsi->height; c++)
+ {
+ if (dli->soi[0] == lsi->loc[c]->soi)
+ if (firstOneNum)
+ {
+ lastOneNum = c + 1;
+ if ( (lsi->loc[firstOneNum - 1]->type == Shared)
+ && (lsi->loc[c]->type == Exclusive))
+ {
+ foundRisingLock = true;
+ lsi->hasRisingLockTypes = true;
+ }
+ }
+ else
+ firstOneNum = c + 1;
+
+ else if (dli->soi[1] == lsi->loc[c]->soi)
+ if (firstTwoNum)
+ {
+ lastTwoNum = c + 1;
+ if ( (lsi->loc[firstTwoNum - 1]->type == Shared)
+ && (lsi->loc[c]->type == Exclusive))
+ {
+ foundRisingLock = true;
+ lsi->hasRisingLockTypes = true;
+ }
+ }
+ else
+ firstTwoNum = c + 1;
+ }
+
+ if (firstOneNum && firstTwoNum)
+ {
+ if (firstOneNum < lastTwoNum && lastTwoNum < lastOneNum)
+ foundBothInOneStack = true;
+ else if (firstTwoNum < lastOneNum && lastOneNum < lastTwoNum)
+ foundBothInOneStack = true;
+ else if (firstOneNum < firstTwoNum)
+ foundOneBeforeTwo = true;
+ else if (firstTwoNum < firstOneNum)
+ foundTwoBeforeOne = true;
+
+ }
+ }
+
+ // Is this still a possible deadlock?
+ if ( foundBothInOneStack
+ && !(foundOneBeforeTwo && foundTwoBeforeOne)
+ && !foundRisingLock)
+ {
+ // Take this possible deadlock out of the list.
+ removePossibleDeadlock(dli);
+ }
}
}
@@ -591,6 +686,7 @@ void SyncHandler::addPossibleDeadlock(Sy
dli->soi[0] = soi1;
dli->soi[1] = soi2;
+ dli->isPossible = true;
// Now calulate the hash number and slot.
// This hash algorithm must return the same slot for two SyncObjectInfo *
@@ -614,50 +710,98 @@ void SyncHandler::addPossibleDeadlock(Sy
delete dli;
}
+void SyncHandler::removePossibleDeadlock(DeadlockInfo* dli)
+{
+ int slot = dli->hash % deadlockHashSize;
+
+ for (DeadlockInfo* stack = possibleDeadlocks[slot]; stack; stack = stack->collision)
+ {
+ if (stack == dli)
+ dli->isPossible = false;
+ }
+}
+
#define FOUND_FIRST 1
#define FOUND_SECOND 2
#define FOUND_BOTH 3
+#define ONE_TWO 1
+#define TWO_ONE 2
void SyncHandler::showPossibleDeadlockStacks(void)
{
- int a,b,c;
+ int a;
int possibleDeadlockCount = 0;
for (a = 0; a < deadlockHashSize; a++)
for (DeadlockInfo *dli = possibleDeadlocks[a]; dli; dli = dli->collision)
- possibleDeadlockCount++;
+ if (dli->isPossible)
+ possibleDeadlockCount++;
Log::debug("\n== SyncHandler has found %d possible deadlocks ==\n", possibleDeadlockCount);
for (a = 0; a < deadlockHashSize; a++)
for (DeadlockInfo *dli = possibleDeadlocks[a]; dli; dli = dli->collision)
- {
- int stackCount = 0;
- Log::debug("\n=== Possible Deadlock; %s and %s ===\n Stacks =", dli->soi[0]->name, dli->soi[1]->name);
+ if (dli->isPossible)
+ {
+ Log::debug("\n=== Possible Deadlock===\n");
+ showPossibleDeadlockStack(dli, ONE_TWO);
+ showPossibleDeadlockStack(dli, TWO_ONE);
+ }
+}
+
+void SyncHandler::showPossibleDeadlockStack(DeadlockInfo *dli, int showOrder)
+{
+ LocationStackInfo *sampleLsi1 = NULL;
+ LocationStackInfo *sampleLsi2 = NULL;
+ int stackCount = 0;
+ if (showOrder == ONE_TWO)
+ Log::debug(" %s before %s\n", dli->soi[0]->name, dli->soi[1]->name);
+ else
+ Log::debug(" %s before %s\n", dli->soi[1]->name, dli->soi[0]->name);
- // Reference all call stacks with these two SyncObjects.
+ // Find call stacks containing these two SyncObjects.
- for (b = 0; b < stackHashSize; b++)
- for (LocationStackInfo *lsi = locationStacks[b]; lsi; lsi = lsi->collision)
- {
- // Does this location stack have both SyncObjects?
+ for (int b = 0; b < stackHashSize; b++)
+ for (LocationStackInfo *lsi = locationStacks[b]; lsi; lsi = lsi->collision)
+ {
+ // Does this location stack have both SyncObjects?
- int numFound = 0;
- for (c = 0; c < lsi->height; c++)
- {
- if (lsi->loc[c]->soi == dli->soi[0])
- numFound |= FOUND_FIRST;
- else if (lsi->loc[c]->soi == dli->soi[1])
- numFound |= FOUND_SECOND;
- }
+ int numFound = 0;
+ int order = 0;
+ for (int c = 0; c < lsi->height; c++)
+ {
+ if (lsi->loc[c]->soi == dli->soi[0])
+ {
+ numFound |= FOUND_FIRST;
+ if (!order)
+ order = ONE_TWO;
+ }
+ else if (lsi->loc[c]->soi == dli->soi[1])
+ {
+ numFound |= FOUND_SECOND;
+ if (!order)
+ order = TWO_ONE;
+ }
+ }
- if (numFound == FOUND_BOTH)
- {
- if (stackCount && ((stackCount % 10) == 0))
- Log::debug("\n ");
- stackCount++;
- Log::debug(" %d", lsi->count);
- }
+ if ( (numFound == FOUND_BOTH) && (order == showOrder) )
+ {
+ if (stackCount == 0)
+ {
+ sampleLsi1 = lsi;
+ Log::debug(" Stacks =", dli->soi[0]->name, dli->soi[1]->name);
}
- Log::debug("\n");
+ else if ((stackCount % 10) == 0)
+ Log::debug("\n ");
+
+ stackCount++;
+ Log::debug(" %d", lsi->count);
+ sampleLsi2 = lsi;
+ }
}
+
+ Log::debug("\n");
+ if (sampleLsi1)
+ showLocationStack(sampleLsi1);
+ if (sampleLsi2)
+ showLocationStack(sampleLsi2);
}
#endif
=== modified file 'storage/falcon/SyncHandler.h'
--- a/storage/falcon/SyncHandler.h 2008-09-03 21:49:18 +0000
+++ b/storage/falcon/SyncHandler.h 2008-10-16 02:59:09 +0000
@@ -28,6 +28,7 @@ static const int locationHashSize = 503;
static const int threadHashSize = 100;
static const int stackHashSize = 1000;
static const int deadlockHashSize = 100;
+static const int beforeAfterSize = 60;
static const int syncStackSize = 20;
struct SyncObjectInfo
@@ -36,6 +37,10 @@ struct SyncObjectInfo
SyncObjectInfo *prev;
SyncObjectInfo *next;
SyncObjectInfo *collision;
+ SyncObjectInfo *beforeList[beforeAfterSize];
+ SyncObjectInfo *afterList[beforeAfterSize];
+ SyncObjectInfo *before;
+ SyncObjectInfo *after;
bool multiple;
};
@@ -43,6 +48,7 @@ struct SyncLocationInfo
{
JString name;
SyncObjectInfo *soi;
+ LockType type;
SyncLocationInfo *collision;
};
@@ -61,6 +67,7 @@ struct LocationStackInfo
int height;
int hash;
int count;
+ bool hasRisingLockTypes;
LocationStackInfo *collision;
};
@@ -68,6 +75,7 @@ struct DeadlockInfo
{
SyncObjectInfo *soi[2];
int hash;
+ bool isPossible;
DeadlockInfo *collision;
};
@@ -84,7 +92,7 @@ public:
SyncHandler(void);
virtual ~SyncHandler(void);
- void addLock(SyncObject *syncObj, const char *locationName);
+ void addLock(SyncObject *syncObj, const char *locationName, LockType type);
void delLock(SyncObject *syncObj);
void dump(void);
@@ -98,12 +106,14 @@ private:
SyncObjectInfo * findSyncObject(const char* syncObjectName, int slot);
SyncObjectInfo * addSyncObject(const char* syncObjectName);
void showSyncObjects(void);
- SyncLocationInfo * findLocation(const char* locationName, int slot);
- SyncLocationInfo * addLocation(const char* locationName, SyncObjectInfo *soi);
+ SyncLocationInfo * findLocation(const char* locationName, LockType type, int slot);
+ SyncLocationInfo * addLocation(const char* locationName, SyncObjectInfo *soi, LockType type);
void showLocations(void);
LocationStackInfo * findStack(LocationStackInfo* stk, int slot);
void addStack(SyncThreadInfo* thd);
void showLocationStacks(void);
+ void showLocationStack(int stackNum);
+ void showLocationStack(LocationStackInfo *lsi);
void countLocationStacks(void);
DeadlockInfo * findDeadlock(DeadlockInfo* dli, int slot);
@@ -113,7 +123,9 @@ private:
void validate(void);
void addPossibleDeadlock(SyncObjectInfo *soi1, SyncObjectInfo *soi2);
+ void removePossibleDeadlock(DeadlockInfo* dli);
void showPossibleDeadlockStacks(void);
+ void showPossibleDeadlockStack(DeadlockInfo *dli, int showOrder);
SyncObject syncObject;
=== modified file 'storage/falcon/SyncObject.cpp'
--- a/storage/falcon/SyncObject.cpp 2008-09-03 21:49:18 +0000
+++ b/storage/falcon/SyncObject.cpp 2008-10-16 02:59:09 +0000
@@ -148,7 +148,7 @@ void SyncObject::lock(Sync *sync, LockTy
#ifdef USE_FALCON_SYNC_HANDLER
SyncHandler *syncHandler = getFalconSyncHandler();
if (sync && syncHandler)
- syncHandler->addLock(this, location);
+ syncHandler->addLock(this, location, type);
#endif
#endif
@@ -320,7 +320,7 @@ void SyncObject::lock(Sync *sync, LockTy
#ifdef USE_FALCON_SYNC_HANDLER
SyncHandler *syncHandler = getFalconSyncHandler();
if (sync && syncHandler)
- syncHandler->addLock(this, location);
+ syncHandler->addLock(this, location, type);
#endif
#endif
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2008-10-03 23:56:24 +0000
+++ b/storage/falcon/Table.cpp 2008-10-16 02:53:35 +0000
@@ -162,6 +162,9 @@ Table::~Table()
if (recordBitmap)
recordBitmap->release();
+
+ if (emptySections)
+ emptySections->release();
}
Field* Table::findField(const char * fieldName)
@@ -1875,7 +1878,7 @@ int Table::retireRecords(RecordScavenge
syncObj.lock(Exclusive);
// Confirm that tree is still empty
-
+
count = records->countActiveRecords();
if (count == 0)
@@ -1888,16 +1891,17 @@ int Table::retireRecords(RecordScavenge
{
// Get an exclusive lock only if there are empty leaf nodes. Find and
// delete the empty nodes using the stored record numbers as identifiers.
-
+
if (emptySections->count > 0)
{
syncObj.unlock();
syncObj.lock(Exclusive);
- for (int recordNumber = 0; (recordNumber = emptySections->nextSet(recordNumber)) >= 0;)
+ for (int sectionNumber = 0; (sectionNumber = emptySections->nextSet(0)) >= 0;)
{
+ int recordNumber = sectionNumber * RECORD_SLOTS;
records->retireSections(this, recordNumber);
- emptySections->clear(recordNumber);
+ emptySections->clear(sectionNumber);
}
}
@@ -2117,10 +2121,10 @@ void Table::garbageCollect(Record *leavi
if (!leaving && !staying)
return;
- Sync sync (&syncObject, "Table::garbageCollect(1)");
+ Sync sync (&syncObject, "Table::garbageCollect(Obj)");
sync.lock(Shared);
- Sync syncPrior(getSyncPrior(leaving ? leaving : staying), "Table::garbageCollect(2)");
+ Sync syncPrior(getSyncPrior(leaving ? leaving : staying), "Table::garbageCollect(prior)");
syncPrior.lock(Shared);
// Clean up field indexes
@@ -2770,6 +2774,17 @@ int Table::countActiveRecords()
return records->countActiveRecords();
}
+int Table::chartActiveRecords(int *chart)
+{
+ Sync sync(&syncObject, "Table::countActiveRecords");
+ sync.lock(Shared);
+
+ if (!records)
+ return 0;
+
+ return records->chartActiveRecords(chart);
+}
+
void Table::rebuildIndex(Index *index, Transaction *transaction)
{
index->rebuildIndex(transaction);
@@ -3364,7 +3379,7 @@ void Table::waitForWriteComplete()
{
database->waitForWriteComplete(this);
}
-
+/*
RecordVersion* Table::lockRecord(Record* record, Transaction* transaction)
{
Record *current = fetch(record->recordNumber);
@@ -3411,7 +3426,7 @@ RecordVersion* Table::lockRecord(Record*
}
return recordVersion;
-}
+} */
void Table::unlockRecord(int recordNumber)
{
=== modified file 'storage/falcon/Table.h'
--- a/storage/falcon/Table.h 2008-08-18 05:45:29 +0000
+++ b/storage/falcon/Table.h 2008-10-16 02:53:35 +0000
@@ -99,6 +99,7 @@ public:
void rebuildIndex (Index *index, Transaction *transaction);
int retireRecords (RecordScavenge *recordScavenge);
int countActiveRecords();
+ int chartActiveRecords(int *chart);
bool foreignKeyMember (ForeignKey *key);
void makeNotSearchable (Field *field, Transaction *transaction);
bool dropForeignKey (int fieldCount, Field **fields, Table *references);
@@ -204,7 +205,7 @@ public:
void inventoryRecords(RecordScavenge* recordScavenge);
Format* getCurrentFormat(void);
Record* fetchForUpdate(Transaction* transaction, Record* record, bool usingIndex);
- RecordVersion* lockRecord(Record* record, Transaction* transaction);
+// RecordVersion* lockRecord(Record* record, Transaction* transaction);
void unlockRecord(int recordNumber);
void unlockRecord(RecordVersion* record, bool remove);
=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp 2008-10-10 18:42:44 +0000
+++ b/storage/falcon/Transaction.cpp 2008-10-16 02:53:35 +0000
@@ -397,7 +397,7 @@ void Transaction::rollback()
// Rollback pending record versions from newest to oldest in case
// there are multiple record versions on a prior record chain
- Sync syncRec(&syncRecords, "Transaction::rollback(1.5)");
+ Sync syncRec(&syncRecords, "Transaction::rollback(records)");
syncRec.lock(Exclusive);
while (firstRecord)
@@ -451,7 +451,7 @@ void Transaction::rollback()
xidLength = 0;
}
- Sync syncActiveTransactions (&transactionManager->activeTransactions.syncObject, "Transaction::rollback(2)");
+ Sync syncActiveTransactions (&transactionManager->activeTransactions.syncObject, "Transaction::rollback(active)");
syncActiveTransactions.lock (Exclusive);
++transactionManager->rolledBack;
@@ -1494,7 +1494,7 @@ void Transaction::releaseDeferredIndexes
ASSERT(deferredIndex->transaction == this);
deferredIndexes = deferredIndex->nextInTransaction;
deferredIndex->detachTransaction();
- deferredIndex->releaseRef();
+ deferredIndex->release();
deferredIndexCount--;
}
}
@@ -1510,7 +1510,7 @@ void Transaction::releaseDeferredIndexes
{
*ptr = deferredIndex->nextInTransaction;
deferredIndex->detachTransaction();
- deferredIndex->releaseRef();
+ deferredIndex->release();
--deferredIndexCount;
}
else
=== modified file 'storage/falcon/TransactionManager.cpp'
--- a/storage/falcon/TransactionManager.cpp 2008-08-25 21:51:46 +0000
+++ b/storage/falcon/TransactionManager.cpp 2008-10-16 02:53:35 +0000
@@ -291,7 +291,7 @@ void TransactionManager::purgeTransactio
Sync syncCommitted(&committedTransactions.syncObject, "Transaction::purgeTransactions");
syncCommitted.lock(Exclusive);
- // And, while we're at it, check for any fully mature transactions to ditch
+ // Check for any fully mature transactions to ditch
for (Transaction *transaction, *next = committedTransactions.first; (transaction = next);)
{
=== modified file 'storage/falcon/WalkDeferred.cpp'
--- a/storage/falcon/WalkDeferred.cpp 2008-07-25 18:07:24 +0000
+++ b/storage/falcon/WalkDeferred.cpp 2008-10-16 02:53:35 +0000
@@ -26,7 +26,7 @@ WalkDeferred::WalkDeferred(DeferredIndex
WalkDeferred::~WalkDeferred(void)
{
- deferredIndex->releaseRef();
+ deferredIndex->release();
}
Record* WalkDeferred::getNext(bool lockForUpdate)
=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp 2008-10-14 13:00:31 +0000
+++ b/storage/falcon/ha_falcon.cpp 2008-10-16 02:53:35 +0000
@@ -1277,7 +1277,7 @@ int StorageInterface::start_consistent_s
{
DBUG_ENTER("StorageInterface::start_consistent_snapshot");
int ret = storageHandler->startTransaction(thd, TRANSACTION_CONSISTENT_READ);
- if (!ret)
+ if (!ret)
trans_register_ha(thd, true, hton);
DBUG_RETURN(ret);
=== modified file 'storage/falcon/ha_falcon.h'
--- a/storage/falcon/ha_falcon.h 2008-09-16 17:58:49 +0000
+++ b/storage/falcon/ha_falcon.h 2008-10-16 02:53:35 +0000
@@ -176,12 +176,12 @@ public:
StorageConnection* storageConnection;
StorageTable* storageTable;
StorageTableShare* storageShare;
- Field **fieldMap;
+ Field **fieldMap;
const char* errorText;
THR_LOCK_DATA lockData; // MySQL lock
THD *mySqlThread;
- TABLE_SHARE *share;
- uint recordLength;
+ TABLE_SHARE *share;
+ uint recordLength;
int lastRecord;
int nextRecord;
int indexErrorId;
@@ -189,12 +189,12 @@ public:
int maxFields;
StorageBlob *activeBlobs;
StorageBlob *freeBlobs;
- bool haveStartKey;
- bool haveEndKey;
- bool tableLocked;
- bool tempTable;
- bool lockForUpdate;
- bool indexOrder;
+ bool haveStartKey;
+ bool haveEndKey;
+ bool tableLocked;
+ bool tempTable;
+ bool lockForUpdate;
+ bool indexOrder;
key_range startKey;
key_range endKey;
uint64 insertCount;
| Thread |
|---|
| • bzr push into mysql-6.0-falcon-team branch (klewis:2865 to 2869) Bug#39672 | Kevin Lewis | 16 Oct |