summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnrico Golfieri <enrico.golfieri@mongodb.com>2023-02-22 16:45:42 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-22 17:24:22 +0000
commitcbb1615777403112d957baee329e8c7d015cf21b (patch)
tree374d6c0c7b557bb8515f75b0af4936a1df419e26
parent65b9065fd72f65047e347f6bb3a56261f4d22810 (diff)
downloadmongo-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.cpp6
-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, 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);
/**