diff options
author | Enrico Golfieri <enrico.golfieri@mongodb.com> | 2022-10-28 09:18:53 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-10-28 09:52:17 +0000 |
commit | 819bdae0b239f0ad75c0791e18943e6c4cf9762d (patch) | |
tree | 190888e588f3e2eced7c5145893b8a96f407c3b6 /src/mongo/db | |
parent | 22afc187e2a5ed450cf608458393830eb40b913a (diff) | |
download | mongo-819bdae0b239f0ad75c0791e18943e6c4cf9762d.tar.gz |
SERVER-70167 Resumed create coordinator may incorrectly try to release the critical section
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/s/create_collection_coordinator.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/s/create_collection_coordinator.h | 2 | ||||
-rw-r--r-- | src/mongo/db/s/sharding_recovery_service.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/s/sharding_recovery_service.h | 6 |
4 files changed, 37 insertions, 8 deletions
diff --git a/src/mongo/db/s/create_collection_coordinator.cpp b/src/mongo/db/s/create_collection_coordinator.cpp index 73ea88abc94..84dbe859961 100644 --- a/src/mongo/db/s/create_collection_coordinator.cpp +++ b/src/mongo/db/s/create_collection_coordinator.cpp @@ -531,7 +531,9 @@ ExecutorFuture<void> CreateCollectionCoordinator::_runImpl( // A previous request already created and committed the collection // but there was a stepdown after the commit. - _releaseCriticalSections(opCtx); + // The critical section might have been taken by a migration, we force + // to skip the invariant check and we do nothing in case it was taken. + _releaseCriticalSections(opCtx, false /* throwIfReasonDiffers */); _result = createCollectionResponseOpt; return; @@ -992,11 +994,16 @@ void CreateCollectionCoordinator::_promoteCriticalSectionsToBlockReads( } } -void CreateCollectionCoordinator::_releaseCriticalSections(OperationContext* opCtx) { +void CreateCollectionCoordinator::_releaseCriticalSections(OperationContext* opCtx, + bool throwIfReasonDiffers) { // TODO SERVER-68084 call ShardingRecoveryService without the try/catch block. try { ShardingRecoveryService::get(opCtx)->releaseRecoverableCriticalSection( - opCtx, originalNss(), _critSecReason, ShardingCatalogClient::kMajorityWriteConcern); + opCtx, + originalNss(), + _critSecReason, + ShardingCatalogClient::kMajorityWriteConcern, + throwIfReasonDiffers); } catch (ExceptionFor<ErrorCodes::CommandNotSupportedOnView>&) { // Ignore the error (when it is raised, we can assume that no critical section for the view // was previously acquired). @@ -1005,7 +1012,11 @@ void CreateCollectionCoordinator::_releaseCriticalSections(OperationContext* opC if (!_timeseriesNssResolvedByCommandHandler()) { const auto bucketsNamespace = originalNss().makeTimeseriesBucketsNamespace(); ShardingRecoveryService::get(opCtx)->releaseRecoverableCriticalSection( - opCtx, bucketsNamespace, _critSecReason, ShardingCatalogClient::kMajorityWriteConcern); + opCtx, + bucketsNamespace, + _critSecReason, + ShardingCatalogClient::kMajorityWriteConcern, + throwIfReasonDiffers); } } diff --git a/src/mongo/db/s/create_collection_coordinator.h b/src/mongo/db/s/create_collection_coordinator.h index a86aee178c4..82ef299f039 100644 --- a/src/mongo/db/s/create_collection_coordinator.h +++ b/src/mongo/db/s/create_collection_coordinator.h @@ -99,7 +99,7 @@ private: void _promoteCriticalSectionsToBlockReads(OperationContext* opCtx) const; - void _releaseCriticalSections(OperationContext* opCtx); + void _releaseCriticalSections(OperationContext* opCt, bool throwIfReasonDiffers = true); /** * Ensures the collection is created locally and has the appropiate shard index. diff --git a/src/mongo/db/s/sharding_recovery_service.cpp b/src/mongo/db/s/sharding_recovery_service.cpp index 6c75fa289ca..d47e4056534 100644 --- a/src/mongo/db/s/sharding_recovery_service.cpp +++ b/src/mongo/db/s/sharding_recovery_service.cpp @@ -333,7 +333,8 @@ void ShardingRecoveryService::releaseRecoverableCriticalSection( OperationContext* opCtx, const NamespaceString& nss, const BSONObj& reason, - const WriteConcernOptions& writeConcern) { + const WriteConcernOptions& writeConcern, + bool throwIfReasonDiffers) { LOGV2_DEBUG(5656606, 3, "Releasing recoverable critical section", @@ -371,8 +372,21 @@ void ShardingRecoveryService::releaseRecoverableCriticalSection( const auto collCSDoc = CollectionCriticalSectionDocument::parse( IDLParserContext("ReleaseRecoverableCS"), bsonObj); + const bool isDifferentReason = collCSDoc.getReason().woCompare(reason) != 0; + if (MONGO_unlikely(!throwIfReasonDiffers && isDifferentReason)) { + LOGV2_DEBUG(7019701, + 2, + "Impossible to release recoverable critical section since it was taken by " + "another operation with different reason", + "namespace"_attr = nss, + "callerReason"_attr = reason, + "storedReason"_attr = collCSDoc.getReason(), + "writeConcern"_attr = writeConcern); + return; + } + invariant( - collCSDoc.getReason().woCompare(reason) == 0, + !isDifferentReason, str::stream() << "Trying to release a critical for namespace " << nss << " and reason " << reason << " but it is already taken by another operation with different reason " diff --git a/src/mongo/db/s/sharding_recovery_service.h b/src/mongo/db/s/sharding_recovery_service.h index 99e4995f802..2913571d180 100644 --- a/src/mongo/db/s/sharding_recovery_service.h +++ b/src/mongo/db/s/sharding_recovery_service.h @@ -93,11 +93,15 @@ public: * responsability of the caller to properly set the filtering information on the primary node. * * Do nothing if the collection critical section is not taken for that nss and reason. + * + * Throw an invariant in case the collection critical section is already taken by another + * operation with a different reason unless the flag 'throwIfReasonDiffers' is set to false. */ void releaseRecoverableCriticalSection(OperationContext* opCtx, const NamespaceString& nss, const BSONObj& reason, - const WriteConcernOptions& writeConcern); + const WriteConcernOptions& writeConcern, + bool throwIfReasonDiffers = true); /** * Recover all sharding related in memory states from disk. |