Return Status::InvalidArgument if user request sync write while disabling WAL

Summary:
write_options.sync = true and write_options.disableWAL is incompatible. When WAL is disabled, we are not able to persist the write immediately. Return an error in this case to avoid misuse of the options.
Closes https://github.com/facebook/rocksdb/pull/3086

Differential Revision: D6176822

Pulled By: yiwu-arbug

fbshipit-source-id: 1eb10028c14fe7d7c13c8bc12c0ef659f75aa071
This commit is contained in:
Yi Wu 2017-10-28 21:56:50 -07:00 committed by Facebook Github Bot
parent 6a9335dbbb
commit 792ef10ca8
4 changed files with 20 additions and 3 deletions

View File

@ -3,6 +3,7 @@
### Public API Change ### Public API Change
* `BackupableDBOptions::max_valid_backups_to_open == 0` now means no backups will be opened during BackupEngine initialization. Previously this condition disabled limiting backups opened. * `BackupableDBOptions::max_valid_backups_to_open == 0` now means no backups will be opened during BackupEngine initialization. Previously this condition disabled limiting backups opened.
* Deprecate trash_dir param in NewSstFileManager, right now we will rename deleted files to <name>.trash instead of moving them to trash directory * Deprecate trash_dir param in NewSstFileManager, right now we will rename deleted files to <name>.trash instead of moving them to trash directory
* Return an error on write if write_options.sync = true and write_options.disableWAL = true to warn user of inconsistent options. Previously we will not write to WAL and not respecting the sync options in this case.
### New Features ### New Features
* `DBOptions::bytes_per_sync` and `DBOptions::wal_bytes_per_sync` can now be changed dynamically, `DBOptions::wal_bytes_per_sync` will flush all memtables and switch to a new WAL file. * `DBOptions::bytes_per_sync` and `DBOptions::wal_bytes_per_sync` can now be changed dynamically, `DBOptions::wal_bytes_per_sync` will flush all memtables and switch to a new WAL file.

View File

@ -64,6 +64,9 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
if (my_batch == nullptr) { if (my_batch == nullptr) {
return Status::Corruption("Batch is nullptr!"); return Status::Corruption("Batch is nullptr!");
} }
if (write_options.sync && write_options.disableWAL) {
return Status::InvalidArgument("Sync writes has to enable WAL.");
}
if (concurrent_prepare_ && immutable_db_options_.enable_pipelined_write) { if (concurrent_prepare_ && immutable_db_options_.enable_pipelined_write) {
return Status::NotSupported( return Status::NotSupported(
"pipelined_writes is not compatible with concurrent prepares"); "pipelined_writes is not compatible with concurrent prepares");
@ -154,7 +157,7 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
mutex_.Lock(); mutex_.Lock();
bool need_log_sync = !write_options.disableWAL && write_options.sync; bool need_log_sync = write_options.sync;
bool need_log_dir_sync = need_log_sync && !log_dir_synced_; bool need_log_dir_sync = need_log_sync && !log_dir_synced_;
if (!concurrent_prepare_ || !disable_memtable) { if (!concurrent_prepare_ || !disable_memtable) {
// With concurrent writes we do preprocess only in the write thread that // With concurrent writes we do preprocess only in the write thread that

View File

@ -60,7 +60,6 @@
#include "util/compression.h" #include "util/compression.h"
#include "util/file_reader_writer.h" #include "util/file_reader_writer.h"
#include "util/filename.h" #include "util/filename.h"
#include "util/hash.h"
#include "util/mutexlock.h" #include "util/mutexlock.h"
#include "util/rate_limiter.h" #include "util/rate_limiter.h"
#include "util/string_util.h" #include "util/string_util.h"
@ -223,6 +222,10 @@ TEST_F(DBTest, SkipDelay) {
for (bool sync : {true, false}) { for (bool sync : {true, false}) {
for (bool disableWAL : {true, false}) { for (bool disableWAL : {true, false}) {
if (sync && disableWAL) {
// sync and disableWAL is incompatible.
continue;
}
// Use a small number to ensure a large delay that is still effective // Use a small number to ensure a large delay that is still effective
// when we do Put // when we do Put
// TODO(myabandeh): this is time dependent and could potentially make // TODO(myabandeh): this is time dependent and could potentially make

View File

@ -9,7 +9,6 @@
#include "db/db_test_util.h" #include "db/db_test_util.h"
#include "db/write_batch_internal.h" #include "db/write_batch_internal.h"
#include "port/stack_trace.h" #include "port/stack_trace.h"
#include "util/sync_point.h"
namespace rocksdb { namespace rocksdb {
@ -21,6 +20,17 @@ class DBWriteTest : public DBTestBase, public testing::WithParamInterface<int> {
void Open() { DBTestBase::Reopen(GetOptions(GetParam())); } void Open() { DBTestBase::Reopen(GetOptions(GetParam())); }
}; };
// It is invalid to do sync write while disabling WAL.
TEST_P(DBWriteTest, SyncAndDisableWAL) {
WriteOptions write_options;
write_options.sync = true;
write_options.disableWAL = true;
ASSERT_TRUE(dbfull()->Put(write_options, "foo", "bar").IsInvalidArgument());
WriteBatch batch;
ASSERT_OK(batch.Put("foo", "bar"));
ASSERT_TRUE(dbfull()->Write(write_options, &batch).IsInvalidArgument());
}
// Sequence number should be return through input write batch. // Sequence number should be return through input write batch.
TEST_P(DBWriteTest, ReturnSeuqneceNumber) { TEST_P(DBWriteTest, ReturnSeuqneceNumber) {
Random rnd(4422); Random rnd(4422);