summaryrefslogtreecommitdiff
path: root/src/mongo/db/stats
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/db/stats
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (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/SConscript22
-rw-r--r--src/mongo/db/stats/counters.cpp31
-rw-r--r--src/mongo/db/stats/counters.h153
-rw-r--r--src/mongo/db/stats/read_preference_metrics.cpp144
-rw-r--r--src/mongo/db/stats/read_preference_metrics.h96
-rw-r--r--src/mongo/db/stats/read_preference_metrics.idl79
-rw-r--r--src/mongo/db/stats/server_write_concern_metrics.cpp16
-rw-r--r--src/mongo/db/stats/storage_stats.cpp73
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();