From 92b440156686ec0cac5adb9833b9f6f4447ee479 Mon Sep 17 00:00:00 2001 From: Yanqin Jin Date: Mon, 29 Oct 2018 09:43:35 -0700 Subject: [PATCH] Avoid memtable cut when active memtable is empty (#4595) Summary: For flush triggered by RocksDB due to memory usage approaching certain threshold (WriteBufferManager or Memtable full), we should cut the memtable only when the current active memtable is not empty, i.e. contains data. This is what we do for non-atomic flush. If we always cut memtable even when the active memtable is empty, we will generate extra, empty immutable memtable. This is not ideal since it may cause write stall. It also causes some DBAtomicFlushTest to fail because cfd->imm()->NumNotFlushed() is different from expectation. Test plan ``` $make clean && make J=1 -j32 all check $make clean && OPT="-DROCKSDB_LITE -g" make J=1 -j32 all check $make clean && TEST_TMPDIR=/dev/shm/rocksdb OPT=-g make J=1 -j32 valgrind_test ``` Pull Request resolved: https://github.com/facebook/rocksdb/pull/4595 Differential Revision: D12818520 Pulled By: riversand963 fbshipit-source-id: d867bdbeacf4199fdd642debb085f94703c41a18 --- db/db_impl_write.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/db/db_impl_write.cc b/db/db_impl_write.cc index 4efb1d00e..a9ea3a788 100644 --- a/db/db_impl_write.cc +++ b/db/db_impl_write.cc @@ -1165,6 +1165,9 @@ Status DBImpl::HandleWriteBufferFull(WriteContext* write_context) { } for (const auto cfd : cfds) { + if (cfd->mem()->IsEmpty()) { + continue; + } cfd->Ref(); status = SwitchMemtable(cfd, write_context); cfd->Unref(); @@ -1318,7 +1321,9 @@ Status DBImpl::ScheduleFlushes(WriteContext* context) { } Status status; for (auto& cfd : cfds) { - status = SwitchMemtable(cfd, context); + if (!cfd->mem()->IsEmpty()) { + status = SwitchMemtable(cfd, context); + } if (cfd->Unref()) { delete cfd; cfd = nullptr;