mirror of https://github.com/facebook/rocksdb.git
Sync blob files before closing them (#7160)
Summary: BlobDB currently syncs each blob file periodically after writing a certain amount of data (as specified by the configuration option `BlobDBOptions::bytes_per_sync`) and all open blob files when the base DB's memtables are flushed. With the patch, in addition to the above, blob files are also synced right before being closed, after the footer has been written. This will be beneficial for the new integrated blob file write path as well. Pull Request resolved: https://github.com/facebook/rocksdb/pull/7160 Test Plan: `make check` Reviewed By: riversand963 Differential Revision: D22672646 Pulled By: ltamasi fbshipit-source-id: 62b34263543a7e74abcbb7adf011daa1e699998f
This commit is contained in:
parent
4a60cb20ad
commit
0d04a8434a
|
@ -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<WritableFileWriter>&& 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 = Sync();
|
||||
if (s.ok()) {
|
||||
s = dest_->Close();
|
||||
}
|
||||
dest_.reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue