diff --git a/db/blob/blob_log_writer.cc b/db/blob/blob_log_writer.cc index d86de7425..27b94a343 100644 --- a/db/blob/blob_log_writer.cc +++ b/db/blob/blob_log_writer.cc @@ -13,6 +13,7 @@ #include "file/writable_file_writer.h" #include "monitoring/statistics.h" #include "rocksdb/env.h" +#include "test_util/sync_point.h" #include "util/coding.h" #include "util/stop_watch.h" @@ -30,6 +31,8 @@ BlobLogWriter::BlobLogWriter(std::unique_ptr&& dest, last_elem_type_(kEtNone) {} Status BlobLogWriter::Sync() { + TEST_SYNC_POINT("BlobLogWriter::Sync"); + StopWatch sync_sw(env_, statistics_, BLOB_DB_BLOB_FILE_SYNC_MICROS); Status s = dest_->Sync(use_fsync_); RecordTick(statistics_, BLOB_DB_BLOB_FILE_SYNCED); @@ -63,7 +66,10 @@ Status BlobLogWriter::AppendFooter(BlobLogFooter& footer) { Status s = dest_->Append(Slice(str)); if (s.ok()) { block_offset_ += str.size(); - s = dest_->Close(); + s = Sync(); + if (s.ok()) { + s = dest_->Close(); + } dest_.reset(); } diff --git a/utilities/blob_db/blob_db_test.cc b/utilities/blob_db/blob_db_test.cc index 95533cd6a..a2e3d39d5 100644 --- a/utilities/blob_db/blob_db_test.cc +++ b/utilities/blob_db/blob_db_test.cc @@ -2127,6 +2127,57 @@ TEST_F(BlobDBTest, ShutdownWait) { SyncPoint::GetInstance()->DisableProcessing(); } +TEST_F(BlobDBTest, SyncBlobFileBeforeClose) { + Options options; + options.statistics = CreateDBStatistics(); + + BlobDBOptions blob_options; + blob_options.min_blob_size = 0; + blob_options.bytes_per_sync = 1 << 20; + blob_options.disable_background_tasks = true; + + Open(blob_options, options); + + Put("foo", "bar"); + + auto blob_files = blob_db_impl()->TEST_GetBlobFiles(); + ASSERT_EQ(blob_files.size(), 1); + + ASSERT_OK(blob_db_impl()->TEST_CloseBlobFile(blob_files[0])); + ASSERT_EQ(options.statistics->getTickerCount(BLOB_DB_BLOB_FILE_SYNCED), 1); +} + +TEST_F(BlobDBTest, SyncBlobFileBeforeCloseIOError) { + Options options; + options.env = fault_injection_env_.get(); + + BlobDBOptions blob_options; + blob_options.min_blob_size = 0; + blob_options.bytes_per_sync = 1 << 20; + blob_options.disable_background_tasks = true; + + Open(blob_options, options); + + Put("foo", "bar"); + + auto blob_files = blob_db_impl()->TEST_GetBlobFiles(); + ASSERT_EQ(blob_files.size(), 1); + + SyncPoint::GetInstance()->SetCallBack( + "BlobLogWriter::Sync", [this](void * /* arg */) { + fault_injection_env_->SetFilesystemActive(false, Status::IOError()); + }); + SyncPoint::GetInstance()->EnableProcessing(); + + const Status s = blob_db_impl()->TEST_CloseBlobFile(blob_files[0]); + + fault_injection_env_->SetFilesystemActive(true); + SyncPoint::GetInstance()->DisableProcessing(); + SyncPoint::GetInstance()->ClearAllCallBacks(); + + ASSERT_TRUE(s.IsIOError()); +} + } // namespace blob_db } // namespace ROCKSDB_NAMESPACE