diff options
author | Benety Goh <benety@mongodb.com> | 2022-08-24 10:21:53 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-25 12:15:58 +0000 |
commit | 26d341317559b63d21f07f25f7ff2f99373891a2 (patch) | |
tree | 1e2293242abd2bb85198e7b3cca4431742aeacca | |
parent | d6ed8415e2499f972dacf479b4760db7e8ee2959 (diff) | |
download | mongo-26d341317559b63d21f07f25f7ff2f99373891a2.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 | 42 | ||||
-rw-r--r-- | src/mongo/db/sorter/sorter.h | 28 | ||||
-rw-r--r-- | src/mongo/db/sorter/sorter_test.cpp | 10 |
3 files changed, 74 insertions, 6 deletions
diff --git a/src/mongo/db/sorter/sorter.cpp b/src/mongo/db/sorter/sorter.cpp index 2f2dc44f1c8..3f532270092 100644 --- a/src/mongo/db/sorter/sorter.cpp +++ b/src/mongo/db/sorter/sorter.cpp @@ -158,17 +158,25 @@ public: FileIterator(const std::string& fileName, std::streampos fileStartOffset, std::streampos fileEndOffset, - const Settings& settings) + const Settings& settings, + SorterFileStats* stats) : _settings(settings), _done(false), _fileName(fileName), _fileStartOffset(fileStartOffset), - _fileEndOffset(fileEndOffset) { + _fileEndOffset(fileEndOffset), + _stats(stats) { uassert(16815, str::stream() << "unexpected empty file: " << _fileName, boost::filesystem::file_size(_fileName) != 0); } + ~FileIterator() { + if (_stats && _file.is_open()) { + _stats->closed.addAndFetch(1); + } + } + void openSource() { _file.open(_fileName.c_str(), std::ios::in | std::ios::binary); uassert(16814, @@ -180,6 +188,10 @@ public: str::stream() << "error seeking starting offset of '" << _fileStartOffset << "' in file \"" << _fileName << "\": " << myErrnoWithDescription(), _file.good()); + + if (_stats) { + _stats->opened.addAndFetch(1); + } } void closeSource() { @@ -188,6 +200,10 @@ public: str::stream() << "error closing file \"" << _fileName << "\": " << myErrnoWithDescription(), !_file.fail()); + + if (_stats) { + _stats->closed.addAndFetch(1); + } } bool more() { @@ -313,6 +329,9 @@ private: std::streampos _fileStartOffset; // File offset at which the sorted data range starts. std::streampos _fileEndOffset; // File offset at which the sorted data range ends. std::ifstream _file; + + // If set, this points to an external metrics holder for tracking file open/close activity. + SorterFileStats* _stats; }; /** @@ -895,7 +914,7 @@ SortedFileWriter<Key, Value>::SortedFileWriter(const SortOptions& opts, const std::string& fileName, const std::streampos fileStartOffset, const Settings& settings) - : _settings(settings) { + : _settings(settings), _stats(opts.sorterFileStats) { // This should be checked by consumers, but if we get here don't allow writes. uassert( @@ -924,6 +943,17 @@ SortedFileWriter<Key, Value>::SortedFileWriter(const SortOptions& opts, // throw on failure _file.exceptions(std::ios::failbit | std::ios::badbit | std::ios::eofbit); + + if (_stats) { + _stats->opened.addAndFetch(1); + } +} + +template <typename Key, typename Value> +SortedFileWriter<Key, Value>::~SortedFileWriter() { + if (_stats && _file.is_open()) { + _stats->closed.addAndFetch(1); + } } template <typename Key, typename Value> @@ -999,8 +1029,12 @@ SortIteratorInterface<Key, Value>* SortedFileWriter<Key, Value>::done() { _fileEndOffset = currentFileOffset < _fileStartOffset ? _fileStartOffset : currentFileOffset; _file.close(); + if (_stats) { + _stats->closed.addAndFetch(1); + } + return new sorter::FileIterator<Key, Value>( - _fileName, _fileStartOffset, _fileEndOffset, _settings); + _fileName, _fileStartOffset, _fileEndOffset, _settings, _stats); } // diff --git a/src/mongo/db/sorter/sorter.h b/src/mongo/db/sorter/sorter.h index fccb3eef115..edd8a5611d1 100644 --- a/src/mongo/db/sorter/sorter.h +++ b/src/mongo/db/sorter/sorter.h @@ -37,6 +37,7 @@ #include <vector> #include "mongo/bson/util/builder.h" +#include "mongo/platform/atomic_word.h" /** * This is the public API for the Sorter (both in-memory and external) @@ -86,6 +87,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 { @@ -103,7 +112,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) @@ -126,6 +142,11 @@ struct SortOptions { tempDir = newTempDir; return *this; } + + SortOptions& FileStats(SorterFileStats* newSorterFileStats) { + sorterFileStats = newSorterFileStats; + return *this; + } }; /** @@ -234,6 +255,8 @@ public: const std::streampos fileStartOffset, const Settings& settings = Settings()); + ~SortedFileWriter(); + void addAlreadySorted(const Key&, const Value&); /** @@ -265,6 +288,9 @@ private: // for the next SortedFileWriter instance using the same file. std::streampos _fileStartOffset; std::streampos _fileEndOffset; + + // If set, this points to an external metrics holder for tracking file open/close activity. + SorterFileStats* _stats; }; } // namespace mongo diff --git a/src/mongo/db/sorter/sorter_test.cpp b/src/mongo/db/sorter/sorter_test.cpp index 18fcf91f0b1..9654d69dd42 100644 --- a/src/mongo/db/sorter/sorter_test.cpp +++ b/src/mongo/db/sorter/sorter_test.cpp @@ -279,7 +279,8 @@ 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); { // small std::string fileName = opts.tempDir + "/" + nextFileName(); SortedFileWriter<IntWrapper, IntWrapper> sorter(opts, fileName, 0); @@ -293,6 +294,10 @@ public: ASSERT_TRUE(boost::filesystem::remove(fileName)); } + + ASSERT_EQ(sorterFileStats.opened.load(), 2); + ASSERT_EQ(sorterFileStats.closed.load(), 2); + { // big std::string fileName = opts.tempDir + "/" + nextFileName(); SortedFileWriter<IntWrapper, IntWrapper> sorter(opts, fileName, 0); @@ -305,6 +310,9 @@ public: ASSERT_TRUE(boost::filesystem::remove(fileName)); } + ASSERT_EQ(sorterFileStats.opened.load(), 4); + ASSERT_EQ(sorterFileStats.closed.load(), 4); + ASSERT(boost::filesystem::is_empty(tempDir.path())); } }; |