From d9f714927f3bb74950ab8654f2a1bb91a92af4f1 Mon Sep 17 00:00:00 2001
From: Zardosht Kasheff <zardosht@tokutek.com>
Date: Tue, 27 Nov 2012 19:14:51 +0000
Subject: [PATCH] refs #5654, grab parent's txn lock when moving rollback
 entries from child to parent when the child commits. This prevents a race
 condition with a hot indexer simultaneously adding something to the parent's
 entry

git-svn-id: file:///svn/toku/tokudb@50375 c7de825b-a66e-492c-adef-691d508d4ae1
---
 ft/rollback-apply.cc   | 2 ++
 src/indexer-undo-do.cc | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/ft/rollback-apply.cc b/ft/rollback-apply.cc
index 879d25c8d1e..f6de4c5d62b 100644
--- a/ft/rollback-apply.cc
+++ b/ft/rollback-apply.cc
@@ -156,6 +156,7 @@ int toku_rollback_commit(TOKUTXN txn, LSN lsn) {
         // list to the end of the parent log entry list.
         if (txn_has_current_rollback_log(txn)) {
             //Pin parent log
+            toku_txn_lock(txn->parent);
             ROLLBACK_LOG_NODE parent_log;
             toku_get_and_pin_rollback_log_for_new_entry(txn->parent, &parent_log);
 
@@ -203,6 +204,7 @@ int toku_rollback_commit(TOKUTXN txn, LSN lsn) {
             toku_maybe_spill_rollbacks(txn->parent, parent_log);
             toku_rollback_log_unpin(txn->parent, parent_log);
             assert(r == 0);
+            toku_txn_unlock(txn->parent);
         }
 
         // Note the open brts, the omts must be merged
diff --git a/src/indexer-undo-do.cc b/src/indexer-undo-do.cc
index aa707cb52f2..3c784aa6883 100644
--- a/src/indexer-undo-do.cc
+++ b/src/indexer-undo-do.cc
@@ -294,6 +294,7 @@ indexer_undo_do_provisional(DB_INDEXER *indexer, DB *hotdb, ULEHANDLE ule, struc
                     case TOKUTXN_LIVE:
                     case TOKUTXN_PREPARING:
                         invariant(this_xid_state != TOKUTXN_ABORTING);
+                        invariant(toku_txn_get_state(curr_txn) == TOKUTXN_LIVE || toku_txn_get_state(curr_txn) == TOKUTXN_PREPARING);
                         result = indexer_ft_delete_provisional(indexer, hotdb, &indexer->i->hotkey, xids, curr_txn);
                         if (result == 0) {
                             indexer_lock_key(indexer, hotdb, &indexer->i->hotkey, prov_ids[0], curr_txn);
@@ -327,6 +328,7 @@ indexer_undo_do_provisional(DB_INDEXER *indexer, DB *hotdb, ULEHANDLE ule, struc
                 case TOKUTXN_LIVE:
                 case TOKUTXN_PREPARING:
                     assert(this_xid_state != TOKUTXN_ABORTING);
+                        invariant(toku_txn_get_state(curr_txn) == TOKUTXN_LIVE || toku_txn_get_state(curr_txn) == TOKUTXN_PREPARING);
                     result = indexer_ft_insert_provisional(indexer, hotdb, &indexer->i->hotkey, &indexer->i->hotval, xids, curr_txn);
                     if (result == 0) {
                         indexer_lock_key(indexer, hotdb, &indexer->i->hotkey, prov_ids[0], prov_txns[0]);
-- 
2.30.9