summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSiyuan Zhou <siyuan.zhou@mongodb.com>2019-01-25 15:30:56 -0500
committerSiyuan Zhou <siyuan.zhou@mongodb.com>2019-02-11 15:45:50 -0500
commita27f223e14ddfe73bc300e4e1801d51575b44795 (patch)
treeac7b105ca2905a44d98b2a22d339b8aaa5538a60 /src
parent9db1a8dffe753808bea0d8c47d9fc959eaea9ea0 (diff)
downloadmongo-a27f223e14ddfe73bc300e4e1801d51575b44795.tar.gz
SERVER-39206 Avoid PBWM lock conflicts for prepared transaction on startup
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/repl/apply_ops.cpp2
-rw-r--r--src/mongo/db/repl/replication_recovery.cpp3
-rw-r--r--src/mongo/db/transaction_participant.cpp3
-rw-r--r--src/mongo/db/transaction_participant_test.cpp1
4 files changed, 9 insertions, 0 deletions
diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp
index 6f90eedf4c1..608e7ce3c64 100644
--- a/src/mongo/db/repl/apply_ops.cpp
+++ b/src/mongo/db/repl/apply_ops.cpp
@@ -455,6 +455,8 @@ Status applyApplyOpsOplogEntry(OperationContext* opCtx,
}
Status applyRecoveredPrepareTransaction(OperationContext* opCtx, const OplogEntry& entry) {
+ // Snapshot transactions never conflict with the PBWM lock.
+ invariant(!opCtx->lockState()->shouldConflictWithSecondaryBatchApplication());
UnreplicatedWritesBlock uwb(opCtx);
return _applyPrepareTransaction(opCtx, entry, OplogApplication::Mode::kRecovering);
}
diff --git a/src/mongo/db/repl/replication_recovery.cpp b/src/mongo/db/repl/replication_recovery.cpp
index ec6a31a99ac..28b0c28562a 100644
--- a/src/mongo/db/repl/replication_recovery.cpp
+++ b/src/mongo/db/repl/replication_recovery.cpp
@@ -308,6 +308,9 @@ void ReplicationRecoveryImpl::_reconstructPreparedTransactions(OperationContext*
AlternativeClientRegion acr(newClient);
const auto newOpCtx = cc().makeOperationContext();
+ // Snapshot transaction can never conflict with the PBWM lock.
+ newOpCtx->lockState()->setShouldConflictWithSecondaryBatchApplication(false);
+
// Checks out the session, applies the operations and prepares the transactions.
uassertStatusOK(applyRecoveredPrepareTransaction(newOpCtx.get(), prepareOplogEntry));
}
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index 83a9b67aeb4..b484d0fc07c 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -869,6 +869,9 @@ void TransactionParticipant::refreshLocksForPreparedTransaction(OperationContext
_txnResourceStash->release(opCtx);
_txnResourceStash = boost::none;
+ // Snapshot transactions don't conflict with PBWM lock on both primary and secondary.
+ invariant(!opCtx->lockState()->shouldConflictWithSecondaryBatchApplication());
+
// Transfer the txn resource back from the operation context to the stash.
auto stashStyle =
yieldLocks ? TxnResources::StashStyle::kSecondary : TxnResources::StashStyle::kPrimary;
diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp
index 0f9713b0598..8cb4808f1f9 100644
--- a/src/mongo/db/transaction_participant_test.cpp
+++ b/src/mongo/db/transaction_participant_test.cpp
@@ -257,6 +257,7 @@ protected:
std::unique_ptr<MongoDOperationContextSession> checkOutSession(
boost::optional<bool> startNewTxn = true) {
+ opCtx()->lockState()->setShouldConflictWithSecondaryBatchApplication(false);
auto opCtxSession = std::make_unique<MongoDOperationContextSession>(opCtx());
auto txnParticipant = TransactionParticipant::get(opCtx());
txnParticipant->beginOrContinue(*opCtx()->getTxnNumber(), false, startNewTxn);