]> git-server-git.apps.pok.os.sepia.ceph.com Git - rocksdb.git/commitdiff
Don't let two L0->L1 compactions run in parallel
authorIgor Canadi <icanadi@fb.com>
Thu, 11 Jun 2015 22:42:16 +0000 (15:42 -0700)
committerIgor Canadi <icanadi@fb.com>
Thu, 11 Jun 2015 22:48:28 +0000 (15:48 -0700)
Summary: With experimental feature SuggestCompactRange() we don't restrict running two L0->L1 compactions in parallel. This diff fixes this.

Test Plan: added a unit test to reproduce the failure. fixed the unit test

Reviewers: yhchiang, rven, sdong

Reviewed By: sdong

Subscribers: dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D39981

Conflicts:
db/db_test.cc

db/compaction_picker.cc
db/db_test.cc

index f8a7c9a5a2c406f7ecd3162fd97ef82794e15c99..70e48146b640b08c7b79eb91f5eb8f829beb780d 100644 (file)
@@ -763,6 +763,10 @@ void LevelCompactionPicker::PickFilesMarkedForCompactionExperimental(
     *level = level_file.first;
     *output_level = (*level == 0) ? vstorage->base_level() : *level + 1;
 
+    if (*level == 0 && !level0_compactions_in_progress_.empty()) {
+      return false;
+    }
+
     inputs->files = {level_file.second};
     inputs->level = *level;
     return ExpandWhileOverlapping(cf_name, vstorage, inputs);
index 9f0bd43d2acabc6bb74eeb82083cef9ded57b5df..eaef2a62644f8333a3c1abc350789aa9c7a7655e 100644 (file)
@@ -12887,7 +12887,6 @@ TEST_F(DBTest, FlushesInParallelWithCompactRange) {
   // iter == 1 -- leveled, but throw in a flush between two levels compacting
   // iter == 2 -- universal
   for (int iter = 0; iter < 3; ++iter) {
-    printf("iter %d\n", iter);
     Options options = CurrentOptions();
     if (iter < 2) {
       options.compaction_style = kCompactionStyleLevel;
@@ -12945,6 +12944,56 @@ TEST_F(DBTest, FlushesInParallelWithCompactRange) {
   }
 }
 
+// This tests for a bug that could cause two level0 compactions running
+// concurrently
+TEST_F(DBTest, SuggestCompactRangeNoTwoLevel0Compactions) {
+  Options options = CurrentOptions();
+  options.compaction_style = kCompactionStyleLevel;
+  options.write_buffer_size = 110 << 10;
+  options.level0_file_num_compaction_trigger = 4;
+  options.num_levels = 4;
+  options.compression = kNoCompression;
+  options.max_bytes_for_level_base = 450 << 10;
+  options.target_file_size_base = 98 << 10;
+  options.max_write_buffer_number = 2;
+  options.max_background_compactions = 2;
+
+  DestroyAndReopen(options);
+
+  // fill up the DB
+  Random rnd(301);
+  for (int num = 0; num < 10; num++) {
+    GenerateNewRandomFile(&rnd);
+  }
+  db_->CompactRange(nullptr, nullptr);
+
+  rocksdb::SyncPoint::GetInstance()->LoadDependency(
+      {{"CompactionJob::Run():Start",
+        "DBTest::SuggestCompactRangeNoTwoLevel0Compactions:1"},
+       {"DBTest::SuggestCompactRangeNoTwoLevel0Compactions:2",
+        "CompactionJob::Run():End"}});
+
+  rocksdb::SyncPoint::GetInstance()->EnableProcessing();
+
+  // trigger L0 compaction
+  for (int num = 0; num < options.level0_file_num_compaction_trigger + 1;
+       num++) {
+    GenerateNewRandomFile(&rnd, /* nowait */ true);
+  }
+
+  TEST_SYNC_POINT("DBTest::SuggestCompactRangeNoTwoLevel0Compactions:1");
+
+  GenerateNewRandomFile(&rnd, /* nowait */ true);
+  dbfull()->TEST_WaitForFlushMemTable();
+  ASSERT_OK(experimental::SuggestCompactRange(db_, nullptr, nullptr));
+  for (int num = 0; num < options.level0_file_num_compaction_trigger + 1;
+       num++) {
+    GenerateNewRandomFile(&rnd, /* nowait */ true);
+  }
+
+  TEST_SYNC_POINT("DBTest::SuggestCompactRangeNoTwoLevel0Compactions:2");
+}
+
 }  // namespace rocksdb
 
 int main(int argc, char** argv) {