mirror of https://github.com/facebook/rocksdb.git
Fix Bug in Binary Search for files containing a seq no. and delete Archived Log Files during Destroy DB.
Summary: * Fixed implementation bug in Binary_Searvch introduced in https://reviews.facebook.net/D7119 * Binary search is also overflow safe. * Delete archive log files and archive dir during DestroyDB Test Plan: make check Reviewers: dhruba CC: kosievdmerwe, emayanke Differential Revision: https://reviews.facebook.net/D7263
This commit is contained in:
parent
24fc379273
commit
22c283625b
|
@ -907,11 +907,10 @@ Status DBImpl::GetUpdatesSince(SequenceNumber seq,
|
||||||
// std::shared_ptr would have been useful here.
|
// std::shared_ptr would have been useful here.
|
||||||
|
|
||||||
std::vector<LogFile>* probableWALFiles = new std::vector<LogFile>();
|
std::vector<LogFile>* probableWALFiles = new std::vector<LogFile>();
|
||||||
FindProbableWALFiles(&walFiles, probableWALFiles, seq);
|
s = FindProbableWALFiles(&walFiles, probableWALFiles, seq);
|
||||||
if (probableWALFiles->empty()) {
|
if (!s.ok()) {
|
||||||
return Status::IOError(" No wal files for the given seqNo. found");
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionLogIteratorImpl* impl =
|
TransactionLogIteratorImpl* impl =
|
||||||
new TransactionLogIteratorImpl(dbname_, &options_, seq, probableWALFiles);
|
new TransactionLogIteratorImpl(dbname_, &options_, seq, probableWALFiles);
|
||||||
*iter = impl;
|
*iter = impl;
|
||||||
|
@ -925,11 +924,11 @@ Status DBImpl::FindProbableWALFiles(std::vector<LogFile>* const allLogs,
|
||||||
assert(result != NULL);
|
assert(result != NULL);
|
||||||
|
|
||||||
std::sort(allLogs->begin(), allLogs->end());
|
std::sort(allLogs->begin(), allLogs->end());
|
||||||
size_t start = 0;
|
long start = 0; // signed to avoid overflow when target is < first file.
|
||||||
size_t end = allLogs->size();
|
long end = static_cast<long>(allLogs->size()) - 1;
|
||||||
// Binary Search. avoid opening all files.
|
// Binary Search. avoid opening all files.
|
||||||
while (start < end) {
|
while (end >= start) {
|
||||||
int mid = (start + end) / 2;
|
long mid = start + (end - start) / 2; // Avoid overflow.
|
||||||
WriteBatch batch;
|
WriteBatch batch;
|
||||||
Status s = ReadFirstRecord(allLogs->at(mid), &batch);
|
Status s = ReadFirstRecord(allLogs->at(mid), &batch);
|
||||||
if (!s.ok()) {
|
if (!s.ok()) {
|
||||||
|
@ -939,14 +938,15 @@ Status DBImpl::FindProbableWALFiles(std::vector<LogFile>* const allLogs,
|
||||||
if (currentSeqNum == target) {
|
if (currentSeqNum == target) {
|
||||||
start = mid;
|
start = mid;
|
||||||
end = mid;
|
end = mid;
|
||||||
|
break;
|
||||||
} else if (currentSeqNum < target) {
|
} else if (currentSeqNum < target) {
|
||||||
start = mid;
|
start = mid + 1;
|
||||||
} else {
|
} else {
|
||||||
end = mid;
|
end = mid - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert( start == end);
|
size_t startIndex = std::max(0l, end); // end could be -ve.
|
||||||
for( size_t i = start; i < allLogs->size(); ++i) {
|
for( size_t i = startIndex; i < allLogs->size(); ++i) {
|
||||||
result->push_back(allLogs->at(i));
|
result->push_back(allLogs->at(i));
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
|
@ -2311,8 +2311,12 @@ Snapshot::~Snapshot() {
|
||||||
Status DestroyDB(const std::string& dbname, const Options& options) {
|
Status DestroyDB(const std::string& dbname, const Options& options) {
|
||||||
Env* env = options.env;
|
Env* env = options.env;
|
||||||
std::vector<std::string> filenames;
|
std::vector<std::string> filenames;
|
||||||
|
std::vector<std::string> archiveFiles;
|
||||||
|
|
||||||
// Ignore error in case directory does not exist
|
// Ignore error in case directory does not exist
|
||||||
env->GetChildren(dbname, &filenames);
|
env->GetChildren(dbname, &filenames);
|
||||||
|
env->GetChildren(ArchivalDirectory(dbname), &archiveFiles);
|
||||||
|
|
||||||
if (filenames.empty()) {
|
if (filenames.empty()) {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
@ -2332,6 +2336,23 @@ Status DestroyDB(const std::string& dbname, const Options& options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete archival files.
|
||||||
|
for (size_t i = 0; i < archiveFiles.size(); ++i) {
|
||||||
|
ParseFileName(archiveFiles[i], &number, &type);
|
||||||
|
if (type == kLogFile) {
|
||||||
|
Status del = env->DeleteFile(ArchivalDirectory(dbname) + "/" +
|
||||||
|
archiveFiles[i]);
|
||||||
|
if (result.ok() && !del.ok()) {
|
||||||
|
result = del;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Status del = env->DeleteDir(ArchivalDirectory(dbname));
|
||||||
|
if (result.ok() && !del.ok()) {
|
||||||
|
result = del;
|
||||||
|
}
|
||||||
|
|
||||||
env->UnlockFile(lock); // Ignore error since state is already gone
|
env->UnlockFile(lock); // Ignore error since state is already gone
|
||||||
env->DeleteFile(lockname);
|
env->DeleteFile(lockname);
|
||||||
env->DeleteDir(dbname); // Ignore error in case dir contains other files
|
env->DeleteDir(dbname); // Ignore error in case dir contains other files
|
||||||
|
|
|
@ -2286,7 +2286,7 @@ TEST(DBTest, TransactionLogIterator) {
|
||||||
WriteBatch batch;
|
WriteBatch batch;
|
||||||
iter->GetBatch(&batch);
|
iter->GetBatch(&batch);
|
||||||
SequenceNumber current = WriteBatchInternal::Sequence(&batch);
|
SequenceNumber current = WriteBatchInternal::Sequence(&batch);
|
||||||
// ASSERT_TRUE(current > lastSequence);
|
ASSERT_TRUE(current > lastSequence);
|
||||||
++i;
|
++i;
|
||||||
lastSequence = current;
|
lastSequence = current;
|
||||||
ASSERT_TRUE(iter->status().ok());
|
ASSERT_TRUE(iter->status().ok());
|
||||||
|
|
Loading…
Reference in New Issue