From 6d54eb3dc2e6d0ef75ffc252479a68f5151fa0d4 Mon Sep 17 00:00:00 2001 From: Levi Tamasi Date: Fri, 13 Dec 2019 12:45:49 -0800 Subject: [PATCH] Do not create/install new SuperVersion if nothing was deleted during memtable trim (#6169) Summary: We have observed an increase in CPU load caused by frequent calls to `ColumnFamilyData::InstallSuperVersion` from `DBImpl::TrimMemtableHistory` when using `max_write_buffer_size_to_maintain` to limit the amount of memtable history maintained for transaction conflict checking. As it turns out, this is caused by the code creating and installing a new `SuperVersion` even if no memtables were actually trimmed. The patch adds a check to avoid this. Pull Request resolved: https://github.com/facebook/rocksdb/pull/6169 Test Plan: Compared `perf` output for ``` ./db_bench -benchmarks=randomtransaction -optimistic_transaction_db=1 -statistics -stats_interval_seconds=1 -duration=90 -num=500000 --max_write_buffer_size_to_maintain=16000000 --transaction_set_snapshot=1 --threads=32 ``` before and after the change. With the fix, the call chain `rocksdb::DBImpl::TrimMemtableHistory` -> `rocksdb::ColumnFamilyData::InstallSuperVersion` -> `rocksdb::ThreadLocalPtr::StaticMeta::Scrape` no longer registers in the `perf` report. Differential Revision: D19031509 Pulled By: ltamasi fbshipit-source-id: 02686fce594e5b50eba0710e4b28a9b808c8aa20 --- db/db_impl/db_impl_write.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/db/db_impl/db_impl_write.cc b/db/db_impl/db_impl_write.cc index 8065f0a79..c74511a47 100644 --- a/db/db_impl/db_impl_write.cc +++ b/db/db_impl/db_impl_write.cc @@ -1518,12 +1518,14 @@ Status DBImpl::TrimMemtableHistory(WriteContext* context) { for (auto& cfd : cfds) { autovector to_delete; cfd->imm()->TrimHistory(&to_delete, cfd->mem()->ApproximateMemoryUsage()); - for (auto m : to_delete) { - delete m; + if (!to_delete.empty()) { + for (auto m : to_delete) { + delete m; + } + context->superversion_context.NewSuperVersion(); + assert(context->superversion_context.new_superversion.get() != nullptr); + cfd->InstallSuperVersion(&context->superversion_context, &mutex_); } - context->superversion_context.NewSuperVersion(); - assert(context->superversion_context.new_superversion.get() != nullptr); - cfd->InstallSuperVersion(&context->superversion_context, &mutex_); if (cfd->UnrefAndTryDelete()) { cfd = nullptr;