]> git-server-git.apps.pok.os.sepia.ceph.com Git - rocksdb.git/commitdiff
Ignore a zero-sized file while looking for a seq-no in GetUpdatesSince
authorAbhishek Kona <abhishekk@fb.com>
Mon, 18 Mar 2013 21:50:59 +0000 (14:50 -0700)
committerAbhishek Kona <abhishekk@fb.com>
Tue, 19 Mar 2013 18:00:09 +0000 (11:00 -0700)
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

db/db_impl.cc
db/db_impl.h
db/db_test.cc

index e4443c75792e87e8eba10111492ffa044f43232e..940164ea5767d8c703d2c0a2222cf4bc6157d55c 100644 (file)
@@ -927,6 +927,13 @@ Status DBImpl::FindProbableWALFiles(std::vector<LogFile>* const allLogs,
     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);
@@ -947,6 +954,24 @@ Status DBImpl::FindProbableWALFiles(std::vector<LogFile>* const allLogs,
   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) {
index e5a2936cb9f2797a9355a78266580acacf6827bf..92ad211d5c6baa4521eaec14138464ce6883db44 100644 (file)
@@ -194,6 +194,8 @@ class DBImpl : public DB {
   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);
index fcdb4917ccb2d4ce4a370a41a9622db1d373720b..dc069a89213986989c6b8b9e7c7c0d2c14b59e67 100644 (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) {
   std::string value(4096, '4'); // a string of size 4K
   {