2016-02-09 23:12:00 +00:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2017-07-15 23:03:42 +00:00
|
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
|
|
// (found in the LICENSE.Apache file in the root directory).
|
2012-11-06 03:18:49 +00:00
|
|
|
|
|
|
|
#include "db/db_impl_readonly.h"
|
2015-07-14 01:10:31 +00:00
|
|
|
|
|
|
|
#include "db/compacted_db_impl.h"
|
2012-11-06 03:18:49 +00:00
|
|
|
#include "db/db_impl.h"
|
2014-09-25 18:14:01 +00:00
|
|
|
#include "db/db_iter.h"
|
2016-11-04 01:40:23 +00:00
|
|
|
#include "db/merge_context.h"
|
|
|
|
#include "db/range_del_aggregator.h"
|
2017-04-06 02:02:00 +00:00
|
|
|
#include "monitoring/perf_context_imp.h"
|
2012-11-06 03:18:49 +00:00
|
|
|
|
2013-10-04 04:49:15 +00:00
|
|
|
namespace rocksdb {
|
2012-11-06 03:18:49 +00:00
|
|
|
|
2014-11-26 19:37:59 +00:00
|
|
|
#ifndef ROCKSDB_LITE
|
|
|
|
|
2014-09-09 01:46:52 +00:00
|
|
|
DBImplReadOnly::DBImplReadOnly(const DBOptions& db_options,
|
2014-02-05 21:12:23 +00:00
|
|
|
const std::string& dbname)
|
2014-09-09 01:46:52 +00:00
|
|
|
: DBImpl(db_options, dbname) {
|
2017-03-16 02:22:52 +00:00
|
|
|
ROCKS_LOG_INFO(immutable_db_options_.info_log,
|
|
|
|
"Opening the db in read only mode");
|
2016-09-23 23:34:04 +00:00
|
|
|
LogFlush(immutable_db_options_.info_log);
|
2012-11-06 03:18:49 +00:00
|
|
|
}
|
|
|
|
|
2018-04-13 00:55:14 +00:00
|
|
|
DBImplReadOnly::~DBImplReadOnly() {}
|
2012-11-06 03:18:49 +00:00
|
|
|
|
|
|
|
// Implementations of the DB interface
|
2014-09-09 01:46:52 +00:00
|
|
|
Status DBImplReadOnly::Get(const ReadOptions& read_options,
|
2014-02-11 01:04:44 +00:00
|
|
|
ColumnFamilyHandle* column_family, const Slice& key,
|
2017-03-13 18:44:50 +00:00
|
|
|
PinnableSlice* pinnable_val) {
|
|
|
|
assert(pinnable_val != nullptr);
|
2018-08-23 05:40:34 +00:00
|
|
|
// TODO: stopwatch DB_GET needed?, perf timer needed?
|
|
|
|
PERF_TIMER_GUARD(get_snapshot_time);
|
2012-11-06 03:18:49 +00:00
|
|
|
Status s;
|
|
|
|
SequenceNumber snapshot = versions_->LastSequence();
|
2014-02-11 01:04:44 +00:00
|
|
|
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
|
|
|
|
auto cfd = cfh->cfd();
|
2018-08-01 07:14:43 +00:00
|
|
|
if (tracer_) {
|
|
|
|
InstrumentedMutexLock lock(&trace_mutex_);
|
|
|
|
if (tracer_) {
|
|
|
|
tracer_->Get(column_family, key);
|
|
|
|
}
|
|
|
|
}
|
2014-02-03 23:28:03 +00:00
|
|
|
SuperVersion* super_version = cfd->GetSuperVersion();
|
2013-12-03 02:34:05 +00:00
|
|
|
MergeContext merge_context;
|
2016-11-19 00:54:09 +00:00
|
|
|
RangeDelAggregator range_del_agg(cfd->internal_comparator(), snapshot);
|
2012-11-06 03:18:49 +00:00
|
|
|
LookupKey lkey(key, snapshot);
|
2018-08-23 05:40:34 +00:00
|
|
|
PERF_TIMER_STOP(get_snapshot_time);
|
2017-03-13 18:44:50 +00:00
|
|
|
if (super_version->mem->Get(lkey, pinnable_val->GetSelf(), &s, &merge_context,
|
|
|
|
&range_del_agg, read_options)) {
|
|
|
|
pinnable_val->PinSelf();
|
2018-08-23 05:40:34 +00:00
|
|
|
RecordTick(stats_, MEMTABLE_HIT);
|
2013-02-15 23:28:24 +00:00
|
|
|
} else {
|
2014-10-03 00:02:30 +00:00
|
|
|
PERF_TIMER_GUARD(get_from_output_files_time);
|
2017-03-13 18:44:50 +00:00
|
|
|
super_version->current->Get(read_options, lkey, pinnable_val, &s,
|
|
|
|
&merge_context, &range_del_agg);
|
2018-08-23 05:40:34 +00:00
|
|
|
RecordTick(stats_, MEMTABLE_MISS);
|
2013-02-15 23:28:24 +00:00
|
|
|
}
|
2018-08-23 05:40:34 +00:00
|
|
|
RecordTick(stats_, NUMBER_KEYS_READ);
|
|
|
|
size_t size = pinnable_val->size();
|
|
|
|
RecordTick(stats_, BYTES_READ, size);
|
|
|
|
MeasureTime(stats_, BYTES_PER_READ, size);
|
|
|
|
PERF_COUNTER_ADD(get_read_bytes, size);
|
2012-11-06 03:18:49 +00:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2014-09-08 22:04:34 +00:00
|
|
|
Iterator* DBImplReadOnly::NewIterator(const ReadOptions& read_options,
|
2014-02-11 01:04:44 +00:00
|
|
|
ColumnFamilyHandle* column_family) {
|
|
|
|
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
|
|
|
|
auto cfd = cfh->cfd();
|
2014-02-03 23:28:03 +00:00
|
|
|
SuperVersion* super_version = cfd->GetSuperVersion()->Ref();
|
|
|
|
SequenceNumber latest_snapshot = versions_->LastSequence();
|
2017-10-10 00:05:34 +00:00
|
|
|
ReadCallback* read_callback = nullptr; // No read callback provided.
|
2014-07-23 20:52:11 +00:00
|
|
|
auto db_iter = NewArenaWrappedDbIterator(
|
2018-05-21 21:33:55 +00:00
|
|
|
env_, read_options, *cfd->ioptions(), super_version->mutable_cf_options,
|
2014-09-08 22:04:34 +00:00
|
|
|
(read_options.snapshot != nullptr
|
2016-03-01 02:38:03 +00:00
|
|
|
? reinterpret_cast<const SnapshotImpl*>(read_options.snapshot)
|
|
|
|
->number_
|
2014-09-08 22:04:34 +00:00
|
|
|
: latest_snapshot),
|
2016-03-01 02:38:03 +00:00
|
|
|
super_version->mutable_cf_options.max_sequential_skip_in_iterations,
|
2017-10-10 00:05:34 +00:00
|
|
|
super_version->version_number, read_callback);
|
2016-11-04 18:53:38 +00:00
|
|
|
auto internal_iter =
|
|
|
|
NewInternalIterator(read_options, cfd, super_version, db_iter->GetArena(),
|
|
|
|
db_iter->GetRangeDelAggregator());
|
2014-07-23 20:52:11 +00:00
|
|
|
db_iter->SetIterUnderDBIter(internal_iter);
|
|
|
|
return db_iter;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status DBImplReadOnly::NewIterators(
|
2014-09-08 22:04:34 +00:00
|
|
|
const ReadOptions& read_options,
|
2014-07-23 20:52:11 +00:00
|
|
|
const std::vector<ColumnFamilyHandle*>& column_families,
|
|
|
|
std::vector<Iterator*>* iterators) {
|
2017-10-10 00:05:34 +00:00
|
|
|
ReadCallback* read_callback = nullptr; // No read callback provided.
|
2014-07-23 20:52:11 +00:00
|
|
|
if (iterators == nullptr) {
|
|
|
|
return Status::InvalidArgument("iterators not allowed to be nullptr");
|
|
|
|
}
|
|
|
|
iterators->clear();
|
|
|
|
iterators->reserve(column_families.size());
|
|
|
|
SequenceNumber latest_snapshot = versions_->LastSequence();
|
|
|
|
|
|
|
|
for (auto cfh : column_families) {
|
2014-10-23 22:34:21 +00:00
|
|
|
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(cfh)->cfd();
|
|
|
|
auto* sv = cfd->GetSuperVersion()->Ref();
|
|
|
|
auto* db_iter = NewArenaWrappedDbIterator(
|
2018-05-21 21:33:55 +00:00
|
|
|
env_, read_options, *cfd->ioptions(), sv->mutable_cf_options,
|
2014-09-08 22:04:34 +00:00
|
|
|
(read_options.snapshot != nullptr
|
2016-03-01 02:38:03 +00:00
|
|
|
? reinterpret_cast<const SnapshotImpl*>(read_options.snapshot)
|
|
|
|
->number_
|
|
|
|
: latest_snapshot),
|
|
|
|
sv->mutable_cf_options.max_sequential_skip_in_iterations,
|
2017-10-10 00:05:34 +00:00
|
|
|
sv->version_number, read_callback);
|
2016-11-04 18:53:38 +00:00
|
|
|
auto* internal_iter =
|
|
|
|
NewInternalIterator(read_options, cfd, sv, db_iter->GetArena(),
|
|
|
|
db_iter->GetRangeDelAggregator());
|
2014-07-23 20:52:11 +00:00
|
|
|
db_iter->SetIterUnderDBIter(internal_iter);
|
|
|
|
iterators->push_back(db_iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status::OK();
|
2012-11-06 03:18:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Status DB::OpenForReadOnly(const Options& options, const std::string& dbname,
|
2018-03-05 21:08:17 +00:00
|
|
|
DB** dbptr, bool /*error_if_log_file_exist*/) {
|
2013-02-15 23:28:24 +00:00
|
|
|
*dbptr = nullptr;
|
2012-11-06 03:18:49 +00:00
|
|
|
|
2014-09-25 18:14:01 +00:00
|
|
|
// Try to first open DB as fully compacted DB
|
|
|
|
Status s;
|
|
|
|
s = CompactedDBImpl::Open(options, dbname, dbptr);
|
|
|
|
if (s.ok()) {
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2014-01-06 21:31:06 +00:00
|
|
|
DBOptions db_options(options);
|
|
|
|
ColumnFamilyOptions cf_options(options);
|
|
|
|
std::vector<ColumnFamilyDescriptor> column_families;
|
|
|
|
column_families.push_back(
|
2014-04-09 16:56:17 +00:00
|
|
|
ColumnFamilyDescriptor(kDefaultColumnFamilyName, cf_options));
|
|
|
|
std::vector<ColumnFamilyHandle*> handles;
|
|
|
|
|
2014-09-25 18:14:01 +00:00
|
|
|
s = DB::OpenForReadOnly(db_options, dbname, column_families, &handles, dbptr);
|
2014-04-09 16:56:17 +00:00
|
|
|
if (s.ok()) {
|
|
|
|
assert(handles.size() == 1);
|
|
|
|
// i can delete the handle since DBImpl is always holding a
|
|
|
|
// reference to default column family
|
|
|
|
delete handles[0];
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status DB::OpenForReadOnly(
|
|
|
|
const DBOptions& db_options, const std::string& dbname,
|
|
|
|
const std::vector<ColumnFamilyDescriptor>& column_families,
|
|
|
|
std::vector<ColumnFamilyHandle*>* handles, DB** dbptr,
|
|
|
|
bool error_if_log_file_exist) {
|
|
|
|
*dbptr = nullptr;
|
|
|
|
handles->clear();
|
2014-02-05 21:12:23 +00:00
|
|
|
|
2017-10-06 01:00:38 +00:00
|
|
|
SuperVersionContext sv_context(/* create_superversion */ true);
|
2014-02-05 21:12:23 +00:00
|
|
|
DBImplReadOnly* impl = new DBImplReadOnly(db_options, dbname);
|
|
|
|
impl->mutex_.Lock();
|
2014-01-24 22:30:28 +00:00
|
|
|
Status s = impl->Recover(column_families, true /* read only */,
|
|
|
|
error_if_log_file_exist);
|
2014-04-09 16:56:17 +00:00
|
|
|
if (s.ok()) {
|
|
|
|
// set column family handles
|
|
|
|
for (auto cf : column_families) {
|
|
|
|
auto cfd =
|
|
|
|
impl->versions_->GetColumnFamilySet()->GetColumnFamily(cf.name);
|
|
|
|
if (cfd == nullptr) {
|
|
|
|
s = Status::InvalidArgument("Column family not found: ", cf.name);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
handles->push_back(new ColumnFamilyHandleImpl(cfd, impl, &impl->mutex_));
|
|
|
|
}
|
|
|
|
}
|
2014-02-03 21:13:36 +00:00
|
|
|
if (s.ok()) {
|
2014-02-03 21:44:47 +00:00
|
|
|
for (auto cfd : *impl->versions_->GetColumnFamilySet()) {
|
2017-10-06 01:00:38 +00:00
|
|
|
sv_context.NewSuperVersion();
|
|
|
|
cfd->InstallSuperVersion(&sv_context, &impl->mutex_);
|
2014-02-03 21:44:47 +00:00
|
|
|
}
|
2014-02-03 21:13:36 +00:00
|
|
|
}
|
2012-11-06 03:18:49 +00:00
|
|
|
impl->mutex_.Unlock();
|
2017-10-06 01:00:38 +00:00
|
|
|
sv_context.Clean();
|
2012-11-06 03:18:49 +00:00
|
|
|
if (s.ok()) {
|
|
|
|
*dbptr = impl;
|
2014-11-20 18:49:32 +00:00
|
|
|
for (auto* h : *handles) {
|
|
|
|
impl->NewThreadStatusCfInfo(
|
|
|
|
reinterpret_cast<ColumnFamilyHandleImpl*>(h)->cfd());
|
|
|
|
}
|
2012-11-06 03:18:49 +00:00
|
|
|
} else {
|
2014-04-09 16:56:17 +00:00
|
|
|
for (auto h : *handles) {
|
|
|
|
delete h;
|
|
|
|
}
|
|
|
|
handles->clear();
|
2012-11-06 03:18:49 +00:00
|
|
|
delete impl;
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2018-04-13 00:55:14 +00:00
|
|
|
#else // !ROCKSDB_LITE
|
2014-11-26 19:37:59 +00:00
|
|
|
|
2018-04-13 00:55:14 +00:00
|
|
|
Status DB::OpenForReadOnly(const Options& /*options*/,
|
|
|
|
const std::string& /*dbname*/, DB** /*dbptr*/,
|
|
|
|
bool /*error_if_log_file_exist*/) {
|
2014-11-26 19:37:59 +00:00
|
|
|
return Status::NotSupported("Not supported in ROCKSDB_LITE.");
|
|
|
|
}
|
|
|
|
|
|
|
|
Status DB::OpenForReadOnly(
|
2018-04-13 00:55:14 +00:00
|
|
|
const DBOptions& /*db_options*/, const std::string& /*dbname*/,
|
|
|
|
const std::vector<ColumnFamilyDescriptor>& /*column_families*/,
|
|
|
|
std::vector<ColumnFamilyHandle*>* /*handles*/, DB** /*dbptr*/,
|
|
|
|
bool /*error_if_log_file_exist*/) {
|
2014-11-26 19:37:59 +00:00
|
|
|
return Status::NotSupported("Not supported in ROCKSDB_LITE.");
|
|
|
|
}
|
|
|
|
#endif // !ROCKSDB_LITE
|
2014-04-09 16:56:17 +00:00
|
|
|
|
2018-04-13 00:55:14 +00:00
|
|
|
} // namespace rocksdb
|