#At file:///home/cpowers/work/dev/dev-03/mysql/
2960 Christopher Powers 2009-01-15
Bug #35755, "Cannot create index on Falcon table(record memory exhausted)"
CREATE INDEX for large tables can fail during Table::populateIndex() because
the Scavenger is blocked by syncSysDDL.
Resolved by eliminating the dependency of Scavenger on syncSysDDL.
modified:
storage/falcon/Database.cpp
storage/falcon/Database.h
per-file messages:
storage/falcon/Database.cpp
Moved updateCardinalities(), which requires a shared lock on syncSysDDL,
out of the Scavenger to a separate thread.
The Scavenger now signals updateCardinalities() and continues to scavenge
asynchronously.
Remove commitSystemTransactions() from Database::scavengeRecords(). This
also requires an exclusive lock on syncSysDDL, thus preventing scavenging
during DDL operations.
storage/falcon/Database.h
Added interface methods to cardinality thread.
=== modified file 'storage/falcon/Database.cpp'
--- a/storage/falcon/Database.cpp 2009-01-10 16:00:02 +0000
+++ b/storage/falcon/Database.cpp 2009-01-15 07:52:32 +0000
@@ -463,6 +463,9 @@ Database::Database(const char *dbName, C
tableSpaceManager = NULL;
timestamp = time (NULL);
tickerThread = NULL;
+ cardinalityThread = NULL;
+ cardinalityThreadSleeping = 0;
+ cardinalityThreadSignaled = 0;
scavengerThread = NULL;
scavengerThreadSleeping = 0;
scavengerThreadSignaled = 0;
@@ -527,6 +530,7 @@ void Database::start()
filterSetManager = new FilterSetManager(this);
timestamp = time(NULL);
tickerThread = threads->start("Database::Database", &Database::ticker, this);
+ cardinalityThread = threads->start("Database::cardinalityThreadMain", &Database::cardinalityThreadMain, this);
scavengerThread = threads->start("Database::scavengerThreadMain", &Database::scavengerThreadMain, this);
internalScheduler->addEvent(scavenger);
internalScheduler->addEvent(garbageCollector);
@@ -1719,7 +1723,7 @@ void Database::validate(int optionMask)
void Database::scavenge()
{
- updateCardinalities();
+ signalCardinality();
// Start by scavenging compiled statements. If they're moldy and not in use,
// off with their heads!
@@ -1778,14 +1782,8 @@ void Database::scavenge()
backLog->reportStatistics();
}
-
void Database::scavengeRecords(void)
{
- // Commit pending system transactions before proceeding
-
- if (systemConnection->transaction)
- commitSystemTransaction();
-
Sync syncScavenger(&syncScavenge, "Database::scavengeRecords(Scavenge)");
syncScavenger.lock(Exclusive);
@@ -1855,7 +1853,6 @@ void Database::pruneRecords(RecordScaven
}
}
-
void Database::retireRecords(RecordScavenge *recordScavenge)
{
// If we passed the upper limit, scavenge.
@@ -1922,6 +1919,7 @@ void Database::scavengerThreadMain(void)
while (!thread->shutdownInProgress)
{
scavenge();
+
if (recordDataPool->activeMemory < recordScavengeThreshold)
{
INTERLOCKED_INCREMENT(scavengerThreadSleeping);
@@ -2409,6 +2407,45 @@ void Database::getTableSpaceFilesInfo(In
tableSpaceManager->getTableSpaceFilesInfo(infoTable);
}
+void Database::cardinalityThreadMain(void * database)
+{
+ ((Database*) database)->cardinalityThreadMain();
+}
+
+void Database::cardinalityThreadMain(void)
+{
+ Thread *thread = Thread::getThread("Database::cardinalityThreadMain");
+
+ thread->sleep(1000);
+
+ while (!thread->shutdownInProgress)
+ {
+ updateCardinalities();
+ INTERLOCKED_INCREMENT(cardinalityThreadSleeping);
+ thread->sleep();
+ cardinalityThreadSignaled = 0;
+ INTERLOCKED_DECREMENT(cardinalityThreadSleeping);
+ }
+}
+
+void Database::signalCardinality(void)
+{
+ Sync syncCard(&syncCardinality, "Database::signalCardinality");
+ syncCard.lock(Exclusive);
+
+ if (cardinalityThreadSleeping && !cardinalityThreadSignaled)
+ {
+ INTERLOCKED_INCREMENT(cardinalityThreadSignaled);
+ cardinalityThreadWakeup();
+ }
+}
+
+void Database::cardinalityThreadWakeup(void)
+{
+ if (cardinalityThread)
+ cardinalityThread->wake();
+}
+
void Database::updateCardinalities(void)
{
Sync syncDDL(&syncSysDDL, "Database::updateCardinalities(1)");
=== modified file 'storage/falcon/Database.h'
--- a/storage/falcon/Database.h 2009-01-08 09:05:26 +0000
+++ b/storage/falcon/Database.h 2009-01-15 07:52:32 +0000
@@ -153,6 +153,9 @@ public:
int createSequence(int64 initialValue);
void ticker();
static void ticker (void *database);
+ static void cardinalityThreadMain(void * database);
+ void cardinalityThreadMain(void);
+ void cardinalityThreadWakeup(void);
static void scavengerThreadMain(void * database);
void scavengerThreadMain(void);
void scavengerThreadWakeup(void);
@@ -229,6 +232,7 @@ public:
void setRecordScavengeThreshold(int value);
void setRecordScavengeFloor(int value);
void checkRecordScavenge(void);
+ void signalCardinality(void);
void signalScavenger(void);
void debugTrace(void);
void pageCacheFlushed(int64 flushArg);
@@ -279,6 +283,7 @@ public:
SyncObject syncConnectionStatements;
SyncObject syncScavenge;
SyncObject syncSysDDL;
+ Mutex syncCardinality;
Mutex syncMemory;
PriorityScheduler *ioScheduler;
Threads *threads;
@@ -300,7 +305,10 @@ public:
SyncHandler *syncHandler;
SearchWords *searchWords;
Thread *tickerThread;
+ Thread *cardinalityThread;
Thread *scavengerThread;
+ volatile INTERLOCK_TYPE cardinalityThreadSleeping;
+ volatile INTERLOCK_TYPE cardinalityThreadSignaled;
volatile INTERLOCK_TYPE scavengerThreadSleeping;
volatile INTERLOCK_TYPE scavengerThreadSignaled;
PageWriter *pageWriter;
Thread |
---|
• bzr commit into mysql-6.0-falcon-team branch (cpowers:2960) Bug#35755 | Christopher Powers | 15 Jan |