From 4197e3c394abea7d01084e035a6ce8af32dc1161 Mon Sep 17 00:00:00 2001 From: Suganthi Mani Date: Mon, 26 Aug 2019 15:03:15 +0000 Subject: SERVER-39996 Moved setting ignorePrepared behavior outside of waitForReadConcern. --- src/mongo/db/read_concern_mongod.cpp | 50 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'src/mongo/db/read_concern_mongod.cpp') diff --git a/src/mongo/db/read_concern_mongod.cpp b/src/mongo/db/read_concern_mongod.cpp index b5ce3b2fdb9..60028d779f9 100644 --- a/src/mongo/db/read_concern_mongod.cpp +++ b/src/mongo/db/read_concern_mongod.cpp @@ -205,35 +205,50 @@ Status makeNoopWriteIfNeeded(OperationContext* opCtx, LogicalTime clusterTime) { } /** - * Returns the PrepareConflictBehavior that a command should use given the requested behavior and - * readConcern options. + * Evaluates if it's safe for the command to ignore prepare conflicts. */ -PrepareConflictBehavior getPrepareBehaviorForReadConcern( - PrepareConflictBehavior requestedBehavior, - repl::ReadConcernLevel readConcernLevel, - boost::optional afterClusterTime, - boost::optional atClusterTime) { - +bool canIgnorePrepareConflicts(const repl::ReadConcernArgs& readConcernArgs) { + auto readConcernLevel = readConcernArgs.getLevel(); // Only these read concern levels are eligible for ignoring prepare conflicts. if (readConcernLevel != repl::ReadConcernLevel::kLocalReadConcern && readConcernLevel != repl::ReadConcernLevel::kAvailableReadConcern && readConcernLevel != repl::ReadConcernLevel::kMajorityReadConcern) { - return PrepareConflictBehavior::kEnforce; + return false; } + auto afterClusterTime = readConcernArgs.getArgsAfterClusterTime(); + auto atClusterTime = readConcernArgs.getArgsAtClusterTime(); + if (afterClusterTime || atClusterTime) { - return PrepareConflictBehavior::kEnforce; + return false; } - return requestedBehavior; + return true; } + } // namespace -MONGO_REGISTER_SHIM(waitForReadConcern) +MONGO_REGISTER_SHIM(setPrepareConflictBehaviorForReadConcern) (OperationContext* opCtx, const repl::ReadConcernArgs& readConcernArgs, - bool allowAfterClusterTime, PrepareConflictBehavior prepareConflictBehavior) + ->void { + // DBDirectClient should inherit whether or not to ignore prepare conflicts from its parent. + if (opCtx->getClient()->isInDirectClient()) { + return; + } + + // Enforce prepare conflict behavior if the command is not eligible to ignore prepare conflicts. + if (!(prepareConflictBehavior == PrepareConflictBehavior::kEnforce || + canIgnorePrepareConflicts(readConcernArgs))) { + prepareConflictBehavior = PrepareConflictBehavior::kEnforce; + } + + opCtx->recoveryUnit()->setPrepareConflictBehavior(prepareConflictBehavior); +} + +MONGO_REGISTER_SHIM(waitForReadConcern) +(OperationContext* opCtx, const repl::ReadConcernArgs& readConcernArgs, bool allowAfterClusterTime) ->Status { // If we are in a direct client within a transaction, then we may be holding locks, so it is // illegal to wait for read concern. This is fine, since the outer operation should have handled @@ -363,15 +378,6 @@ MONGO_REGISTER_SHIM(waitForReadConcern) LOG(debugLevel) << "Using 'committed' snapshot: " << CurOp::get(opCtx)->opDescription() << " with readTs: " << opCtx->recoveryUnit()->getPointInTimeReadTimestamp(); } - - // DBDirectClient should inherit whether or not to ignore prepare conflicts from its parent. - if (!opCtx->getClient()->isInDirectClient()) { - // Set whether this command should ignore prepare conflicts or not. - const auto behavior = getPrepareBehaviorForReadConcern( - prepareConflictBehavior, readConcernArgs.getLevel(), afterClusterTime, atClusterTime); - opCtx->recoveryUnit()->setPrepareConflictBehavior(behavior); - } - return Status::OK(); } -- cgit v1.2.1