diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
| commit | 4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch) | |
| tree | 1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/db/stats | |
| parent | aa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff) | |
| parent | 8f0827553e09872941945a093b647a4211a9db7f (diff) | |
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0'
with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/db/stats')
| -rw-r--r-- | src/mongo/db/stats/SConscript | 22 | ||||
| -rw-r--r-- | src/mongo/db/stats/counters.cpp | 31 | ||||
| -rw-r--r-- | src/mongo/db/stats/counters.h | 153 | ||||
| -rw-r--r-- | src/mongo/db/stats/read_preference_metrics.cpp | 144 | ||||
| -rw-r--r-- | src/mongo/db/stats/read_preference_metrics.h | 96 | ||||
| -rw-r--r-- | src/mongo/db/stats/read_preference_metrics.idl | 79 | ||||
| -rw-r--r-- | src/mongo/db/stats/server_write_concern_metrics.cpp | 16 | ||||
| -rw-r--r-- | src/mongo/db/stats/storage_stats.cpp | 73 |
8 files changed, 105 insertions, 509 deletions
diff --git a/src/mongo/db/stats/SConscript b/src/mongo/db/stats/SConscript index dfaf4a6a533..17bbe0cb144 100644 --- a/src/mongo/db/stats/SConscript +++ b/src/mongo/db/stats/SConscript @@ -22,7 +22,6 @@ env.Library( 'operation_latency_histogram.cpp' ], LIBDEPS=[ - '$BUILD_DIR/mongo/db/query/query_stats/query_stats', '$BUILD_DIR/mongo/db/server_options_core', '$BUILD_DIR/mongo/db/service_context', ], @@ -75,24 +74,6 @@ env.Library( ) env.Library( - target='read_preference_metrics', - source=[ - 'read_preference_metrics.cpp', - 'read_preference_metrics.idl', - ], - LIBDEPS=[ - '$BUILD_DIR/mongo/base', - '$BUILD_DIR/mongo/db/commands/server_status', - '$BUILD_DIR/mongo/idl/idl_parser', - ], - LIBDEPS_PRIVATE=[ - '$BUILD_DIR/mongo/client/read_preference', - '$BUILD_DIR/mongo/db/repl/repl_coordinator_interface', - '$BUILD_DIR/mongo/db/repl/repl_settings', - ], -) - -env.Library( target='resource_consumption_metrics', source=[ 'resource_consumption_metrics.cpp', @@ -145,9 +126,10 @@ 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/s/balancer_stats_registry', '$BUILD_DIR/mongo/db/timeseries/bucket_catalog', '$BUILD_DIR/mongo/db/timeseries/timeseries_stats', 'fill_locker_info', diff --git a/src/mongo/db/stats/counters.cpp b/src/mongo/db/stats/counters.cpp index 5f571640b5d..1f3f4c901bb 100644 --- a/src/mongo/db/stats/counters.cpp +++ b/src/mongo/db/stats/counters.cpp @@ -335,32 +335,7 @@ NetworkCounter networkCounter; AuthCounter authCounter; AggStageCounters aggStageCounters; DotsAndDollarsFieldsCounters dotsAndDollarsFieldsCounters; -QueryFrameworkCounters queryFrameworkCounters; -ValidatorCounters validatorCounters; - -OperatorCounters operatorCountersAggExpressions{"operatorCounters.expressions."}; -OperatorCounters operatorCountersMatchExpressions{"operatorCounters.match."}; -OperatorCounters operatorCountersGroupAccumulatorExpressions{"operatorCounters.groupAccumulators."}; -OperatorCounters operatorCountersWindowAccumulatorExpressions{ - "operatorCounters.windowAccumulators."}; - -Counter64 updateManyCount; -ServerStatusMetricField<Counter64> displayUpdateManyCount("query.updateManyCount", - &updateManyCount); -Counter64 deleteManyCount; -ServerStatusMetricField<Counter64> displayDeleteManyCount("query.deleteManyCount", - &deleteManyCount); - -Counter64 internalRetryableWriteCount; -ServerStatusMetricField<Counter64> displayInternalRetryableWriteCount( - "query.internalRetryableWriteCount", &internalRetryableWriteCount); - -Counter64 externalRetryableWriteCount; -ServerStatusMetricField<Counter64> displayExternalRetryableWriteCount( - "query.externalRetryableWriteCount", &externalRetryableWriteCount); - -Counter64 retryableInternalTransactionCount; -ServerStatusMetricField<Counter64> displayRetryableInternalTransactionCount( - "query.retryableInternalTransactionCount", &retryableInternalTransactionCount); - +QueryEngineCounters queryEngineCounters; +OperatorCountersAggExpressions operatorCountersAggExpressions; +OperatorCountersMatchExpressions operatorCountersMatchExpressions; } // namespace mongo diff --git a/src/mongo/db/stats/counters.h b/src/mongo/db/stats/counters.h index d314ec49302..5e22a46aece 100644 --- a/src/mongo/db/stats/counters.h +++ b/src/mongo/db/stats/counters.h @@ -337,21 +337,20 @@ public: extern DotsAndDollarsFieldsCounters dotsAndDollarsFieldsCounters; -class QueryFrameworkCounters { +class QueryEngineCounters { public: - QueryFrameworkCounters() - : sbeFindQueryMetric("query.queryFramework.find.sbe", &sbeFindQueryCounter), - classicFindQueryMetric("query.queryFramework.find.classic", &classicFindQueryCounter), - cqfFindQueryMetric("query.queryFramework.find.cqf", &cqfFindQueryCounter), - sbeOnlyAggregationMetric("query.queryFramework.aggregate.sbeOnly", + QueryEngineCounters() + : sbeFindQueryMetric("query.queryExecutionEngine.find.sbe", &sbeFindQueryCounter), + classicFindQueryMetric("query.queryExecutionEngine.find.classic", + &classicFindQueryCounter), + sbeOnlyAggregationMetric("query.queryExecutionEngine.aggregate.sbeOnly", &sbeOnlyAggregationCounter), - classicOnlyAggregationMetric("query.queryFramework.aggregate.classicOnly", + classicOnlyAggregationMetric("query.queryExecutionEngine.aggregate.classicOnly", &classicOnlyAggregationCounter), - sbeHybridAggregationMetric("query.queryFramework.aggregate.sbeHybrid", + sbeHybridAggregationMetric("query.queryExecutionEngine.aggregate.sbeHybrid", &sbeHybridAggregationCounter), - classicHybridAggregationMetric("query.queryFramework.aggregate.classicHybrid", - &classicHybridAggregationCounter), - cqfAggregationMetric("query.queryFramework.aggregate.cqf", &cqfAggregationQueryCounter) {} + classicHybridAggregationMetric("query.queryExecutionEngine.aggregate.classicHybrid", + &classicHybridAggregationCounter) {} void incrementQueryEngineCounters(CurOp* curop) { auto& debug = curop->debug(); @@ -377,137 +376,91 @@ public: sbeOnlyAggregationCounter.increment(); } } - } else if (debug.cqfUsed) { - if (cmdName == "find") { - cqfFindQueryCounter.increment(); - } else { - cqfAggregationQueryCounter.increment(); - } } } - // Query counters that record whether a find query was fully or partially executed in SBE, fully - // executed using the classic engine, or fully executed using the common query framework (CQF). - // One of these will always be incremented during a query. + // Query counters that record whether a find query was fully or partially executed in SBE, or + // fully executed using the classic engine. One or the other will always be incremented during a + // query. Counter64 sbeFindQueryCounter; Counter64 classicFindQueryCounter; - Counter64 cqfFindQueryCounter; ServerStatusMetricField<Counter64> sbeFindQueryMetric; ServerStatusMetricField<Counter64> classicFindQueryMetric; - ServerStatusMetricField<Counter64> cqfFindQueryMetric; // Aggregation query counters that record whether an aggregation was fully or partially executed - // in DocumentSource (an sbe/classic hybrid plan), fully pushed down to the sbe/classic layer, - // or executed using CQF. These are only incremented during aggregations. + // in DocumentSource (an sbe/classic hybrid plan), or fully pushed down to the sbe/classic + // layer. Only incremented during aggregations. Counter64 sbeOnlyAggregationCounter; Counter64 classicOnlyAggregationCounter; Counter64 sbeHybridAggregationCounter; Counter64 classicHybridAggregationCounter; - Counter64 cqfAggregationQueryCounter; ServerStatusMetricField<Counter64> sbeOnlyAggregationMetric; ServerStatusMetricField<Counter64> classicOnlyAggregationMetric; ServerStatusMetricField<Counter64> sbeHybridAggregationMetric; ServerStatusMetricField<Counter64> classicHybridAggregationMetric; - ServerStatusMetricField<Counter64> cqfAggregationMetric; }; -extern QueryFrameworkCounters queryFrameworkCounters; +extern QueryEngineCounters queryEngineCounters; -/** - * Generic class for counters of expressions inside various MQL statements. - */ -class OperatorCounters { +class OperatorCountersAggExpressions { private: - struct ExprCounter { - ExprCounter(const std::string name) : metric(name, &counter) {} + struct AggExprCounter { + AggExprCounter(StringData name) + : metric("operatorCounters.expressions." + name, &counter) {} + Counter64 counter; ServerStatusMetricField<Counter64> metric; }; public: - OperatorCounters(const std::string prefix) : _prefix{prefix} {} - - void addCounter(const std::string name) { - const StringData sdName(name); - operatorCountersExprMap[sdName] = std::make_unique<ExprCounter>(_prefix + name); + void addAggExpressionCounter(StringData name) { + operatorCountersAggExpressionMap[name] = std::make_unique<AggExprCounter>(name); } void mergeCounters(StringMap<uint64_t>& toMerge) { for (auto&& [name, cnt] : toMerge) { - if (auto it = operatorCountersExprMap.find(name); it != operatorCountersExprMap.end()) { + if (auto it = operatorCountersAggExpressionMap.find(name); + it != operatorCountersAggExpressionMap.end()) { it->second->counter.increment(cnt); } } } private: - const std::string _prefix; - // Map of expressions to the number of occurrences in queries. - StringMap<std::unique_ptr<ExprCounter>> operatorCountersExprMap = {}; + // Map of aggregation expressions to the number of occurrences in aggregation pipelines. + StringMap<std::unique_ptr<AggExprCounter>> operatorCountersAggExpressionMap = {}; }; -class ValidatorCounters { +extern OperatorCountersAggExpressions operatorCountersAggExpressions; + +/** + * Global counters for match expressions. + */ +class OperatorCountersMatchExpressions { +private: + struct MatchExprCounter { + MatchExprCounter(StringData name) : metric("operatorCounters.match." + name, &counter) {} + + Counter64 counter; + ServerStatusMetricField<Counter64> metric; + }; + public: - ValidatorCounters() { - _validatorCounterMap["create"] = std::make_unique<ValidatorCounter>("create"); - _validatorCounterMap["collMod"] = std::make_unique<ValidatorCounter>("collMod"); - } - - void incrementCounters(const StringData cmdName, - const BSONObj& validator, - bool parsingSucceeded) { - if (!validator.isEmpty()) { - auto validatorCounter = _validatorCounterMap.find(cmdName); - tassert(7139200, - str::stream() << "The validator counters are not support for the command: " - << cmdName, - validatorCounter != _validatorCounterMap.end()); - validatorCounter->second->total.increment(); - - if (!parsingSucceeded) { - validatorCounter->second->failed.increment(); - } - if (validator.hasField("$jsonSchema")) { - validatorCounter->second->jsonSchema.increment(); + void addMatchExprCounter(StringData name) { + operatorCountersMatchExprMap[name] = std::make_unique<MatchExprCounter>(name); + } + + void mergeCounters(StringMap<uint64_t>& toMerge) { + for (auto&& [name, cnt] : toMerge) { + if (auto it = operatorCountersMatchExprMap.find(name); + it != operatorCountersMatchExprMap.end()) { + it->second->counter.increment(cnt); } } } private: - struct ValidatorCounter { - ValidatorCounter(const StringData name) - : totalMetric("commands." + name + ".validator.total", &total), - failedMetric("commands." + name + ".validator.failed", &failed), - jsonSchemaMetric("commands." + name + ".validator.jsonSchema", &jsonSchema) {} - Counter64 total; - Counter64 failed; - Counter64 jsonSchema; - ServerStatusMetricField<Counter64> totalMetric; - ServerStatusMetricField<Counter64> failedMetric; - ServerStatusMetricField<Counter64> jsonSchemaMetric; - }; - - StringMap<std::unique_ptr<ValidatorCounter>> _validatorCounterMap = {}; + // Map of match expressions to the number of occurrences in queries. + StringMap<std::unique_ptr<MatchExprCounter>> operatorCountersMatchExprMap = {}; }; -extern ValidatorCounters validatorCounters; - -// Global counters for expressions inside aggregation pipelines. -extern OperatorCounters operatorCountersAggExpressions; -// Global counters for match expressions. -extern OperatorCounters operatorCountersMatchExpressions; -// Global counters for accumulator expressions apply to $group. -extern OperatorCounters operatorCountersGroupAccumulatorExpressions; -// Global counters for accumulator expressions apply to $setWindowFields. -extern OperatorCounters operatorCountersWindowAccumulatorExpressions; - -// Track the number of {multi:true} updates. -extern Counter64 updateManyCount; -// Track the number of deleteMany calls. -extern Counter64 deleteManyCount; -// Track the number of internal retryable writes -extern Counter64 internalRetryableWriteCount; -// Track the number of external retryable writes -extern Counter64 externalRetryableWriteCount; -// Track the number of internal transactions for retryable writes -extern Counter64 retryableInternalTransactionCount; - +extern OperatorCountersMatchExpressions operatorCountersMatchExpressions; } // namespace mongo diff --git a/src/mongo/db/stats/read_preference_metrics.cpp b/src/mongo/db/stats/read_preference_metrics.cpp deleted file mode 100644 index 776271ee70d..00000000000 --- a/src/mongo/db/stats/read_preference_metrics.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Copyright (C) 2023-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/db/stats/read_preference_metrics.h" -#include "mongo/bson/bsonobj.h" -#include "mongo/db/commands/server_status.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/repl/replication_coordinator.h" -#include "mongo/db/service_context.h" -#include "mongo/db/stats/read_preference_metrics_gen.h" -#include "mongo/util/decorable.h" - -namespace mongo { -namespace { -const auto ReadPreferenceMetricsDecoration = - ServiceContext::declareDecoration<ReadPreferenceMetrics>(); -} // namespace - -ReadPreferenceMetrics* ReadPreferenceMetrics::get(ServiceContext* service) { - return &ReadPreferenceMetricsDecoration(service); -} - -ReadPreferenceMetrics* ReadPreferenceMetrics::get(OperationContext* opCtx) { - return get(opCtx->getServiceContext()); -} - -void ReadPreferenceMetrics::recordReadPreference(ReadPreferenceSetting readPref, - bool isInternal, - bool isPrimary) { - auto& counters = isPrimary ? primaryCounters : secondaryCounters; - counters.increment(readPref, isInternal); -} - -void ReadPreferenceMetrics::Counters::increment(ReadPreferenceSetting readPref, bool isInternal) { - switch (readPref.pref) { - case ReadPreference::PrimaryOnly: - primary.increment(isInternal); - break; - case ReadPreference::PrimaryPreferred: - primaryPreferred.increment(isInternal); - break; - case ReadPreference::SecondaryOnly: - secondary.increment(isInternal); - break; - case ReadPreference::SecondaryPreferred: - secondaryPreferred.increment(isInternal); - break; - case ReadPreference::Nearest: - nearest.increment(isInternal); - break; - default: - MONGO_UNREACHABLE; - } - - // For primary read preference, the tag set will be empty, which is represented by an empty BSON - // array. For other read preference values without tags, the tag set contains one empty document - // in the BSON array. See the TagSet class definition for more details. - if (readPref.tags != TagSet::primaryOnly() && readPref.tags != TagSet()) { - tagged.increment(isInternal); - } -} - -void ReadPreferenceMetrics::Counter::increment(bool isInternal) { - auto& counter = isInternal ? internal : external; - counter.fetchAndAdd(1); -} - -ReadPrefOps ReadPreferenceMetrics::Counter::toReadPrefOps() const { - ReadPrefOps ops; - ops.setInternal(internal.load()); - ops.setExternal(external.load()); - return ops; -} - -void ReadPreferenceMetrics::Counters::flushCounters(ReadPrefDoc* doc) { - doc->setPrimary(primary.toReadPrefOps()); - doc->setPrimaryPreferred(primaryPreferred.toReadPrefOps()); - doc->setSecondary(secondary.toReadPrefOps()); - doc->setSecondaryPreferred(secondaryPreferred.toReadPrefOps()); - doc->setNearest(nearest.toReadPrefOps()); - doc->setTagged(tagged.toReadPrefOps()); -} - -void ReadPreferenceMetrics::generateMetricsDoc(ReadPreferenceMetricsDoc* doc) { - ReadPrefDoc primary; - primaryCounters.flushCounters(&primary); - doc->setExecutedOnPrimary(primary); - - ReadPrefDoc secondary; - secondaryCounters.flushCounters(&secondary); - doc->setExecutedOnSecondary(secondary); -} - -namespace { -class ReadPreferenceMetricsSSS : public ServerStatusSection { -public: - ReadPreferenceMetricsSSS() : ServerStatusSection("readPreferenceCounters") {} - - ~ReadPreferenceMetricsSSS() override = default; - - bool includeByDefault() const override { - return true; - } - - BSONObj generateSection(OperationContext* opCtx, - const BSONElement& configElement) const override { - if (!repl::ReplicationCoordinator::get(opCtx)->getSettings().usingReplSets()) { - return BSONObj(); - } - ReadPreferenceMetricsDoc stats; - ReadPreferenceMetrics::get(opCtx)->generateMetricsDoc(&stats); - return stats.toBSON(); - } - -} ReadPreferenceMetricsSSS; -} // namespace - -} // namespace mongo diff --git a/src/mongo/db/stats/read_preference_metrics.h b/src/mongo/db/stats/read_preference_metrics.h deleted file mode 100644 index c2ccb78ddcb..00000000000 --- a/src/mongo/db/stats/read_preference_metrics.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (C) 2023-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/client/read_preference.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/service_context.h" -#include "mongo/db/stats/read_preference_metrics_gen.h" - -namespace mongo { - -/** - * Contains server-wide metrics on read preference usage. Metrics are first split into two - * sub-documents that specify if the operation containing the read preference executed while the - * node was a primary or secondary. For each sub-document, metrics are collected for each read - * preference mode and if a tag set list was used. For each metric, operations are - * further split into internal and external operations. - */ - -class ReadPreferenceMetrics { - ReadPreferenceMetrics(const ReadPreferenceMetrics&) = delete; - ReadPreferenceMetrics& operator=(const ReadPreferenceMetrics&) = delete; - -public: - ReadPreferenceMetrics() = default; - - static ReadPreferenceMetrics* get(ServiceContext* service); - static ReadPreferenceMetrics* get(OperationContext* opCtx); - - void recordReadPreference(ReadPreferenceSetting readPref, bool isInternal, bool isPrimary); - - // Generates the overall read preference metrics document, with two sub-documents for operations - // that executed while in primary state and secondary state. This function and functions called - // within it construct the metrics IDL classes, fill their values, and serialize them to BSON - // for serverStatus. - void generateMetricsDoc(ReadPreferenceMetricsDoc* stats); - -private: - struct Counter { - AtomicWord<unsigned long long> internal{0}; - AtomicWord<unsigned long long> external{0}; - - // Loads an individual counter's internal and external operation counters into a - // 'ReadPrefOps' object. - ReadPrefOps toReadPrefOps() const; - // Increments one of the two counters, based on 'isInternal'. - void increment(bool isInternal); - }; - struct Counters { - Counter primary; - Counter primaryPreferred; - Counter secondary; - Counter secondaryPreferred; - Counter nearest; - Counter tagged; - - // Flushes all the individual read preference metrics while in a particular replica set - // state, which is part of generating the overall read preference metrics document. - void flushCounters(ReadPrefDoc* doc); - // Increments the correct counter based on the passed in 'readPref' and 'isInternal' - // arguments. - void increment(ReadPreferenceSetting readPref, bool isInternal); - }; - - Counters primaryCounters; - Counters secondaryCounters; -}; - -} // namespace mongo diff --git a/src/mongo/db/stats/read_preference_metrics.idl b/src/mongo/db/stats/read_preference_metrics.idl deleted file mode 100644 index 82f19fd3947..00000000000 --- a/src/mongo/db/stats/read_preference_metrics.idl +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (C) 2023-present MongoDB, Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the Server Side Public License, version 1, -# as published by MongoDB, Inc. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# Server Side Public License for more details. -# -# You should have received a copy of the Server Side Public License -# along with this program. If not, see -# <http://www.mongodb.com/licensing/server-side-public-license>. -# -# As a special exception, the copyright holders give permission to link the -# code of portions of this program with the OpenSSL library under certain -# conditions as described in each individual source file and distribute -# linked combinations including the program with the OpenSSL library. You -# must comply with the Server Side Public License in all respects for -# all of the code used other than as permitted herein. If you modify file(s) -# with this exception, you may extend this exception to your version of the -# file(s), but you are not obligated to do so. If you do not wish to do so, -# delete this exception statement from your version. If you delete this -# exception statement from all source files in the program, then also delete -# it in the license file. -# - -# This IDL file describes the BSON format for ReadConcernStats, and -# handles the serialization to and deserialization from its BSON representation -# for that class. - -global: - cpp_namespace: "mongo" - -imports: - - "mongo/client/read_preference.idl" - - "mongo/idl/basic_types.idl" - -structs: - ReadPrefOps: - description: "A struct containing the number of internal and external operations - using a particular read preference" - strict: true - fields: - internal: - type: long - default: 0 - external: - type: long - default: 0 - - ReadPrefDoc: - description: "A struct defining the metrics sub-document, with counters for each read - preference metric" - strict: true - fields: - primary: - type: ReadPrefOps - primaryPreferred: - type: ReadPrefOps - secondary: - type: ReadPrefOps - secondaryPreferred: - type: ReadPrefOps - nearest: - type: ReadPrefOps - tagged: - type: ReadPrefOps - - ReadPreferenceMetricsDoc: - description: "A struct defining the overall read preference metrics document. The document has - two sub-documents, outlining whether the read preference executed while the node was a primary or a secondary" - strict: true - fields: - executedOnPrimary: - type: ReadPrefDoc - executedOnSecondary: - type: ReadPrefDoc diff --git a/src/mongo/db/stats/server_write_concern_metrics.cpp b/src/mongo/db/stats/server_write_concern_metrics.cpp index 544d611f01c..7dcedc40ef6 100644 --- a/src/mongo/db/stats/server_write_concern_metrics.cpp +++ b/src/mongo/db/stats/server_write_concern_metrics.cpp @@ -134,25 +134,17 @@ void ServerWriteConcernMetrics::WriteConcernMetricsForOperationType::recordWrite } else { // Provenance is either: // - "implicitDefault" : implicit default WC (w:1 or w:"majority") is used. + // - "clientSupplied" : set without "w" value, so implicit default WC (w:1) is used. // - "internalWriteDefault" : if internal command sets empty WC ({writeConcern: {}}), // then default constructed WC (w:1) is used. implicitDefaultWC.recordWriteConcern(writeConcernOptions, numOps); } notExplicitWCount += numOps; - } else { - // Supplied write concern contains 'w' field, the provenance can still be default if it is - // being set by mongos. - if (writeConcernOptions.getProvenance().isCustomDefault()) { - cWWC.recordWriteConcern(writeConcernOptions, numOps); - notExplicitWCount += numOps; - } else if (writeConcernOptions.getProvenance().isImplicitDefault()) { - implicitDefaultWC.recordWriteConcern(writeConcernOptions, numOps); - notExplicitWCount += numOps; - } else { - explicitWC.recordWriteConcern(writeConcernOptions, numOps); - } + return; } + + explicitWC.recordWriteConcern(writeConcernOptions, numOps); } void ServerWriteConcernMetrics::WriteConcernCounters::toBSON(BSONObjBuilder* builder) const { diff --git a/src/mongo/db/stats/storage_stats.cpp b/src/mongo/db/stats/storage_stats.cpp index 203c762856d..870dc908021 100644 --- a/src/mongo/db/stats/storage_stats.cpp +++ b/src/mongo/db/stats/storage_stats.cpp @@ -36,9 +36,10 @@ #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/s/balancer_stats_registry.h" +#include "mongo/db/pipeline/aggregate_command_gen.h" // TODO (SERVER-64162) remove #include "mongo/db/timeseries/bucket_catalog.h" #include "mongo/db/timeseries/timeseries_stats.h" #include "mongo/logv2/log.h" @@ -48,6 +49,36 @@ 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<BSONObj> 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, @@ -59,14 +90,11 @@ Status appendCollectionStorageStats(OperationContext* opCtx, bool waitForLock = storageStatsSpec.getWaitForLock(); bool numericOnly = storageStatsSpec.getNumericOnly(); - const auto bucketNss = - nss.isTimeseriesBucketsCollection() ? nss : nss.makeTimeseriesBucketsNamespace(); - // Hold reference to the catalog for collection lookup without locks to be safe. - auto catalog = CollectionCatalog::get(opCtx); - auto bucketsColl = catalog->lookupCollectionByNamespace(opCtx, bucketNss); - const bool mayBeTimeseries = bucketsColl && bucketsColl->getTimeseriesOptions(); + const auto bucketNss = nss.makeTimeseriesBucketsNamespace(); + const auto isTimeseries = nss.isTimeseriesBucketsCollection() || + CollectionCatalog::get(opCtx)->lookupCollectionByNamespaceForRead(opCtx, bucketNss); const auto collNss = - (mayBeTimeseries && !nss.isTimeseriesBucketsCollection()) ? std::move(bucketNss) : nss; + (isTimeseries && !nss.isTimeseriesBucketsCollection()) ? std::move(bucketNss) : nss; boost::optional<AutoGetCollectionForReadCommandMaybeLockFree> autoColl; try { @@ -80,15 +108,7 @@ Status appendCollectionStorageStats(OperationContext* opCtx, } const auto& collection = autoColl->getCollection(); // Will be set if present - const bool isTimeseries = collection && collection->getTimeseriesOptions().has_value(); - - // We decided the requested namespace was a time series view, so we redirected to the underlying - // buckets collection. However, when we tried to acquire that collection, it did not exist or it - // did not have time series options, which means it was dropped and potentially recreated in - // between the two calls. Logically, the collection that we were looking for does not exist. - bool logicallyNotFound = collNss != nss && !isTimeseries; - - if (!collection || logicallyNotFound) { + if (!collection) { result->appendNumber("size", 0); result->appendNumber("count", 0); result->appendNumber(kOrphanCountField, 0); @@ -123,17 +143,10 @@ Status appendCollectionStorageStats(OperationContext* opCtx, } } - if (serverGlobalParams.clusterRole == ClusterRole::ShardServer && - !nss.isNamespaceAlwaysUnsharded()) { - if (serverGlobalParams.featureCompatibility.isVersionInitialized() && - feature_flags::gOrphanTracking.isEnabled(serverGlobalParams.featureCompatibility)) { - result->appendNumber( - kOrphanCountField, - BalancerStatsRegistry::get(opCtx)->getCollNumOrphanDocsFromDiskIfNeeded( - opCtx, collection->uuid())); - } - } else { - result->appendNumber(kOrphanCountField, 0); + if (serverGlobalParams.featureCompatibility.isVersionInitialized() && + feature_flags::gOrphanTracking.isEnabled(serverGlobalParams.featureCompatibility)) { + result->appendNumber(kOrphanCountField, + countOrphanDocsForCollection(opCtx, collection->uuid())); } const RecordStore* recordStore = collection->getRecordStore(); @@ -162,8 +175,8 @@ Status appendCollectionStorageStats(OperationContext* opCtx, BSONObjBuilder indexDetails; std::vector<std::string> indexBuilds; - auto it = indexCatalog->getIndexIterator( - opCtx, IndexCatalog::InclusionPolicy::kReady | IndexCatalog::InclusionPolicy::kUnfinished); + std::unique_ptr<IndexCatalog::IndexIterator> it = + indexCatalog->getIndexIterator(opCtx, /*includeUnfinishedIndexes=*/true); while (it->more()) { const IndexCatalogEntry* entry = it->next(); const IndexDescriptor* descriptor = entry->descriptor(); |
