improve ldb CLI option support

Summary:
- Made CLI arguments take precedence over options file when both are provided. Note some of the CLI args are not settable via options file, like `--compression_max_dict_bytes`, so it's necessary to allow both ways of providing options simultaneously.
- Changed `PrepareOptionsForOpenDB` to update the proper `ColumnFamilyOptions` if one exists for the user's `--column_family_name` argument. I supported this only in the base class, `LDBCommand`, so it works for the general arguments. Will defer adding support for subcommand-specific arguments.
- Made the command fail if `--try_load_options` is provided and loading options file returns NotFound. I found the previous behavior of silently continuing confusing.
Closes https://github.com/facebook/rocksdb/pull/3144

Differential Revision: D6270544

Pulled By: ajkr

fbshipit-source-id: 7c2eac9f9b38720523d74466fb9e78db53561367
main
Andrew Kryczka 7 years ago committed by Facebook Github Bot
parent c85f8ccca3
commit ed3af9ef99
  1. 87
      tools/ldb_cmd.cc

@ -312,14 +312,10 @@ LDBCommand::LDBCommand(const std::map<std::string, std::string>& options,
} }
void LDBCommand::OpenDB() { void LDBCommand::OpenDB() {
Options opt;
bool opt_set = false;
if (!create_if_missing_ && try_load_options_) { if (!create_if_missing_ && try_load_options_) {
Status s = LoadLatestOptions(db_path_, Env::Default(), &opt, Status s = LoadLatestOptions(db_path_, Env::Default(), &options_,
&column_families_, ignore_unknown_options_); &column_families_, ignore_unknown_options_);
if (s.ok()) { if (!s.ok()) {
opt_set = true;
} else if (!s.IsNotFound()) {
// Option file exists but load option file error. // Option file exists but load option file error.
std::string msg = s.ToString(); std::string msg = s.ToString();
exec_state_ = LDBCommandExecuteResult::Failed(msg); exec_state_ = LDBCommandExecuteResult::Failed(msg);
@ -327,9 +323,7 @@ void LDBCommand::OpenDB() {
return; return;
} }
} }
if (!opt_set) { options_ = PrepareOptionsForOpenDB();
opt = PrepareOptionsForOpenDB();
}
if (!exec_state_.IsNotStarted()) { if (!exec_state_.IsNotStarted()) {
return; return;
} }
@ -343,13 +337,13 @@ void LDBCommand::OpenDB() {
"ldb doesn't support TTL DB with multiple column families"); "ldb doesn't support TTL DB with multiple column families");
} }
if (is_read_only_) { if (is_read_only_) {
st = DBWithTTL::Open(opt, db_path_, &db_ttl_, 0, true); st = DBWithTTL::Open(options_, db_path_, &db_ttl_, 0, true);
} else { } else {
st = DBWithTTL::Open(opt, db_path_, &db_ttl_); st = DBWithTTL::Open(options_, db_path_, &db_ttl_);
} }
db_ = db_ttl_; db_ = db_ttl_;
} else { } else {
if (!opt_set && column_families_.empty()) { if (column_families_.empty()) {
// Try to figure out column family lists // Try to figure out column family lists
std::vector<std::string> cf_list; std::vector<std::string> cf_list;
st = DB::ListColumnFamilies(DBOptions(), db_path_, &cf_list); st = DB::ListColumnFamilies(DBOptions(), db_path_, &cf_list);
@ -360,22 +354,22 @@ void LDBCommand::OpenDB() {
if (st.ok() && cf_list.size() > 1) { if (st.ok() && cf_list.size() > 1) {
// Ignore single column family DB. // Ignore single column family DB.
for (auto cf_name : cf_list) { for (auto cf_name : cf_list) {
column_families_.emplace_back(cf_name, opt); column_families_.emplace_back(cf_name, options_);
} }
} }
} }
if (is_read_only_) { if (is_read_only_) {
if (column_families_.empty()) { if (column_families_.empty()) {
st = DB::OpenForReadOnly(opt, db_path_, &db_); st = DB::OpenForReadOnly(options_, db_path_, &db_);
} else { } else {
st = DB::OpenForReadOnly(opt, db_path_, column_families_, st = DB::OpenForReadOnly(options_, db_path_, column_families_,
&handles_opened, &db_); &handles_opened, &db_);
} }
} else { } else {
if (column_families_.empty()) { if (column_families_.empty()) {
st = DB::Open(opt, db_path_, &db_); st = DB::Open(options_, db_path_, &db_);
} else { } else {
st = DB::Open(opt, db_path_, column_families_, &handles_opened, &db_); st = DB::Open(options_, db_path_, column_families_, &handles_opened, &db_);
} }
} }
} }
@ -405,8 +399,6 @@ void LDBCommand::OpenDB() {
CloseDB(); CloseDB();
} }
} }
options_ = opt;
} }
void LDBCommand::CloseDB() { void LDBCommand::CloseDB() {
@ -499,9 +491,19 @@ bool LDBCommand::ParseStringOption(
} }
Options LDBCommand::PrepareOptionsForOpenDB() { Options LDBCommand::PrepareOptionsForOpenDB() {
ColumnFamilyOptions* cf_opts;
Options opt = options_; auto column_families_iter =
opt.create_if_missing = false; std::find_if(column_families_.begin(), column_families_.end(),
[this](const ColumnFamilyDescriptor& cf_desc) {
return cf_desc.name == column_family_name_;
});
if (column_families_iter != column_families_.end()) {
cf_opts = &column_families_iter->options;
} else {
cf_opts = static_cast<ColumnFamilyOptions*>(&options_);
}
DBOptions* db_opts = static_cast<DBOptions*>(&options_);
db_opts->create_if_missing = false;
std::map<std::string, std::string>::const_iterator itr; std::map<std::string, std::string>::const_iterator itr;
@ -530,33 +532,33 @@ Options LDBCommand::PrepareOptionsForOpenDB() {
} }
if (use_table_options) { if (use_table_options) {
opt.table_factory.reset(NewBlockBasedTableFactory(table_options)); cf_opts->table_factory.reset(NewBlockBasedTableFactory(table_options));
} }
itr = option_map_.find(ARG_AUTO_COMPACTION); itr = option_map_.find(ARG_AUTO_COMPACTION);
if (itr != option_map_.end()) { if (itr != option_map_.end()) {
opt.disable_auto_compactions = ! StringToBool(itr->second); cf_opts->disable_auto_compactions = !StringToBool(itr->second);
} }
itr = option_map_.find(ARG_COMPRESSION_TYPE); itr = option_map_.find(ARG_COMPRESSION_TYPE);
if (itr != option_map_.end()) { if (itr != option_map_.end()) {
std::string comp = itr->second; std::string comp = itr->second;
if (comp == "no") { if (comp == "no") {
opt.compression = kNoCompression; cf_opts->compression = kNoCompression;
} else if (comp == "snappy") { } else if (comp == "snappy") {
opt.compression = kSnappyCompression; cf_opts->compression = kSnappyCompression;
} else if (comp == "zlib") { } else if (comp == "zlib") {
opt.compression = kZlibCompression; cf_opts->compression = kZlibCompression;
} else if (comp == "bzip2") { } else if (comp == "bzip2") {
opt.compression = kBZip2Compression; cf_opts->compression = kBZip2Compression;
} else if (comp == "lz4") { } else if (comp == "lz4") {
opt.compression = kLZ4Compression; cf_opts->compression = kLZ4Compression;
} else if (comp == "lz4hc") { } else if (comp == "lz4hc") {
opt.compression = kLZ4HCCompression; cf_opts->compression = kLZ4HCCompression;
} else if (comp == "xpress") { } else if (comp == "xpress") {
opt.compression = kXpressCompression; cf_opts->compression = kXpressCompression;
} else if (comp == "zstd") { } else if (comp == "zstd") {
opt.compression = kZSTD; cf_opts->compression = kZSTD;
} else { } else {
// Unknown compression. // Unknown compression.
exec_state_ = exec_state_ =
@ -568,7 +570,7 @@ Options LDBCommand::PrepareOptionsForOpenDB() {
if (ParseIntOption(option_map_, ARG_COMPRESSION_MAX_DICT_BYTES, if (ParseIntOption(option_map_, ARG_COMPRESSION_MAX_DICT_BYTES,
compression_max_dict_bytes, exec_state_)) { compression_max_dict_bytes, exec_state_)) {
if (compression_max_dict_bytes >= 0) { if (compression_max_dict_bytes >= 0) {
opt.compression_opts.max_dict_bytes = compression_max_dict_bytes; cf_opts->compression_opts.max_dict_bytes = compression_max_dict_bytes;
} else { } else {
exec_state_ = LDBCommandExecuteResult::Failed( exec_state_ = LDBCommandExecuteResult::Failed(
ARG_COMPRESSION_MAX_DICT_BYTES + " must be >= 0."); ARG_COMPRESSION_MAX_DICT_BYTES + " must be >= 0.");
@ -579,7 +581,7 @@ Options LDBCommand::PrepareOptionsForOpenDB() {
if (ParseIntOption(option_map_, ARG_DB_WRITE_BUFFER_SIZE, if (ParseIntOption(option_map_, ARG_DB_WRITE_BUFFER_SIZE,
db_write_buffer_size, exec_state_)) { db_write_buffer_size, exec_state_)) {
if (db_write_buffer_size >= 0) { if (db_write_buffer_size >= 0) {
opt.db_write_buffer_size = db_write_buffer_size; db_opts->db_write_buffer_size = db_write_buffer_size;
} else { } else {
exec_state_ = LDBCommandExecuteResult::Failed(ARG_DB_WRITE_BUFFER_SIZE + exec_state_ = LDBCommandExecuteResult::Failed(ARG_DB_WRITE_BUFFER_SIZE +
" must be >= 0."); " must be >= 0.");
@ -590,7 +592,7 @@ Options LDBCommand::PrepareOptionsForOpenDB() {
if (ParseIntOption(option_map_, ARG_WRITE_BUFFER_SIZE, write_buffer_size, if (ParseIntOption(option_map_, ARG_WRITE_BUFFER_SIZE, write_buffer_size,
exec_state_)) { exec_state_)) {
if (write_buffer_size > 0) { if (write_buffer_size > 0) {
opt.write_buffer_size = write_buffer_size; cf_opts->write_buffer_size = write_buffer_size;
} else { } else {
exec_state_ = LDBCommandExecuteResult::Failed(ARG_WRITE_BUFFER_SIZE + exec_state_ = LDBCommandExecuteResult::Failed(ARG_WRITE_BUFFER_SIZE +
" must be > 0."); " must be > 0.");
@ -600,30 +602,33 @@ Options LDBCommand::PrepareOptionsForOpenDB() {
int file_size; int file_size;
if (ParseIntOption(option_map_, ARG_FILE_SIZE, file_size, exec_state_)) { if (ParseIntOption(option_map_, ARG_FILE_SIZE, file_size, exec_state_)) {
if (file_size > 0) { if (file_size > 0) {
opt.target_file_size_base = file_size; cf_opts->target_file_size_base = file_size;
} else { } else {
exec_state_ = exec_state_ =
LDBCommandExecuteResult::Failed(ARG_FILE_SIZE + " must be > 0."); LDBCommandExecuteResult::Failed(ARG_FILE_SIZE + " must be > 0.");
} }
} }
if (opt.db_paths.size() == 0) { if (db_opts->db_paths.size() == 0) {
opt.db_paths.emplace_back(db_path_, std::numeric_limits<uint64_t>::max()); db_opts->db_paths.emplace_back(db_path_,
std::numeric_limits<uint64_t>::max());
} }
int fix_prefix_len; int fix_prefix_len;
if (ParseIntOption(option_map_, ARG_FIX_PREFIX_LEN, fix_prefix_len, if (ParseIntOption(option_map_, ARG_FIX_PREFIX_LEN, fix_prefix_len,
exec_state_)) { exec_state_)) {
if (fix_prefix_len > 0) { if (fix_prefix_len > 0) {
opt.prefix_extractor.reset( cf_opts->prefix_extractor.reset(
NewFixedPrefixTransform(static_cast<size_t>(fix_prefix_len))); NewFixedPrefixTransform(static_cast<size_t>(fix_prefix_len)));
} else { } else {
exec_state_ = exec_state_ =
LDBCommandExecuteResult::Failed(ARG_FIX_PREFIX_LEN + " must be > 0."); LDBCommandExecuteResult::Failed(ARG_FIX_PREFIX_LEN + " must be > 0.");
} }
} }
// TODO(ajkr): this return value doesn't reflect the CF options changed, so
return opt; // subcommands that rely on this won't see the effect of CF-related CLI args.
// Such subcommands need to be changed to properly support CFs.
return options_;
} }
bool LDBCommand::ParseKeyValue(const std::string& line, std::string* key, bool LDBCommand::ParseKeyValue(const std::string& line, std::string* key,

Loading…
Cancel
Save