summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnrico Golfieri <enrico.golfieri@mongodb.com>2022-11-04 15:19:40 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-08 09:05:57 +0000
commit2551216048b331f5ea1da9ff8472e7305f3d5980 (patch)
tree89437598b9c691638c0ea29ea8fbfc109d2bbfbf
parent1361c0b10d4da2d1f646dfccda1c4c8ad426d38e (diff)
downloadmongo-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.cpp9
-rw-r--r--src/mongo/db/s/recoverable_critical_section_service.cpp18
-rw-r--r--src/mongo/db/s/recoverable_critical_section_service.h6
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);
/**