#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;
}
Thread |
---|
• bzr commit into mysql-6.0-falcon-team branch (klewis:2897) Bug#40112 | Kevin Lewis | 3 Nov |