diff options
-rw-r--r-- | src/mongo/db/commands/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/commands/set_feature_compatibility_version_command.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.h | 18 | ||||
-rw-r--r-- | src/mongo/db/s/SConscript | 18 | ||||
-rw-r--r-- | src/mongo/db/s/balancer_stats_registry.cpp | 25 | ||||
-rw-r--r-- | src/mongo/db/s/balancer_stats_registry.h | 15 | ||||
-rw-r--r-- | src/mongo/db/s/migration_util.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/s/range_deletion_util.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/stats/SConscript | 1 |
9 files changed, 45 insertions, 42 deletions
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index f58ae902be6..e68bfd0b11d 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -576,6 +576,7 @@ env.Library( '$BUILD_DIR/mongo/db/repl/tenant_migration_donor_service', '$BUILD_DIR/mongo/db/repl/tenant_migration_recipient_service', '$BUILD_DIR/mongo/db/rw_concern_d', + '$BUILD_DIR/mongo/db/s/balancer_stats_registry', '$BUILD_DIR/mongo/db/s/sharding_api_d', '$BUILD_DIR/mongo/db/s/sharding_catalog_manager', '$BUILD_DIR/mongo/db/s/sharding_commands_d', diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp index 73933d1abe2..0c8f5a42c99 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -465,7 +465,7 @@ public: if (actualVersion > requestedVersion && !feature_flags::gOrphanTracking.isEnabledOnVersion(requestedVersion)) { BalancerStatsRegistry::get(opCtx)->terminate(); - ScopedRangeDeleterLock rangeDeleterLock(opCtx); + ScopedRangeDeleterLock rangeDeleterLock(opCtx, LockMode::MODE_X); clearOrphanCountersFromRangeDeletionTasks(opCtx); } diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h index 4e3433d5f6d..930e1436517 100644 --- a/src/mongo/db/concurrency/d_concurrency.h +++ b/src/mongo/db/concurrency/d_concurrency.h @@ -121,6 +121,13 @@ public: static std::string getName(ResourceId resourceId); + /** + * Each instantiation of this class allocates a new ResourceId. + */ + ResourceId getRid() const { + return _rid; + } + bool isExclusivelyLocked(Locker* locker); bool isAtLeastReadLocked(Locker* locker); @@ -129,13 +136,6 @@ public: friend class Lock::SharedLock; friend class Lock::ExclusiveLock; - /** - * Each instantiation of this class allocates a new ResourceId. - */ - ResourceId rid() const { - return _rid; - } - const ResourceId _rid; }; @@ -151,7 +151,7 @@ public: * Interruptible lock acquisition. */ ExclusiveLock(OperationContext* opCtx, Locker* locker, ResourceMutex mutex) - : ResourceLock(opCtx, locker, mutex.rid(), MODE_X) {} + : ResourceLock(opCtx, locker, mutex.getRid(), MODE_X) {} using ResourceLock::lock; @@ -177,7 +177,7 @@ public: * Interruptible lock acquisition. */ SharedLock(OperationContext* opCtx, Locker* locker, ResourceMutex mutex) - : ResourceLock(opCtx, locker, mutex.rid(), MODE_IS) {} + : ResourceLock(opCtx, locker, mutex.getRid(), MODE_IS) {} }; /** diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 401e8942e15..7ded31465e1 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -11,7 +11,6 @@ env = env.Clone() env.Library( target='sharding_api_d', source=[ - 'balancer_stats_registry.cpp', 'collection_metadata.cpp', 'collection_sharding_state_factory_standalone.cpp', 'collection_sharding_state.cpp', @@ -33,9 +32,7 @@ env.Library( '$BUILD_DIR/mongo/base', '$BUILD_DIR/mongo/db/catalog/index_catalog', '$BUILD_DIR/mongo/db/concurrency/lock_manager', - '$BUILD_DIR/mongo/db/dbdirectclient', '$BUILD_DIR/mongo/db/range_arithmetic', - '$BUILD_DIR/mongo/db/repl/replica_set_aware_service', '$BUILD_DIR/mongo/s/grid', '$BUILD_DIR/mongo/s/sharding_routing_table', ], @@ -45,6 +42,19 @@ env.Library( ) env.Library( + target='balancer_stats_registry', + source=[ + 'balancer_stats_registry.cpp', + ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/catalog_raii', + '$BUILD_DIR/mongo/db/dbdirectclient', + '$BUILD_DIR/mongo/db/repl/replica_set_aware_service', + '$BUILD_DIR/mongo/s/grid', + ], +) + +env.Library( target='sharding_runtime_d', source=[ 'active_migrations_registry.cpp', @@ -173,6 +183,7 @@ env.Library( '$BUILD_DIR/mongo/db/session_catalog', '$BUILD_DIR/mongo/idl/server_parameter', '$BUILD_DIR/mongo/util/future_util', + 'balancer_stats_registry', ], ) @@ -469,6 +480,7 @@ env.Library( '$BUILD_DIR/mongo/s/commands/sharded_cluster_sharding_commands', '$BUILD_DIR/mongo/s/sharding_initialization', '$BUILD_DIR/mongo/s/sharding_router_api', + 'balancer_stats_registry', 'forwardable_operation_metadata', 'sharding_runtime_d', 'user_writes_recoverable_critical_section', diff --git a/src/mongo/db/s/balancer_stats_registry.cpp b/src/mongo/db/s/balancer_stats_registry.cpp index 0dd50c06275..6a06486181a 100644 --- a/src/mongo/db/s/balancer_stats_registry.cpp +++ b/src/mongo/db/s/balancer_stats_registry.cpp @@ -31,6 +31,7 @@ #include "mongo/db/s/balancer_stats_registry.h" +#include "mongo/db/catalog_raii.h" #include "mongo/db/dbdirectclient.h" #include "mongo/db/pipeline/aggregate_command_gen.h" #include "mongo/db/repl/replication_coordinator.h" @@ -58,21 +59,6 @@ ThreadPool::Options makeDefaultThreadPoolOptions() { } } // namespace -ScopedRangeDeleterLock::ScopedRangeDeleterLock(OperationContext* opCtx) - : _configLock(opCtx, NamespaceString::kConfigDb, MODE_IX), - _rangeDeletionLock(opCtx, NamespaceString::kRangeDeletionNamespace, MODE_X) {} - -// Take DB and Collection lock in mode IX as well as collection UUID lock to serialize with -// operations that take the above version of the ScopedRangeDeleterLock such as FCV downgrade and -// BalancerStatsRegistry initialization. -ScopedRangeDeleterLock::ScopedRangeDeleterLock(OperationContext* opCtx, const UUID& collectionUuid) - : _configLock(opCtx, NamespaceString::kConfigDb, MODE_IX), - _rangeDeletionLock(opCtx, NamespaceString::kRangeDeletionNamespace, MODE_IX), - _collectionUuidLock(Lock::ResourceLock( - opCtx->lockState(), - ResourceId(RESOURCE_MUTEX, "RangeDeleterCollLock::" + collectionUuid.toString()), - MODE_X)) {} - const ReplicaSetAwareServiceRegistry::Registerer<BalancerStatsRegistry> balancerStatsRegistryRegisterer("BalancerStatsRegistry"); @@ -129,9 +115,12 @@ void BalancerStatsRegistry::initializeAsync(OperationContext* opCtx) { LOGV2_DEBUG(6419601, 2, "Initializing BalancerStatsRegistry"); try { - // Lock the range deleter to prevent - // concurrent modifications of orphans count - ScopedRangeDeleterLock rangeDeleterLock(opCtx); + // Lock the range deleter to prevent concurrent modifications of orphans count + ScopedRangeDeleterLock rangeDeleterLock(opCtx, LockMode::MODE_S); + // The collection lock is needed to serialize with direct writes to + // config.rangeDeletions + AutoGetCollection rangeDeletionLock( + opCtx, NamespaceString::kRangeDeletionNamespace, MODE_S); // Load current ophans count from disk _loadOrphansCount(opCtx); LOGV2_DEBUG(6419602, 2, "Completed BalancerStatsRegistry initialization"); diff --git a/src/mongo/db/s/balancer_stats_registry.h b/src/mongo/db/s/balancer_stats_registry.h index 473285b627c..e35ae419539 100644 --- a/src/mongo/db/s/balancer_stats_registry.h +++ b/src/mongo/db/s/balancer_stats_registry.h @@ -38,18 +38,19 @@ namespace mongo { /** - * Acquires the config db lock in IX mode and the collection lock for config.rangeDeletions in X - * mode. + * Scoped lock to synchronize with the execution of range deletions. + * The range-deleter acquires a scoped lock in IX mode while orphans are being deleted. + * Acquiring the scoped lock in MODE_X ensures that no orphan counter in `config.rangeDeletions` + * entries is going to be updated concurrently. */ class ScopedRangeDeleterLock { public: - ScopedRangeDeleterLock(OperationContext* opCtx); - ScopedRangeDeleterLock(OperationContext* opCtx, const UUID& collectionUuid); + ScopedRangeDeleterLock(OperationContext* opCtx, LockMode mode) + : _resourceLock(opCtx, opCtx->lockState(), _mutex.getRid(), mode) {} private: - Lock::DBLock _configLock; - Lock::CollectionLock _rangeDeletionLock; - boost::optional<Lock::ResourceLock> _collectionUuidLock; + const Lock::ResourceLock _resourceLock; + static inline const Lock::ResourceMutex _mutex{"ScopedRangeDeleterLock"}; }; /** diff --git a/src/mongo/db/s/migration_util.cpp b/src/mongo/db/s/migration_util.cpp index 170e31aa58e..656054d4514 100644 --- a/src/mongo/db/s/migration_util.cpp +++ b/src/mongo/db/s/migration_util.cpp @@ -719,7 +719,7 @@ void persistUpdatedNumOrphans(OperationContext* opCtx, << BSON("$exists" << true)); try { PersistentTaskStore<RangeDeletionTask> store(NamespaceString::kRangeDeletionNamespace); - ScopedRangeDeleterLock rangeDeleterLock(opCtx, collectionUuid); + ScopedRangeDeleterLock rangeDeleterLock(opCtx, MODE_IX); // TODO (SERVER-54284) Remove writeConflictRetry loop writeConflictRetry( opCtx, "updateOrphanCount", NamespaceString::kRangeDeletionNamespace.ns(), [&] { diff --git a/src/mongo/db/s/range_deletion_util.cpp b/src/mongo/db/s/range_deletion_util.cpp index 721646f5ab4..00435d0dba7 100644 --- a/src/mongo/db/s/range_deletion_util.cpp +++ b/src/mongo/db/s/range_deletion_util.cpp @@ -328,6 +328,7 @@ ExecutorFuture<void> deleteRangeInBatches(const std::shared_ptr<executor::TaskEx int numDeleted; { + ScopedRangeDeleterLock rangeDeleterLock(opCtx, MODE_IX); AutoGetCollection collection(opCtx, nss, MODE_IX); // Ensure the collection exists and has not been dropped or dropped @@ -343,8 +344,6 @@ ExecutorFuture<void> deleteRangeInBatches(const std::shared_ptr<executor::TaskEx markRangeDeletionTaskAsProcessing(opCtx, migrationId); { - ScopedRangeDeleterLock rangeDeleterLock(opCtx, collectionUuid); - numDeleted = uassertStatusOK(deleteNextBatch(opCtx, collection.getCollection(), @@ -649,12 +648,12 @@ void setOrphanCountersOnRangeDeletionTasks(OperationContext* opCtx) { ShardingCatalogClient::kLocalWriteConcern); }; + ScopedRangeDeleterLock rangeDeleterLock(opCtx, MODE_X); store.forEach( opCtx, BSONObj(), [opCtx, &store, &setNumOrphansOnTask](const RangeDeletionTask& deletionTask) { AutoGetCollection collection(opCtx, deletionTask.getNss(), MODE_IX); - ScopedRangeDeleterLock rangeDeleterLock(opCtx, deletionTask.getCollectionUuid()); if (!collection || collection->uuid() != deletionTask.getCollectionUuid()) { // The deletion task is referring to a collection that has been dropped setNumOrphansOnTask(deletionTask, 0); diff --git a/src/mongo/db/stats/SConscript b/src/mongo/db/stats/SConscript index b27a81181ac..845600bfacb 100644 --- a/src/mongo/db/stats/SConscript +++ b/src/mongo/db/stats/SConscript @@ -128,6 +128,7 @@ env.Library( '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/index/index_access_method', '$BUILD_DIR/mongo/db/pipeline/document_sources_idl', + '$BUILD_DIR/mongo/db/s/balancer_stats_registry', '$BUILD_DIR/mongo/db/timeseries/bucket_catalog', '$BUILD_DIR/mongo/db/timeseries/timeseries_stats', 'fill_locker_info', |