summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2022-08-24 10:21:53 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-25 12:15:58 +0000
commit26d341317559b63d21f07f25f7ff2f99373891a2 (patch)
tree1e2293242abd2bb85198e7b3cca4431742aeacca
parentd6ed8415e2499f972dacf479b4760db7e8ee2959 (diff)
downloadmongo-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.cpp42
-rw-r--r--src/mongo/db/sorter/sorter.h28
-rw-r--r--src/mongo/db/sorter/sorter_test.cpp10
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()));
}
};