List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:January 15 2009 7:52am
Subject:bzr commit into mysql-6.0-falcon-team branch (cpowers:2960) Bug#35755
View as plain text  
#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#35755Christopher Powers15 Jan