MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:klewis Date:March 25 2008 3:55am
Subject:bk commit into 6.0 tree (klewis:1.2608) BUG#35538
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of klewis.  When klewis does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-03-24 22:55:03-05:00, klewis@klewis-mysql. +10 -0
  Bug#35538 - Fix three-way deadlock between scavenger, gopher and 
  an insert by moving the call to Table::validateUpdate() up to the 
  top of Section::updateRecord() so that it does not hold any locks 
  on any BDBs.
  
  Also, prevent an inadvertent wakeup of an active gopher thread 
  waiting on another syncObject.

  storage/falcon/Gopher.cpp@stripped, 2008-03-24 22:54:32-05:00, klewis@klewis-mysql. +4 -0
    Prevent an inadvertent wakeup of an active gopher thread waiting on another syncObject.

  storage/falcon/IO.cpp@stripped, 2008-03-24 22:54:35-05:00, klewis@klewis-mysql. +0 -4
    Cleanup

  storage/falcon/IndexPage.cpp@stripped, 2008-03-24 22:54:37-05:00, klewis@klewis-mysql. +0 -10
    Cleanup

  storage/falcon/IndexPage.h@stripped, 2008-03-24 22:54:39-05:00, klewis@klewis-mysql. +0 -1
    Cleanup

  storage/falcon/IndexRootPage.cpp@stripped, 2008-03-24 22:54:41-05:00, klewis@klewis-mysql. +0 -1
    Cleanup

  storage/falcon/Section.cpp@stripped, 2008-03-24 22:54:43-05:00, klewis@klewis-mysql. +9 -8
    Bug#35538 - Fix three-way deadlock between scavenger, gopher and 
    an insert by moving the call to Table::validateUpdate() up to the 
    top of Section::updateRecord() so that it does not hold any locks 
    on any BDBs.

  storage/falcon/SerialLog.cpp@stripped, 2008-03-24 22:54:45-05:00, klewis@klewis-mysql. +7 -3
    Prevent an inadvertent wakeup of an active gopher thread waiting
    on another syncObject.

  storage/falcon/SyncObject.cpp@stripped, 2008-03-24 22:54:47-05:00, klewis@klewis-mysql. +6 -4
    Check for lockGranted before sleeping and throw a timedOut 
    exception only if sleep actually timed out.

  storage/falcon/Table.cpp@stripped, 2008-03-24 22:54:48-05:00, klewis@klewis-mysql. +0 -4
    Cleanup; Finish deleting all references to unused Table::syncObject

  storage/falcon/Table.h@stripped, 2008-03-24 22:54:50-05:00, klewis@klewis-mysql. +0 -1
    Cleanup; Finish deleting all references to unused Table::syncObject

diff -Nrup a/storage/falcon/Gopher.cpp b/storage/falcon/Gopher.cpp
--- a/storage/falcon/Gopher.cpp	2007-10-25 17:06:45 -05:00
+++ b/storage/falcon/Gopher.cpp	2008-03-24 22:54:32 -05:00
@@ -54,7 +54,9 @@ void Gopher::gopherThread(void)
 				log->unblockUpdates();
 
 			sync.unlock();
+			active = false;
 			workerThread->sleep();
+			active = true;
 			sync.lock(Exclusive);
 
 			continue;
@@ -63,7 +65,9 @@ void Gopher::gopherThread(void)
 		SerialLogTransaction *transaction = log->pending.first;
 		log->pending.remove(transaction);
 		sync.unlock();
+
 		transaction->doAction();
+
 		sync.lock(Exclusive);
 		log->inactions.append(transaction);
 		
diff -Nrup a/storage/falcon/IO.cpp b/storage/falcon/IO.cpp
--- a/storage/falcon/IO.cpp	2008-03-12 07:15:13 -05:00
+++ b/storage/falcon/IO.cpp	2008-03-24 22:54:35 -05:00
@@ -66,10 +66,6 @@ static  int getLinuxVersion();
 #define O_SYNC		0
 #endif
 
-#ifndef O_SYNC
-#define O_SYNC		0
-#endif
-
 #ifndef LSEEK
 #define LSEEK		lseek
 #define SEEK_OFFSET	off_t
