diff options
author | Benety Goh <benety@mongodb.com> | 2022-04-28 12:47:21 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-06-22 03:23:17 +0000 |
commit | ead0d926edbbcbb795776a2f05f8e4245920c8ff (patch) | |
tree | 70fbfab3df5af6c786d5d29d582ad28559c1a728 | |
parent | 8d0122b7a40316abeca3480788c60da6b2dd3b23 (diff) | |
download | mongo-ead0d926edbbcbb795776a2f05f8e4245920c8ff.tar.gz |
SERVER-64659 Sorter::File accepts optional SorterFileStats for tracking file open/close operations
(cherry picked from commit 176747132c3be0b0e73adebf55ba4acf6211934f)
-rw-r--r-- | src/mongo/db/sorter/sorter.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/sorter/sorter.h | 29 | ||||
-rw-r--r-- | src/mongo/db/sorter/sorter_test.cpp | 14 |
3 files changed, 51 insertions, 9 deletions
diff --git a/src/mongo/db/sorter/sorter.cpp b/src/mongo/db/sorter/sorter.cpp index 39639153d7b..c5f6471c1d5 100644 --- a/src/mongo/db/sorter/sorter.cpp +++ b/src/mongo/db/sorter/sorter.cpp @@ -859,14 +859,15 @@ private: template <typename Key, typename Value> Sorter<Key, Value>::Sorter(const SortOptions& opts) : _opts(opts), - _file(opts.extSortAllowed - ? std::make_shared<Sorter<Key, Value>::File>(opts.tempDir + "/" + nextFileName()) - : nullptr) {} + _file(opts.extSortAllowed ? std::make_shared<Sorter<Key, Value>::File>( + opts.tempDir + "/" + nextFileName(), opts.sorterFileStats) + : nullptr) {} template <typename Key, typename Value> Sorter<Key, Value>::Sorter(const SortOptions& opts, const std::string& fileName) : _opts(opts), - _file(std::make_shared<Sorter<Key, Value>::File>(opts.tempDir + "/" + fileName)) { + _file(std::make_shared<Sorter<Key, Value>::File>(opts.tempDir + "/" + fileName, + opts.sorterFileStats)) { invariant(opts.extSortAllowed); invariant(!opts.tempDir.empty()); invariant(!fileName.empty()); @@ -874,6 +875,10 @@ Sorter<Key, Value>::Sorter(const SortOptions& opts, const std::string& fileName) template <typename Key, typename Value> Sorter<Key, Value>::File::~File() { + if (_stats && _file.is_open()) { + _stats->closed.addAndFetch(1); + } + if (_keep) { return; } @@ -964,6 +969,10 @@ void Sorter<Key, Value>::File::_open() { str::stream() << "Error opening file " << _path.string() << ": " << sorter::myErrnoWithDescription(), _file.good()); + + if (_stats) { + _stats->opened.addAndFetch(1); + } } template <typename Key, typename Value> diff --git a/src/mongo/db/sorter/sorter.h b/src/mongo/db/sorter/sorter.h index aed12ffdfe2..440da3b54c3 100644 --- a/src/mongo/db/sorter/sorter.h +++ b/src/mongo/db/sorter/sorter.h @@ -40,6 +40,7 @@ #include <vector> #include "mongo/bson/util/builder.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/bufreader.h" /** @@ -91,6 +92,14 @@ namespace mongo { /** + * For collecting file usage metrics. + */ +struct SorterFileStats { + AtomicWord<long long> opened; + AtomicWord<long long> closed; +}; + +/** * Runtime options that control the Sorter's behavior */ struct SortOptions { @@ -108,7 +117,14 @@ struct SortOptions { // extSortAllowed is true. std::string tempDir; - SortOptions() : limit(0), maxMemoryUsageBytes(64 * 1024 * 1024), extSortAllowed(false) {} + // If set, allows us to observe Sorter file handle usage. + SorterFileStats* sorterFileStats; + + SortOptions() + : limit(0), + maxMemoryUsageBytes(64 * 1024 * 1024), + extSortAllowed(false), + sorterFileStats(nullptr) {} // Fluent API to support expressions like SortOptions().Limit(1000).ExtSortAllowed(true) @@ -131,6 +147,11 @@ struct SortOptions { tempDir = newTempDir; return *this; } + + SortOptions& FileStats(SorterFileStats* newSorterFileStats) { + sorterFileStats = newSorterFileStats; + return *this; + } }; /** @@ -219,7 +240,8 @@ public: */ class File { public: - File(std::string path) : _path(std::move(path)) { + File(std::string path, SorterFileStats* stats = nullptr) + : _path(std::move(path)), _stats(stats) { invariant(!_path.empty()); } @@ -266,6 +288,9 @@ public: // Whether to keep the on-disk file even after this in-memory object has been destructed. bool _keep = false; + + // If set, this points to an external metrics holder for tracking file open/close activity. + SorterFileStats* _stats; }; explicit Sorter(const SortOptions& opts); diff --git a/src/mongo/db/sorter/sorter_test.cpp b/src/mongo/db/sorter/sorter_test.cpp index bda75dc17af..2d23292f439 100644 --- a/src/mongo/db/sorter/sorter_test.cpp +++ b/src/mongo/db/sorter/sorter_test.cpp @@ -284,10 +284,11 @@ class SortedFileWriterAndFileIteratorTests : public ScopedGlobalServiceContextFo public: void run() { unittest::TempDir tempDir("sortedFileWriterTests"); - const SortOptions opts = SortOptions().TempDir(tempDir.path()); + SorterFileStats sorterFileStats; + const SortOptions opts = SortOptions().TempDir(tempDir.path()).FileStats(&sorterFileStats); auto makeFile = [&] { - return std::make_shared<Sorter<IntWrapper, IntWrapper>::File>(opts.tempDir + "/" + - nextFileName()); + return std::make_shared<Sorter<IntWrapper, IntWrapper>::File>( + opts.tempDir + "/" + nextFileName(), opts.sorterFileStats); }; { // small @@ -300,6 +301,10 @@ public: ASSERT_ITERATORS_EQUIVALENT(std::shared_ptr<IWIterator>(sorter.done()), std::make_shared<IntIterator>(0, 5)); } + + ASSERT_EQ(sorterFileStats.opened.load(), 1); + ASSERT_EQ(sorterFileStats.closed.load(), 1); + { // big SortedFileWriter<IntWrapper, IntWrapper> sorter(opts, makeFile()); for (int i = 0; i < 10 * 1000 * 1000; i++) @@ -309,6 +314,9 @@ public: std::make_shared<IntIterator>(0, 10 * 1000 * 1000)); } + ASSERT_EQ(sorterFileStats.opened.load(), 2); + ASSERT_EQ(sorterFileStats.closed.load(), 2); + ASSERT(boost::filesystem::is_empty(tempDir.path())); } }; |