diff --git a/HISTORY.md b/HISTORY.md index 168496b4a1..7382a017f1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,8 +5,10 @@ ### New Features * DB::ResetStats() to reset internal stats. +* Support dynamically change `max_open_files` option via SetDBOptions() * Statistics::Reset() to reset user stats. * ldb add option --try_load_options, which will open DB with its own option file. +* Support dynamically change `max_open_files` option via SetDBOptions() ## 5.4.0 (04/11/2017) ### Public API Change diff --git a/db/db_impl.cc b/db/db_impl.cc index c02de994f1..d4f59d3303 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -192,9 +192,9 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname) // Reserve ten files or so for other uses and give the rest to TableCache. // Give a large number for setting of "infinite" open files. - const int table_cache_size = (immutable_db_options_.max_open_files == -1) - ? 4194304 - : immutable_db_options_.max_open_files - 10; + const int table_cache_size = (mutable_db_options_.max_open_files == -1) + ? 0x400000 + : mutable_db_options_.max_open_files - 10; table_cache_ = NewLRUCache(table_cache_size, immutable_db_options_.table_cache_numshardbits); @@ -581,6 +581,9 @@ Status DBImpl::SetDBOptions( } write_controller_.set_max_delayed_write_rate(new_options.delayed_write_rate); + table_cache_.get()->SetCapacity(new_options.max_open_files == -1 + ? 0x400000 + : new_options.max_open_files - 10); mutable_db_options_ = new_options; diff --git a/db/db_impl_open.cc b/db/db_impl_open.cc index 9ef7d70c0f..341f01d047 100644 --- a/db/db_impl_open.cc +++ b/db/db_impl_open.cc @@ -38,7 +38,7 @@ DBOptions SanitizeOptions(const std::string& dbname, const DBOptions& src) { if (result.max_open_files != -1) { int max_max_open_files = port::GetMaxOpenFiles(); if (max_max_open_files == -1) { - max_max_open_files = 1000000; + max_max_open_files = 0x400000; } ClipToRange(&result.max_open_files, 20, max_max_open_files); } diff --git a/db/db_options_test.cc b/db/db_options_test.cc index 158eaa04b6..30c0a2ebf6 100644 --- a/db/db_options_test.cc +++ b/db/db_options_test.cc @@ -17,6 +17,7 @@ #include "db/db_test_util.h" #include "options/options_helper.h" #include "port/stack_trace.h" +#include "rocksdb/cache.h" #include "rocksdb/convenience.h" #include "util/random.h" #include "util/sync_point.h" @@ -385,6 +386,24 @@ TEST_F(DBOptionsTest, DeleteObsoleteFilesPeriodChange) { Close(); } +TEST_F(DBOptionsTest, MaxOpenFilesChange) { + SpecialEnv env(env_); + Options options; + options.max_open_files = -1; + + Reopen(options); + + Cache* tc = dbfull()->TEST_table_cache(); + + ASSERT_EQ(-1, dbfull()->GetDBOptions().max_open_files); + ASSERT_LT(2000, tc->GetCapacity()); + ASSERT_OK(dbfull()->SetDBOptions({{"max_open_files", "1024"}})); + ASSERT_EQ(1024, dbfull()->GetDBOptions().max_open_files); + // examine the table cache (actual size should be 1014) + ASSERT_GT(1500, tc->GetCapacity()); + Close(); +} + #endif // ROCKSDB_LITE } // namespace rocksdb diff --git a/db/version_set.cc b/db/version_set.cc index 9da583b694..99493daa9a 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -1121,8 +1121,11 @@ void Version::UpdateAccumulatedStats(bool update_stats) { storage_info_.UpdateAccumulatedStats(file_meta); // when option "max_open_files" is -1, all the file metadata has // already been read, so MaybeInitializeFileMetaData() won't incur - // any I/O cost. - if (vset_->db_options_->max_open_files == -1) { + // any I/O cost. "max_open_files=-1" means that the table cache passed + // to the VersionSet and then to the ColumnFamilySet has a size of + // 0x400000 + if (vset_->GetColumnFamilySet()->get_table_cache()->GetCapacity() == + 0x400000) { continue; } if (++init_count >= kMaxInitCount) { @@ -2380,7 +2383,8 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data, TEST_SYNC_POINT("VersionSet::LogAndApply:WriteManifest"); if (!w.edit_list.front()->IsColumnFamilyManipulation() && - db_options_->max_open_files == -1) { + this->GetColumnFamilySet()->get_table_cache()->GetCapacity() == + 0x400000) { // unlimited table cache. Pre-load table handle now. // Need to do it out of the mutex. builder_guard->version_builder()->LoadTableHandlers( @@ -2826,7 +2830,7 @@ Status VersionSet::Recover( assert(builders_iter != builders.end()); auto* builder = builders_iter->second->version_builder(); - if (db_options_->max_open_files == -1) { + if (GetColumnFamilySet()->get_table_cache()->GetCapacity() == 0x400000) { // unlimited table cache. Pre-load table handle now. // Need to do it out of the mutex. builder->LoadTableHandlers( diff --git a/options/db_options.cc b/options/db_options.cc index 25c8cf3583..fc7ebcfd7c 100644 --- a/options/db_options.cc +++ b/options/db_options.cc @@ -32,7 +32,6 @@ ImmutableDBOptions::ImmutableDBOptions(const DBOptions& options) sst_file_manager(options.sst_file_manager), info_log(options.info_log), info_log_level(options.info_log_level), - max_open_files(options.max_open_files), max_file_opening_threads(options.max_file_opening_threads), statistics(options.statistics), use_fsync(options.use_fsync), @@ -99,8 +98,6 @@ void ImmutableDBOptions::Dump(Logger* log) const { env); ROCKS_LOG_HEADER(log, " Options.info_log: %p", info_log.get()); - ROCKS_LOG_HEADER(log, " Options.max_open_files: %d", - max_open_files); ROCKS_LOG_HEADER(log, " Options.max_file_opening_threads: %d", max_file_opening_threads); ROCKS_LOG_HEADER(log, " Options.use_fsync: %d", @@ -224,7 +221,8 @@ MutableDBOptions::MutableDBOptions() delayed_write_rate(2 * 1024U * 1024U), max_total_wal_size(0), delete_obsolete_files_period_micros(6ULL * 60 * 60 * 1000000), - stats_dump_period_sec(600) {} + stats_dump_period_sec(600), + max_open_files(-1) {} MutableDBOptions::MutableDBOptions(const DBOptions& options) : base_background_compactions(options.base_background_compactions), @@ -234,7 +232,8 @@ MutableDBOptions::MutableDBOptions(const DBOptions& options) max_total_wal_size(options.max_total_wal_size), delete_obsolete_files_period_micros( options.delete_obsolete_files_period_micros), - stats_dump_period_sec(options.stats_dump_period_sec) {} + stats_dump_period_sec(options.stats_dump_period_sec), + max_open_files(options.max_open_files) {} void MutableDBOptions::Dump(Logger* log) const { ROCKS_LOG_HEADER(log, " Options.base_background_compactions: %d", @@ -252,6 +251,8 @@ void MutableDBOptions::Dump(Logger* log) const { delete_obsolete_files_period_micros); ROCKS_LOG_HEADER(log, " Options.stats_dump_period_sec: %u", stats_dump_period_sec); + ROCKS_LOG_HEADER(log, " Options.max_open_files: %d", + max_open_files); } } // namespace rocksdb diff --git a/options/db_options.h b/options/db_options.h index bea73560a1..c77eeaa7b6 100644 --- a/options/db_options.h +++ b/options/db_options.h @@ -27,7 +27,6 @@ struct ImmutableDBOptions { std::shared_ptr sst_file_manager; std::shared_ptr info_log; InfoLogLevel info_log_level; - int max_open_files; int max_file_opening_threads; std::shared_ptr statistics; bool use_fsync; @@ -94,6 +93,7 @@ struct MutableDBOptions { uint64_t max_total_wal_size; uint64_t delete_obsolete_files_period_micros; unsigned int stats_dump_period_sec; + int max_open_files; }; } // namespace rocksdb diff --git a/options/options_helper.cc b/options/options_helper.cc index 68d19cf77c..01066c6e90 100644 --- a/options/options_helper.cc +++ b/options/options_helper.cc @@ -41,7 +41,7 @@ DBOptions BuildDBOptions(const ImmutableDBOptions& immutable_db_options, options.sst_file_manager = immutable_db_options.sst_file_manager; options.info_log = immutable_db_options.info_log; options.info_log_level = immutable_db_options.info_log_level; - options.max_open_files = immutable_db_options.max_open_files; + options.max_open_files = mutable_db_options.max_open_files; options.max_file_opening_threads = immutable_db_options.max_file_opening_threads; options.max_total_wal_size = mutable_db_options.max_total_wal_size; diff --git a/options/options_helper.h b/options/options_helper.h index 6a729db411..97630a0a6a 100644 --- a/options/options_helper.h +++ b/options/options_helper.h @@ -234,7 +234,8 @@ static std::unordered_map db_options_type_info = { OptionVerificationType::kNormal, false, 0}}, {"max_open_files", {offsetof(struct DBOptions, max_open_files), OptionType::kInt, - OptionVerificationType::kNormal, false, 0}}, + OptionVerificationType::kNormal, true, + offsetof(struct MutableDBOptions, max_open_files)}}, {"table_cache_numshardbits", {offsetof(struct DBOptions, table_cache_numshardbits), OptionType::kInt, OptionVerificationType::kNormal, false, 0}},