diff options
author | Enrico Golfieri <enrico.golfieri@mongodb.com> | 2023-02-22 16:45:42 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-02-22 17:24:22 +0000 |
commit | cbb1615777403112d957baee329e8c7d015cf21b (patch) | |
tree | 374d6c0c7b557bb8515f75b0af4936a1df419e26 | |
parent | 65b9065fd72f65047e347f6bb3a56261f4d22810 (diff) | |
download | mongo-cbb1615777403112d957baee329e8c7d015cf21b.tar.gz |
SERVER-70167 Resumed create coordinator may incorrectly try to release the critical section
(cherry picked from commit 2551216048b331f5ea1da9ff8472e7305f3d5980)
-rw-r--r-- | src/mongo/db/s/create_collection_coordinator.cpp | 6 | ||||
-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, 25 insertions, 5 deletions
diff --git a/src/mongo/db/s/create_collection_coordinator.cpp b/src/mongo/db/s/create_collection_coordinator.cpp index 357c345546a..4c477843f35 100644 --- a/src/mongo/db/s/create_collection_coordinator.cpp +++ b/src/mongo/db/s/create_collection_coordinator.cpp @@ -513,7 +513,8 @@ ExecutorFuture<void> CreateCollectionCoordinator::_runImpl( opCtx, nss(), _getCriticalSectionReason(), - ShardingCatalogClient::kMajorityWriteConcern); + ShardingCatalogClient::kMajorityWriteConcern, + false /* throwIfReasonDiffers */); _result = createCollectionResponseOpt; return; @@ -619,7 +620,8 @@ ExecutorFuture<void> CreateCollectionCoordinator::_runImpl( opCtx, nss(), _getCriticalSectionReason(), - ShardingCatalogClient::kMajorityWriteConcern); + 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 6d10fdb4ef7..95214c05857 100644 --- a/src/mongo/db/s/recoverable_critical_section_service.cpp +++ b/src/mongo/db/s/recoverable_critical_section_service.cpp @@ -295,7 +295,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", @@ -336,13 +337,26 @@ void RecoverableCriticalSectionService::releaseRecoverableCriticalSection( const auto collCSDoc = CollectionCriticalSectionDocument::parse( IDLParserErrorContext("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; + } + tassert(7032366, fmt::format("Trying to release a critical for namespace '{}' and reason '{}' but " "it is already taken by another operation with different reason '{}'", nss.toString(), reason.toString(), collCSDoc.getReason().toString()), - collCSDoc.getReason().woCompare(reason) == 0); + !isDifferentReason); // The collection critical section is taken (in any phase), try to release it. 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); /** |