summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2022-04-28 12:47:21 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-22 03:23:17 +0000
commitead0d926edbbcbb795776a2f05f8e4245920c8ff (patch)
tree70fbfab3df5af6c786d5d29d582ad28559c1a728
parent8d0122b7a40316abeca3480788c60da6b2dd3b23 (diff)
downloadmongo-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.cpp17
-rw-r--r--src/mongo/db/sorter/sorter.h29
-rw-r--r--src/mongo/db/sorter/sorter_test.cpp14
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()));
}
};