From a30b567ecb69c80a1b69ebe6897dc3ab3905f25f Mon Sep 17 00:00:00 2001 From: Jordi Serra Torrens Date: Wed, 16 Mar 2022 18:48:49 +0000 Subject: SERVER-64517 Recover RecoverableCriticalSection after initialSync and startupRecovery have completed (cherry picked from commit ce0bbc5ec1728e443c5ff893a78693b24570b80d) --- src/mongo/db/s/shard_server_op_observer.cpp | 110 +++++++++++++--------------- 1 file changed, 49 insertions(+), 61 deletions(-) (limited to 'src/mongo/db/s/shard_server_op_observer.cpp') diff --git a/src/mongo/db/s/shard_server_op_observer.cpp b/src/mongo/db/s/shard_server_op_observer.cpp index 6fb7c341cba..b680a8e2457 100644 --- a/src/mongo/db/s/shard_server_op_observer.cpp +++ b/src/mongo/db/s/shard_server_op_observer.cpp @@ -273,17 +273,14 @@ void ShardServerOpObserver::onInserts(OperationContext* opCtx, } } - if (nss == NamespaceString::kCollectionCriticalSectionsNamespace) { - auto replCoord = repl::ReplicationCoordinator::get(opCtx); - if (!replCoord->isReplEnabled() || - (!replCoord->getMemberState().recovering() && - !replCoord->getMemberState().rollback())) { - const auto collCSDoc = CollectionCriticalSectionDocument::parse( - IDLParserErrorContext("ShardServerOpObserver"), insertedDoc); - opCtx->recoveryUnit()->onCommit([opCtx, - insertedNss = collCSDoc.getNss(), - reason = collCSDoc.getReason().getOwned()]( - boost::optional) { + if (nss == NamespaceString::kCollectionCriticalSectionsNamespace && + !recoverable_critical_section_util::inRecoveryMode(opCtx)) { + const auto collCSDoc = CollectionCriticalSectionDocument::parse( + IDLParserErrorContext("ShardServerOpObserver"), insertedDoc); + opCtx->recoveryUnit()->onCommit( + [opCtx, + insertedNss = collCSDoc.getNss(), + reason = collCSDoc.getReason().getOwned()](boost::optional) { boost::optional lockCollectionIfNotPrimary; if (!isStandaloneOrPrimary(opCtx)) lockCollectionIfNotPrimary.emplace(opCtx, insertedNss, MODE_IX); @@ -293,7 +290,6 @@ void ShardServerOpObserver::onInserts(OperationContext* opCtx, auto csrLock = CollectionShardingRuntime ::CSRLock::lockExclusive(opCtx, csr); csr->enterCriticalSectionCatchUpPhase(csrLock, reason); }); - } } if (metadata && metadata->isSharded()) { @@ -410,27 +406,23 @@ void ShardServerOpObserver::onUpdate(OperationContext* opCtx, const OplogUpdateE } } - if (args.nss == NamespaceString::kCollectionCriticalSectionsNamespace) { - auto replCoord = repl::ReplicationCoordinator::get(opCtx); - if (!replCoord->isReplEnabled() || - (!replCoord->getMemberState().recovering() && - !replCoord->getMemberState().rollback())) { - const auto collCSDoc = CollectionCriticalSectionDocument::parse( - IDLParserErrorContext("ShardServerOpObserver"), args.updateArgs.updatedDoc); - - opCtx->recoveryUnit()->onCommit( - [opCtx, updatedNss = collCSDoc.getNss(), reason = collCSDoc.getReason().getOwned()]( - boost::optional) { - boost::optional lockCollectionIfNotPrimary; - if (!isStandaloneOrPrimary(opCtx)) - lockCollectionIfNotPrimary.emplace(opCtx, updatedNss, MODE_IX); - - UninterruptibleLockGuard noInterrupt(opCtx->lockState()); - auto* const csr = CollectionShardingRuntime::get(opCtx, updatedNss); - auto csrLock = CollectionShardingRuntime ::CSRLock::lockExclusive(opCtx, csr); - csr->enterCriticalSectionCommitPhase(csrLock, reason); - }); - } + if (args.nss == NamespaceString::kCollectionCriticalSectionsNamespace && + !recoverable_critical_section_util::inRecoveryMode(opCtx)) { + const auto collCSDoc = CollectionCriticalSectionDocument::parse( + IDLParserErrorContext("ShardServerOpObserver"), args.updateArgs.updatedDoc); + + opCtx->recoveryUnit()->onCommit( + [opCtx, updatedNss = collCSDoc.getNss(), reason = collCSDoc.getReason().getOwned()]( + boost::optional) { + boost::optional lockCollectionIfNotPrimary; + if (!isStandaloneOrPrimary(opCtx)) + lockCollectionIfNotPrimary.emplace(opCtx, updatedNss, MODE_IX); + + UninterruptibleLockGuard noInterrupt(opCtx->lockState()); + auto* const csr = CollectionShardingRuntime::get(opCtx, updatedNss); + auto csrLock = CollectionShardingRuntime ::CSRLock::lockExclusive(opCtx, csr); + csr->enterCriticalSectionCommitPhase(csrLock, reason); + }); } auto* const csr = CollectionShardingRuntime::get(opCtx, args.nss); @@ -503,34 +495,30 @@ void ShardServerOpObserver::onDelete(OperationContext* opCtx, } } - if (nss == NamespaceString::kCollectionCriticalSectionsNamespace) { - auto replCoord = repl::ReplicationCoordinator::get(opCtx); - if (!replCoord->isReplEnabled() || - (!replCoord->getMemberState().recovering() && - !replCoord->getMemberState().rollback())) { - const auto& deletedDoc = documentId; - const auto collCSDoc = CollectionCriticalSectionDocument::parse( - IDLParserErrorContext("ShardServerOpObserver"), deletedDoc); - - opCtx->recoveryUnit()->onCommit( - [opCtx, deletedNss = collCSDoc.getNss(), reason = collCSDoc.getReason().getOwned()]( - boost::optional) { - boost::optional lockCollectionIfNotPrimary; - if (!isStandaloneOrPrimary(opCtx)) - lockCollectionIfNotPrimary.emplace(opCtx, deletedNss, MODE_IX); - - UninterruptibleLockGuard noInterrupt(opCtx->lockState()); - auto* const csr = CollectionShardingRuntime::get(opCtx, deletedNss); - - // Secondary nodes must clear the filtering metadata before releasing the - // in-memory critical section - if (!isStandaloneOrPrimary(opCtx)) - csr->clearFilteringMetadata(opCtx); - - auto csrLock = CollectionShardingRuntime::CSRLock::lockExclusive(opCtx, csr); - csr->exitCriticalSection(csrLock, reason); - }); - } + if (nss == NamespaceString::kCollectionCriticalSectionsNamespace && + !recoverable_critical_section_util::inRecoveryMode(opCtx)) { + const auto& deletedDoc = documentId; + const auto collCSDoc = CollectionCriticalSectionDocument::parse( + IDLParserErrorContext("ShardServerOpObserver"), deletedDoc); + + opCtx->recoveryUnit()->onCommit( + [opCtx, deletedNss = collCSDoc.getNss(), reason = collCSDoc.getReason().getOwned()]( + boost::optional) { + boost::optional lockCollectionIfNotPrimary; + if (!isStandaloneOrPrimary(opCtx)) + lockCollectionIfNotPrimary.emplace(opCtx, deletedNss, MODE_IX); + + UninterruptibleLockGuard noInterrupt(opCtx->lockState()); + auto* const csr = CollectionShardingRuntime::get(opCtx, deletedNss); + + // Secondary nodes must clear the filtering metadata before releasing the + // in-memory critical section + if (!isStandaloneOrPrimary(opCtx)) + csr->clearFilteringMetadata(opCtx); + + auto csrLock = CollectionShardingRuntime::CSRLock::lockExclusive(opCtx, csr); + csr->exitCriticalSection(csrLock, reason); + }); } } -- cgit v1.2.1