summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorPierlauro Sciarelli <pierlauro.sciarelli@mongodb.com>2022-07-27 14:36:52 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-07-27 15:04:39 +0000
commit24013503c0cd1244c154594e17b8aca6281bdeab (patch)
tree1f597f48406154340da40ed569fbe68b24134870 /src/mongo
parentc42b4e0287cee7894cc4fc6d295a28c03f49baaa (diff)
downloadmongo-24013503c0cd1244c154594e17b8aca6281bdeab.tar.gz
SERVER-67845 Acquire critical section in rename "check preconditions" phase only if target not sharded
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/s/rename_collection_coordinator.cpp55
-rw-r--r--src/mongo/db/s/rename_collection_participant_service.cpp5
-rw-r--r--src/mongo/db/s/sharding_ddl_util.cpp6
-rw-r--r--src/mongo/db/s/sharding_ddl_util.h2
4 files changed, 61 insertions, 7 deletions
diff --git a/src/mongo/db/s/rename_collection_coordinator.cpp b/src/mongo/db/s/rename_collection_coordinator.cpp
index 294dfc61bf3..79dcaa4254d 100644
--- a/src/mongo/db/s/rename_collection_coordinator.cpp
+++ b/src/mongo/db/s/rename_collection_coordinator.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/ops/insert.h"
#include "mongo/db/persistent_task_store.h"
#include "mongo/db/s/collection_sharding_runtime.h"
+#include "mongo/db/s/recoverable_critical_section_service.h"
#include "mongo/db/s/sharding_ddl_util.h"
#include "mongo/db/s/sharding_logging.h"
#include "mongo/db/s/sharding_state.h"
@@ -189,6 +190,9 @@ ExecutorFuture<void> RenameCollectionCoordinator::_runImpl(
const auto& fromNss = nss();
const auto& toNss = _request.getTo();
+ const auto criticalSectionReason =
+ sharding_ddl_util::getCriticalSectionReasonForRename(fromNss, toNss);
+
try {
// Make sure the source collection exists
const auto optSourceCollType = getShardedCollection(opCtx, fromNss);
@@ -206,6 +210,28 @@ ExecutorFuture<void> RenameCollectionCoordinator::_runImpl(
sharding_ddl_util::checkDbPrimariesOnTheSameShard(opCtx, fromNss, toNss);
}
+ const auto optTargetCollType = getShardedCollection(opCtx, toNss);
+ const bool targetIsSharded = (bool)optTargetCollType;
+ _doc.setTargetIsSharded(targetIsSharded);
+ _doc.setTargetUUID(getCollectionUUID(
+ opCtx, toNss, optTargetCollType, /*throwNotFound*/ false));
+
+ auto criticalSection = RecoverableCriticalSectionService::get(opCtx);
+ if (!targetIsSharded) {
+ // (SERVER-67325) Acquire critical section on the target collection in order
+ // to disallow concurrent `createCollection`
+ criticalSection->acquireRecoverableCriticalSectionBlockWrites(
+ opCtx,
+ toNss,
+ criticalSectionReason,
+ ShardingCatalogClient::kLocalWriteConcern);
+ criticalSection->promoteRecoverableCriticalSectionToBlockAlsoReads(
+ opCtx,
+ toNss,
+ criticalSectionReason,
+ ShardingCatalogClient::kLocalWriteConcern);
+ }
+
// Make sure the target namespace is not a view
{
Lock::DBLock dbLock(opCtx, toNss.db(), MODE_IS);
@@ -218,15 +244,36 @@ ExecutorFuture<void> RenameCollectionCoordinator::_runImpl(
}
}
- const auto optTargetCollType = getShardedCollection(opCtx, toNss);
- _doc.setTargetIsSharded((bool)optTargetCollType);
- _doc.setTargetUUID(getCollectionUUID(
- opCtx, toNss, optTargetCollType, /*throwNotFound*/ false));
+ const bool targetExists = [&]() {
+ if (targetIsSharded) {
+ return true;
+ }
+ auto collectionCatalog = CollectionCatalog::get(opCtx);
+ auto targetColl =
+ collectionCatalog->lookupCollectionByNamespace(opCtx, toNss);
+ return (bool)targetColl; // true if exists and is unsharded
+ }();
+
+ if (targetExists) {
+ // Release the critical section because the target collection
+ // already exists, hence no risk of concurrent `createCollection`
+ criticalSection->releaseRecoverableCriticalSection(
+ opCtx,
+ toNss,
+ criticalSectionReason,
+ ShardingCatalogClient::kLocalWriteConcern);
+ }
sharding_ddl_util::checkRenamePreconditions(
opCtx, sourceIsSharded, toNss, _doc.getDropTarget());
} catch (const DBException&) {
+ auto criticalSection = RecoverableCriticalSectionService::get(opCtx);
+ criticalSection->releaseRecoverableCriticalSection(
+ opCtx,
+ toNss,
+ criticalSectionReason,
+ ShardingCatalogClient::kLocalWriteConcern);
_completeOnError = true;
throw;
}
diff --git a/src/mongo/db/s/rename_collection_participant_service.cpp b/src/mongo/db/s/rename_collection_participant_service.cpp
index 51256975393..15d7d11bd3c 100644
--- a/src/mongo/db/s/rename_collection_participant_service.cpp
+++ b/src/mongo/db/s/rename_collection_participant_service.cpp
@@ -43,6 +43,7 @@
#include "mongo/db/s/recoverable_critical_section_service.h"
#include "mongo/db/s/rename_collection_participant_service.h"
#include "mongo/db/s/shard_metadata_util.h"
+#include "mongo/db/s/sharding_ddl_util.h"
#include "mongo/logv2/log.h"
#include "mongo/s/catalog/sharding_catalog_client.h"
#include "mongo/s/grid.h"
@@ -307,9 +308,7 @@ SemiFuture<void> RenameParticipantInstance::_runImpl(
// Acquire source/target critical sections
const auto reason =
- BSON("command"
- << "rename"
- << "from" << fromNss().toString() << "to" << toNss().toString());
+ sharding_ddl_util::getCriticalSectionReasonForRename(fromNss(), toNss());
auto service = RecoverableCriticalSectionService::get(opCtx);
service->acquireRecoverableCriticalSectionBlockWrites(
opCtx, fromNss(), reason, ShardingCatalogClient::kLocalWriteConcern);
diff --git a/src/mongo/db/s/sharding_ddl_util.cpp b/src/mongo/db/s/sharding_ddl_util.cpp
index fd4a9af6c2c..ec0af295d45 100644
--- a/src/mongo/db/s/sharding_ddl_util.cpp
+++ b/src/mongo/db/s/sharding_ddl_util.cpp
@@ -487,5 +487,11 @@ void sendDropCollectionParticipantCommandToShards(OperationContext* opCtx,
}
}
+BSONObj getCriticalSectionReasonForRename(const NamespaceString& from, const NamespaceString& to) {
+ return BSON("command"
+ << "rename"
+ << "from" << from.toString() << "to" << to.toString());
+}
+
} // namespace sharding_ddl_util
} // namespace mongo
diff --git a/src/mongo/db/s/sharding_ddl_util.h b/src/mongo/db/s/sharding_ddl_util.h
index da78ce04a8b..99816c6fa02 100644
--- a/src/mongo/db/s/sharding_ddl_util.h
+++ b/src/mongo/db/s/sharding_ddl_util.h
@@ -173,5 +173,7 @@ void sendDropCollectionParticipantCommandToShards(OperationContext* opCtx,
std::shared_ptr<executor::TaskExecutor> executor,
const OperationSessionInfo& osi);
+BSONObj getCriticalSectionReasonForRename(const NamespaceString& from, const NamespaceString& to);
+
} // namespace sharding_ddl_util
} // namespace mongo