From c9a52cbdc8fc8fffa793de29a8086f7a7ca802f6 Mon Sep 17 00:00:00 2001 From: Jay Zhuang Date: Tue, 5 Feb 2019 11:20:37 -0800 Subject: [PATCH] Fix potential DB hang while using CompactFiles (#4940) Summary: CompactFiles() may block auto compaction which could cuase DB hang when it reachs level0_stop_writes_trigger. Pull Request resolved: https://github.com/facebook/rocksdb/pull/4940 Differential Revision: D13929648 Pulled By: cooldoger fbshipit-source-id: 10842df38df3bebf862cd1a120a88ce961fdd381 --- db/db_impl_compaction_flush.cc | 1 + db/db_test.cc | 61 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/db/db_impl_compaction_flush.cc b/db/db_impl_compaction_flush.cc index 6c907882b..2c8c42685 100644 --- a/db/db_impl_compaction_flush.cc +++ b/db/db_impl_compaction_flush.cc @@ -1023,6 +1023,7 @@ Status DBImpl::CompactFilesImpl( if (bg_compaction_scheduled_ == 0) { bg_cv_.SignalAll(); } + MaybeScheduleFlushOrCompaction(); TEST_SYNC_POINT("CompactFilesImpl:End"); return status; diff --git a/db/db_test.cc b/db/db_test.cc index 81a7fc9da..0a3c55063 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -5440,6 +5440,67 @@ TEST_F(DBTest, AutomaticConflictsWithManualCompaction) { dbfull()->TEST_WaitForCompact(); } +TEST_F(DBTest, CompactFilesShouldTriggerAutoCompaction) { + Options options = CurrentOptions(); + options.max_background_compactions = 1; + options.level0_file_num_compaction_trigger = 4; + options.level0_slowdown_writes_trigger = 36; + options.level0_stop_writes_trigger = 36; + DestroyAndReopen(options); + + // generate files for manual compaction + Random rnd(301); + for (int i = 0; i < 2; ++i) { + // put two keys to ensure no trivial move + for (int j = 0; j < 2; ++j) { + ASSERT_OK(Put(Key(j), RandomString(&rnd, 1024))); + } + ASSERT_OK(Flush()); + } + + rocksdb::ColumnFamilyMetaData cf_meta_data; + db_->GetColumnFamilyMetaData(db_->DefaultColumnFamily(), &cf_meta_data); + + std::vector input_files; + input_files.push_back(cf_meta_data.levels[0].files[0].name); + + SyncPoint::GetInstance()->LoadDependency({ + {"CompactFilesImpl:0", + "DBTest::CompactFilesShouldTriggerAutoCompaction:Begin"}, + {"DBTest::CompactFilesShouldTriggerAutoCompaction:End", + "CompactFilesImpl:1"}, + }); + + SyncPoint::GetInstance()->EnableProcessing(); + + port::Thread manual_compaction_thread([&]() { + auto s = db_->CompactFiles(CompactionOptions(), + db_->DefaultColumnFamily(), input_files, 0); + }); + + TEST_SYNC_POINT( + "DBTest::CompactFilesShouldTriggerAutoCompaction:Begin"); + // generate enough files to trigger compaction + for (int i = 0; i < 20; ++i) { + for (int j = 0; j < 2; ++j) { + ASSERT_OK(Put(Key(j), RandomString(&rnd, 1024))); + } + ASSERT_OK(Flush()); + } + db_->GetColumnFamilyMetaData(db_->DefaultColumnFamily(), &cf_meta_data); + ASSERT_GT(cf_meta_data.levels[0].files.size(), + options.level0_file_num_compaction_trigger); + TEST_SYNC_POINT( + "DBTest::CompactFilesShouldTriggerAutoCompaction:End"); + + manual_compaction_thread.join(); + dbfull()->TEST_WaitForCompact(); + + db_->GetColumnFamilyMetaData(db_->DefaultColumnFamily(), &cf_meta_data); + ASSERT_LE(cf_meta_data.levels[0].files.size(), + options.level0_file_num_compaction_trigger); +} + // Github issue #595 // Large write batch with column families TEST_F(DBTest, LargeBatchWithColumnFamilies) {