From f86a959e46955ef409787abced4a32655a362fe7 Mon Sep 17 00:00:00 2001 From: Allison Easton Date: Mon, 25 Jul 2022 14:06:30 +0000 Subject: SERVER-64242 Make collStats aggregation stage retrieve orphans from BalancerStatisticsRegistry (cherry picked from commit 2a7a609a78eb12dd5a237933b49b5f6bd03043f2) --- src/mongo/db/s/SConscript | 6 ++-- src/mongo/db/s/balancer_stats_registry.cpp | 50 ++++++++++++++++++++++++++++++ src/mongo/db/s/balancer_stats_registry.h | 23 ++++++++++++++ src/mongo/db/s/range_deletion_util.cpp | 15 --------- src/mongo/db/s/range_deletion_util.h | 15 --------- src/mongo/db/stats/SConscript | 2 -- src/mongo/db/stats/storage_stats.cpp | 39 +++-------------------- 7 files changed, 82 insertions(+), 68 deletions(-) (limited to 'src/mongo') diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 237dad8bcf8..08af4e461bd 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -11,12 +11,14 @@ 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', 'database_sharding_state.cpp', 'global_user_write_block_state.cpp', 'operation_sharding_state.cpp', + 'range_deletion_task.idl', 'shard_key_index_util.cpp', 'sharding_api_d_params.idl', 'sharding_migration_critical_section.cpp', @@ -31,7 +33,9 @@ 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', ], @@ -47,7 +51,6 @@ env.Library( 'auto_split_vector.cpp', 'chunk_move_write_concern_options.cpp', 'chunk_split_state_driver.cpp', - 'balancer_stats_registry.cpp', 'chunk_splitter.cpp', 'collection_critical_section_document.idl', 'collection_sharding_runtime.cpp', @@ -70,7 +73,6 @@ env.Library( 'op_observer_sharding_impl.cpp', 'periodic_balancer_config_refresher.cpp', 'periodic_sharded_index_consistency_checker.cpp', - 'range_deletion_task.idl', 'range_deletion_util.cpp', 'read_only_catalog_cache_loader.cpp', 'recoverable_critical_section_service.cpp', diff --git a/src/mongo/db/s/balancer_stats_registry.cpp b/src/mongo/db/s/balancer_stats_registry.cpp index 0d664c0762c..0dd50c06275 100644 --- a/src/mongo/db/s/balancer_stats_registry.cpp +++ b/src/mongo/db/s/balancer_stats_registry.cpp @@ -58,6 +58,21 @@ 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 balancerStatsRegistryRegisterer("BalancerStatsRegistry"); @@ -176,6 +191,41 @@ long long BalancerStatsRegistry::getCollNumOrphanDocs(const UUID& collectionUUID return 0; } +long long BalancerStatsRegistry::getCollNumOrphanDocsFromDiskIfNeeded( + OperationContext* opCtx, const UUID& collectionUUID) const { + try { + return getCollNumOrphanDocs(collectionUUID); + } catch (const ExceptionFor&) { + // Since the registry is not initialized, run an aggregation to get the number of orphans + DBDirectClient client(opCtx); + std::vector pipeline; + pipeline.push_back( + BSON("$match" << BSON(RangeDeletionTask::kCollectionUuidFieldName << collectionUUID))); + pipeline.push_back( + BSON("$group" << BSON("_id" + << "numOrphans" + << "count" + << BSON("$sum" + << "$" + RangeDeletionTask::kNumOrphanDocsFieldName)))); + AggregateCommandRequest aggRequest(NamespaceString::kRangeDeletionNamespace, pipeline); + auto swCursor = DBClientCursor::fromAggregationRequest( + &client, aggRequest, false /* secondaryOk */, true /* useExhaust */); + if (!swCursor.isOK()) { + return 0; + } + auto cursor = std::move(swCursor.getValue()); + if (!cursor->more()) { + return 0; + } + auto res = cursor->nextSafe(); + invariant(!cursor->more()); + auto numOrphans = res.getField("count"); + invariant(numOrphans); + return numOrphans.exactNumberLong(); + } +} + + void BalancerStatsRegistry::onRangeDeletionTaskInsertion(const UUID& collectionUUID, long long numOrphanDocs) { if (!_isInitialized()) diff --git a/src/mongo/db/s/balancer_stats_registry.h b/src/mongo/db/s/balancer_stats_registry.h index 6dcfae68609..473285b627c 100644 --- a/src/mongo/db/s/balancer_stats_registry.h +++ b/src/mongo/db/s/balancer_stats_registry.h @@ -29,6 +29,7 @@ #pragma once +#include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/replica_set_aware_service.h" #include "mongo/util/concurrency/thread_pool.h" @@ -36,6 +37,21 @@ namespace mongo { +/** + * Acquires the config db lock in IX mode and the collection lock for config.rangeDeletions in X + * mode. + */ +class ScopedRangeDeleterLock { +public: + ScopedRangeDeleterLock(OperationContext* opCtx); + ScopedRangeDeleterLock(OperationContext* opCtx, const UUID& collectionUuid); + +private: + Lock::DBLock _configLock; + Lock::CollectionLock _rangeDeletionLock; + boost::optional _collectionUuidLock; +}; + /** * The BalancerStatsRegistry is used to cache metadata on shards, such as the orphan documents * count. The blancer (on the config sever) periodically fetches this metadata through the @@ -78,6 +94,13 @@ public: long long getCollNumOrphanDocs(const UUID& collectionUUID) const; + /** + * Retrieves the numOrphanDocs from the balancer stats registry if initialized or runs an + * aggregation on disk if not. + */ + long long getCollNumOrphanDocsFromDiskIfNeeded(OperationContext* opCtx, + const UUID& collectionUUID) const; + private: void onInitialDataAvailable(OperationContext* opCtx, bool isMajorityDataAvailable) override final {} diff --git a/src/mongo/db/s/range_deletion_util.cpp b/src/mongo/db/s/range_deletion_util.cpp index ee4562105d9..e291cf82097 100644 --- a/src/mongo/db/s/range_deletion_util.cpp +++ b/src/mongo/db/s/range_deletion_util.cpp @@ -717,19 +717,4 @@ void clearOrphanCountersFromRangeDeletionTasks(OperationContext* opCtx) { } } -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)) {} - } // namespace mongo diff --git a/src/mongo/db/s/range_deletion_util.h b/src/mongo/db/s/range_deletion_util.h index 1c2fdffef1d..fb2eae0d610 100644 --- a/src/mongo/db/s/range_deletion_util.h +++ b/src/mongo/db/s/range_deletion_util.h @@ -39,21 +39,6 @@ namespace mongo { -/** - * Acquires the config db lock in IX mode and the collection lock for config.rangeDeletions in X - * mode. - */ -class ScopedRangeDeleterLock { -public: - ScopedRangeDeleterLock(OperationContext* opCtx); - ScopedRangeDeleterLock(OperationContext* opCtx, const UUID& collectionUuid); - -private: - Lock::DBLock _configLock; - Lock::CollectionLock _rangeDeletionLock; - boost::optional _collectionUuidLock; -}; - /** * Deletes a range of orphaned documents for the given namespace and collection UUID. Returns a * future which will be resolved when the range has finished being deleted. The resulting future diff --git a/src/mongo/db/stats/SConscript b/src/mongo/db/stats/SConscript index 17bbe0cb144..b27a81181ac 100644 --- a/src/mongo/db/stats/SConscript +++ b/src/mongo/db/stats/SConscript @@ -126,9 +126,7 @@ env.Library( '$BUILD_DIR/mongo/db/catalog/index_catalog', '$BUILD_DIR/mongo/db/commands/server_status', '$BUILD_DIR/mongo/db/db_raii', - '$BUILD_DIR/mongo/db/dbdirectclient', # TODO (SERVER-64162) remove '$BUILD_DIR/mongo/db/index/index_access_method', - '$BUILD_DIR/mongo/db/pipeline/aggregation_request_helper', # TODO (SERVER-64162) remove '$BUILD_DIR/mongo/db/pipeline/document_sources_idl', '$BUILD_DIR/mongo/db/timeseries/bucket_catalog', '$BUILD_DIR/mongo/db/timeseries/timeseries_stats', diff --git a/src/mongo/db/stats/storage_stats.cpp b/src/mongo/db/stats/storage_stats.cpp index 870dc908021..e3c2385630f 100644 --- a/src/mongo/db/stats/storage_stats.cpp +++ b/src/mongo/db/stats/storage_stats.cpp @@ -36,10 +36,9 @@ #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/db_raii.h" -#include "mongo/db/dbdirectclient.h" // TODO (SERVER-64162) remove #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/pipeline/aggregate_command_gen.h" // TODO (SERVER-64162) remove +#include "mongo/db/s/balancer_stats_registry.h" #include "mongo/db/timeseries/bucket_catalog.h" #include "mongo/db/timeseries/timeseries_stats.h" #include "mongo/logv2/log.h" @@ -49,36 +48,6 @@ namespace mongo { -namespace { -long long countOrphanDocsForCollection(OperationContext* opCtx, const UUID& uuid) { - // TODO (SERVER-64162): move this function to range_deletion_util.cpp and replace - // "collectionUuid" and "numOrphanDocs" with RangeDeletionTask field names. - DBDirectClient client(opCtx); - std::vector pipeline; - pipeline.push_back(BSON("$match" << BSON("collectionUuid" << uuid))); - pipeline.push_back(BSON("$group" << BSON("_id" - << "numOrphans" - << "count" - << BSON("$sum" - << "$numOrphanDocs")))); - AggregateCommandRequest aggRequest(NamespaceString::kRangeDeletionNamespace, pipeline); - auto swCursor = DBClientCursor::fromAggregationRequest( - &client, aggRequest, false /* secondaryOk */, true /* useExhaust */); - if (!swCursor.isOK()) { - return 0; - } - auto cursor = std::move(swCursor.getValue()); - if (!cursor->more()) { - return 0; - } - auto res = cursor->nextSafe(); - invariant(!cursor->more()); - auto numOrphans = res.getField("count"); - invariant(numOrphans); - return numOrphans.exactNumberLong(); -} -} // namespace - Status appendCollectionStorageStats(OperationContext* opCtx, const NamespaceString& nss, const StorageStatsSpec& storageStatsSpec, @@ -145,8 +114,10 @@ Status appendCollectionStorageStats(OperationContext* opCtx, if (serverGlobalParams.featureCompatibility.isVersionInitialized() && feature_flags::gOrphanTracking.isEnabled(serverGlobalParams.featureCompatibility)) { - result->appendNumber(kOrphanCountField, - countOrphanDocsForCollection(opCtx, collection->uuid())); + result->appendNumber( + kOrphanCountField, + BalancerStatsRegistry::get(opCtx)->getCollNumOrphanDocsFromDiskIfNeeded( + opCtx, collection->uuid())); } const RecordStore* recordStore = collection->getRecordStore(); -- cgit v1.2.1