summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2017-04-17 17:59:05 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2017-04-17 17:59:05 -0400
commit145be8c08243566275b86eefa8939f05eb823173 (patch)
tree8c3a42b2aebab8e760ccefe5b41491c96bd93b95 /src
parent2d15e1d82feefaada7c422c37c21da3bfb9dc1a0 (diff)
downloadmongo-145be8c08243566275b86eefa8939f05eb823173.tar.gz
SERVER-25868 Incomplete FTDC files on Windows
(cherry picked from commit b5277068ff66e7fe2b2a98144aa6993ca6e17f5c)
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/ftdc/file_writer.cpp18
-rw-r--r--src/mongo/db/ftdc/file_writer_test.cpp40
-rw-r--r--src/mongo/db/ftdc/ftdc_test.cpp2
3 files changed, 53 insertions, 7 deletions
diff --git a/src/mongo/db/ftdc/file_writer.cpp b/src/mongo/db/ftdc/file_writer.cpp
index 576f946700a..1f290249c67 100644
--- a/src/mongo/db/ftdc/file_writer.cpp
+++ b/src/mongo/db/ftdc/file_writer.cpp
@@ -57,9 +57,6 @@ Status FTDCFileWriter::open(const boost::filesystem::path& file) {
_archiveFile = file;
- // Disable file buffering
- _archiveStream.rdbuf()->pubsetbuf(0, 0);
-
// Ideally, we create a file from scratch via O_CREAT but there is not portable way via C++
// iostreams to do this.
_archiveStream.open(_archiveFile.c_str(),
@@ -87,9 +84,6 @@ Status FTDCFileWriter::writeInterimFileBuffer(ConstDataRange buf) {
// Fixed size interim stream
std::ofstream interimStream;
- // Disable file buffering
- interimStream.rdbuf()->pubsetbuf(0, 0);
-
// Open up a temporary interim file
interimStream.open(_interimTempFile.c_str(),
std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
@@ -134,6 +128,18 @@ Status FTDCFileWriter::writeArchiveFileBuffer(ConstDataRange buf) {
<< _archiveFile.generic_string()};
}
+ // Flush the stream explictly, this is preferred over "pubsetbuf(0,0)" which has implementation
+ // defined behavior of "before any I/O has occurred".
+ _archiveStream.flush();
+
+ if (_archiveStream.fail()) {
+ return {
+ ErrorCodes::FileStreamFailed,
+ str::stream()
+ << "Failed to flush to archive file buffer for full-time diagnostic data capture: "
+ << _archiveFile.generic_string()};
+ }
+
_size += buf.length();
return Status::OK();
diff --git a/src/mongo/db/ftdc/file_writer_test.cpp b/src/mongo/db/ftdc/file_writer_test.cpp
index 6555a13c115..719f1ee87bd 100644
--- a/src/mongo/db/ftdc/file_writer_test.cpp
+++ b/src/mongo/db/ftdc/file_writer_test.cpp
@@ -45,6 +45,7 @@
namespace mongo {
const char* kTestFile = "metrics.test";
+const char* kTestFileCopy = "metrics.test.copy";
// File Sanity check
TEST(FTDCFileTest, TestFileBasicMetadata) {
@@ -160,7 +161,27 @@ public:
}
private:
- void validate(bool forceCompress = true) {
+ void validate() {
+ // Verify we are flushing writes correctly by copying the file, and then reading it.
+ auto tempfile(boost::filesystem::path(_tempdir.path()) / kTestFileCopy);
+ boost::filesystem::copy_file(_path, tempfile);
+
+ // Read the file to make sure it is correct.
+ // We do not verify contents because the compressor may not have flushed the final records
+ // which is expected.
+ {
+ FTDCFileReader reader;
+
+ ASSERT_OK(reader.open(tempfile));
+
+ auto sw = reader.hasNext();
+ while (sw.isOK() && sw.getValue()) {
+ sw = reader.hasNext();
+ }
+
+ ASSERT_OK(sw);
+ }
+
_writer.close();
ValidateDocumentList(_path, _docs);
@@ -244,6 +265,23 @@ TEST(FTDCFileTest, TestFull) {
}
}
+// Test a large documents so that we cause multiple 4kb buffers to flush on Windows.
+TEST(FTDCFileTest, TestLargeDocuments) {
+ FileTestTie c;
+
+ for (int j = 0; j < 5; j++) {
+ for (size_t i = 0; i <= FTDCConfig::kMaxSamplesPerArchiveMetricChunkDefault; i++) {
+ BSONObjBuilder b;
+ b.append("name", "joe");
+ for (size_t k = 0; k < 200; k++) {
+ b.appendNumber("num", static_cast<long long int>(i * j + 5000 - (sin(k) * 100)));
+ }
+
+ c.addSample(b.obj());
+ }
+ }
+}
+
// Test a bad file
TEST(FTDCFileTest, TestBadFile) {
unittest::TempDir tempdir("metrics_testpath");
diff --git a/src/mongo/db/ftdc/ftdc_test.cpp b/src/mongo/db/ftdc/ftdc_test.cpp
index 33fcce62eff..28910def1a1 100644
--- a/src/mongo/db/ftdc/ftdc_test.cpp
+++ b/src/mongo/db/ftdc/ftdc_test.cpp
@@ -58,6 +58,8 @@ void ValidateDocumentList(const boost::filesystem::path& p, const std::vector<BS
sw = reader.hasNext();
}
+ ASSERT_OK(sw);
+
ValidateDocumentList(list, docs);
}