diff -Nrup a/storage/falcon/IndexPage.cpp b/storage/falcon/IndexPage.cpp
--- a/storage/falcon/IndexPage.cpp	2008-03-22 09:52:15 -05:00
+++ b/storage/falcon/IndexPage.cpp	2008-03-24 22:54:37 -05:00
@@ -385,8 +385,6 @@ Bdb* IndexPage::splitIndexPageMiddle(Dbb
 
 	if (level == 0)
 		splitKey->appendRecordNumber(recordNumber);
-	
-
 
 	// Split supernodes
 	memset(split->superNodes,0, sizeof(split->superNodes));
@@ -420,7 +418,6 @@ Bdb* IndexPage::splitIndexPageMiddle(Dbb
 	return splitBdb;
 }
 
-
 Btn* IndexPage::findNodeInBranch(IndexKey *searchKey, int32 searchRecordNumber)
 {
 	ASSERT(level > 0);
@@ -443,7 +440,6 @@ Btn* IndexPage::findNodeInBranch(IndexKe
 
 	for (IndexNode node(super) ; node.node < bucketEnd ; prior = node.node, node.getNext(bucketEnd))
 		{
-
 		if (node.offset < matchedOffset)
 			return prior;
 
@@ -580,11 +576,9 @@ void IndexPage::validate(void *before)
 				FATAL("node not correctly prefix-compressed");
 			}
 
-
 		if(node.length == 0 && recordNumber < priorRecordNumber)
 			FATAL ("Index validate:  record numbers out of order");
 
-
 		bool equalKeys = (priorKeyLength == keyLength);
 		for (UCHAR *p = node.key, *q = key + node.offset, *end = key + l; q < end; p++, q++)
 			{
@@ -790,8 +784,6 @@ int IndexPage::deleteNode(Dbb * dbb, Ind
 	return 0;
 }
 
-
-
 void IndexPage::printPage(IndexPage * page, int32 pageNumber, bool inversion)
 {
 	LogLock logLock;
@@ -1143,7 +1135,6 @@ Bdb* IndexPage::splitIndexPageEnd(Dbb *d
 	int nodeOverhead = 3 + (offset >= 128) + (insertKey->keyLength - offset >= 128);
 	char *nextNextNode = (char*) node.nextNode - node.length + insertKey->keyLength - offset + nodeOverhead;
 
-
 	Btn *splitPos;
 	if (nextNextNode >= (char*) this + dbb->pageSize)
 		{
@@ -1408,7 +1399,6 @@ Btn* IndexPage::getEnd(void)
 {
 	return (Btn*) ((UCHAR*) this + length);
 }
-
 
 /* During node insertion, check whether supernode should be added at insertion point */
 bool IndexPage::checkAddSuperNode(int pageSize, IndexNode* node, IndexKey *indexKey, int recordNumber, int offset)
diff -Nrup a/storage/falcon/IndexPage.h b/storage/falcon/IndexPage.h
--- a/storage/falcon/IndexPage.h	2008-03-20 15:56:50 -05:00
+++ b/storage/falcon/IndexPage.h	2008-03-24 22:54:39 -05:00
@@ -77,7 +77,6 @@ public:
 	static int32	getRecordNumber(const UCHAR *ptr);
 	static void		logIndexPage (Bdb *bdb, TransId transId);
 
-
 	int32	parentPage;
 	int32	priorPage;
 	int32	nextPage;
diff -Nrup a/storage/falcon/IndexRootPage.cpp b/storage/falcon/IndexRootPage.cpp
--- a/storage/falcon/IndexRootPage.cpp	2008-03-19 18:46:00 -05:00
+++ b/storage/falcon/IndexRootPage.cpp	2008-03-24 22:54:41 -05:00
@@ -818,7 +818,6 @@ void IndexRootPage::redoIndexPage(Dbb* d
 		memset(indexPage->superNodes, 0, sizeof(indexPage->superNodes));
 		}
 
-	
 	// If we have a parent page, propogate the first node upward
 
 	if (parentPage && indexPage->priorPage != 0)
diff -Nrup a/storage/falcon/Section.cpp b/storage/falcon/Section.cpp
--- a/storage/falcon/Section.cpp	2008-03-12 07:15:13 -05:00
+++ b/storage/falcon/Section.cpp	2008-03-24 22:54:43 -05:00
@@ -495,12 +495,20 @@ void Section::updateRecord(int32 recordN
 		Log::debug("UpdateRecord %d in section %d/%d\n", recordNumber, sectionId, dbb->tableSpaceId);
 #endif
 
+	// Since different gopher threads are processing different 
+	// committed transations, and a later smaller transaction 
+	// can be proccessed faster than an earlier larger transaction, 
+	// be sure this record update will not wipe out a later change.
+
+	if (!dbb->serialLog->recovering && table && !table->validateUpdate(recordNumber, transId))
+		return;
+
 	// Do some fancy accounting to avoid premature use of record number.
 	// If the record number has been reserved, don't bother to delete it.
 
 	if (!stream)
 		reserveRecordNumber(recordNumber);
-	
+
 	// Find section page and slot for record number within section
 
 	int32 slot = recordNumber / dbb->linesPerPage;
@@ -514,13 +522,6 @@ void Section::updateRecord(int32 recordN
 	bdb = dbb->handoffPage (bdb, pageNumber, PAGE_record_locator, Exclusive);
 	BDB_HISTORY(bdb);
 	
-	if (!dbb->serialLog->recovering && table && !table->validateUpdate(recordNumber, transId))
-		{
-		bdb->release();
-		
-		return;
-		}
-
 	// We've found the section index page.  Mark it
 
 	bdb->mark(transId);
diff -Nrup a/storage/falcon/SerialLog.cpp b/storage/falcon/SerialLog.cpp
--- a/storage/falcon/SerialLog.cpp	2008-03-12 07:15:13 -05:00
+++ b/storage/falcon/SerialLog.cpp	2008-03-24 22:54:45 -05:00
@@ -611,9 +611,13 @@ void SerialLog::createNewWindow(void)
 void SerialLog::shutdown()
 {
 	finishing = true;
-	
+
+	// Wake up gophers that are not currently doing anything.  
+	// If they are active, they will see the shutdownInProgress flag.
+
 	for (Gopher *gopher = gophers; gopher; gopher = gopher->next)
-		gopher->wakeup();
+		if ((gopher->workerThread) && gopher->workerThread->sleeping && !gopher->active)
+			gopher->wakeup();
 
 	// Wait for all gopher threads to exit
 	
@@ -705,7 +709,7 @@ void SerialLog::endRecord(void)
 void SerialLog::wakeup()
 {	
 	for (Gopher *gopher = gophers; gopher; gopher = gopher->next)
-		if ((gopher->workerThread) && gopher->workerThread->sleeping)
+		if ((gopher->workerThread) && gopher->workerThread->sleeping && !gopher->active)
 			{
 			gopher->wakeup();
 			break;
diff -Nrup a/storage/falcon/SyncObject.cpp b/storage/falcon/SyncObject.cpp
--- a/storage/falcon/SyncObject.cpp	2008-03-11 10:16:31 -05:00
+++ b/storage/falcon/SyncObject.cpp	2008-03-24 22:54:47 -05:00
@@ -352,11 +352,12 @@ void SyncObject::wait(LockType type, Thr
 	thread->lockPending = sync;
 	++thread->activeLocks;
 	mutex.release();
+	bool wakeup = 0;
 
 	if (timeout)
-		for (;;)
+		while (!thread->lockGranted)
 			{
-			thread->sleep (timeout);
+			wakeup = thread->sleep (timeout);
 			
 			if (thread->lockGranted)
 				return;
@@ -379,13 +380,14 @@ void SyncObject::wait(LockType type, Thr
 					}
 			
 			mutex.unlock();
-			timedout(timeout);
+			if (!wakeup)
+				timedout(timeout);
 			}
 		
 		
 	while (!thread->lockGranted)
 		{
-		bool wakeup = thread->sleep (10000);
+		wakeup = thread->sleep (10000);
 		
 		if (thread->lockGranted)
 			{
diff -Nrup a/storage/falcon/Table.cpp b/storage/falcon/Table.cpp
--- a/storage/falcon/Table.cpp	2008-03-12 07:15:13 -05:00
+++ b/storage/falcon/Table.cpp	2008-03-24 22:54:48 -05:00
@@ -346,7 +346,6 @@ void Table::insert(Transaction *transact
 
 		// Make insert/update atomic, then check for unique index duplicats
 		
-		Sync sync(&syncUpdate, "Table::insert");
 		recordNumber = record->recordNumber = dbb->insertStub(dataSection, transaction);
 		
 		if (indexes)
@@ -837,7 +836,6 @@ void Table::init(int id, const char *sch
 	syncObject.setName("Table::syncObject");
 	syncTriggers.setName("Table::syncTriggers");
 	syncScavenge.setName("Table::syncScavenge");
-	syncUpdate.setName("Table::syncUpdate");
 	syncAlter.setName("Table::syncAlter");
 }
 
@@ -2942,8 +2940,6 @@ uint Table::insert(Transaction *transact
 		
 		// Make insert/update atomic, then check for unique index duplicats
 
-		Sync sync(&syncUpdate, "Table::insert");
-		
 		if (indexes)
 			{
 			checkUniqueIndexes(transaction, record);
diff -Nrup a/storage/falcon/Table.h b/storage/falcon/Table.h
--- a/storage/falcon/Table.h	2008-03-12 07:15:13 -05:00
+++ b/storage/falcon/Table.h	2008-03-24 22:54:50 -05:00
@@ -219,7 +219,6 @@ public:
 	SyncObject		syncObject;
 	SyncObject		syncTriggers;
 	SyncObject		syncScavenge;
-	SyncObject		syncUpdate;
 	SyncObject		syncAlter;				// prevent concurrent Alter statements.
 	Table			*collision;				// Hash collision in database
 	Table			*idCollision;			// mod(id) collision in database
Thread
bk commit into 6.0 tree (klewis:1.2608) BUG#35538klewis25 Mar