diff options
10 files changed, 36 insertions, 19 deletions
diff --git a/src/mongo/db/exec/write_stage_common.cpp b/src/mongo/db/exec/write_stage_common.cpp index b4d744d04fa..a96a1b068ab 100644 --- a/src/mongo/db/exec/write_stage_common.cpp +++ b/src/mongo/db/exec/write_stage_common.cpp @@ -176,8 +176,8 @@ bool ensureStillMatches(const CollectionPtr& collection, } bool isRetryableWrite(OperationContext* opCtx) { - static auto w = MONGO_WEAK_FUNCTION_DEFINITION(write_stage_common::isRetryableWrite); - return w(opCtx); + const auto replCoord{repl::ReplicationCoordinator::get(opCtx)}; + return replCoord->isRetryableWrite(opCtx); } } // namespace write_stage_common diff --git a/src/mongo/db/repl/replication_coordinator.h b/src/mongo/db/repl/replication_coordinator.h index 84f4e869eae..085bf888dc0 100644 --- a/src/mongo/db/repl/replication_coordinator.h +++ b/src/mongo/db/repl/replication_coordinator.h @@ -1190,6 +1190,12 @@ public: */ virtual SplitPrepareSessionManager* getSplitPrepareSessionManager() = 0; + /** + * Returns true if we are running retryable write or retryable internal multi-document + * transaction. + */ + virtual bool isRetryableWrite(OperationContext* opCtx) const = 0; + protected: ReplicationCoordinator(); }; diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp index d4bd43a16ff..58a6127b885 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl.cpp @@ -94,6 +94,7 @@ #include "mongo/db/shutdown_in_progress_quiesce_info.h" #include "mongo/db/storage/control/journal_flusher.h" #include "mongo/db/storage/storage_options.h" +#include "mongo/db/transaction/transaction_participant.h" #include "mongo/db/vector_clock.h" #include "mongo/db/vector_clock_mutable.h" #include "mongo/db/write_concern.h" @@ -6343,5 +6344,14 @@ SplitPrepareSessionManager* ReplicationCoordinatorImpl::getSplitPrepareSessionMa return &_splitSessionManager; } +bool ReplicationCoordinatorImpl::isRetryableWrite(OperationContext* opCtx) const { + if (!opCtx->writesAreReplicated() || !opCtx->isRetryableWrite()) { + return false; + } + auto txnParticipant = TransactionParticipant::get(opCtx); + return txnParticipant && + (!opCtx->inMultiDocumentTransaction() || txnParticipant.transactionIsOpen()); +} + } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/replication_coordinator_impl.h b/src/mongo/db/repl/replication_coordinator_impl.h index 4fdeebcde65..da88e94dc46 100644 --- a/src/mongo/db/repl/replication_coordinator_impl.h +++ b/src/mongo/db/repl/replication_coordinator_impl.h @@ -590,6 +590,8 @@ public: */ WriteConcernTagChanges* getWriteConcernTagChanges() override; + bool isRetryableWrite(OperationContext* opCtx) const override; + private: using CallbackFn = executor::TaskExecutor::CallbackFn; diff --git a/src/mongo/db/repl/replication_coordinator_mock.h b/src/mongo/db/repl/replication_coordinator_mock.h index ef43e450400..51899a75e5a 100644 --- a/src/mongo/db/repl/replication_coordinator_mock.h +++ b/src/mongo/db/repl/replication_coordinator_mock.h @@ -432,6 +432,10 @@ public: _updateCommittedSnapshot = val; } + bool isRetryableWrite(OperationContext* opCtx) const override { + return false; + } + private: void _setMyLastAppliedOpTimeAndWallTime(WithLock lk, const OpTimeAndWallTime& opTimeAndWallTime); diff --git a/src/mongo/db/repl/replication_coordinator_noop.cpp b/src/mongo/db/repl/replication_coordinator_noop.cpp index 330040d7c56..ac7bb2697d5 100644 --- a/src/mongo/db/repl/replication_coordinator_noop.cpp +++ b/src/mongo/db/repl/replication_coordinator_noop.cpp @@ -620,5 +620,9 @@ SplitPrepareSessionManager* ReplicationCoordinatorNoOp::getSplitPrepareSessionMa MONGO_UNREACHABLE; } +bool ReplicationCoordinatorNoOp::isRetryableWrite(OperationContext* opCtx) const { + MONGO_UNREACHABLE; +} + } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/replication_coordinator_noop.h b/src/mongo/db/repl/replication_coordinator_noop.h index 610fa983d16..73fb6a7f016 100644 --- a/src/mongo/db/repl/replication_coordinator_noop.h +++ b/src/mongo/db/repl/replication_coordinator_noop.h @@ -351,6 +351,8 @@ public: virtual SplitPrepareSessionManager* getSplitPrepareSessionManager() override; + virtual bool isRetryableWrite(OperationContext* opCtx) const override; + private: ServiceContext* const _service; }; diff --git a/src/mongo/db/transaction/transaction_participant.cpp b/src/mongo/db/transaction/transaction_participant.cpp index 72df0adddd4..51027ba402b 100644 --- a/src/mongo/db/transaction/transaction_participant.cpp +++ b/src/mongo/db/transaction/transaction_participant.cpp @@ -50,12 +50,10 @@ #include "mongo/db/curop_failpoint_helpers.h" #include "mongo/db/dbdirectclient.h" #include "mongo/db/dbhelpers.h" -#include "mongo/db/exec/write_stage_common.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/op_observer/op_observer.h" #include "mongo/db/ops/update.h" #include "mongo/db/ops/write_ops_retryability.h" -#include "mongo/db/query/get_executor.h" #include "mongo/db/repl/apply_ops_command_info.h" #include "mongo/db/repl/repl_client_info.h" #include "mongo/db/repl/storage_interface.h" @@ -474,21 +472,6 @@ void updateSessionEntry(OperationContext* opCtx, // will be allowed to commit. MONGO_FAIL_POINT_DEFINE(onPrimaryTransactionalWrite); -/** - * Returns true if we are running retryable write or retryable internal multi-document transaction. - */ -bool writeStageCommonIsRetryableWriteImpl(OperationContext* opCtx) { - if (!opCtx->writesAreReplicated() || !opCtx->isRetryableWrite()) { - return false; - } - auto txnParticipant = TransactionParticipant::get(opCtx); - return txnParticipant && - (!opCtx->inMultiDocumentTransaction() || txnParticipant.transactionIsOpen()); -} - -auto isRetryableWriteRegistration = MONGO_WEAK_FUNCTION_REGISTRATION( - write_stage_common::isRetryableWrite, writeStageCommonIsRetryableWriteImpl); - } // namespace const BSONObj TransactionParticipant::kDeadEndSentinel(BSON("$incompleteOplogHistory" << 1)); diff --git a/src/mongo/embedded/replication_coordinator_embedded.cpp b/src/mongo/embedded/replication_coordinator_embedded.cpp index c04c69d47a4..7e19e13487f 100644 --- a/src/mongo/embedded/replication_coordinator_embedded.cpp +++ b/src/mongo/embedded/replication_coordinator_embedded.cpp @@ -651,5 +651,9 @@ repl::SplitPrepareSessionManager* ReplicationCoordinatorEmbedded::getSplitPrepar UASSERT_NOT_IMPLEMENTED; } +bool ReplicationCoordinatorEmbedded::isRetryableWrite(OperationContext* opCtx) const { + return false; +} + } // namespace embedded } // namespace mongo diff --git a/src/mongo/embedded/replication_coordinator_embedded.h b/src/mongo/embedded/replication_coordinator_embedded.h index df55e27ff20..00463a42220 100644 --- a/src/mongo/embedded/replication_coordinator_embedded.h +++ b/src/mongo/embedded/replication_coordinator_embedded.h @@ -361,6 +361,8 @@ public: virtual repl::SplitPrepareSessionManager* getSplitPrepareSessionManager() override; + virtual bool isRetryableWrite(OperationContext* opCtx) const override; + private: // Back pointer to the ServiceContext that has started the instance. ServiceContext* const _service; |