From f5a839835263ec3a296b731a89ddbdb65d580a80 Mon Sep 17 00:00:00 2001 From: Igor Canadi Date: Fri, 23 Jan 2015 17:35:12 -0800 Subject: [PATCH] Fix archive WAL race conditions Summary: More race condition bugs with our archive WAL files. I do believe this caused t5988326, but can't reproduce the failure unfortunately. Test Plan: make check Reviewers: yhchiang, rven, sdong Reviewed By: sdong Subscribers: dhruba, leveldb Differential Revision: https://reviews.facebook.net/D32103 --- db/wal_manager.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/db/wal_manager.cc b/db/wal_manager.cc index 7fac575f2..aa79b0280 100644 --- a/db/wal_manager.cc +++ b/db/wal_manager.cc @@ -310,9 +310,15 @@ Status WalManager::GetSortedWalsOfType(const std::string& path, uint64_t size_bytes; s = env_->GetFileSize(LogFileName(path, number), &size_bytes); // re-try in case the alive log file has been moved to archive. + std::string archived_file = ArchivedLogFileName(path, number); if (!s.ok() && log_type == kAliveLogFile && - env_->FileExists(ArchivedLogFileName(path, number))) { - s = env_->GetFileSize(ArchivedLogFileName(path, number), &size_bytes); + env_->FileExists(archived_file)) { + s = env_->GetFileSize(archived_file, &size_bytes); + if (!s.ok() && !env_->FileExists(archived_file)) { + // oops, the file just got deleted from archived dir! move on + s = Status::OK(); + continue; + } } if (!s.ok()) { return s; @@ -354,6 +360,7 @@ Status WalManager::RetainProbableWalFiles(VectorLogPtr& all_logs, Status WalManager::ReadFirstRecord(const WalFileType type, const uint64_t number, SequenceNumber* sequence) { + *sequence = 0; if (type != kAliveLogFile && type != kArchivedLogFile) { Log(InfoLogLevel::ERROR_LEVEL, db_options_.info_log, "[WalManger] Unknown file type %s", ToString(type).c_str()); @@ -383,6 +390,12 @@ Status WalManager::ReadFirstRecord(const WalFileType type, std::string archived_file = ArchivedLogFileName(db_options_.wal_dir, number); s = ReadFirstLine(archived_file, sequence); + // maybe the file was deleted from archive dir. If that's the case, return + // Status::OK(). The caller with identify this as empty file because + // *sequence == 0 + if (!s.ok() && !env_->FileExists(archived_file)) { + return Status::OK(); + } } if (s.ok() && *sequence != 0) {