diff options
author | Tommaso Tocci <tommaso.tocci@mongodb.com> | 2022-10-31 23:45:21 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-01 10:42:29 +0000 |
commit | a4c2c33a3154c86ec245556f1122091f87d407de (patch) | |
tree | 2d4dbe10f6691ed945b99c4eeeb2d5e4175f355a | |
parent | 39e14246a6e1b332e57f017b727207b766cb313b (diff) | |
download | mongo-a4c2c33a3154c86ec245556f1122091f87d407de.tar.gz |
SERVER-70864 Get rid of fine-grained range deleter lock
(cherry picked from commit 9cad5aec81a4d40a5d61fe8e63ddc02c869b1a12)
-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 | 28 | ||||
-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/stats/SConscript | 1 |
6 files changed, 42 insertions, 40 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h index df64a741e59..52f9f8e6421 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 a47874ee8e1..2694fa7b51b 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', @@ -36,14 +35,25 @@ env.Library( LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/db/catalog/index_catalog', '$BUILD_DIR/mongo/db/concurrency/lock_manager', - '$BUILD_DIR/mongo/db/dbdirectclient', - '$BUILD_DIR/mongo/db/repl/replica_set_aware_service', '$BUILD_DIR/mongo/db/server_base', '$BUILD_DIR/mongo/db/write_block_bypass', ], ) 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', @@ -196,6 +206,7 @@ env.Library( '$BUILD_DIR/mongo/db/timeseries/bucket_catalog', '$BUILD_DIR/mongo/idl/server_parameter', '$BUILD_DIR/mongo/util/future_util', + 'balancer_stats_registry', 'sharding_logging', ], ) @@ -498,6 +509,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_logging', 'sharding_runtime_d', diff --git a/src/mongo/db/s/balancer_stats_registry.cpp b/src/mongo/db/s/balancer_stats_registry.cpp index c2308b26d2d..281e6714385 100644 --- a/src/mongo/db/s/balancer_stats_registry.cpp +++ b/src/mongo/db/s/balancer_stats_registry.cpp @@ -30,6 +30,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" @@ -60,23 +61,6 @@ ThreadPool::Options makeDefaultThreadPoolOptions() { } } // namespace -ScopedRangeDeleterLock::ScopedRangeDeleterLock(OperationContext* opCtx) - // TODO SERVER-62491 Use system tenantId for DBLock - : _configLock(opCtx, DatabaseName(boost::none, 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) - // TODO SERVER-62491 Use system tenantId for DBLock - : _configLock(opCtx, DatabaseName(boost::none, 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"); @@ -133,9 +117,13 @@ 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 09d0a97b118..d24ee7ff7b3 100644 --- a/src/mongo/db/s/migration_util.cpp +++ b/src/mongo/db/s/migration_util.cpp @@ -594,7 +594,7 @@ void persistUpdatedNumOrphans(OperationContext* opCtx, BSONObj query = BSON("_id" << migrationId); try { PersistentTaskStore<RangeDeletionTask> store(NamespaceString::kRangeDeletionNamespace); - ScopedRangeDeleterLock rangeDeleterLock(opCtx, collectionUuid); + ScopedRangeDeleterLock rangeDeleterLock(opCtx, MODE_IX); // The DBDirectClient will not retry WriteConflictExceptions internally while holding an X // mode lock, so we need to retry at this level. writeConflictRetry( diff --git a/src/mongo/db/stats/SConscript b/src/mongo/db/stats/SConscript index 7d07cadb4b4..9296c474778 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', |