diff --git a/db/compaction/compaction_job.cc b/db/compaction/compaction_job.cc index 31365d8fe42..852f9d1246f 100644 --- a/db/compaction/compaction_job.cc +++ b/db/compaction/compaction_job.cc @@ -1586,6 +1586,8 @@ Status CompactionJob::FinishCompactionOutputFile( const uint64_t current_entries = outputs.NumEntries(); s = outputs.Finish(s, seqno_to_time_mapping_); + TEST_SYNC_POINT_CALLBACK( + "CompactionJob::FinishCompactionOutputFile()::AfterFinish", &s); if (s.ok()) { // With accurate smallest and largest key, we can get a slightly more diff --git a/db/compaction/compaction_service_job.cc b/db/compaction/compaction_service_job.cc index 949ca19eb7f..2e5839b82e5 100644 --- a/db/compaction/compaction_service_job.cc +++ b/db/compaction/compaction_service_job.cc @@ -376,16 +376,18 @@ Status CompactionServiceCompactionJob::Run() { // Build Output compaction_result_->output_level = compact_->compaction->output_level(); compaction_result_->output_path = output_path_; - for (const auto& output_file : sub_compact->GetOutputs()) { - auto& meta = output_file.meta; - compaction_result_->output_files.emplace_back( - MakeTableFileName(meta.fd.GetNumber()), meta.fd.smallest_seqno, - meta.fd.largest_seqno, meta.smallest.Encode().ToString(), - meta.largest.Encode().ToString(), meta.oldest_ancester_time, - meta.file_creation_time, meta.epoch_number, meta.file_checksum, - meta.file_checksum_func_name, output_file.validator.GetHash(), - meta.marked_for_compaction, meta.unique_id, - *output_file.table_properties); + if (status.ok()) { + for (const auto& output_file : sub_compact->GetOutputs()) { + auto& meta = output_file.meta; + compaction_result_->output_files.emplace_back( + MakeTableFileName(meta.fd.GetNumber()), meta.fd.smallest_seqno, + meta.fd.largest_seqno, meta.smallest.Encode().ToString(), + meta.largest.Encode().ToString(), meta.oldest_ancester_time, + meta.file_creation_time, meta.epoch_number, meta.file_checksum, + meta.file_checksum_func_name, output_file.validator.GetHash(), + meta.marked_for_compaction, meta.unique_id, + *output_file.table_properties); + } } TEST_SYNC_POINT_CALLBACK("CompactionServiceCompactionJob::Run:0", diff --git a/db/compaction/compaction_service_test.cc b/db/compaction/compaction_service_test.cc index 52d24f061eb..b76066788e4 100644 --- a/db/compaction/compaction_service_test.cc +++ b/db/compaction/compaction_service_test.cc @@ -416,6 +416,38 @@ TEST_F(CompactionServiceTest, ManualCompaction) { ASSERT_TRUE(result.stats.is_remote_compaction); } +TEST_F(CompactionServiceTest, CompactionOutputFileIOError) { + Options options = CurrentOptions(); + options.disable_auto_compactions = true; + ReopenWithCompactionService(&options); + GenerateTestData(); + + auto my_cs = GetCompactionService(); + + SyncPoint::GetInstance()->SetCallBack( + "CompactionJob::FinishCompactionOutputFile()::AfterFinish", + [&](void* status) { + // override status + auto s = static_cast(status); + *s = Status::IOError("Injected IOError!"); + }); + SyncPoint::GetInstance()->EnableProcessing(); + + std::string start_str = Key(15); + std::string end_str = Key(45); + Slice start(start_str); + Slice end(end_str); + uint64_t comp_num = my_cs->GetCompactionNum(); + ASSERT_NOK(db_->CompactRange(CompactRangeOptions(), &start, &end)); + ASSERT_GE(my_cs->GetCompactionNum(), comp_num + 1); + + CompactionServiceResult result; + my_cs->GetResult(&result); + ASSERT_NOK(result.status); + ASSERT_TRUE(result.stats.is_manual_compaction); + ASSERT_TRUE(result.stats.is_remote_compaction); +} + TEST_F(CompactionServiceTest, PreservedOptionsLocalCompaction) { Options options = CurrentOptions(); options.level0_file_num_compaction_trigger = 2;