From ac95ae1b5d9b58606160dc856d04ed7bb5c06ac5 Mon Sep 17 00:00:00 2001 From: sdong Date: Wed, 5 Nov 2014 18:07:22 -0800 Subject: [PATCH] Make sure WAL is synced for DB::Write() if write batch is empty Summary: This patch makes it a contract that if an empty write batch is passed to DB::Write() and WriteOptions.sync = true, fsync is called to WAL. Test Plan: A new unit test Reviewers: ljin, rven, yhchiang, igor Reviewed By: igor Subscribers: dhruba, MarkCallaghan, leveldb Differential Revision: https://reviews.facebook.net/D28365 --- db/db_test.cc | 21 +++++++++++++++++++++ include/rocksdb/db.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/db/db_test.cc b/db/db_test.cc index 7aea863f8..b81b7c08e 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -1270,6 +1270,27 @@ TEST(DBTest, Empty) { } while (ChangeOptions()); } +TEST(DBTest, WriteEmptyBatch) { + Options options; + options.env = env_; + options.write_buffer_size = 100000; + options = CurrentOptions(options); + CreateAndReopenWithCF({"pikachu"}, options); + + ASSERT_OK(Put(1, "foo", "bar")); + env_->sync_counter_.store(0); + WriteOptions wo; + wo.sync = true; + wo.disableWAL = false; + WriteBatch empty_batch; + ASSERT_OK(dbfull()->Write(wo, &empty_batch)); + ASSERT_GE(env_->sync_counter_.load(), 1); + + // make sure we can re-open it. + ASSERT_OK(TryReopenWithColumnFamilies({"default", "pikachu"}, options)); + ASSERT_EQ("bar", Get(1, "foo")); +} + TEST(DBTest, ReadOnlyDB) { ASSERT_OK(Put("foo", "v1")); ASSERT_OK(Put("bar", "v2")); diff --git a/include/rocksdb/db.h b/include/rocksdb/db.h index 21fa43838..65b517f54 100644 --- a/include/rocksdb/db.h +++ b/include/rocksdb/db.h @@ -195,6 +195,8 @@ class DB { } // Apply the specified updates to the database. + // If `updates` contains no update, WAL will still be synced if + // options.sync=true. // Returns OK on success, non-OK on failure. // Note: consider setting options.sync = true. virtual Status Write(const WriteOptions& options, WriteBatch* updates) = 0;