diff options
author | Enrico Golfieri <enrico.golfieri@mongodb.com> | 2022-11-04 15:19:40 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-08 09:05:57 +0000 |
commit | 2551216048b331f5ea1da9ff8472e7305f3d5980 (patch) | |
tree | 89437598b9c691638c0ea29ea8fbfc109d2bbfbf | |
parent | 1361c0b10d4da2d1f646dfccda1c4c8ad426d38e (diff) | |
download | mongo-2551216048b331f5ea1da9ff8472e7305f3d5980.tar.gz |
SERVER-70167 Resumed create coordinator may incorrectly try to release the critical section
(cherry picked from commit 819bdae0b239f0ad75c0791e18943e6c4cf9762d)
-rw-r--r-- | src/mongo/db/s/create_collection_coordinator.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/s/recoverable_critical_section_service.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/s/recoverable_critical_section_service.h | 6 |
3 files changed, 28 insertions, 5 deletions
diff --git a/src/mongo/db/s/create_collection_coordinator.cpp b/src/mongo/db/s/create_collection_coordinator.cpp index ae2f53f7399..e1b8d31dc25 100644 --- a/src/mongo/db/s/create_collection_coordinator.cpp +++ b/src/mongo/db/s/create_collection_coordinator.cpp @@ -432,7 +432,8 @@ ExecutorFuture<void> CreateCollectionCoordinator::_runImpl( opCtx, nss(), _critSecReason, - ShardingCatalogClient::kMajorityWriteConcern); + ShardingCatalogClient::kMajorityWriteConcern, + false /* throwIfReasonDiffers */); _result = createCollectionResponseOpt; return; @@ -521,7 +522,11 @@ ExecutorFuture<void> CreateCollectionCoordinator::_runImpl( auto* opCtx = opCtxHolder.get(); RecoverableCriticalSectionService::get(opCtx)->releaseRecoverableCriticalSection( - opCtx, nss(), _critSecReason, ShardingCatalogClient::kMajorityWriteConcern); + opCtx, + nss(), + _critSecReason, + ShardingCatalogClient::kMajorityWriteConcern, + false /* throwIfReasonDiffers */); } return status; }); diff --git a/src/mongo/db/s/recoverable_critical_section_service.cpp b/src/mongo/db/s/recoverable_critical_section_service.cpp index 8febf53fde2..b8812c094cd 100644 --- a/src/mongo/db/s/recoverable_critical_section_service.cpp +++ b/src/mongo/db/s/recoverable_critical_section_service.cpp @@ -273,7 +273,8 @@ void RecoverableCriticalSectionService::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", @@ -309,8 +310,21 @@ void RecoverableCriticalSectionService::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/recoverable_critical_section_service.h b/src/mongo/db/s/recoverable_critical_section_service.h index d9ef1c75195..621e3b5cdde 100644 --- a/src/mongo/db/s/recoverable_critical_section_service.h +++ b/src/mongo/db/s/recoverable_critical_section_service.h @@ -94,11 +94,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); /** |