summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorEnrico Golfieri <enrico.golfieri@mongodb.com>2022-10-28 09:18:53 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-10-28 09:52:17 +0000
commit819bdae0b239f0ad75c0791e18943e6c4cf9762d (patch)
tree190888e588f3e2eced7c5145893b8a96f407c3b6 /src/mongo/db
parent22afc187e2a5ed450cf608458393830eb40b913a (diff)
downloadmongo-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.cpp19
-rw-r--r--src/mongo/db/s/create_collection_coordinator.h2
-rw-r--r--src/mongo/db/s/sharding_recovery_service.cpp18
-rw-r--r--src/mongo/db/s/sharding_recovery_service.h6
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.