diff --git a/db/db_impl.cc b/db/db_impl.cc index 228621a24..a788979f1 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -859,7 +859,9 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force, } } - if (!alive_log_files_.empty()) { + // logs_ is empty when called during recovery, in which case there can't yet + // be any tracked obsolete logs + if (!alive_log_files_.empty() && !logs_.empty()) { uint64_t min_log_number = job_context->log_number; size_t num_alive_log_files = alive_log_files_.size(); // find newly obsoleted log files @@ -990,8 +992,7 @@ void DBImpl::PurgeObsoleteFiles(const JobContext& state, bool schedule_only) { for (auto file_num : state.log_delete_files) { if (file_num > 0) { - candidate_files.emplace_back(LogFileName(kDumbDbName, file_num).substr(1), - 0); + candidate_files.emplace_back(LogFileName(kDumbDbName, file_num), 0); } } for (const auto& filename : state.manifest_delete_files) { @@ -1746,6 +1747,14 @@ Status DBImpl::RecoverLogFiles(const std::vector& log_numbers, } } + if (!flushed) { + // Mark these as alive so they'll be considered for deletion later by + // FindObsoleteFiles() + for (auto log_number : log_numbers) { + alive_log_files_.push_back(LogFileNumberSize(log_number)); + } + } + event_logger_.Log() << "job" << job_id << "event" << "recovery_finished"; diff --git a/db/db_wal_test.cc b/db/db_wal_test.cc index 523450dcc..532cb3052 100644 --- a/db/db_wal_test.cc +++ b/db/db_wal_test.cc @@ -1006,6 +1006,32 @@ TEST_F(DBWALTest, AvoidFlushDuringRecovery) { ASSERT_EQ(2, TotalTableFiles()); } +TEST_F(DBWALTest, WalCleanupAfterAvoidFlushDuringRecovery) { + // Verifies WAL files that were present during recovery, but not flushed due + // to avoid_flush_during_recovery, will be considered for deletion at a later + // stage. We check at least one such file is deleted during Flush(). + Options options = CurrentOptions(); + options.disable_auto_compactions = true; + options.avoid_flush_during_recovery = true; + Reopen(options); + + ASSERT_OK(Put("foo", "v1")); + Reopen(options); + for (int i = 0; i < 2; ++i) { + if (i > 0) { + // Flush() triggers deletion of obsolete tracked files + Flush(); + } + VectorLogPtr log_files; + ASSERT_OK(dbfull()->GetSortedWalFiles(log_files)); + if (i == 0) { + ASSERT_GT(log_files.size(), 0); + } else { + ASSERT_EQ(0, log_files.size()); + } + } +} + TEST_F(DBWALTest, RecoverWithoutFlush) { Options options = CurrentOptions(); options.avoid_flush_during_recovery = true;