diff options
author | Gregory Noma <gregory.noma@gmail.com> | 2022-10-28 17:43:48 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-10-31 22:33:55 +0000 |
commit | cc733015b5f72b51475460d24096f8a8c45d0647 (patch) | |
tree | 2805d9f8485b873fc30b621c58d79e84336903f9 /src/mongo/db/storage | |
parent | 201497d405225041f1806d25dfed475f3ec3f7ae (diff) | |
download | mongo-cc733015b5f72b51475460d24096f8a8c45d0647.tar.gz |
SERVER-70830 Unit test `WiredTigerOperationStats`
Diffstat (limited to 'src/mongo/db/storage')
8 files changed, 471 insertions, 179 deletions
diff --git a/src/mongo/db/storage/recovery_unit.h b/src/mongo/db/storage/recovery_unit.h index 20c49c637d3..9e173d632e7 100644 --- a/src/mongo/db/storage/recovery_unit.h +++ b/src/mongo/db/storage/recovery_unit.h @@ -37,6 +37,7 @@ #include "mongo/bson/timestamp.h" #include "mongo/db/repl/read_concern_level.h" #include "mongo/db/storage/snapshot.h" +#include "mongo/db/storage/storage_stats.h" #include "mongo/util/decorable.h" namespace mongo { @@ -76,37 +77,6 @@ enum class PrepareConflictBehavior { }; /** - * Storage statistics management class, with interfaces to provide the statistics in the BSON format - * and an operator to add the statistics values. - */ -class StorageStats { - StorageStats(const StorageStats&) = delete; - StorageStats& operator=(const StorageStats&) = delete; - -public: - StorageStats() = default; - - virtual ~StorageStats(){}; - - /** - * Provides the storage statistics in the form of a BSONObj. - */ - virtual BSONObj toBSON() = 0; - - /** - * Add the statistics values. - */ - virtual StorageStats& operator+=(const StorageStats&) = 0; - - /** - * Provides the ability to create an instance of this class outside of the storage integration - * layer. - */ - virtual std::shared_ptr<StorageStats> getCopy() = 0; -}; - - -/** * A RecoveryUnit is responsible for ensuring that data is persisted. * All on-disk information must be mutated through this interface. */ diff --git a/src/mongo/db/storage/storage_stats.h b/src/mongo/db/storage/storage_stats.h new file mode 100644 index 00000000000..b0afd2ba16d --- /dev/null +++ b/src/mongo/db/storage/storage_stats.h @@ -0,0 +1,57 @@ +/** + * 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/bson/bsonobj.h" + +namespace mongo { + +/** + * Manages statistics from the storage engine, allowing addition of statistics and serialization to + * BSON. + */ +class StorageStats { +public: + StorageStats() = default; + + StorageStats(const StorageStats&) = delete; + StorageStats(StorageStats&&) = delete; + StorageStats& operator=(const StorageStats&) = delete; + + virtual ~StorageStats() = default; + + virtual BSONObj toBSON() const = 0; + + virtual std::shared_ptr<StorageStats> clone() const = 0; + + virtual StorageStats& operator+=(const StorageStats&) = 0; +}; + +} // namespace mongo diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript index 68a76639ed5..638cf0b933c 100644 --- a/src/mongo/db/storage/wiredtiger/SConscript +++ b/src/mongo/db/storage/wiredtiger/SConscript @@ -37,6 +37,7 @@ wtEnv.Library( 'wiredtiger_index.cpp', 'wiredtiger_index_util.cpp', 'wiredtiger_kv_engine.cpp', + 'wiredtiger_operation_stats.cpp', 'wiredtiger_oplog_manager.cpp', 'wiredtiger_parameters.cpp', 'wiredtiger_prepare_conflict.cpp', @@ -133,6 +134,7 @@ wtEnv.CppUnitTest( 'wiredtiger_init_test.cpp', 'wiredtiger_c_api_test.cpp', 'wiredtiger_kv_engine_test.cpp', + 'wiredtiger_operation_stats_test.cpp', 'wiredtiger_recovery_unit_test.cpp', 'wiredtiger_session_cache_test.cpp', 'wiredtiger_util_test.cpp', diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats.cpp new file mode 100644 index 00000000000..ebf3842e7bc --- /dev/null +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats.cpp @@ -0,0 +1,139 @@ +/** + * 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/storage/wiredtiger/wiredtiger_operation_stats.h" + +#include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/storage/wiredtiger/wiredtiger_util.h" + +namespace mongo { +namespace { + +enum class StatType { kData, kWait }; + +struct StatInfo { + StringData name; + StatType type; +}; + +stdx::unordered_map<int, StatInfo> statInfo = { + {WT_STAT_SESSION_BYTES_READ, {"bytesRead"_sd, StatType::kData}}, + {WT_STAT_SESSION_BYTES_WRITE, {"bytesWritten"_sd, StatType::kData}}, + {WT_STAT_SESSION_LOCK_DHANDLE_WAIT, {"handleLock"_sd, StatType::kWait}}, + {WT_STAT_SESSION_READ_TIME, {"timeReadingMicros"_sd, StatType::kData}}, + {WT_STAT_SESSION_WRITE_TIME, {"timeWritingMicros"_sd, StatType::kData}}, + {WT_STAT_SESSION_LOCK_SCHEMA_WAIT, {"schemaLock"_sd, StatType::kWait}}, + {WT_STAT_SESSION_CACHE_TIME, {"cache"_sd, StatType::kWait}}}; + +} // namespace + +WiredTigerOperationStats::WiredTigerOperationStats(WT_SESSION* session) { + invariant(session); + + WT_CURSOR* c; + uassert(ErrorCodes::CursorNotFound, + "Unable to open statistics cursor", + !session->open_cursor(session, "statistics:session", nullptr, "statistics=(fast)", &c)); + + ScopeGuard guard{[c] { c->close(c); }}; + + int32_t key; + uint64_t value; + while (c->next(c) == 0 && c->get_key(c, &key) == 0) { + fassert(51035, c->get_value(c, nullptr, nullptr, &value) == 0); + _stats[key] = WiredTigerUtil::castStatisticsValue<long long>(value); + } + + // Reset the statistics so that the next fetch gives the recent values. + invariantWTOK(c->reset(c), c->session); +} + +BSONObj WiredTigerOperationStats::toBSON() const { + boost::optional<BSONObjBuilder> dataSection; + boost::optional<BSONObjBuilder> waitSection; + + for (auto&& [stat, value] : _stats) { + if (value == 0) { + continue; + } + + auto it = statInfo.find(stat); + if (it == statInfo.end()) { + continue; + } + auto&& [name, type] = it->second; + + auto appendToSection = [name = name, + value = value](boost::optional<BSONObjBuilder>& section) { + if (!section) { + section.emplace(); + } + section->append(name, value); + }; + + switch (type) { + case StatType::kData: + appendToSection(dataSection); + break; + case StatType::kWait: + appendToSection(waitSection); + break; + } + } + + BSONObjBuilder builder; + if (dataSection) { + builder.append("data", dataSection->obj()); + } + if (waitSection) { + builder.append("timeWaitingMicros", waitSection->obj()); + } + + return builder.obj(); +} + +std::shared_ptr<StorageStats> WiredTigerOperationStats::clone() const { + auto copy = std::make_shared<WiredTigerOperationStats>(); + *copy += *this; + return copy; +} + +WiredTigerOperationStats& WiredTigerOperationStats::operator+=( + const WiredTigerOperationStats& other) { + for (auto&& [stat, value] : other._stats) { + _stats[stat] += value; + } + return *this; +} + +StorageStats& WiredTigerOperationStats::operator+=(const StorageStats& other) { + return *this += checked_cast<const WiredTigerOperationStats&>(other); +} + +} // namespace mongo diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats.h b/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats.h new file mode 100644 index 00000000000..581303e30b8 --- /dev/null +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats.h @@ -0,0 +1,55 @@ +/** + * 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 <wiredtiger.h> + +#include "mongo/db/storage/storage_stats.h" + +namespace mongo { + +class WiredTigerOperationStats final : public StorageStats { +public: + WiredTigerOperationStats() = default; + WiredTigerOperationStats(WT_SESSION* session); + + BSONObj toBSON() const final; + + std::shared_ptr<StorageStats> clone() const final; + + StorageStats& operator+=(const StorageStats&) final; + + WiredTigerOperationStats& operator+=(const WiredTigerOperationStats&); + +private: + std::map<int, long long> _stats; +}; + +} // namespace mongo diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats_test.cpp new file mode 100644 index 00000000000..5151f59cb48 --- /dev/null +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_operation_stats_test.cpp @@ -0,0 +1,215 @@ +/** + * 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/storage/wiredtiger/wiredtiger_operation_stats.h" +#include "mongo/unittest/temp_dir.h" +#include "mongo/unittest/unittest.h" + +namespace mongo { +namespace { + +#define ASSERT_WT_OK(result) ASSERT_EQ(result, 0) << wiredtiger_strerror(result) + +class WiredTigerOperationStatsTest : public unittest::Test { +protected: + void setUp() override { + ASSERT_WT_OK( + wiredtiger_open(_path.path().c_str(), nullptr, "create,statistics=(fast),", &_conn)); + ASSERT_WT_OK(_conn->open_session(_conn, nullptr, "isolation=snapshot", &_session)); + ASSERT_WT_OK(_session->create( + _session, _uri.c_str(), "type=file,key_format=q,value_format=u,log=(enabled=false)")); + } + + void tearDown() override { + ASSERT_EQ(_conn->close(_conn, nullptr), 0); + } + + /** + * Writes the given data using WT. Causes the bytesWritten and timeWritingMicros stats to be + * incremented. + */ + void write(const std::string& data) { + ASSERT_WT_OK(_session->begin_transaction(_session, nullptr)); + + WT_CURSOR* cursor; + ASSERT_WT_OK(_session->open_cursor(_session, _uri.c_str(), nullptr, nullptr, &cursor)); + + cursor->set_key(cursor, _key++); + + WT_ITEM item{data.data(), data.size()}; + cursor->set_value(cursor, &item); + + ASSERT_WT_OK(cursor->insert(cursor)); + ASSERT_WT_OK(cursor->close(cursor)); + ASSERT_WT_OK(_session->commit_transaction(_session, nullptr)); + ASSERT_WT_OK(_session->checkpoint(_session, nullptr)); + } + + /** + * Reads all of the previously written data from WT. Causes the bytesRead and timeReadingMicros + * stats to be incremented. + */ + void read() { + tearDown(); + setUp(); + + ASSERT_WT_OK(_session->begin_transaction(_session, nullptr)); + + WT_CURSOR* cursor; + ASSERT_WT_OK(_session->open_cursor(_session, _uri.c_str(), nullptr, nullptr, &cursor)); + + for (int64_t i = 0; i < _key; ++i) { + cursor->set_key(cursor, i); + ASSERT_WT_OK(cursor->search(cursor)); + + WT_ITEM value; + ASSERT_WT_OK(cursor->get_value(cursor, &value)); + } + + ASSERT_WT_OK(cursor->close(cursor)); + ASSERT_WT_OK(_session->commit_transaction(_session, nullptr)); + } + + unittest::TempDir _path{"wiredtiger_operation_stats_test"}; + std::string _uri{"table:wiredtiger_operation_stats_test"}; + WT_CONNECTION* _conn; + WT_SESSION* _session; + int64_t _key = 0; +}; + +TEST_F(WiredTigerOperationStatsTest, Empty) { + ASSERT_BSONOBJ_EQ(WiredTigerOperationStats{_session}.toBSON(), BSONObj{}); +} + +TEST_F(WiredTigerOperationStatsTest, Write) { + write("a"); + + auto statsObj = WiredTigerOperationStats{_session}.toBSON(); + + auto dataSection = statsObj["data"]; + ASSERT_EQ(dataSection.type(), BSONType::Object) << statsObj; + + ASSERT(dataSection["bytesWritten"]) << statsObj; + for (auto&& [name, value] : dataSection.Obj()) { + ASSERT_EQ(value.type(), BSONType::NumberLong) << statsObj; + ASSERT_GT(value.numberLong(), 0) << statsObj; + } +} + +TEST_F(WiredTigerOperationStatsTest, Read) { + write("a"); + read(); + + auto statsObj = WiredTigerOperationStats{_session}.toBSON(); + + auto dataSection = statsObj["data"]; + ASSERT_EQ(dataSection.type(), BSONType::Object) << statsObj; + + ASSERT(dataSection["bytesRead"]) << statsObj; + for (auto&& [name, value] : dataSection.Obj()) { + ASSERT_EQ(value.type(), BSONType::NumberLong) << statsObj; + ASSERT_GT(value.numberLong(), 0) << statsObj; + } +} + +TEST_F(WiredTigerOperationStatsTest, Large) { + auto remaining = static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) + 1; + while (remaining > 0) { + std::string data(1024 * 1024, 'a'); + remaining -= data.size(); + write(data); + } + + auto statsObj = WiredTigerOperationStats{_session}.toBSON(); + ASSERT_GT(statsObj["data"]["bytesWritten"].numberLong(), std::numeric_limits<uint32_t>::max()) + << statsObj; + + read(); + + statsObj = WiredTigerOperationStats{_session}.toBSON(); + ASSERT_GT(statsObj["data"]["bytesRead"].numberLong(), std::numeric_limits<uint32_t>::max()) + << statsObj; +} + +TEST_F(WiredTigerOperationStatsTest, Add) { + std::vector<std::unique_ptr<WiredTigerOperationStats>> stats; + + write("a"); + stats.push_back(std::make_unique<WiredTigerOperationStats>(_session)); + + read(); + stats.push_back(std::make_unique<WiredTigerOperationStats>(_session)); + + write("aa"); + stats.push_back(std::make_unique<WiredTigerOperationStats>(_session)); + + read(); + stats.push_back(std::make_unique<WiredTigerOperationStats>(_session)); + + long long bytesWritten = 0; + long long timeWritingMicros = 0; + long long bytesRead = 0; + long long timeReadingMicros = 0; + + WiredTigerOperationStats combined; + + for (auto&& op : stats) { + auto statsObj = op->toBSON(); + + bytesWritten += statsObj["data"]["bytesWritten"].numberLong(); + timeWritingMicros += statsObj["data"]["timeWritingMicros"].numberLong(); + bytesRead += statsObj["data"]["bytesRead"].numberLong(); + timeReadingMicros += statsObj["data"]["timeReadingMicros"].numberLong(); + + combined += *op; + } + + auto combinedObj = combined.toBSON(); + auto dataSection = combinedObj["data"]; + ASSERT_EQ(dataSection.type(), BSONType::Object) << combinedObj; + ASSERT_EQ(dataSection["bytesWritten"].numberLong(), bytesWritten) << combinedObj; + ASSERT_EQ(dataSection["timeWritingMicros"].numberLong(), timeWritingMicros) << combinedObj; + ASSERT_EQ(dataSection["bytesRead"].numberLong(), bytesRead) << combinedObj; + ASSERT_EQ(dataSection["timeReadingMicros"].numberLong(), timeReadingMicros) << combinedObj; +} + +TEST_F(WiredTigerOperationStatsTest, Clone) { + write("a"); + + WiredTigerOperationStats stats{_session}; + auto clone = stats.clone(); + + ASSERT_BSONOBJ_EQ(stats.toBSON(), clone->toBSON()); + + stats += *clone; + ASSERT_BSONOBJ_NE(stats.toBSON(), clone->toBSON()); +} + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp index 1f4d9d567b7..26f91072bbd 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp @@ -37,6 +37,7 @@ #include "mongo/db/server_options.h" #include "mongo/db/storage/wiredtiger/wiredtiger_begin_transaction_block.h" #include "mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h" +#include "mongo/db/storage/wiredtiger/wiredtiger_operation_stats.h" #include "mongo/db/storage/wiredtiger/wiredtiger_prepare_conflict.h" #include "mongo/db/storage/wiredtiger/wiredtiger_session_cache.h" #include "mongo/db/storage/wiredtiger/wiredtiger_util.h" @@ -82,107 +83,6 @@ void handleWriteContextForDebugging(WiredTigerRecoveryUnit& ru, Timestamp& ts) { AtomicWord<std::int64_t> snapshotTooOldErrorCount{0}; -using Section = WiredTigerOperationStats::Section; - -std::map<int, std::pair<StringData, Section>> WiredTigerOperationStats::_statNameMap = { - {WT_STAT_SESSION_BYTES_READ, std::make_pair("bytesRead"_sd, Section::DATA)}, - {WT_STAT_SESSION_BYTES_WRITE, std::make_pair("bytesWritten"_sd, Section::DATA)}, - {WT_STAT_SESSION_LOCK_DHANDLE_WAIT, std::make_pair("handleLock"_sd, Section::WAIT)}, - {WT_STAT_SESSION_READ_TIME, std::make_pair("timeReadingMicros"_sd, Section::DATA)}, - {WT_STAT_SESSION_WRITE_TIME, std::make_pair("timeWritingMicros"_sd, Section::DATA)}, - {WT_STAT_SESSION_LOCK_SCHEMA_WAIT, std::make_pair("schemaLock"_sd, Section::WAIT)}, - {WT_STAT_SESSION_CACHE_TIME, std::make_pair("cache"_sd, Section::WAIT)}}; - -std::shared_ptr<StorageStats> WiredTigerOperationStats::getCopy() { - std::shared_ptr<WiredTigerOperationStats> copy = std::make_shared<WiredTigerOperationStats>(); - *copy += *this; - return copy; -} - -void WiredTigerOperationStats::fetchStats(WT_SESSION* session, - const std::string& uri, - const std::string& config) { - invariant(session); - - WT_CURSOR* c = nullptr; - const char* cursorConfig = config.empty() ? nullptr : config.c_str(); - int ret = session->open_cursor(session, uri.c_str(), nullptr, cursorConfig, &c); - uassert(ErrorCodes::CursorNotFound, "Unable to open statistics cursor", ret == 0); - - invariant(c); - ON_BLOCK_EXIT([&] { c->close(c); }); - - const char* desc; - uint64_t value; - int32_t key; - while (c->next(c) == 0 && c->get_key(c, &key) == 0) { - fassert(51035, c->get_value(c, &desc, nullptr, &value) == 0); - _stats[key] = WiredTigerUtil::castStatisticsValue<long long>(value); - } - - // Reset the statistics so that the next fetch gives the recent values. - invariantWTOK(c->reset(c), c->session); -} - -BSONObj WiredTigerOperationStats::toBSON() { - BSONObjBuilder bob; - std::unique_ptr<BSONObjBuilder> dataSection; - std::unique_ptr<BSONObjBuilder> waitSection; - - for (auto const& stat : _stats) { - // Find the user consumable name for this statistic. - auto statIt = _statNameMap.find(stat.first); - - // Ignore the session statistic that is not reported for the slow operations. - if (statIt == _statNameMap.end()) - continue; - - auto statName = statIt->second.first; - Section subs = statIt->second.second; - long long val = stat.second; - // Add this statistic only if higher than zero. - if (val > 0) { - // Gather the statistic into its own subsection in the BSONObj. - switch (subs) { - case Section::DATA: - if (!dataSection) - dataSection = std::make_unique<BSONObjBuilder>(); - - dataSection->append(statName, val); - break; - case Section::WAIT: - if (!waitSection) - waitSection = std::make_unique<BSONObjBuilder>(); - - waitSection->append(statName, val); - break; - default: - MONGO_UNREACHABLE; - } - } - } - - if (dataSection) - bob.append("data", dataSection->obj()); - if (waitSection) - bob.append("timeWaitingMicros", waitSection->obj()); - - return bob.obj(); -} - -WiredTigerOperationStats& WiredTigerOperationStats::operator+=( - const WiredTigerOperationStats& other) { - for (auto const& otherStat : other._stats) { - _stats[otherStat.first] += otherStat.second; - } - return (*this); -} - -StorageStats& WiredTigerOperationStats::operator+=(const StorageStats& other) { - *this += checked_cast<const WiredTigerOperationStats&>(other); - return (*this); -} - WiredTigerRecoveryUnit::WiredTigerRecoveryUnit(WiredTigerSessionCache* sc) : WiredTigerRecoveryUnit(sc, sc->getKVEngine()->getOplogManager()) {} @@ -996,18 +896,7 @@ void WiredTigerRecoveryUnit::beginIdle() { } std::shared_ptr<StorageStats> WiredTigerRecoveryUnit::getOperationStatistics() const { - std::shared_ptr<WiredTigerOperationStats> statsPtr(nullptr); - - if (!_session) - return statsPtr; - - WT_SESSION* s = _session->getSession(); - invariant(s); - - statsPtr = std::make_shared<WiredTigerOperationStats>(); - statsPtr->fetchStats(s, "statistics:session", "statistics=(fast)"); - - return statsPtr; + return _session ? std::make_shared<WiredTigerOperationStats>(_session->getSession()) : nullptr; } void WiredTigerRecoveryUnit::setCatalogConflictingTimestamp(Timestamp timestamp) { diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h index 26102686dbd..2d38888dc90 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h @@ -56,41 +56,6 @@ extern AtomicWord<std::int64_t> snapshotTooOldErrorCount; class BSONObjBuilder; -class WiredTigerOperationStats final : public StorageStats { -public: - /** - * There are two types of statistics provided by WiredTiger engine - data and wait. - */ - enum class Section { DATA, WAIT }; - - BSONObj toBSON() final; - - StorageStats& operator+=(const StorageStats&) final; - - WiredTigerOperationStats& operator+=(const WiredTigerOperationStats&); - - /** - * Fetches an operation's storage statistics from WiredTiger engine. - */ - void fetchStats(WT_SESSION*, const std::string&, const std::string&); - - std::shared_ptr<StorageStats> getCopy() final; - -private: - /** - * Each statistic in WiredTiger has an integer key, which this map associates with a section - * (either DATA or WAIT) and user-readable name. - */ - static std::map<int, std::pair<StringData, Section>> _statNameMap; - - /** - * Stores the value for each statistic returned by a WiredTiger cursor. Each statistic is - * associated with an integer key, which can be mapped to a name and section using the - * '_statNameMap'. - */ - std::map<int, long long> _stats; -}; - class WiredTigerRecoveryUnit final : public RecoveryUnit { public: WiredTigerRecoveryUnit(WiredTigerSessionCache* sc); |