Fix for the weird behaviour encountered by ldb Get where it could read only the second-latest value

Summary:
flush_on_destroy has a default value of false and the memtable is flushed
in the dbimpl-destructor only when that is set to true. Because we want the memtable to be flushed everytime that
the destructor is called(db is closed) and the cases where we work with the memtable only are very less
it is a good idea to give this a default value of true. Thus the put from ldb
wil have its data flushed to disk in the destructor and the next Get will be able to
read it when opened with OpenForReadOnly. The reason that ldb could read the latest value when
the db was opened in the normal Open mode is that the Get from normal Open first reads
the memtable and directly finds the latest value written there and the Get from OpenForReadOnly
doesn't have access to the memtable (which is correct because all its Put/Modify) are disabled

Test Plan: make all; ldb put and get and scans

Reviewers: dhruba, heyongqiang, sheki

Reviewed By: heyongqiang

CC: kosievdmerwe, zshao, dilipj, kailiu

Differential Revision: https://reviews.facebook.net/D8631
This commit is contained in:
amayank 2013-02-15 15:28:24 -08:00
parent aaa0cbb97a
commit 4c696ed001
3 changed files with 5 additions and 5 deletions

View File

@ -160,7 +160,7 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
stall_level0_num_files_(0),
stall_leveln_slowdown_(0),
started_at_(options.env->NowMicros()),
flush_on_destroy_(false),
flush_on_destroy_(true),
delayed_writes_(0) {
mem_->Ref();

View File

@ -65,7 +65,9 @@ Iterator* DBImplReadOnly::NewIterator(const ReadOptions& options) {
NewMergingIterator(&internal_comparator_, &list[0], list.size());
return NewDBIterator(
&dbname_, env_, user_comparator(), internal_iter,
reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_);
(options.snapshot != NULL
? reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_
: versions_->LastSequence()));
}

View File

@ -190,9 +190,7 @@ protected:
// Open the DB.
leveldb::Status st;
if (is_read_only_) {
//st = leveldb::DB::OpenForReadOnly(opt, db_path_, &db_);
// Could not get this to work
st = leveldb::DB::Open(opt, db_path_, &db_);
st = leveldb::DB::OpenForReadOnly(opt, db_path_, &db_);
} else {
st = leveldb::DB::Open(opt, db_path_, &db_);
}