WriteBatch batch;
Status s = ReadFirstRecord(allLogs->at(mid), &batch);
if (!s.ok()) {
+ if (CheckFileExistsAndEmpty(allLogs->at(mid))) {
+ allLogs->erase(allLogs->begin() + mid);
+ if (mid == start) {
+ ++start;
+ }
+ continue;
+ }
return s;
}
SequenceNumber currentSeqNum = WriteBatchInternal::Sequence(&batch);
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) {
if (file.type == kAliveLogFile) {
Status FindProbableWALFiles(std::vector<LogFile>* const allLogs,
std::vector<LogFile>* const result,
const SequenceNumber target);
+ // return true if
+ bool CheckFileExistsAndEmpty(const LogFile& file);
Status ReadFirstRecord(const LogFile& file, WriteBatch* const result);
}
}
+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) {
std::string value(4096, '4'); // a string of size 4K
{