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
main
Jay Zhuang 6 years ago committed by Facebook Github Bot
parent 8fe073324f
commit c9a52cbdc8
  1. 1
      db/db_impl_compaction_flush.cc
  2. 61
      db/db_test.cc

@ -1023,6 +1023,7 @@ Status DBImpl::CompactFilesImpl(
if (bg_compaction_scheduled_ == 0) { if (bg_compaction_scheduled_ == 0) {
bg_cv_.SignalAll(); bg_cv_.SignalAll();
} }
MaybeScheduleFlushOrCompaction();
TEST_SYNC_POINT("CompactFilesImpl:End"); TEST_SYNC_POINT("CompactFilesImpl:End");
return status; return status;

@ -5440,6 +5440,67 @@ TEST_F(DBTest, AutomaticConflictsWithManualCompaction) {
dbfull()->TEST_WaitForCompact(); 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<std::string> 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 // Github issue #595
// Large write batch with column families // Large write batch with column families
TEST_F(DBTest, LargeBatchWithColumnFamilies) { TEST_F(DBTest, LargeBatchWithColumnFamilies) {

Loading…
Cancel
Save