Fix recovery for WALs without data for all CFs

Summary:
if one or more CFs had no data in the WAL, the log number that's used
by FindObsoleteFiles() wasn't updated. We need to treat this case the same as
if the data for that WAL had been flushed.

Test Plan: new unit test

Reviewers: IslamAbdelRahman, yiwu, sdong

Reviewed By: sdong

Subscribers: andrewkr, dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D63963
main
Andrew Kryczka 8 years ago
parent d7242ff4d5
commit 06b4785fec
  1. 2
      db/db_impl.cc
  2. 25
      db/db_wal_test.cc

@ -1722,7 +1722,7 @@ Status DBImpl::RecoverLogFiles(const std::vector<uint64_t>& log_numbers,
// recovered and should be ignored on next reincarnation. // recovered and should be ignored on next reincarnation.
// Since we already recovered max_log_number, we want all logs // Since we already recovered max_log_number, we want all logs
// with numbers `<= max_log_number` (includes this one) to be ignored // with numbers `<= max_log_number` (includes this one) to be ignored
if (flushed) { if (flushed || cfd->mem()->GetFirstSequenceNumber() == 0) {
edit->SetLogNumber(max_log_number + 1); edit->SetLogNumber(max_log_number + 1);
} }
// we must mark the next log number as used, even though it's // we must mark the next log number as used, even though it's

@ -305,6 +305,31 @@ TEST_F(DBWALTest, GetSortedWalFiles) {
} while (ChangeOptions()); } while (ChangeOptions());
} }
TEST_F(DBWALTest, RecoveryWithLogDataForSomeCFs) {
// Test for regression of WAL cleanup missing files that don't contain data
// for every column family.
do {
CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
ASSERT_OK(Put(1, "foo", "v1"));
ASSERT_OK(Put(1, "foo", "v2"));
std::array<uint64_t, 2> earliest_log_nums;
for (int i = 0; i < 2; ++i) {
if (i > 0) {
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions());
}
VectorLogPtr log_files;
ASSERT_OK(dbfull()->GetSortedWalFiles(log_files));
if (log_files.size() > 0) {
earliest_log_nums[i] = log_files[0]->LogNumber();
} else {
earliest_log_nums[i] = port::kMaxUint64;
}
}
// Check at least the first WAL was cleaned up during the recovery.
ASSERT_LT(earliest_log_nums[0], earliest_log_nums[1]);
} while (ChangeOptions());
}
TEST_F(DBWALTest, RecoverWithLargeLog) { TEST_F(DBWALTest, RecoverWithLargeLog) {
do { do {
{ {

Loading…
Cancel
Save