From 658a3ce2fa1d69b1eaec671ebf78ba8269b85a17 Mon Sep 17 00:00:00 2001 From: Xing Jin Date: Wed, 2 Oct 2013 16:20:17 -0700 Subject: [PATCH] Fix SIGSEGV issue in universal compaction Summary: We saw SIGSEGV when set options.num_levels=1 in universal compaction style. Dug into this issue for a while, and finally found the root cause (thank Haobo for discussion). Test Plan: Add new unit test. It throws SIGSEGV without this change. Also run "make all check". Reviewers: haobo, dhruba CC: leveldb Differential Revision: https://reviews.facebook.net/D13251 --- db/db_impl.cc | 2 +- db/db_test.cc | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/db/db_impl.cc b/db/db_impl.cc index da4b3b4d3..619b6cc1c 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -2126,7 +2126,7 @@ Status DBImpl::DoCompactionWork(CompactionState* compact) { } mutex_.Lock(); - stats_[compact->compaction->level() + 1].Add(stats); + stats_[compact->compaction->output_level()].Add(stats); // if there were any unused file number (mostly in case of // compaction error), free up the entry from pending_putputs diff --git a/db/db_test.cc b/db/db_test.cc index dff6837eb..34a2e444d 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -1803,6 +1803,39 @@ TEST(DBTest, UniversalCompactionSizeAmplification) { ASSERT_EQ(NumTableFilesAtLevel(0), 1); } +TEST(DBTest, UniversalCompactionOptions) { + Options options = CurrentOptions(); + options.compaction_style = kCompactionStyleUniversal; + options.write_buffer_size = 100<<10; //100KB + options.level0_file_num_compaction_trigger = 4; + options.num_levels = 1; + Reopen(&options); + + Random rnd(301); + int key_idx = 0; + + for (int num = 0; + num < options.level0_file_num_compaction_trigger; + num++) { + // Write 120KB (12 values, each 10K) + for (int i = 0; i < 12; i++) { + ASSERT_OK(Put(Key(key_idx), RandomString(&rnd, 10000))); + key_idx++; + } + dbfull()->TEST_WaitForCompactMemTable(); + + if (num < options.level0_file_num_compaction_trigger - 1) { + ASSERT_EQ(NumTableFilesAtLevel(0), num + 1); + } + } + + dbfull()->TEST_WaitForCompact(); + ASSERT_EQ(NumTableFilesAtLevel(0), 1); + for (int i = 1; i < options.num_levels ; i++) { + ASSERT_EQ(NumTableFilesAtLevel(i), 0); + } +} + TEST(DBTest, ConvertCompactionStyle) { Random rnd(301); int max_key_level_insert = 200;