diff options
author | Benety Goh <benety@mongodb.com> | 2022-04-28 12:47:21 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-05-17 12:56:03 +0000 |
commit | a470de123615559ab3ddc244f71e79e6c52c7812 (patch) | |
tree | 139c7c09080a17f36c2773cf8c5e6552f12227e1 | |
parent | b4a5a6dcfda57656e08fb9a356ab4121c0dd4def (diff) | |
download | mongo-a470de123615559ab3ddc244f71e79e6c52c7812.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 | 24 | ||||
-rw-r--r-- | src/mongo/db/sorter/sorter_test.cpp | 14 |
3 files changed, 47 insertions, 8 deletions
diff --git a/src/mongo/db/sorter/sorter.cpp b/src/mongo/db/sorter/sorter.cpp index b4d223b15ed..3f3b82870e9 100644 --- a/src/mongo/db/sorter/sorter.cpp +++ b/src/mongo/db/sorter/sorter.cpp @@ -953,14 +953,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()); @@ -982,6 +983,10 @@ typename Sorter<Key, Value>::PersistedState Sorter<Key, Value>::persistDataForSh template <typename Key, typename Value> Sorter<Key, Value>::File::~File() { + if (_stats && _file.is_open()) { + _stats->closed.addAndFetch(1); + } + if (_keep) { return; } @@ -1072,6 +1077,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 66ec284cedc..224671b0858 100644 --- a/src/mongo/db/sorter/sorter.h +++ b/src/mongo/db/sorter/sorter.h @@ -41,6 +41,7 @@ #include "mongo/bson/util/builder.h" #include "mongo/db/sorter/sorter_gen.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/bufreader.h" /** @@ -92,6 +93,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 { @@ -115,6 +124,9 @@ struct SortOptions { // extSortAllowed is true. std::string tempDir; + // If set, allows us to observe Sorter file handle usage. + SorterFileStats* sorterFileStats; + // If set to true and sorted data fits into memory, sorted data will be moved into iterator // instead of copying. bool moveSortedDataIntoIterator; @@ -123,6 +135,7 @@ struct SortOptions { : limit(0), maxMemoryUsageBytes(64 * 1024 * 1024), extSortAllowed(false), + sorterFileStats(nullptr), moveSortedDataIntoIterator(false) {} // Fluent API to support expressions like SortOptions().Limit(1000).ExtSortAllowed(true) @@ -152,6 +165,11 @@ struct SortOptions { return *this; } + SortOptions& FileStats(SorterFileStats* newSorterFileStats) { + sorterFileStats = newSorterFileStats; + return *this; + } + SortOptions& MoveSortedDataIntoIterator(bool newMoveSortedDataIntoIterator = true) { moveSortedDataIntoIterator = newMoveSortedDataIntoIterator; return *this; @@ -257,7 +275,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()); } @@ -304,6 +323,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 4607fef685c..cac95dc998f 100644 --- a/src/mongo/db/sorter/sorter_test.cpp +++ b/src/mongo/db/sorter/sorter_test.cpp @@ -280,10 +280,11 @@ class SortedFileWriterAndFileIteratorTests { 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 @@ -296,6 +297,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++) @@ -305,6 +310,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())); } }; |