From: Date: November 3 2008 1:33am Subject: bzr commit into mysql-6.0-falcon-team branch (klewis:2897) Bug#40112 List-Archive: http://lists.mysql.com/commits/57650 X-Bug: 40112 Message-Id: <200811030033.mA30XEdG011645@mail.mysql.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ 2897 Kevin Lewis 2008-11-02 Bug#40112 - DeferredIndexWalker::next() was not prepared for the first leaf bucket to be empty. But it can become empty after several verbs in the same transaction change the same records. When the same record is changed more than once in the same transaction, the older unneeded versions are deleted along with the index entries. Even though DeferredIndex key nodes can be deleted, the buckets are not. If the first leaf bucket is empty, DeferredIndexWalker::next() would return NULL on the first call. In SRLUpdateIndex::append(), this would result that nothing would be put into the Serial log at commit time for this DeferredIndex. Then this DefferedIndex would not get put into index pages. The solution is to only return NULL on the first call to DeferredIndexWalker::next() if the first leaf bucket is empty AND there is no parent bucket. Otherwise, use the normal mechanism to advance to the next slot. modified: storage/falcon/DeferredIndexWalker.cpp storage/falcon/Transaction.cpp per-file messages: storage/falcon/DeferredIndexWalker.cpp Bug#40112 - Only return NULL on the first call to DeferredIndexWalker:: next() if the first leaf bucket is empty AND there is no parent bucket. Otherwise, use the normal mechanism to advance to the next slot. storage/falcon/Transaction.cpp Distinguish a System Transaction in LogXARecovery messages. Add LogXARecovery messages for rollbacks and commitNoUpdates. === modified file 'storage/falcon/DeferredIndexWalker.cpp' --- a/storage/falcon/DeferredIndexWalker.cpp 2008-10-16 02:53:35 +0000 +++ b/storage/falcon/DeferredIndexWalker.cpp 2008-11-03 00:33:04 +0000 @@ -110,10 +110,16 @@ DINode* DeferredIndexWalker::next(void) { nodePending = false; - return currentNode = (slot >= leaf->count) ? NULL : leaf->nodes[slot]; + if (slot < leaf->count) + return (currentNode = leaf->nodes[slot]); + + if (!deferredIndex->levels) + return NULL; // Only one bucket and it is empty + // else the first leaf is empty. Back up a level. } + else + ++slot; - ++slot; DIBucket *bucket; for (;;) === modified file 'storage/falcon/Transaction.cpp' --- a/storage/falcon/Transaction.cpp 2008-10-24 05:06:52 +0000 +++ b/storage/falcon/Transaction.cpp 2008-11-03 00:33:04 +0000 @@ -250,7 +250,8 @@ void Transaction::commit() TransactionManager *transactionManager = database->transactionManager; addRef(); - Log::log(LogXARecovery, "%d: Commit transaction %d\n", database->deltaTime, transactionId); + Log::log(LogXARecovery, "%d: Commit %sTransaction %d\n", + database->deltaTime, (systemTransaction ? "System " : ""), transactionId); if (state == Active) { @@ -340,6 +341,7 @@ void Transaction::commitNoUpdates(void) TransactionManager *transactionManager = database->transactionManager; addRef(); ASSERT(!deferredIndexes); + Log::log(LogXARecovery, "%d: CommitNoUpdates transaction %d\n", database->deltaTime, transactionId); ++transactionManager->committed; if (deferredIndexes) @@ -384,6 +386,8 @@ void Transaction::rollback() if (!isActive()) throw SQLEXCEPTION (RUNTIME_ERROR, "transaction is not active"); + Log::log(LogXARecovery, "%d: Rollback transaction %d\n", database->deltaTime, transactionId); + if (deferredIndexes) releaseDeferredIndexes(); @@ -951,6 +955,9 @@ void Transaction::writeComplete(void) if (dependencies == 0) commitRecords(); +// Log::log(LogXARecovery, "%d: WriteComplete %sTransaction %d\n", +// database->deltaTime, (systemTransaction ? "System " : ""), transactionId); + writePending = false; }