summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommaso Tocci <tommaso.tocci@mongodb.com>2022-11-01 02:33:55 +0100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-01 02:18:51 +0000
commit4645125b6cf7effd4788a543cf7f8acdc8fded13 (patch)
tree4ade449017307604eb8b69ab6b6c83c6b6898704
parentda6372ff24beea9f1db7a29b255572279b7a2dea (diff)
downloadmongo-4645125b6cf7effd4788a543cf7f8acdc8fded13.tar.gz
SERVER-70864 Get rid of fine-grained range deleter lock
(cherry picked from commit 5fc0b006e4362f80a449dffb2a5ff0039d80817b)
-rw-r--r--src/mongo/db/commands/SConscript1
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp2
-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.cpp25
-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/s/range_deletion_util.cpp5
-rw-r--r--src/mongo/db/stats/SConscript1
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',