mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 06:47:41 +03:00
move some logic from RocksHandles to RocksDbLocalStore
Summary: This moves some logic from the RocksHandles class up to RocksDbLocalStore. The main thing moved here is the logic to automatically try and repair the DB if opening fails. This will make it easier in a subsequent diff to make the repair logic a bit smarter and more aware of our column family semantics. This keeps RocksHandles a pretty dumb wrapper around the RocksDB object and column family handles, whose only purpose is to manage destroying these two things in the correct order. Reviewed By: chadaustin Differential Revision: D15043208 fbshipit-source-id: ee2d5619ac7781a892e1ba151712eee9e3ebfb14
This commit is contained in:
parent
256422737d
commit
2faa637da5
@ -11,6 +11,8 @@
|
||||
|
||||
#include <folly/logging/xlog.h>
|
||||
|
||||
#include "eden/fs/rocksdb/RocksException.h"
|
||||
|
||||
using folly::StringPiece;
|
||||
using rocksdb::ColumnFamilyDescriptor;
|
||||
using rocksdb::ColumnFamilyHandle;
|
||||
@ -26,6 +28,10 @@ namespace facebook {
|
||||
namespace eden {
|
||||
|
||||
RocksHandles::~RocksHandles() {
|
||||
close();
|
||||
}
|
||||
|
||||
void RocksHandles::close() {
|
||||
// MUST destroy the column handles first
|
||||
columns.clear();
|
||||
db.reset();
|
||||
@ -33,33 +39,12 @@ RocksHandles::~RocksHandles() {
|
||||
|
||||
RocksHandles::RocksHandles(
|
||||
StringPiece dbPath,
|
||||
const Options& options,
|
||||
const std::vector<ColumnFamilyDescriptor>& columnDescriptors) {
|
||||
auto dbPathStr = dbPath.str();
|
||||
|
||||
Options options;
|
||||
// Optimize RocksDB. This is the easiest way to get RocksDB to perform well.
|
||||
options.IncreaseParallelism();
|
||||
|
||||
// Create the DB if it's not already present.
|
||||
options.create_if_missing = true;
|
||||
// Automatically create column families as we define new ones.
|
||||
options.create_missing_column_families = true;
|
||||
|
||||
// If we wanted we could set options.info_log to control where RocksDB
|
||||
// log messages get sent. By default they are written to a file named "LOG"
|
||||
// in the DB directory.
|
||||
// options.info_log = make_shared<CustomLogger>(InfoLogLevel::INFO_LEVEL);
|
||||
|
||||
DB* dbRaw;
|
||||
columns.reserve(columnDescriptors.size());
|
||||
|
||||
std::vector<ColumnFamilyHandle*> columnHandles;
|
||||
|
||||
auto openDB = [&] {
|
||||
return DB::Open(
|
||||
options, dbPathStr, columnDescriptors, &columnHandles, &dbRaw);
|
||||
};
|
||||
|
||||
// This will create any newly defined column families automatically,
|
||||
// so we needn't make any special migration steps here; just define
|
||||
// a new family and start to use it.
|
||||
@ -67,36 +52,17 @@ RocksHandles::RocksHandles(
|
||||
// and shout at us for not opening up the database with them defined.
|
||||
// We will need to do "something smarter" if we ever decide to perform
|
||||
// that kind of a migration.
|
||||
auto status = openDB();
|
||||
auto status =
|
||||
DB::Open(options, dbPathStr, columnDescriptors, &columnHandles, &dbRaw);
|
||||
if (!status.ok()) {
|
||||
XLOG(ERR) << "Error opening RocksDB storage at " << dbPathStr << ": "
|
||||
<< status.ToString();
|
||||
XLOG(ERR) << "Attempting to repair RocksDB " << dbPathStr;
|
||||
|
||||
rocksdb::ColumnFamilyOptions unknownColumFamilyOptions;
|
||||
unknownColumFamilyOptions.OptimizeForPointLookup(8);
|
||||
unknownColumFamilyOptions.OptimizeLevelStyleCompaction();
|
||||
|
||||
DBOptions dbOptions(options);
|
||||
status = RepairDB(
|
||||
dbPathStr, dbOptions, columnDescriptors, unknownColumFamilyOptions);
|
||||
if (!status.ok()) {
|
||||
throw std::runtime_error(folly::to<string>(
|
||||
"Unable to repair RocksDB at ", dbPathStr, ": ", status.ToString()));
|
||||
}
|
||||
|
||||
columnHandles.clear();
|
||||
status = openDB();
|
||||
if (!status.ok()) {
|
||||
throw std::runtime_error(folly::to<string>(
|
||||
"Failed to open RocksDB at ",
|
||||
dbPathStr,
|
||||
" after repair attempt: ",
|
||||
status.ToString()));
|
||||
}
|
||||
throw RocksException::build(
|
||||
status, "error opening RocksDB storage at", dbPathStr);
|
||||
}
|
||||
|
||||
db.reset(dbRaw);
|
||||
columns.reserve(columnHandles.size());
|
||||
for (auto h : columnHandles) {
|
||||
columns.emplace_back(h);
|
||||
}
|
||||
|
@ -48,12 +48,10 @@ struct RocksHandles {
|
||||
*/
|
||||
RocksHandles(
|
||||
folly::StringPiece dbPath,
|
||||
const rocksdb::Options& options,
|
||||
const std::vector<rocksdb::ColumnFamilyDescriptor>& columnDescriptors);
|
||||
|
||||
RocksHandles(const RocksHandles&) = delete;
|
||||
RocksHandles& operator=(const RocksHandles&) = delete;
|
||||
RocksHandles(RocksHandles&&) = default;
|
||||
RocksHandles& operator=(RocksHandles&&) = default;
|
||||
void close();
|
||||
};
|
||||
} // namespace eden
|
||||
} // namespace facebook
|
||||
|
@ -178,6 +178,52 @@ void RocksDbWriteBatch::put(
|
||||
flushIfNeeded();
|
||||
}
|
||||
|
||||
rocksdb::Options getRocksdbOptions() {
|
||||
rocksdb::Options options;
|
||||
// Optimize RocksDB. This is the easiest way to get RocksDB to perform well.
|
||||
options.IncreaseParallelism();
|
||||
|
||||
// Create the DB if it's not already present.
|
||||
options.create_if_missing = true;
|
||||
// Automatically create column families as we define new ones.
|
||||
options.create_missing_column_families = true;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
void repairDB(AbsolutePathPiece path) {
|
||||
XLOG(ERR) << "Attempting to repair RocksDB " << path;
|
||||
rocksdb::ColumnFamilyOptions unknownColumFamilyOptions;
|
||||
unknownColumFamilyOptions.OptimizeForPointLookup(8);
|
||||
unknownColumFamilyOptions.OptimizeLevelStyleCompaction();
|
||||
|
||||
const auto& columnDescriptors = columnFamilies();
|
||||
|
||||
auto dbPathStr = path.stringPiece().str();
|
||||
rocksdb::DBOptions dbOptions(getRocksdbOptions());
|
||||
auto status = RepairDB(
|
||||
dbPathStr, dbOptions, columnDescriptors, unknownColumFamilyOptions);
|
||||
if (!status.ok()) {
|
||||
throw RocksException::build(status, "unable to repair RocksDB at ", path);
|
||||
}
|
||||
}
|
||||
|
||||
RocksHandles openDB(AbsolutePathPiece path) {
|
||||
auto options = getRocksdbOptions();
|
||||
try {
|
||||
return RocksHandles(path.stringPiece(), options, columnFamilies());
|
||||
} catch (const RocksException& ex) {
|
||||
XLOG(ERR) << "Error opening RocksDB storage at " << path << ": "
|
||||
<< ex.what();
|
||||
// Fall through and attempt to repair the DB
|
||||
}
|
||||
|
||||
repairDB(path);
|
||||
|
||||
// Now try opening the DB again.
|
||||
return RocksHandles(path.stringPiece(), options, columnFamilies());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace facebook {
|
||||
@ -189,9 +235,8 @@ RocksDbLocalStore::RocksDbLocalStore(
|
||||
std::shared_ptr<ReloadableConfig> config)
|
||||
: LocalStore(std::move(config)),
|
||||
faultInjector_(*faultInjector),
|
||||
dbHandles_(pathToRocksDb.stringPiece(), columnFamilies()),
|
||||
ioPool_(12, "RocksLocalStore") {
|
||||
}
|
||||
dbHandles_(openDB(pathToRocksDb)),
|
||||
ioPool_(12, "RocksLocalStore") {}
|
||||
|
||||
RocksDbLocalStore::~RocksDbLocalStore() {
|
||||
#ifdef FOLLY_SANITIZE_ADDRESS
|
||||
@ -209,8 +254,7 @@ RocksDbLocalStore::~RocksDbLocalStore() {
|
||||
}
|
||||
|
||||
void RocksDbLocalStore::close() {
|
||||
dbHandles_.columns.clear();
|
||||
dbHandles_.db.reset();
|
||||
dbHandles_.close();
|
||||
}
|
||||
|
||||
void RocksDbLocalStore::clearKeySpace(KeySpace keySpace) {
|
||||
|
Loading…
Reference in New Issue
Block a user