Ignore a zero-sized file while looking for a seq-no in GetUpdatesSince

Summary:
Rocksdb can create 0 sized log files when it is opened and closed without any operations.
The GetUpdatesSince fails currently if there is a log file of size zero.

This diff fixes this. If there is a log file is 0, it is removed form the probable_file_list

Test Plan: unit test

Reviewers: dhruba, heyongqiang

Reviewed By: heyongqiang

CC: leveldb

Differential Revision: https://reviews.facebook.net/D9507
This commit is contained in:
Abhishek Kona 2013-03-18 14:50:59 -07:00
parent 7b9db9c98e
commit 02c459805b
3 changed files with 59 additions and 0 deletions

View File

@ -927,6 +927,13 @@ Status DBImpl::FindProbableWALFiles(std::vector<LogFile>* const allLogs,
WriteBatch batch; WriteBatch batch;
Status s = ReadFirstRecord(allLogs->at(mid), &batch); Status s = ReadFirstRecord(allLogs->at(mid), &batch);
if (!s.ok()) { if (!s.ok()) {
if (CheckFileExistsAndEmpty(allLogs->at(mid))) {
allLogs->erase(allLogs->begin() + mid);
if (mid == start) {
++start;
}
continue;
}
return s; return s;
} }
SequenceNumber currentSeqNum = WriteBatchInternal::Sequence(&batch); SequenceNumber currentSeqNum = WriteBatchInternal::Sequence(&batch);
@ -947,6 +954,24 @@ Status DBImpl::FindProbableWALFiles(std::vector<LogFile>* const allLogs,
return Status::OK(); return Status::OK();
} }
bool DBImpl::CheckFileExistsAndEmpty(const LogFile& file) {
if (file.type == kAliveLogFile) {
const std::string fname = LogFileName(dbname_, file.logNumber);
uint64_t file_size;
Status s = env_->GetFileSize(fname, &file_size);
if (s.ok() && file_size == 0) {
return true;
}
}
const std::string fname = ArchivedLogFileName(dbname_, file.logNumber);
uint64_t file_size;
Status s = env_->GetFileSize(fname, &file_size);
if (s.ok() && file_size == 0) {
return true;
}
return false;
}
Status DBImpl::ReadFirstRecord(const LogFile& file, WriteBatch* const result) { Status DBImpl::ReadFirstRecord(const LogFile& file, WriteBatch* const result) {
if (file.type == kAliveLogFile) { if (file.type == kAliveLogFile) {

View File

@ -194,6 +194,8 @@ class DBImpl : public DB {
Status FindProbableWALFiles(std::vector<LogFile>* const allLogs, Status FindProbableWALFiles(std::vector<LogFile>* const allLogs,
std::vector<LogFile>* const result, std::vector<LogFile>* const result,
const SequenceNumber target); const SequenceNumber target);
// return true if
bool CheckFileExistsAndEmpty(const LogFile& file);
Status ReadFirstRecord(const LogFile& file, WriteBatch* const result); Status ReadFirstRecord(const LogFile& file, WriteBatch* const result);

View File

@ -2638,6 +2638,38 @@ TEST(DBTest, TransactionLogIterator) {
} }
} }
TEST(DBTest, TransactionLogIteratorMoveOverZeroFiles) {
std::string value(1024, '1');
Options options = CurrentOptions();
options.create_if_missing = true;
options.WAL_ttl_seconds = 1000;
DestroyAndReopen(&options);
// Do a plain Reopen.
Put("key1", value);
// Two reopens should create a zero record WAL file.
Reopen(&options);
Reopen(&options);
Put("key2", value);
unique_ptr<TransactionLogIterator> iter;
Status status = dbfull()->GetUpdatesSince(0, &iter);
ASSERT_TRUE(status.ok());
ASSERT_TRUE(iter->Valid());
ASSERT_TRUE(status.ok());
ASSERT_TRUE(iter->Valid());
int i = 0;
SequenceNumber lastSequence = 0;
while (iter->Valid()) {
BatchResult res = iter->GetBatch();
ASSERT_TRUE(res.sequence > lastSequence);
lastSequence = res.sequence;
ASSERT_TRUE(iter->status().ok());
iter->Next();
++i;
}
ASSERT_EQ(i, 2);
}
TEST(DBTest, ReadCompaction) { TEST(DBTest, ReadCompaction) {
std::string value(4096, '4'); // a string of size 4K std::string value(4096, '4'); // a string of size 4K
{ {