diff options
author | Brett Nawrocki <brett.nawrocki@mongodb.com> | 2022-03-02 17:58:19 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-04 20:28:20 +0000 |
commit | 7212a6838e327a498a56b52f42ddd6ba0f80fce4 (patch) | |
tree | 2841ab8861c97b89a9025f4df69483f90ae252b5 /src/mongo/db | |
parent | f3672960cc89c6f7c6cd50cb18cfd8d8d116e43b (diff) | |
download | mongo-7212a6838e327a498a56b52f42ddd6ba0f80fce4.tar.gz |
SERVER-63728 Differentiate observers by role in cumulative metrics
Differentiate observers by role so that recipient and coordinator
estimates can be reported separately. Additionally, split reporting into
high/low estimates and replace placeholder values in the ServerStatus
report with those estimates.
Diffstat (limited to 'src/mongo/db')
19 files changed, 320 insertions, 87 deletions
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 7b6deed301d..b1b3515e4b0 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -111,6 +111,7 @@ env.Library( 'shard_metadata_util.cpp', 'shard_server_catalog_cache_loader.cpp', 'shard_server_op_observer.cpp', + 'sharding_data_transform_metrics.cpp', 'sharding_data_transform_cumulative_metrics.cpp', 'sharding_data_transform_instance_metrics.cpp', 'sharding_data_transform_metrics_observer.cpp', diff --git a/src/mongo/db/s/global_index_metrics.cpp b/src/mongo/db/s/global_index_metrics.cpp index a0d4e1e9443..d697063a0b1 100644 --- a/src/mongo/db/s/global_index_metrics.cpp +++ b/src/mongo/db/s/global_index_metrics.cpp @@ -61,7 +61,8 @@ GlobalIndexMetrics::GlobalIndexMetrics(UUID uuid, cumulativeMetrics) {} std::string GlobalIndexMetrics::createOperationDescription() const noexcept { - return fmt::format( - "GlobalIndexMetrics{}Service {}", getRoleName(_role), _instanceId.toString()); + return fmt::format("GlobalIndexMetrics{}Service {}", + ShardingDataTransformMetrics::getRoleName(_role), + _instanceId.toString()); } } // namespace mongo diff --git a/src/mongo/db/s/global_index_metrics_test.cpp b/src/mongo/db/s/global_index_metrics_test.cpp index bf948cb8914..dbca397d0b3 100644 --- a/src/mongo/db/s/global_index_metrics_test.cpp +++ b/src/mongo/db/s/global_index_metrics_test.cpp @@ -61,7 +61,7 @@ TEST_F(GlobalIndexMetricsTest, ReportForCurrentOpShouldHaveGlobalIndexDescriptio ASSERT_EQ(report.getStringField("desc").toString(), fmt::format("GlobalIndexMetrics{}Service {}", - GlobalIndexMetrics::getRoleName(role), + ShardingDataTransformMetrics::getRoleName(role), instanceId.toString())); }); } diff --git a/src/mongo/db/s/resharding/resharding_metrics_new.cpp b/src/mongo/db/s/resharding/resharding_metrics_new.cpp index e81704c0b3b..9452cb445a6 100644 --- a/src/mongo/db/s/resharding/resharding_metrics_new.cpp +++ b/src/mongo/db/s/resharding/resharding_metrics_new.cpp @@ -62,7 +62,9 @@ ReshardingMetricsNew::ReshardingMetricsNew( cumulativeMetrics) {} std::string ReshardingMetricsNew::createOperationDescription() const noexcept { - return fmt::format("ReshardingMetrics{}Service {}", getRoleName(_role), _instanceId.toString()); + return fmt::format("ReshardingMetrics{}Service {}", + ShardingDataTransformMetrics::getRoleName(_role), + _instanceId.toString()); } std::unique_ptr<ReshardingMetricsNew> ReshardingMetricsNew::makeInstance( diff --git a/src/mongo/db/s/resharding/resharding_metrics_new_test.cpp b/src/mongo/db/s/resharding/resharding_metrics_new_test.cpp index 0eaaf781594..b2c043a642c 100644 --- a/src/mongo/db/s/resharding/resharding_metrics_new_test.cpp +++ b/src/mongo/db/s/resharding/resharding_metrics_new_test.cpp @@ -61,7 +61,7 @@ TEST_F(ReshardingMetricsTest, ReportForCurrentOpShouldHaveGlobalIndexDescription ASSERT_EQ(report.getStringField("desc").toString(), fmt::format("ReshardingMetrics{}Service {}", - ReshardingMetricsNew::getRoleName(role), + ShardingDataTransformMetrics::getRoleName(role), instanceId.toString())); }); } diff --git a/src/mongo/db/s/resharding/resharding_oplog_batch_applier_test.cpp b/src/mongo/db/s/resharding/resharding_oplog_batch_applier_test.cpp index 27d1c2ef4f3..1a54401c910 100644 --- a/src/mongo/db/s/resharding/resharding_oplog_batch_applier_test.cpp +++ b/src/mongo/db/s/resharding/resharding_oplog_batch_applier_test.cpp @@ -109,12 +109,13 @@ public: } _metrics = std::make_unique<ReshardingMetrics>(serviceContext); - _metricsNew = ReshardingMetricsNew::makeInstance(UUID::gen(), - _outputNss, - ReshardingMetricsNew::kRecipient, - BSON("y" << 1), - false, - serviceContext); + _metricsNew = + ReshardingMetricsNew::makeInstance(UUID::gen(), + _outputNss, + ShardingDataTransformMetrics::Role::kRecipient, + BSON("y" << 1), + false, + serviceContext); _crudApplication = std::make_unique<ReshardingOplogApplicationRules>( _outputNss, std::vector<NamespaceString>{_myStashNss, _otherStashNss}, diff --git a/src/mongo/db/s/resharding/resharding_oplog_crud_application_test.cpp b/src/mongo/db/s/resharding/resharding_oplog_crud_application_test.cpp index 154baba79c8..046b457f876 100644 --- a/src/mongo/db/s/resharding/resharding_oplog_crud_application_test.cpp +++ b/src/mongo/db/s/resharding/resharding_oplog_crud_application_test.cpp @@ -111,12 +111,13 @@ public: } _metrics = std::make_unique<ReshardingMetrics>(getServiceContext()); - _metricsNew = ReshardingMetricsNew::makeInstance(_sourceUUID, - _outputNss, - ReshardingMetricsNew::kRecipient, - BSON(_newShardKey << 1), - false, - serviceContext); + _metricsNew = + ReshardingMetricsNew::makeInstance(_sourceUUID, + _outputNss, + ShardingDataTransformMetrics::Role::kRecipient, + BSON(_newShardKey << 1), + false, + serviceContext); _applier = std::make_unique<ReshardingOplogApplicationRules>( _outputNss, std::vector<NamespaceString>{_myStashNss, _otherStashNss}, diff --git a/src/mongo/db/s/sharding_data_transform_cumulative_metrics.cpp b/src/mongo/db/s/sharding_data_transform_cumulative_metrics.cpp index ba18bd7d8de..82933cd6c87 100644 --- a/src/mongo/db/s/sharding_data_transform_cumulative_metrics.cpp +++ b/src/mongo/db/s/sharding_data_transform_cumulative_metrics.cpp @@ -148,29 +148,49 @@ ShardingDataTransformCumulativeMetrics* ShardingDataTransformCumulativeMetrics:: ShardingDataTransformCumulativeMetrics::ShardingDataTransformCumulativeMetrics( const std::string& rootSectionName) - : _rootSectionName{rootSectionName}, _operationWasAttempted{false} {} + : _rootSectionName{rootSectionName}, + _instanceMetricsForAllRoles(ShardingDataTransformMetrics::kRoleCount), + _operationWasAttempted{false} {} ShardingDataTransformCumulativeMetrics::DeregistrationFunction ShardingDataTransformCumulativeMetrics::registerInstanceMetrics(const InstanceObserver* metrics) { _operationWasAttempted.store(true); - auto it = insertMetrics(metrics); + auto role = metrics->getRole(); + auto it = insertMetrics(metrics, getMetricsSetForRole(role)); return [=] { stdx::unique_lock guard(_mutex); - _instanceMetrics.erase(it); + getMetricsSetForRole(role).erase(it); }; } -int64_t ShardingDataTransformCumulativeMetrics::getOldestOperationRemainingTimeMillis() const { +int64_t ShardingDataTransformCumulativeMetrics::getOldestOperationHighEstimateRemainingTimeMillis( + Role role) const { + stdx::unique_lock guard(_mutex); - if (_instanceMetrics.empty()) { - return 0; - } - return (*_instanceMetrics.begin())->getRemainingTimeMillis(); + auto op = getOldestOperation(guard, role); + return op ? op->getHighEstimateRemainingTimeMillis() : 0; +} + +int64_t ShardingDataTransformCumulativeMetrics::getOldestOperationLowEstimateRemainingTimeMillis( + Role role) const { + + stdx::unique_lock guard(_mutex); + auto op = getOldestOperation(guard, role); + return op ? op->getLowEstimateRemainingTimeMillis() : 0; } size_t ShardingDataTransformCumulativeMetrics::getObservedMetricsCount() const { stdx::unique_lock guard(_mutex); - return _instanceMetrics.size(); + size_t count = 0; + for (const auto& set : _instanceMetricsForAllRoles) { + count += set.size(); + } + return count; +} + +size_t ShardingDataTransformCumulativeMetrics::getObservedMetricsCount(Role role) const { + stdx::unique_lock guard(_mutex); + return getMetricsSetForRole(role).size(); } void ShardingDataTransformCumulativeMetrics::reportForServerStatus(BSONObjBuilder* bob) const { @@ -205,9 +225,12 @@ void ShardingDataTransformCumulativeMetrics::reportActive(BSONObjBuilder* bob) c void ShardingDataTransformCumulativeMetrics::reportOldestActive(BSONObjBuilder* bob) const { BSONObjBuilder s(bob->subobjStart(kOldestActive)); - s.append(kCoordinatorAllShardsHighestRemainingOperationTimeEstimatedMillis, kPlaceholderLong); - s.append(kCoordinatorAllShardsLowestRemainingOperationTimeEstimatedMillis, kPlaceholderLong); - s.append(kRecipientRemainingOperationTimeEstimatedMillis, kPlaceholderLong); + s.append(kCoordinatorAllShardsHighestRemainingOperationTimeEstimatedMillis, + getOldestOperationHighEstimateRemainingTimeMillis(Role::kCoordinator)); + s.append(kCoordinatorAllShardsLowestRemainingOperationTimeEstimatedMillis, + getOldestOperationLowEstimateRemainingTimeMillis(Role::kCoordinator)); + s.append(kRecipientRemainingOperationTimeEstimatedMillis, + getOldestOperationHighEstimateRemainingTimeMillis(Role::kRecipient)); } void ShardingDataTransformCumulativeMetrics::reportLatencies(BSONObjBuilder* bob) const { @@ -251,12 +274,32 @@ void ShardingDataTransformCumulativeMetrics::reportCurrentInSteps(BSONObjBuilder s.append(kCountInstancesInDonorState7Done, kPlaceholderInt); } +const ShardingDataTransformCumulativeMetrics::InstanceObserver* +ShardingDataTransformCumulativeMetrics::getOldestOperation(WithLock, Role role) const { + auto set = getMetricsSetForRole(role); + if (set.empty()) { + return nullptr; + } + return *set.begin(); +} + +ShardingDataTransformCumulativeMetrics::MetricsSet& +ShardingDataTransformCumulativeMetrics::getMetricsSetForRole(Role role) { + return _instanceMetricsForAllRoles[static_cast<size_t>(role)]; +} + +const ShardingDataTransformCumulativeMetrics::MetricsSet& +ShardingDataTransformCumulativeMetrics::getMetricsSetForRole(Role role) const { + return _instanceMetricsForAllRoles[static_cast<size_t>(role)]; +} + ShardingDataTransformCumulativeMetrics::MetricsSet::iterator -ShardingDataTransformCumulativeMetrics::insertMetrics(const InstanceObserver* metrics) { +ShardingDataTransformCumulativeMetrics::insertMetrics(const InstanceObserver* metrics, + MetricsSet& set) { stdx::unique_lock guard(_mutex); - auto before = _instanceMetrics.size(); - auto it = _instanceMetrics.insert(_instanceMetrics.end(), metrics); - invariant(before + 1 == _instanceMetrics.size()); + auto before = set.size(); + auto it = set.insert(set.end(), metrics); + invariant(before + 1 == set.size()); return it; } diff --git a/src/mongo/db/s/sharding_data_transform_cumulative_metrics.h b/src/mongo/db/s/sharding_data_transform_cumulative_metrics.h index 10b41a7875a..930ebab2f4e 100644 --- a/src/mongo/db/s/sharding_data_transform_cumulative_metrics.h +++ b/src/mongo/db/s/sharding_data_transform_cumulative_metrics.h @@ -41,6 +41,7 @@ namespace mongo { class ShardingDataTransformCumulativeMetrics { public: + using Role = ShardingDataTransformMetrics::Role; using InstanceObserver = ShardingDataTransformMetricsObserverInterface; using DeregistrationFunction = unique_function<void()>; @@ -49,8 +50,10 @@ public: ShardingDataTransformCumulativeMetrics(const std::string& rootSectionName); [[nodiscard]] DeregistrationFunction registerInstanceMetrics(const InstanceObserver* metrics); - int64_t getOldestOperationRemainingTimeMillis() const; + int64_t getOldestOperationHighEstimateRemainingTimeMillis(Role role) const; + int64_t getOldestOperationLowEstimateRemainingTimeMillis(Role role) const; size_t getObservedMetricsCount() const; + size_t getObservedMetricsCount(Role role) const; void reportForServerStatus(BSONObjBuilder* bob) const; private: @@ -70,11 +73,14 @@ private: void reportOldestActive(BSONObjBuilder* bob) const; void reportLatencies(BSONObjBuilder* bob) const; void reportCurrentInSteps(BSONObjBuilder* bob) const; - MetricsSet::iterator insertMetrics(const InstanceObserver* metrics); + MetricsSet& getMetricsSetForRole(Role role); + const MetricsSet& getMetricsSetForRole(Role role) const; + const InstanceObserver* getOldestOperation(WithLock, Role role) const; + MetricsSet::iterator insertMetrics(const InstanceObserver* metrics, MetricsSet& set); mutable Mutex _mutex; const std::string _rootSectionName; - MetricsSet _instanceMetrics; + std::vector<MetricsSet> _instanceMetricsForAllRoles; AtomicWord<bool> _operationWasAttempted; }; diff --git a/src/mongo/db/s/sharding_data_transform_cumulative_metrics_test.cpp b/src/mongo/db/s/sharding_data_transform_cumulative_metrics_test.cpp index 6d6cd9b987d..eacb5fcbf35 100644 --- a/src/mongo/db/s/sharding_data_transform_cumulative_metrics_test.cpp +++ b/src/mongo/db/s/sharding_data_transform_cumulative_metrics_test.cpp @@ -76,26 +76,36 @@ TEST_F(ShardingDataTransformCumulativeMetricsTest, AddAndRemoveMetrics) { TEST_F(ShardingDataTransformCumulativeMetricsTest, MetricsReportsOldestWhenInsertedFirst) { auto deregisterOldest = _cumulativeMetrics.registerInstanceMetrics(getOldestObserver()); auto deregisterYoungest = _cumulativeMetrics.registerInstanceMetrics(getYoungestObserver()); - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), kOldestTime); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + kOldestTime); } TEST_F(ShardingDataTransformCumulativeMetricsTest, MetricsReportsOldestWhenInsertedLast) { auto deregisterYoungest = _cumulativeMetrics.registerInstanceMetrics(getYoungestObserver()); auto deregisterOldest = _cumulativeMetrics.registerInstanceMetrics(getOldestObserver()); - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), kOldestTime); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + kOldestTime); } TEST_F(ShardingDataTransformCumulativeMetricsTest, RemainingTimeReports0WhenEmpty) { ASSERT_EQ(_cumulativeMetrics.getObservedMetricsCount(), 0); - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), 0); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + 0); } TEST_F(ShardingDataTransformCumulativeMetricsTest, UpdatesOldestWhenOldestIsRemoved) { auto deregisterYoungest = _cumulativeMetrics.registerInstanceMetrics(getYoungestObserver()); auto deregisterOldest = _cumulativeMetrics.registerInstanceMetrics(getOldestObserver()); - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), kOldestTime); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + kOldestTime); deregisterOldest(); - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), kYoungestTime); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + kYoungestTime); } TEST_F(ShardingDataTransformCumulativeMetricsTest, InsertsTwoWithSameStartTime) { @@ -103,7 +113,9 @@ TEST_F(ShardingDataTransformCumulativeMetricsTest, InsertsTwoWithSameStartTime) ObserverMock sameAsOldest{kOldestTime, kOldestTime}; auto deregisterOldest2 = _cumulativeMetrics.registerInstanceMetrics(&sameAsOldest); ASSERT_EQ(_cumulativeMetrics.getObservedMetricsCount(), 2); - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), kOldestTime); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + kOldestTime); } TEST_F(ShardingDataTransformCumulativeMetricsTest, StillReportsOldestAfterRandomOperations) { @@ -115,5 +127,52 @@ TEST_F(ShardingDataTransformCumulativeMetricsTest, doRandomOperationsMultithreadedTest<ScopedObserverMock>(); } +TEST_F(ShardingDataTransformCumulativeMetricsTest, ReportsOldestByRole) { + using Role = ShardingDataTransformMetrics::Role; + auto& metrics = _cumulativeMetrics; + ObserverMock oldDonor{100, 100, 100, Role::kDonor}; + ObserverMock youngDonor{200, 200, 200, Role::kDonor}; + ObserverMock oldRecipient{300, 300, 300, Role::kRecipient}; + ObserverMock youngRecipient{400, 400, 400, Role::kRecipient}; + auto removeOldD = metrics.registerInstanceMetrics(&oldDonor); + auto removeYoungD = metrics.registerInstanceMetrics(&youngDonor); + auto removeOldR = metrics.registerInstanceMetrics(&oldRecipient); + auto removeYoungR = metrics.registerInstanceMetrics(&youngRecipient); + + ASSERT_EQ(metrics.getObservedMetricsCount(), 4); + ASSERT_EQ(metrics.getObservedMetricsCount(Role::kDonor), 2); + ASSERT_EQ(metrics.getObservedMetricsCount(Role::kRecipient), 2); + ASSERT_EQ(metrics.getOldestOperationHighEstimateRemainingTimeMillis(Role::kDonor), 100); + ASSERT_EQ(metrics.getOldestOperationHighEstimateRemainingTimeMillis(Role::kRecipient), 300); + removeOldD(); + ASSERT_EQ(metrics.getObservedMetricsCount(), 3); + ASSERT_EQ(metrics.getObservedMetricsCount(Role::kDonor), 1); + ASSERT_EQ(metrics.getOldestOperationHighEstimateRemainingTimeMillis(Role::kDonor), 200); + removeOldR(); + ASSERT_EQ(metrics.getObservedMetricsCount(), 2); + ASSERT_EQ(metrics.getObservedMetricsCount(Role::kRecipient), 1); + ASSERT_EQ(metrics.getOldestOperationHighEstimateRemainingTimeMillis(Role::kRecipient), 400); +} + +TEST_F(ShardingDataTransformCumulativeMetricsTest, ReportContainsTimeEstimates) { + using Role = ShardingDataTransformMetrics::Role; + ObserverMock recipient{100, 100, 100, Role::kRecipient}; + ObserverMock coordinator{200, 400, 300, Role::kCoordinator}; + auto ignore = _cumulativeMetrics.registerInstanceMetrics(&recipient); + ignore = _cumulativeMetrics.registerInstanceMetrics(&coordinator); + + BSONObjBuilder bob; + _cumulativeMetrics.reportForServerStatus(&bob); + auto report = bob.done(); + auto section = report.getObjectField(kTestMetricsName).getObjectField("oldestActive"); + ASSERT_EQ(section.getIntField("recipientRemainingOperationTimeEstimatedMillis"), 100); + ASSERT_EQ( + section.getIntField("coordinatorAllShardsHighestRemainingOperationTimeEstimatedMillis"), + 400); + ASSERT_EQ( + section.getIntField("coordinatorAllShardsLowestRemainingOperationTimeEstimatedMillis"), + 300); +} + } // namespace } // namespace mongo diff --git a/src/mongo/db/s/sharding_data_transform_instance_metrics.cpp b/src/mongo/db/s/sharding_data_transform_instance_metrics.cpp index f678b446d4c..6bba04dd1c1 100644 --- a/src/mongo/db/s/sharding_data_transform_instance_metrics.cpp +++ b/src/mongo/db/s/sharding_data_transform_instance_metrics.cpp @@ -32,32 +32,18 @@ namespace { constexpr int64_t kPlaceholderTimestampForTesting = 0; +constexpr int64_t kPlaceholderTimeRemainingForTesting = 0; constexpr auto TEMP_VALUE = "placeholder"; } // namespace namespace mongo { -namespace { -const stdx::unordered_map<ShardingDataTransformInstanceMetrics::Role, StringData> roleToName = { - {ShardingDataTransformInstanceMetrics::kCoordinator, "Coordinator"_sd}, - {ShardingDataTransformInstanceMetrics::kDonor, "Donor"_sd}, - {ShardingDataTransformInstanceMetrics::kRecipient, "Recipient"_sd}, -}; -} - -StringData ShardingDataTransformInstanceMetrics::getRoleName(Role role) { - auto it = roleToName.find(role); - invariant(it != roleToName.end()); - return it->second; -} - ShardingDataTransformInstanceMetrics::ShardingDataTransformInstanceMetrics( UUID instanceId, BSONObj originalCommand, NamespaceString sourceNs, Role role, - ShardingDataTransformCumulativeMetrics* cumulativeMetrics) : ShardingDataTransformInstanceMetrics{ std::move(instanceId), @@ -93,8 +79,12 @@ ShardingDataTransformInstanceMetrics::~ShardingDataTransformInstanceMetrics() { } } -int64_t ShardingDataTransformInstanceMetrics::getRemainingTimeMillis() const { - return _observer->getRemainingTimeMillis(); +int64_t ShardingDataTransformInstanceMetrics::getHighEstimateRemainingTimeMillis() const { + return kPlaceholderTimeRemainingForTesting; +} + +int64_t ShardingDataTransformInstanceMetrics::getLowEstimateRemainingTimeMillis() const { + return kPlaceholderTimeRemainingForTesting; } int64_t ShardingDataTransformInstanceMetrics::getStartTimestamp() const { @@ -105,10 +95,14 @@ const UUID& ShardingDataTransformInstanceMetrics::getUuid() const { return _placeholderUuidForTesting; } -std::string ShardingDataTransformInstanceMetrics::createOperationDescription() const noexcept { +ShardingDataTransformInstanceMetrics::Role ShardingDataTransformInstanceMetrics::getRole() const { + return _role; +} - return fmt::format( - "ShardingDataTransformMetrics{}Service {}", getRoleName(_role), _instanceId.toString()); +std::string ShardingDataTransformInstanceMetrics::createOperationDescription() const noexcept { + return fmt::format("ShardingDataTransformMetrics{}Service {}", + ShardingDataTransformMetrics::getRoleName(_role), + _instanceId.toString()); } BSONObj ShardingDataTransformInstanceMetrics::reportForCurrentOp() const noexcept { diff --git a/src/mongo/db/s/sharding_data_transform_instance_metrics.h b/src/mongo/db/s/sharding_data_transform_instance_metrics.h index a2afce0775e..6c204bc717a 100644 --- a/src/mongo/db/s/sharding_data_transform_instance_metrics.h +++ b/src/mongo/db/s/sharding_data_transform_instance_metrics.h @@ -31,13 +31,14 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/s/sharding_data_transform_cumulative_metrics.h" +#include "mongo/db/s/sharding_data_transform_metrics.h" #include "mongo/db/s/sharding_data_transform_metrics_observer_interface.h" namespace mongo { class ShardingDataTransformInstanceMetrics { public: - enum Role { kCoordinator, kDonor, kRecipient }; + using Role = ShardingDataTransformMetrics::Role; using ObserverPtr = std::unique_ptr<ShardingDataTransformMetricsObserverInterface>; ShardingDataTransformInstanceMetrics(UUID instanceId, @@ -55,14 +56,15 @@ public: virtual ~ShardingDataTransformInstanceMetrics(); BSONObj reportForCurrentOp() const noexcept; - static StringData getRoleName(Role role); - int64_t getRemainingTimeMillis() const; + int64_t getHighEstimateRemainingTimeMillis() const; + int64_t getLowEstimateRemainingTimeMillis() const; int64_t getStartTimestamp() const; const UUID& getUuid() const; void onInsertApplied(); void onUpdateApplied(); void onDeleteApplied(); void onOplogEntriesApplied(int64_t numEntries); + Role getRole() const; protected: virtual std::string createOperationDescription() const noexcept; diff --git a/src/mongo/db/s/sharding_data_transform_instance_metrics_test.cpp b/src/mongo/db/s/sharding_data_transform_instance_metrics_test.cpp index 8546ca02931..a88404700a4 100644 --- a/src/mongo/db/s/sharding_data_transform_instance_metrics_test.cpp +++ b/src/mongo/db/s/sharding_data_transform_instance_metrics_test.cpp @@ -96,12 +96,6 @@ TEST_F(ShardingDataTransformInstanceMetricsTest, RegisterAndDeregisterMetricsAtO ASSERT_EQ(_cumulativeMetrics.getObservedMetricsCount(), 0); } -TEST_F(ShardingDataTransformInstanceMetricsTest, UsesObserverToReportTimeEstimate) { - constexpr auto kExpectedTimeLeft = 1000; - auto metrics = createInstanceMetrics(std::make_unique<ObserverMock>(0, kExpectedTimeLeft)); - ASSERT_EQ(metrics->getRemainingTimeMillis(), kExpectedTimeLeft); -} - TEST_F(ShardingDataTransformInstanceMetricsTest, RandomOperations) { doRandomOperationsTest<InstanceMetricsWithObserverMock>(); } @@ -122,7 +116,7 @@ TEST_F(ShardingDataTransformInstanceMetricsTest, ReportForCurrentOpShouldHaveGen auto report = metrics->reportForCurrentOp(); ASSERT_EQ(report.getStringField("desc").toString(), fmt::format("ShardingDataTransformMetrics{}Service {}", - ShardingDataTransformInstanceMetrics::getRoleName(role), + ShardingDataTransformMetrics::getRoleName(role), instanceId.toString())); }); } @@ -135,7 +129,7 @@ TEST_F(ShardingDataTransformInstanceMetricsTest, GetRoleNameShouldReturnCorrectN }; std::for_each(roles.begin(), roles.end(), [&](auto role) { - ASSERT_EQ(ShardingDataTransformInstanceMetrics::getRoleName(role.first), role.second); + ASSERT_EQ(ShardingDataTransformMetrics::getRoleName(role.first), role.second); }); } diff --git a/src/mongo/db/s/sharding_data_transform_metrics.cpp b/src/mongo/db/s/sharding_data_transform_metrics.cpp new file mode 100644 index 00000000000..7c5ba3b39c4 --- /dev/null +++ b/src/mongo/db/s/sharding_data_transform_metrics.cpp @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2022-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/s/sharding_data_transform_metrics.h" +#include "mongo/stdx/unordered_map.h" + +namespace mongo { + +namespace { +const stdx::unordered_map<ShardingDataTransformMetrics::Role, StringData> roleToName = { + {ShardingDataTransformMetrics::Role::kCoordinator, "Coordinator"_sd}, + {ShardingDataTransformMetrics::Role::kDonor, "Donor"_sd}, + {ShardingDataTransformMetrics::Role::kRecipient, "Recipient"_sd}, +}; +} + +StringData ShardingDataTransformMetrics::getRoleName(Role role) { + auto it = roleToName.find(role); + invariant(it != roleToName.end()); + return it->second; +} + +} // namespace mongo diff --git a/src/mongo/db/s/sharding_data_transform_metrics.h b/src/mongo/db/s/sharding_data_transform_metrics.h new file mode 100644 index 00000000000..92edf30a10b --- /dev/null +++ b/src/mongo/db/s/sharding_data_transform_metrics.h @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2022-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/base/string_data.h" + +namespace mongo { + +class ShardingDataTransformMetrics { +public: + static constexpr size_t kRoleCount = 3; + enum class Role { kCoordinator, kDonor, kRecipient }; + static StringData getRoleName(Role role); +}; + +} // namespace mongo diff --git a/src/mongo/db/s/sharding_data_transform_metrics_observer.cpp b/src/mongo/db/s/sharding_data_transform_metrics_observer.cpp index 1282731129e..419f3643a9e 100644 --- a/src/mongo/db/s/sharding_data_transform_metrics_observer.cpp +++ b/src/mongo/db/s/sharding_data_transform_metrics_observer.cpp @@ -29,17 +29,18 @@ #include "mongo/db/s/sharding_data_transform_metrics_observer.h" -namespace { -constexpr int64_t kPlaceholderTimeRemainingForTesting = 0; -} namespace mongo { ShardingDataTransformMetricsObserver::ShardingDataTransformMetricsObserver( ShardingDataTransformInstanceMetrics* metrics) : _metrics(metrics) {} -int64_t ShardingDataTransformMetricsObserver::getRemainingTimeMillis() const { - return kPlaceholderTimeRemainingForTesting; +int64_t ShardingDataTransformMetricsObserver::getHighEstimateRemainingTimeMillis() const { + return _metrics->getHighEstimateRemainingTimeMillis(); +} + +int64_t ShardingDataTransformMetricsObserver::getLowEstimateRemainingTimeMillis() const { + return _metrics->getLowEstimateRemainingTimeMillis(); } int64_t ShardingDataTransformMetricsObserver::getStartTimestamp() const { @@ -50,4 +51,8 @@ const UUID& ShardingDataTransformMetricsObserver::getUuid() const { return _metrics->getUuid(); } +ShardingDataTransformMetrics::Role ShardingDataTransformMetricsObserver::getRole() const { + return _metrics->getRole(); +} + } // namespace mongo diff --git a/src/mongo/db/s/sharding_data_transform_metrics_observer.h b/src/mongo/db/s/sharding_data_transform_metrics_observer.h index 85ed5e7e399..0bcf95ad553 100644 --- a/src/mongo/db/s/sharding_data_transform_metrics_observer.h +++ b/src/mongo/db/s/sharding_data_transform_metrics_observer.h @@ -38,9 +38,11 @@ namespace mongo { class ShardingDataTransformMetricsObserver : public ShardingDataTransformMetricsObserverInterface { public: ShardingDataTransformMetricsObserver(ShardingDataTransformInstanceMetrics* metrics); - int64_t getRemainingTimeMillis() const override; + int64_t getHighEstimateRemainingTimeMillis() const override; + int64_t getLowEstimateRemainingTimeMillis() const override; int64_t getStartTimestamp() const override; const UUID& getUuid() const override; + ShardingDataTransformMetrics::Role getRole() const override; private: ShardingDataTransformInstanceMetrics* _metrics; diff --git a/src/mongo/db/s/sharding_data_transform_metrics_observer_interface.h b/src/mongo/db/s/sharding_data_transform_metrics_observer_interface.h index e114ea44e58..611cdaa9491 100644 --- a/src/mongo/db/s/sharding_data_transform_metrics_observer_interface.h +++ b/src/mongo/db/s/sharding_data_transform_metrics_observer_interface.h @@ -29,15 +29,18 @@ #pragma once +#include "mongo/db/s/sharding_data_transform_metrics.h" #include "mongo/util/uuid.h" namespace mongo { class ShardingDataTransformMetricsObserverInterface { public: virtual ~ShardingDataTransformMetricsObserverInterface() = default; - virtual int64_t getRemainingTimeMillis() const = 0; + virtual int64_t getHighEstimateRemainingTimeMillis() const = 0; + virtual int64_t getLowEstimateRemainingTimeMillis() const = 0; virtual int64_t getStartTimestamp() const = 0; virtual const UUID& getUuid() const = 0; + virtual ShardingDataTransformMetrics::Role getRole() const = 0; }; } // namespace mongo diff --git a/src/mongo/db/s/sharding_data_transform_metrics_test_fixture.h b/src/mongo/db/s/sharding_data_transform_metrics_test_fixture.h index 90922842f5c..049d4445223 100644 --- a/src/mongo/db/s/sharding_data_transform_metrics_test_fixture.h +++ b/src/mongo/db/s/sharding_data_transform_metrics_test_fixture.h @@ -45,29 +45,52 @@ namespace mongo { class ObserverMock : public ShardingDataTransformMetricsObserverInterface { public: + constexpr static auto kDefaultRole = ShardingDataTransformMetrics::Role::kCoordinator; ObserverMock(int64_t startTime, int64_t timeRemaining) - : _uuid{UUID::gen()}, _startTime{startTime}, _timeRemaining{timeRemaining} {} + : ObserverMock{startTime, timeRemaining, timeRemaining, kDefaultRole} {} + ObserverMock(int64_t startTime, + int64_t timeRemainingHigh, + int64_t timeRemainingLow, + ShardingDataTransformMetrics::Role role) + : _uuid{UUID::gen()}, + _startTime{startTime}, + _timeRemainingHigh{timeRemainingHigh}, + _timeRemainingLow{timeRemainingLow}, + _role{role} { + invariant(timeRemainingHigh >= timeRemainingLow); + } virtual const UUID& getUuid() const override { return _uuid; } - virtual int64_t getRemainingTimeMillis() const override { - return _timeRemaining; + virtual int64_t getHighEstimateRemainingTimeMillis() const override { + return _timeRemainingHigh; + } + + virtual int64_t getLowEstimateRemainingTimeMillis() const override { + return _timeRemainingLow; } virtual int64_t getStartTimestamp() const override { return _startTime; } + virtual ShardingDataTransformMetrics::Role getRole() const override { + return _role; + } + private: UUID _uuid; int64_t _startTime; - int64_t _timeRemaining; + int64_t _timeRemainingHigh; + int64_t _timeRemainingLow; + ShardingDataTransformMetrics::Role _role; }; class ShardingDataTransformMetricsTestFixture : public unittest::Test { protected: + constexpr static auto kTestMetricsName = "testMetrics"; constexpr static int64_t kYoungestTime = std::numeric_limits<int64_t>::max(); constexpr static int64_t kOldestTime = 1; using Role = ShardingDataTransformInstanceMetrics::Role; @@ -75,7 +98,7 @@ protected: const BSONObj kTestCommand = BSON("command" << "test"); - ShardingDataTransformMetricsTestFixture() : _cumulativeMetrics{"testMetrics"} {} + ShardingDataTransformMetricsTestFixture() : _cumulativeMetrics{kTestMetricsName} {} const ObserverMock* getYoungestObserver() { static StaticImmortal<ObserverMock> youngest{kYoungestTime, kYoungestTime}; @@ -142,7 +165,9 @@ protected: kRemovalOdds, rng.nextInt64(), registerAtIndex(rng.nextInt32(kIterations), getOldestObserver())); - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), kOldestTime); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + kOldestTime); } template <typename ScopedObserverType> @@ -177,7 +202,9 @@ protected: for (auto& pf : threadPFs) { pf.future.wait(); } - ASSERT_EQ(_cumulativeMetrics.getOldestOperationRemainingTimeMillis(), kOldestTime); + ASSERT_EQ(_cumulativeMetrics.getOldestOperationHighEstimateRemainingTimeMillis( + ObserverMock::kDefaultRole), + kOldestTime); size_t expectedCount = 1; // Special insert for kOldest is not counted in vector size. for (auto& v : threadStorage) { expectedCount += v.size(); |