Vlad, Ann, Kelly and Jim,
Please take a look at this change to move the point of durability up
higher in the commit process. I also needed to make the gopher thread
wait for the transaction. Many bad things would happen when a
transaction is completed before it is fully committed.
Kevin
Bug#41194 Falcon durability should occur earlier in the commit process.
http://lists.mysql.com/commits/61832
2938 Kevin Lewis 2008-12-16
Bug#41194 - Move point of durability up higher in the commit
so that by the time other waiting threads are signaled that
this transaction is committed, it will already be durable.
modified:
storage/falcon/Transaction.cpp
per-file messages:
storage/falcon/Transaction.cpp
Bug#41194 - Move point of durability up higher in the commit
so that by the time other waiting threads are signalled that
this transaction is committed, it will already be durable.
=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp 2008-12-16 20:40:38 +0000
+++ b/storage/falcon/Transaction.cpp 2008-12-16 22:48:55 +0000
@@ -266,6 +266,11 @@ void Transaction::commit()
database->flushInversion(this);
+ // Write the commit message to the serial log for durability.
+ // If a crash happens after this, the recover will commit.
+
+ database->commit(this);
+
// Transfer transaction from active list to committed list, set
committed state
Sync
syncActiveTransactions(&transactionManager->activeTransactions.syncObject,
"Transaction::commit(2)");
@@ -294,8 +299,6 @@ void Transaction::commit()
syncIsActive.unlock(); // signal waiting transactions
- database->commit(this);
-
delete [] xid;
xid = NULL;
xidLength = 0;
@@ -1413,12 +1416,30 @@ void Transaction::getInfo(InfoTable* inf
}
}
+// Called by the gopher thread to complete this transaction
+
void Transaction::fullyCommitted(void)
{
ASSERT(inList);
if (useCount < 2)
- Log::debug("Transaction::fullyCommitted: funny use count\n");
+ Log::debug("Transaction::fullyCommitted: Unusual use count=%d\n",
useCount);
+
+ // The commit record is flushed to the serial log before the transaction
+ // is fully committed and waiting threads are signalled. This gopher may
+ // have picked up that record too soon, so wait for that transaction.
+
+ while (isActive())
+ {
+ try
+ {
+ Sync sync(&syncIsActive, "Transaction::fullyCommitted");
+ sync.lock(Shared, 1000);
+ }
+ catch (...)
+ {
+ }
+ }
writeComplete();
releaseCommittedTransaction();