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#35538 | klewis | 25 Mar |