diff --git a/db/compaction_job.cc b/db/compaction_job.cc index af83532a1..4dc9574ea 100644 --- a/db/compaction_job.cc +++ b/db/compaction_job.cc @@ -1080,6 +1080,23 @@ Status CompactionJob::FinishCompactionOutputFile( } sub_compact->outfile.reset(); + if (s.ok() && current_entries == 0) { + // If there is nothing to output, no necessary to generate a sst file. + // This happens when the output level is bottom level, at the same time + // the sub_compact output nothing. + std::string fname = TableFileName( + db_options_.db_paths, meta->fd.GetNumber(), meta->fd.GetPathId()); + env_->DeleteFile(fname); + + // Also need to remove the file from outputs, or it will be added to the + // VersionEdit. + assert(!sub_compact->outputs.empty()); + sub_compact->outputs.pop_back(); + sub_compact->builder.reset(); + sub_compact->current_output_file_size = 0; + return s; + } + ColumnFamilyData* cfd = sub_compact->compaction->column_family_data(); TableProperties tp; if (s.ok() && current_entries > 0) { diff --git a/db/compaction_job_test.cc b/db/compaction_job_test.cc index 967ac72b5..102401364 100644 --- a/db/compaction_job_test.cc +++ b/db/compaction_job_test.cc @@ -340,6 +340,24 @@ TEST_F(CompactionJobTest, SimpleDeletion) { RunCompaction({files}, expected_results); } +TEST_F(CompactionJobTest, OutputNothing) { + NewDB(); + + auto file1 = mock::MakeMockFile({{KeyStr("a", 1U, kTypeValue), "val"}}); + + AddMockFile(file1); + + auto file2 = mock::MakeMockFile({{KeyStr("a", 2U, kTypeDeletion), ""}}); + + AddMockFile(file2); + + auto expected_results = mock::MakeMockFile(); + + SetLastSequence(4U); + auto files = cfd_->current()->storage_info()->LevelFiles(0); + RunCompaction({files}, expected_results); +} + TEST_F(CompactionJobTest, SimpleOverwrite) { NewDB();