InstrumentedMutexLock l(&mutex_);
s = GetMutableDBOptionsFromStrings(mutable_db_options_, options_map,
&new_options);
+
if (new_options.bytes_per_sync == 0) {
new_options.bytes_per_sync = 1024 * 1024;
}
+
+ if (MutableDBOptionsAreEqual(mutable_db_options_, new_options)) {
+ ROCKS_LOG_INFO(immutable_db_options_.info_log,
+ "SetDBOptions(), input option value is not changed, "
+ "skipping updating.");
+ persist_options_status.PermitUncheckedError();
+ return s;
+ }
+
DBOptions new_db_options =
BuildDBOptions(immutable_db_options_, new_options);
if (s.ok()) {
TEST_SYNC_POINT("DBImpl::WriteOptionsFile:1");
TEST_SYNC_POINT("DBImpl::WriteOptionsFile:2");
+ TEST_SYNC_POINT_CALLBACK("DBImpl::WriteOptionsFile:PersistOptions",
+ &db_options);
std::string file_name =
TempOptionsFileName(GetName(), versions_->NewFileNumber());
// RocksDB lite don't support dynamic options.
#ifndef ROCKSDB_LITE
+TEST_F(DBOptionsTest, AvoidUpdatingOptions) {
+ Options options;
+ options.env = env_;
+ options.max_background_jobs = 4;
+ options.delayed_write_rate = 1024;
+
+ Reopen(options);
+
+ SyncPoint::GetInstance()->DisableProcessing();
+ SyncPoint::GetInstance()->ClearAllCallBacks();
+ bool is_changed_stats = false;
+ SyncPoint::GetInstance()->SetCallBack(
+ "DBImpl::WriteOptionsFile:PersistOptions", [&](void* /*arg*/) {
+ ASSERT_FALSE(is_changed_stats); // should only save options file once
+ is_changed_stats = true;
+ });
+ SyncPoint::GetInstance()->EnableProcessing();
+
+ // helper function to check the status and reset after each check
+ auto is_changed = [&] {
+ bool ret = is_changed_stats;
+ is_changed_stats = false;
+ return ret;
+ };
+
+ // without changing the value, but it's sanitized to a different value
+ ASSERT_OK(dbfull()->SetDBOptions({{"bytes_per_sync", "0"}}));
+ ASSERT_TRUE(is_changed());
+
+ // without changing the value
+ ASSERT_OK(dbfull()->SetDBOptions({{"max_background_jobs", "4"}}));
+ ASSERT_FALSE(is_changed());
+
+ // changing the value
+ ASSERT_OK(dbfull()->SetDBOptions({{"bytes_per_sync", "123"}}));
+ ASSERT_TRUE(is_changed());
+
+ // update again
+ ASSERT_OK(dbfull()->SetDBOptions({{"bytes_per_sync", "123"}}));
+ ASSERT_FALSE(is_changed());
+
+ // without changing a default value
+ ASSERT_OK(dbfull()->SetDBOptions({{"strict_bytes_per_sync", "false"}}));
+ ASSERT_FALSE(is_changed());
+
+ // now change
+ ASSERT_OK(dbfull()->SetDBOptions({{"strict_bytes_per_sync", "true"}}));
+ ASSERT_TRUE(is_changed());
+
+ // multiple values without change
+ ASSERT_OK(dbfull()->SetDBOptions(
+ {{"max_total_wal_size", "0"}, {"stats_dump_period_sec", "600"}}));
+ ASSERT_FALSE(is_changed());
+
+ // multiple values with change
+ ASSERT_OK(dbfull()->SetDBOptions(
+ {{"max_open_files", "100"}, {"stats_dump_period_sec", "600"}}));
+ ASSERT_TRUE(is_changed());
+}
+
TEST_F(DBOptionsTest, GetLatestDBOptions) {
// GetOptions should be able to get latest option changed by SetOptions.
Options options;
return s;
}
+bool MutableDBOptionsAreEqual(const MutableDBOptions& this_options,
+ const MutableDBOptions& that_options) {
+ ConfigOptions config_options;
+ std::string mismatch;
+ return OptionTypeInfo::StructsAreEqual(
+ config_options, "MutableDBOptions", &db_mutable_options_type_info,
+ "MutableDBOptions", &this_options, &that_options, &mismatch);
+}
+
Status GetStringFromMutableDBOptions(const ConfigOptions& config_options,
const MutableDBOptions& mutable_opts,
std::string* opt_string) {