summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommaso Tocci <tommaso.tocci@mongodb.com>2022-10-31 23:45:21 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-01 10:42:29 +0000
commita4c2c33a3154c86ec245556f1122091f87d407de (patch)
tree2d4dbe10f6691ed945b99c4eeeb2d5e4175f355a
parent39e14246a6e1b332e57f017b727207b766cb313b (diff)
downloadmongo-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.h18
-rw-r--r--src/mongo/db/s/SConscript18
-rw-r--r--src/mongo/db/s/balancer_stats_registry.cpp28
-rw-r--r--src/mongo/db/s/balancer_stats_registry.h15
-rw-r--r--src/mongo/db/s/migration_util.cpp2
-rw-r--r--src/mongo/db/stats/SConscript1
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',