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-05-17 12:56:03 +0000
commita470de123615559ab3ddc244f71e79e6c52c7812 (patch)
tree139c7c09080a17f36c2773cf8c5e6552f12227e1
parentb4a5a6dcfda57656e08fb9a356ab4121c0dd4def (diff)
downloadmongo-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.cpp17
-rw-r--r--src/mongo/db/sorter/sorter.h24
-rw-r--r--src/mongo/db/sorter/sorter_test.cpp14
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()));
}
};