diff --git a/ft/cachetable.c b/ft/cachetable.c index 33d1e41ce38d7a471f340d993026eb9661f16ea1..110af5fa6fdc2101133bd36bd0d5a6306ef7f28c 100644 --- a/ft/cachetable.c +++ b/ft/cachetable.c @@ -3068,8 +3068,7 @@ log_open_txn (OMTVALUE txnv, u_int32_t UU(index), void *extra) { FILENUMS open_filenums; uint32_t num_filenums = toku_omt_size(txn->open_fts); FILENUM array[num_filenums]; - if (!txn->begin_was_logged) { - invariant(num_filenums == 0); + if (toku_txn_is_read_only(txn)) { goto cleanup; } else { diff --git a/ft/txn.c b/ft/txn.c index b05e21a38979eeb08ae9eeb412ca671e3e0dfdb5..67c32eb2069661e23bb7aa739aa06cd003b6bfda 100644 --- a/ft/txn.c +++ b/ft/txn.c @@ -349,7 +349,10 @@ static void copy_xid (TOKU_XA_XID *dest, TOKU_XA_XID *source) { int toku_txn_prepare_txn (TOKUTXN txn, TOKU_XA_XID *xa_xid) { int r = 0; if (txn->parent || toku_txn_is_read_only(txn)) { - // nothing to do if there's a parent, or if it's read-only + // We do not prepare children. + // + // Readonly transactions do the same if they commit or abort, so + // XA guarantees are free. No need to pay for overhead of prepare. goto cleanup; } toku_txn_manager_add_prepared_txn(txn->logger->txn_manager, txn); diff --git a/ft/txn_manager.c b/ft/txn_manager.c index 1a00697ba5d42021d784291fc77d5f85b2a46736..b7cf89a006c4db0716b5d46a5651e0b514d993b4 100644 --- a/ft/txn_manager.c +++ b/ft/txn_manager.c @@ -551,7 +551,7 @@ void toku_txn_manager_finish_txn(TXN_MANAGER txn_manager, TOKUTXN txn) { r = toku_omt_delete_at(txn_manager->live_root_txns, idx); invariant_zero(r); - if (txn->begin_was_logged || garbage_collection_debug) { + if (!toku_txn_is_read_only(txn) || garbage_collection_debug) { if (!is_snapshot) { // If it's a snapshot, we already calculated index_in_snapshot_txnids. // Otherwise, calculate it now. @@ -693,7 +693,14 @@ static void invalidate_xa_xid (TOKU_XA_XID *xid) { } void toku_txn_manager_note_abort_txn(TXN_MANAGER txn_manager, TOKUTXN txn) { + // Purpose: + // Delay until any indexer is done pinning this transaction. + // Update status of a transaction from live->aborting (or prepared->aborting) + // Do so in a thread-safe manner that does not conflict with hot indexing or + // begin checkpoint. if (toku_txn_is_read_only(txn)) { + // Neither hot indexing nor checkpoint do any work with readonly txns, + // so we can skip taking the txn_manager lock here. invariant(txn->state==TOKUTXN_LIVE); txn->state = TOKUTXN_ABORTING; goto done; @@ -720,7 +727,14 @@ void toku_txn_manager_note_abort_txn(TXN_MANAGER txn_manager, TOKUTXN txn) { } void toku_txn_manager_note_commit_txn(TXN_MANAGER txn_manager, TOKUTXN txn) { + // Purpose: + // Delay until any indexer is done pinning this transaction. + // Update status of a transaction from live->committing (or prepared->committing) + // Do so in a thread-safe manner that does not conflict with hot indexing or + // begin checkpoint. if (toku_txn_is_read_only(txn)) { + // Neither hot indexing nor checkpoint do any work with readonly txns, + // so we can skip taking the txn_manager lock here. invariant(txn->state==TOKUTXN_LIVE); txn->state = TOKUTXN_COMMITTING; goto done;