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:
parent
7b9db9c98e
commit
02c459805b
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user