This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git
The following commit(s) were added to refs/heads/master by this push:
new fc616286b Feature:Online Query and Dynamic Modification of Table-level
RocksDB Options (#1511)
fc616286b is described below
commit fc616286b3f14b6f4ce92da95e83e74e333ba463
Author: Pengfan Lu <[email protected]>
AuthorDate: Fri Aug 11 10:41:47 2023 +0800
Feature:Online Query and Dynamic Modification of Table-level RocksDB
Options (#1511)
https://github.com/apache/incubator-pegasus/issues/1488
Complete the dynamic setting function of num_levels and write_buffer_size
option.
I use rocksdb.write_buffer_size as a dynamically modifiable parameter and
rocksdb.num_levels
as a non-dynamically modifiable parameter to test my idea.
---
src/base/pegasus_const.cpp | 49 +++++++
src/base/pegasus_const.h | 22 +++
src/common/replica_envs.h | 6 +
src/common/replication_common.cpp | 9 ++
src/meta/app_env_validator.cpp | 58 +++++++-
src/meta/app_env_validator.h | 2 +
src/meta/server_state.cpp | 3 +
src/meta/test/meta_app_envs_test.cpp | 24 ++++
src/meta/test/meta_app_operation_test.cpp | 191 +++++++++++++++++++++------
src/server/pegasus_server_impl.cpp | 108 ++++++++++++++-
src/server/pegasus_server_impl.h | 9 ++
src/server/pegasus_server_impl_init.cpp | 47 ++++---
src/server/test/pegasus_server_impl_test.cpp | 58 ++++++++
13 files changed, 520 insertions(+), 66 deletions(-)
diff --git a/src/base/pegasus_const.cpp b/src/base/pegasus_const.cpp
index c93c0baf5..2a788cd24 100644
--- a/src/base/pegasus_const.cpp
+++ b/src/base/pegasus_const.cpp
@@ -19,6 +19,12 @@
#include "pegasus_const.h"
+#include <rocksdb/options.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "utils/string_conv.h"
+
namespace pegasus {
// should be same with items in dsn::backup_restore_constant
@@ -101,4 +107,47 @@ const std::string
USER_SPECIFIED_COMPACTION("user_specified_compaction");
const std::string READ_SIZE_THROTTLING("replica.read_throttling_by_size");
const std::string ROCKSDB_ALLOW_INGEST_BEHIND("rocksdb.allow_ingest_behind");
+
+const std::string ROCKSDB_WRITE_BUFFER_SIZE("rocksdb.write_buffer_size");
+
+const std::string ROCKSDB_NUM_LEVELS("rocksdb.num_levels");
+
+const std::set<std::string> ROCKSDB_DYNAMIC_OPTIONS = {
+ ROCKSDB_WRITE_BUFFER_SIZE,
+};
+const std::set<std::string> ROCKSDB_STATIC_OPTIONS = {
+ ROCKSDB_NUM_LEVELS,
+};
+
+const std::unordered_map<std::string, cf_opts_setter> cf_opts_setters = {
+ {ROCKSDB_WRITE_BUFFER_SIZE,
+ [](const std::string &str, rocksdb::ColumnFamilyOptions &option) -> bool {
+ uint64_t val = 0;
+ if (!dsn::buf2uint64(str, val)) {
+ return false;
+ }
+ option.write_buffer_size = static_cast<size_t>(val);
+ return true;
+ }},
+ {ROCKSDB_NUM_LEVELS,
+ [](const std::string &str, rocksdb::ColumnFamilyOptions &option) -> bool {
+ int32_t val = 0;
+ if (!dsn::buf2int32(str, val)) {
+ return false;
+ }
+ option.num_levels = val;
+ return true;
+ }},
+};
+
+const std::unordered_map<std::string, cf_opts_getter> cf_opts_getters = {
+ {ROCKSDB_WRITE_BUFFER_SIZE,
+ [](const rocksdb::ColumnFamilyOptions &option, /*out*/ std::string &str) {
+ str = std::to_string(option.write_buffer_size);
+ }},
+ {ROCKSDB_NUM_LEVELS,
+ [](const rocksdb::ColumnFamilyOptions &option, /*out*/ std::string &str) {
+ str = std::to_string(option.num_levels);
+ }},
+};
} // namespace pegasus
diff --git a/src/base/pegasus_const.h b/src/base/pegasus_const.h
index c2a47ce51..e9326dfaa 100644
--- a/src/base/pegasus_const.h
+++ b/src/base/pegasus_const.h
@@ -19,7 +19,14 @@
#pragma once
+#include <functional>
+#include <set>
#include <string>
+#include <unordered_map>
+
+namespace rocksdb {
+struct ColumnFamilyOptions;
+} // namespace rocksdb
namespace pegasus {
@@ -72,4 +79,19 @@ extern const std::string USER_SPECIFIED_COMPACTION;
extern const std::string READ_SIZE_THROTTLING;
extern const std::string ROCKSDB_ALLOW_INGEST_BEHIND;
+
+extern const std::string ROCKSDB_WRITE_BUFFER_SIZE;
+
+extern const std::string ROCKSDB_NUM_LEVELS;
+
+extern const std::set<std::string> ROCKSDB_DYNAMIC_OPTIONS;
+
+extern const std::set<std::string> ROCKSDB_STATIC_OPTIONS;
+
+using cf_opts_setter = std::function<bool(const std::string &,
rocksdb::ColumnFamilyOptions &)>;
+extern const std::unordered_map<std::string, cf_opts_setter> cf_opts_setters;
+
+using cf_opts_getter =
+ std::function<void(const rocksdb::ColumnFamilyOptions &, /*out*/
std::string &)>;
+extern const std::unordered_map<std::string, cf_opts_getter> cf_opts_getters;
} // namespace pegasus
diff --git a/src/common/replica_envs.h b/src/common/replica_envs.h
index 4db367a7f..1db2e5399 100644
--- a/src/common/replica_envs.h
+++ b/src/common/replica_envs.h
@@ -28,6 +28,7 @@
#include <cstdint>
#include <string>
+#include <set>
namespace dsn {
namespace replication {
@@ -64,6 +65,11 @@ public:
static const std::string USER_SPECIFIED_COMPACTION;
static const std::string ROCKSDB_ALLOW_INGEST_BEHIND;
static const std::string UPDATE_MAX_REPLICA_COUNT;
+ static const std::string ROCKSDB_WRITE_BUFFER_SIZE;
+ static const std::string ROCKSDB_NUM_LEVELS;
+
+ static const std::set<std::string> ROCKSDB_DYNAMIC_OPTIONS;
+ static const std::set<std::string> ROCKSDB_STATIC_OPTIONS;
};
} // namespace replication
diff --git a/src/common/replication_common.cpp
b/src/common/replication_common.cpp
index 63617797a..1afe9d49f 100644
--- a/src/common/replication_common.cpp
+++ b/src/common/replication_common.cpp
@@ -29,6 +29,7 @@
#include <algorithm>
#include <fstream>
#include <memory>
+#include <set>
#include "common/gpid.h"
#include "common/replica_envs.h"
@@ -394,6 +395,14 @@ const std::string
replica_envs::USER_SPECIFIED_COMPACTION("user_specified_compac
const std::string
replica_envs::BACKUP_REQUEST_QPS_THROTTLING("replica.backup_request_throttling");
const std::string
replica_envs::ROCKSDB_ALLOW_INGEST_BEHIND("rocksdb.allow_ingest_behind");
const std::string
replica_envs::UPDATE_MAX_REPLICA_COUNT("max_replica_count.update");
+const std::string
replica_envs::ROCKSDB_WRITE_BUFFER_SIZE("rocksdb.write_buffer_size");
+const std::string replica_envs::ROCKSDB_NUM_LEVELS("rocksdb.num_levels");
+const std::set<std::string> replica_envs::ROCKSDB_DYNAMIC_OPTIONS = {
+ replica_envs::ROCKSDB_WRITE_BUFFER_SIZE,
+};
+const std::set<std::string> replica_envs::ROCKSDB_STATIC_OPTIONS = {
+ replica_envs::ROCKSDB_NUM_LEVELS,
+};
} // namespace replication
} // namespace dsn
diff --git a/src/meta/app_env_validator.cpp b/src/meta/app_env_validator.cpp
index 41f9c299c..7f197f5a0 100644
--- a/src/meta/app_env_validator.cpp
+++ b/src/meta/app_env_validator.cpp
@@ -20,6 +20,7 @@
#include <fmt/core.h>
#include <stdint.h>
#include <memory>
+#include <set>
#include <utility>
#include <vector>
@@ -31,6 +32,26 @@
namespace dsn {
namespace replication {
+bool validate_app_envs(const std::map<std::string, std::string> &envs)
+{
+ // only check rocksdb app envs currently
+
+ for (const auto &it : envs) {
+ if (replica_envs::ROCKSDB_STATIC_OPTIONS.find(it.first) ==
+ replica_envs::ROCKSDB_STATIC_OPTIONS.end() &&
+ replica_envs::ROCKSDB_DYNAMIC_OPTIONS.find(it.first) ==
+ replica_envs::ROCKSDB_DYNAMIC_OPTIONS.end()) {
+ continue;
+ }
+ std::string hint_message;
+ if (!validate_app_env(it.first, it.second, hint_message)) {
+ LOG_WARNING(
+ "app env {}={} is invaild, hint_message:{}", it.first,
it.second, hint_message);
+ return false;
+ }
+ }
+ return true;
+}
bool validate_app_env(const std::string &env_name,
const std::string &env_value,
@@ -151,6 +172,36 @@ bool check_bool_value(const std::string &env_value,
std::string &hint_message)
return true;
}
+bool check_rocksdb_write_buffer_size(const std::string &env_value, std::string
&hint_message)
+{
+ uint64_t val = 0;
+
+ if (!dsn::buf2uint64(env_value, val)) {
+ hint_message = fmt::format("rocksdb.write_buffer_size cannot set this
val: {}", env_value);
+ return false;
+ }
+ if (val < (16 << 20) || val > (512 << 20)) {
+ hint_message =
+ fmt::format("rocksdb.write_buffer_size suggest set val in range
[16777216, 536870912]");
+ return false;
+ }
+ return true;
+}
+bool check_rocksdb_num_levels(const std::string &env_value, std::string
&hint_message)
+{
+ int32_t val = 0;
+
+ if (!dsn::buf2int32(env_value, val)) {
+ hint_message = fmt::format("rocksdb.num_levels cannot set this val:
{}", env_value);
+ return false;
+ }
+ if (val < 1 || val > 10) {
+ hint_message = fmt::format("rocksdb.num_levels suggest set val in
range [1 , 10]");
+ return false;
+ }
+ return true;
+}
+
bool app_env_validator::validate_app_env(const std::string &env_name,
const std::string &env_value,
std::string &hint_message)
@@ -198,6 +249,10 @@ void app_env_validator::register_all_validators()
std::bind(&check_bool_value, std::placeholders::_1,
std::placeholders::_2)},
{replica_envs::DENY_CLIENT_REQUEST,
std::bind(&check_deny_client, std::placeholders::_1,
std::placeholders::_2)},
+ {replica_envs::ROCKSDB_WRITE_BUFFER_SIZE,
+ std::bind(&check_rocksdb_write_buffer_size, std::placeholders::_1,
std::placeholders::_2)},
+ {replica_envs::ROCKSDB_NUM_LEVELS,
+ std::bind(&check_rocksdb_num_levels, std::placeholders::_1,
std::placeholders::_2)},
// TODO(zhaoliwei): not implemented
{replica_envs::BUSINESS_INFO, nullptr},
{replica_envs::TABLE_LEVEL_DEFAULT_TTL, nullptr},
@@ -213,7 +268,8 @@ void app_env_validator::register_all_validators()
{replica_envs::MANUAL_COMPACT_PERIODIC_TARGET_LEVEL, nullptr},
{replica_envs::MANUAL_COMPACT_PERIODIC_BOTTOMMOST_LEVEL_COMPACTION,
nullptr},
{replica_envs::REPLICA_ACCESS_CONTROLLER_ALLOWED_USERS, nullptr},
- {replica_envs::REPLICA_ACCESS_CONTROLLER_RANGER_POLICIES, nullptr}};
+ {replica_envs::REPLICA_ACCESS_CONTROLLER_RANGER_POLICIES, nullptr},
+ };
}
} // namespace replication
diff --git a/src/meta/app_env_validator.h b/src/meta/app_env_validator.h
index c401c3959..d963df051 100644
--- a/src/meta/app_env_validator.h
+++ b/src/meta/app_env_validator.h
@@ -25,6 +25,8 @@
namespace dsn {
namespace replication {
+bool validate_app_envs(const std::map<std::string, std::string> &envs);
+
bool validate_app_env(const std::string &env_name,
const std::string &env_value,
std::string &hint_message);
diff --git a/src/meta/server_state.cpp b/src/meta/server_state.cpp
index ecf66a92b..2b6c6d910 100644
--- a/src/meta/server_state.cpp
+++ b/src/meta/server_state.cpp
@@ -1151,6 +1151,9 @@ void server_state::create_app(dsn::message_ex *msg)
!validate_target_max_replica_count(request.options.replica_count)) {
response.err = ERR_INVALID_PARAMETERS;
will_create_app = false;
+ } else if (!validate_app_envs(request.options.envs)) {
+ response.err = ERR_INVALID_PARAMETERS;
+ will_create_app = false;
} else {
zauto_write_lock l(_lock);
app = get_app(request.app_name);
diff --git a/src/meta/test/meta_app_envs_test.cpp
b/src/meta/test/meta_app_envs_test.cpp
index 255930320..d5dc21eda 100644
--- a/src/meta/test/meta_app_envs_test.cpp
+++ b/src/meta/test/meta_app_envs_test.cpp
@@ -29,6 +29,7 @@
#include <gtest/gtest.h>
#include <map>
#include <memory>
+#include <set>
#include <string>
#include "common/replica_envs.h"
@@ -142,6 +143,17 @@ TEST_F(meta_app_envs_test, update_app_envs_test)
{replica_envs::MANUAL_COMPACT_ONCE_TARGET_LEVEL, "80", ERR_OK, "",
"80"},
{replica_envs::MANUAL_COMPACT_PERIODIC_TRIGGER_TIME, "90", ERR_OK, "",
"90"},
{replica_envs::MANUAL_COMPACT_PERIODIC_TARGET_LEVEL, "100", ERR_OK,
"", "100"},
+ {replica_envs::ROCKSDB_WRITE_BUFFER_SIZE,
+ "100",
+ ERR_INVALID_PARAMETERS,
+ "rocksdb.write_buffer_size suggest set val in range [16777216,
536870912]",
+ "67108864"},
+ {replica_envs::ROCKSDB_WRITE_BUFFER_SIZE,
+ "636870912",
+ ERR_INVALID_PARAMETERS,
+ "rocksdb.write_buffer_size suggest set val in range [16777216,
536870912]",
+ "536870912"},
+ {replica_envs::ROCKSDB_WRITE_BUFFER_SIZE, "67108864", ERR_OK, "",
"67108864"},
{replica_envs::MANUAL_COMPACT_PERIODIC_BOTTOMMOST_LEVEL_COMPACTION,
"200",
ERR_OK,
@@ -192,6 +204,18 @@ TEST_F(meta_app_envs_test, update_app_envs_test)
ASSERT_EQ(app->envs.at(test.env_key), test.expect_value);
}
}
+
+ {
+ // Make sure all rocksdb options of ROCKSDB_DYNAMIC_OPTIONS are tested.
+ // Hint: Mainly verify the update_rocksdb_dynamic_options function.
+ std::map<std::string, std::string> all_test_envs;
+ for (const auto &test : tests) {
+ all_test_envs[test.env_key] = test.env_value;
+ }
+ for (const auto &option : replica_envs::ROCKSDB_DYNAMIC_OPTIONS) {
+ ASSERT_TRUE(all_test_envs.find(option) != all_test_envs.end());
+ }
+ }
}
} // namespace replication
diff --git a/src/meta/test/meta_app_operation_test.cpp
b/src/meta/test/meta_app_operation_test.cpp
index c3ddafa72..e0afc1baa 100644
--- a/src/meta/test/meta_app_operation_test.cpp
+++ b/src/meta/test/meta_app_operation_test.cpp
@@ -24,6 +24,7 @@
#include <iostream>
#include <map>
#include <memory>
+#include <set>
#include <string>
#include <utility>
#include <vector>
@@ -68,7 +69,8 @@ public:
error_code create_app_test(int32_t partition_count,
int32_t replica_count,
bool success_if_exist,
- const std::string &app_name)
+ const std::string &app_name,
+ const std::map<std::string, std::string> &envs
= {})
{
configuration_create_app_request create_request;
configuration_create_app_response create_response;
@@ -78,6 +80,7 @@ public:
create_request.options.replica_count = replica_count;
create_request.options.success_if_exist = success_if_exist;
create_request.options.is_stateful = true;
+ create_request.options.envs = envs;
auto result = fake_create_app(_ss.get(), create_request);
fake_wait_rpc(result, create_response);
@@ -362,6 +365,14 @@ TEST_F(meta_app_operation_test, create_app)
// - wrong app_status dropping
// - create succeed with app_status dropped
// - create succeed with success_if_exist=true
+ // - wrong rocksdb.num_levels (< 1)
+ // - wrong rocksdb.num_levels (> 10)
+ // - wrong rocksdb.num_levels (non-digital character)
+ // - create app with rocksdb.num_levels (= 5) succeed
+ // - wrong rocksdb.write_buffer_size (< (16<<20))
+ // - wrong rocksdb.write_buffer_size (> (512<<20))
+ // - wrong rocksdb.write_buffer_size (non-digital character)
+ // - create app with rocksdb.write_buffer_size (= (32<<20)) succeed
struct create_test
{
std::string app_name;
@@ -373,43 +384,126 @@ TEST_F(meta_app_operation_test, create_app)
bool success_if_exist;
app_status::type before_status;
error_code expected_err;
- } tests[] = {{APP_NAME, -1, 3, 2, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 0, 3, 2, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, -1, 1, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 0, 1, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 6, 2, 4, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 7, 2, 6, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 6, 2, 5, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 5, 2, 4, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 4, 2, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 6, 2, 6, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 6, 2, 7, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME + "_1", 4, 5, 2, 5, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME + "_2", 4, 5, 2, 6, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME + "_3", 4, 4, 2, 4, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME + "_4", 4, 4, 2, 6, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME + "_5", 4, 3, 2, 4, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME + "_6", 4, 4, 2, 5, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME, 4, 3, 2, 5, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 3, 2, 4, 5, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 3, 2, 4, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 3, 2, 2, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 3, 2, 3, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME, 4, 4, 2, 3, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
- {APP_NAME + "_7", 4, 3, 2, 4, 3, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME, 4, 1, 1, 0, 1, false, app_status::AS_INVALID,
ERR_STATE_FREEZED},
- {APP_NAME, 4, 2, 2, 1, 1, false, app_status::AS_INVALID,
ERR_STATE_FREEZED},
- {APP_NAME, 4, 3, 3, 2, 1, false, app_status::AS_INVALID,
ERR_STATE_FREEZED},
- {APP_NAME + "_8", 4, 3, 3, 3, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME + "_9", 4, 1, 1, 1, 1, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME + "_10", 4, 2, 1, 2, 2, false,
app_status::AS_INVALID, ERR_OK},
- {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_INVALID,
ERR_OK},
- {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_INVALID,
ERR_APP_EXIST},
- {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_CREATING,
ERR_BUSY_CREATING},
- {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_RECALLING,
ERR_BUSY_CREATING},
- {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_DROPPING,
ERR_BUSY_DROPPING},
- {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_DROPPED,
ERR_OK},
- {APP_NAME, 4, 3, 2, 3, 3, true, app_status::AS_INVALID,
ERR_OK}};
+ std::map<std::string, std::string> envs = {};
+ } tests[] = {
+ {APP_NAME, -1, 3, 2, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 0, 3, 2, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, -1, 1, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 0, 1, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 6, 2, 4, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 7, 2, 6, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 6, 2, 5, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 5, 2, 4, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 4, 2, 3, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 6, 2, 6, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 6, 2, 7, 1, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME + "_1", 4, 5, 2, 5, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME + "_2", 4, 5, 2, 6, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME + "_3", 4, 4, 2, 4, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME + "_4", 4, 4, 2, 6, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME + "_5", 4, 3, 2, 4, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME + "_6", 4, 4, 2, 5, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME, 4, 3, 2, 5, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 3, 2, 4, 5, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 3, 2, 4, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 3, 2, 2, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 3, 2, 3, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME, 4, 4, 2, 3, 4, false, app_status::AS_INVALID,
ERR_INVALID_PARAMETERS},
+ {APP_NAME + "_7", 4, 3, 2, 4, 3, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME, 4, 1, 1, 0, 1, false, app_status::AS_INVALID,
ERR_STATE_FREEZED},
+ {APP_NAME, 4, 2, 2, 1, 1, false, app_status::AS_INVALID,
ERR_STATE_FREEZED},
+ {APP_NAME, 4, 3, 3, 2, 1, false, app_status::AS_INVALID,
ERR_STATE_FREEZED},
+ {APP_NAME + "_8", 4, 3, 3, 3, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME + "_9", 4, 1, 1, 1, 1, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME + "_10", 4, 2, 1, 2, 2, false, app_status::AS_INVALID,
ERR_OK},
+ {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_INVALID, ERR_OK},
+ {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_INVALID,
ERR_APP_EXIST},
+ {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_CREATING,
ERR_BUSY_CREATING},
+ {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_RECALLING,
ERR_BUSY_CREATING},
+ {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_DROPPING,
ERR_BUSY_DROPPING},
+ {APP_NAME, 4, 3, 2, 3, 3, false, app_status::AS_DROPPED, ERR_OK},
+ {APP_NAME, 4, 3, 2, 3, 3, true, app_status::AS_INVALID, ERR_OK},
+ {APP_NAME,
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_INVALID_PARAMETERS,
+ {{"rocksdb.num_levels", "0"}}},
+ {APP_NAME,
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_INVALID_PARAMETERS,
+ {{"rocksdb.num_levels", "11"}}},
+ {APP_NAME + "_11",
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_INVALID_PARAMETERS,
+ {{"rocksdb.num_levels", "5i"}}},
+ {APP_NAME + "_11",
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_OK,
+ {{"rocksdb.num_levels", "5"}}},
+ {APP_NAME,
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_INVALID_PARAMETERS,
+ {{"rocksdb.write_buffer_size", "1000"}}},
+ {APP_NAME,
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_INVALID_PARAMETERS,
+ {{"rocksdb.write_buffer_size", "1073741824"}}},
+ {APP_NAME,
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_INVALID_PARAMETERS,
+ {{"rocksdb.write_buffer_size", "n33554432"}}},
+ {APP_NAME + "_12",
+ 4,
+ 3,
+ 2,
+ 3,
+ 3,
+ false,
+ app_status::AS_INVALID,
+ ERR_OK,
+ {{"rocksdb.write_buffer_size", "33554432"}}},
+ };
clear_nodes();
@@ -453,13 +547,30 @@ TEST_F(meta_app_operation_test, create_app)
} else if (test.before_status != app_status::AS_INVALID) {
update_app_status(test.before_status);
}
- auto err = create_app_test(
- test.partition_count, test.replica_count, test.success_if_exist,
test.app_name);
+ auto err = create_app_test(test.partition_count,
+ test.replica_count,
+ test.success_if_exist,
+ test.app_name,
+ test.envs);
ASSERT_EQ(err, test.expected_err);
_ms->set_node_state(nodes, true);
}
+ {
+ // Make sure all rocksdb options of ROCKSDB_DYNAMIC_OPTIONS and
ROCKSDB_STATIC_OPTIONS are
+ // tested. Hint: Mainly verify the validate_app_envs function.
+ std::map<std::string, std::string> all_test_envs;
+ for (const auto &test : tests) {
+ all_test_envs.insert(test.envs.begin(), test.envs.end());
+ }
+ for (const auto &option : replica_envs::ROCKSDB_DYNAMIC_OPTIONS) {
+ ASSERT_TRUE(all_test_envs.find(option) != all_test_envs.end());
+ }
+ for (const auto &option : replica_envs::ROCKSDB_STATIC_OPTIONS) {
+ ASSERT_TRUE(all_test_envs.find(option) != all_test_envs.end());
+ }
+ }
// set FLAGS_min_allowed_replica_count successfully
res = update_flag("min_allowed_replica_count", "2");
ASSERT_TRUE(res.is_ok());
diff --git a/src/server/pegasus_server_impl.cpp
b/src/server/pegasus_server_impl.cpp
index e6e9d48ed..998b4873f 100644
--- a/src/server/pegasus_server_impl.cpp
+++ b/src/server/pegasus_server_impl.cpp
@@ -38,10 +38,12 @@
#include <unistd.h> // IWYU pragma: keep
#include <algorithm>
#include <cstdint>
+#include <functional>
#include <limits>
#include <list>
#include <mutex>
#include <ostream>
+#include <set>
#include "base/pegasus_key_schema.h"
#include "base/pegasus_utils.h"
@@ -1663,7 +1665,7 @@ dsn::error_code pegasus_server_impl::start(int argc, char
**argv)
// We don't use `loaded_data_cf_opts` directly because
pointer-typed options will
// only be initialized with default values when calling
'LoadLatestOptions', see
// 'rocksdb/utilities/options_util.h'.
- reset_usage_scenario_options(loaded_data_cf_opts,
&_table_data_cf_opts);
+ reset_rocksdb_options(loaded_data_cf_opts, &_table_data_cf_opts);
_db_opts.allow_ingest_behind = parse_allow_ingest_behind(envs);
}
} else {
@@ -2625,6 +2627,67 @@ pegasus_server_impl::get_restore_dir_from_env(const
std::map<std::string, std::s
return res;
}
+void pegasus_server_impl::update_rocksdb_dynamic_options(
+ const std::map<std::string, std::string> &envs)
+{
+ if (envs.empty()) {
+ return;
+ }
+
+ std::unordered_map<std::string, std::string> new_options;
+ for (const auto &option : ROCKSDB_DYNAMIC_OPTIONS) {
+ const auto &find = envs.find(option);
+ if (find == envs.end()) {
+ continue;
+ }
+
+ std::vector<std::string> args;
+ // split_args example: Parse "write_buffer_size" from
"rocksdb.write_buffer_size"
+ dsn::utils::split_args(option.c_str(), args, '.');
+ CHECK_EQ(args.size(), 2);
+ new_options[args[1]] = find->second;
+ }
+
+ // doing set option
+ if (!new_options.empty() && set_options(new_options)) {
+ LOG_INFO("Set rocksdb dynamic options success");
+ }
+}
+
+void pegasus_server_impl::set_rocksdb_options_before_creating(
+ const std::map<std::string, std::string> &envs)
+{
+ if (envs.empty()) {
+ return;
+ }
+
+ for (const auto &option : pegasus::ROCKSDB_STATIC_OPTIONS) {
+ const auto &find = envs.find(option);
+ if (find == envs.end()) {
+ continue;
+ }
+
+ const auto &setter = cf_opts_setters.find(option);
+ CHECK_TRUE(setter != cf_opts_setters.end());
+ if (setter->second(find->second, _data_cf_opts)) {
+ LOG_INFO_PREFIX("Set {} \"{}\" succeed", find->first,
find->second);
+ }
+ }
+
+ for (const auto &option : pegasus::ROCKSDB_DYNAMIC_OPTIONS) {
+ const auto &find = envs.find(option);
+ if (find == envs.end()) {
+ continue;
+ }
+
+ const auto &setter = cf_opts_setters.find(option);
+ CHECK_TRUE(setter != cf_opts_setters.end());
+ if (setter->second(find->second, _data_cf_opts)) {
+ LOG_INFO_PREFIX("Set {} \"{}\" succeed", find->first,
find->second);
+ }
+ }
+}
+
void pegasus_server_impl::update_app_envs(const std::map<std::string,
std::string> &envs)
{
update_usage_scenario(envs);
@@ -2637,6 +2700,7 @@ void pegasus_server_impl::update_app_envs(const
std::map<std::string, std::strin
_manual_compact_svc.start_manual_compact_if_needed(envs);
update_throttling_controller(envs);
+ update_rocksdb_dynamic_options(envs);
}
void pegasus_server_impl::update_app_envs_before_open_db(
@@ -2650,11 +2714,36 @@ void
pegasus_server_impl::update_app_envs_before_open_db(
update_validate_partition_hash(envs);
update_user_specified_compaction(envs);
_manual_compact_svc.start_manual_compact_if_needed(envs);
+ set_rocksdb_options_before_creating(envs);
}
void pegasus_server_impl::query_app_envs(/*out*/ std::map<std::string,
std::string> &envs)
{
envs[ROCKSDB_ENV_USAGE_SCENARIO_KEY] = _usage_scenario;
+ // write_buffer_size involves random values (refer to
pegasus_server_impl::set_usage_scenario),
+ // so it can only be taken from _data_cf_opts
+ envs[ROCKSDB_WRITE_BUFFER_SIZE] =
std::to_string(_data_cf_opts.write_buffer_size);
+
+ // Get Data ColumnFamilyOptions directly from _data_cf
+ rocksdb::ColumnFamilyDescriptor desc;
+ CHECK_TRUE(_data_cf->GetDescriptor(&desc).ok());
+ for (const auto &option : pegasus::ROCKSDB_STATIC_OPTIONS) {
+ auto getter = cf_opts_getters.find(option);
+ CHECK_TRUE(getter != cf_opts_getters.end());
+ std::string option_val;
+ getter->second(desc.options, option_val);
+ envs[option] = option_val;
+ }
+ for (const auto &option : pegasus::ROCKSDB_DYNAMIC_OPTIONS) {
+ if (option.compare(ROCKSDB_WRITE_BUFFER_SIZE) == 0) {
+ continue;
+ }
+ auto getter = cf_opts_getters.find(option);
+ CHECK_TRUE(getter != cf_opts_getters.end());
+ std::string option_val;
+ getter->second(desc.options, option_val);
+ envs[option] = option_val;
+ }
}
void pegasus_server_impl::update_usage_scenario(const std::map<std::string,
std::string> &envs)
@@ -3038,6 +3127,23 @@ bool pegasus_server_impl::set_usage_scenario(const
std::string &usage_scenario)
}
}
+void pegasus_server_impl::reset_rocksdb_options(const
rocksdb::ColumnFamilyOptions &base_opts,
+ rocksdb::ColumnFamilyOptions
*target_opts)
+{
+ LOG_INFO_PREFIX("Reset rocksdb envs options");
+ // Reset rocksdb option includes two aspects:
+ // 1. Set usage_scenario related rocksdb options
+ // 2. Rocksdb option set in app envs, consists of ROCKSDB_DYNAMIC_OPTIONS
and
+ // ROCKSDB_STATIC_OPTIONS
+
+ // aspect 1:
+ reset_usage_scenario_options(base_opts, target_opts);
+
+ // aspect 2:
+ target_opts->num_levels = base_opts.num_levels;
+ target_opts->write_buffer_size = base_opts.write_buffer_size;
+}
+
void pegasus_server_impl::reset_usage_scenario_options(
const rocksdb::ColumnFamilyOptions &base_opts,
rocksdb::ColumnFamilyOptions *target_opts)
{
diff --git a/src/server/pegasus_server_impl.h b/src/server/pegasus_server_impl.h
index d156acdce..c9c5b90ef 100644
--- a/src/server/pegasus_server_impl.h
+++ b/src/server/pegasus_server_impl.h
@@ -22,6 +22,7 @@
#include <gtest/gtest_prod.h>
#include <rocksdb/options.h>
#include <rocksdb/slice.h>
+#include <rocksdb/table.h>
#include <rrdb/rrdb_types.h>
#include <stdint.h>
#include <atomic>
@@ -328,6 +329,10 @@ private:
void update_user_specified_compaction(const std::map<std::string,
std::string> &envs);
+ void update_rocksdb_dynamic_options(const std::map<std::string,
std::string> &envs);
+
+ void set_rocksdb_options_before_creating(const std::map<std::string,
std::string> &envs);
+
void update_throttling_controller(const std::map<std::string, std::string>
&envs);
bool parse_allow_ingest_behind(const std::map<std::string, std::string>
&envs);
@@ -359,6 +364,9 @@ private:
void reset_usage_scenario_options(const rocksdb::ColumnFamilyOptions
&base_opts,
rocksdb::ColumnFamilyOptions
*target_opts);
+ void reset_rocksdb_options(const rocksdb::ColumnFamilyOptions &base_opts,
+ rocksdb::ColumnFamilyOptions *target_opts);
+
// return true if successfully set
bool set_options(const std::unordered_map<std::string, std::string>
&new_options);
@@ -468,6 +476,7 @@ private:
// Dynamically calculate the value of current data_cf option according to
the conf module file
// and usage scenario
rocksdb::ColumnFamilyOptions _table_data_cf_opts;
+ rocksdb::BlockBasedTableOptions _tbl_opts;
rocksdb::ColumnFamilyOptions _meta_cf_opts;
rocksdb::ReadOptions _data_cf_rd_opts;
std::string _usage_scenario;
diff --git a/src/server/pegasus_server_impl_init.cpp
b/src/server/pegasus_server_impl_init.cpp
index 896f8ab94..c457ebd9f 100644
--- a/src/server/pegasus_server_impl_init.cpp
+++ b/src/server/pegasus_server_impl_init.cpp
@@ -137,7 +137,7 @@ DSN_DEFINE_bool(pegasus.server,
DSN_DEFINE_bool(pegasus.server,
rocksdb_disable_table_block_cache,
false,
- "rocksdb tbl_opts.no_block_cache");
+ "rocksdb _tbl_opts.no_block_cache");
DSN_DEFINE_bool(pegasus.server,
rocksdb_enable_write_buffer_manager,
false,
@@ -466,12 +466,11 @@
pegasus_server_impl::pegasus_server_impl(dsn::replication::replica *r)
CHECK(parse_compression_types("none", _meta_cf_opts.compression_per_level),
"parse rocksdb_compression_type failed.");
- rocksdb::BlockBasedTableOptions tbl_opts;
- tbl_opts.read_amp_bytes_per_bit = FLAGS_read_amp_bytes_per_bit;
+ _tbl_opts.read_amp_bytes_per_bit = FLAGS_read_amp_bytes_per_bit;
if (FLAGS_rocksdb_disable_table_block_cache) {
- tbl_opts.no_block_cache = true;
- tbl_opts.block_restart_interval = 4;
+ _tbl_opts.no_block_cache = true;
+ _tbl_opts.block_restart_interval = 4;
} else {
// If block cache is enabled, all replicas on this server will share
the same block cache
// object. It's convenient to control the total memory used by this
server, and the LRU
@@ -484,7 +483,7 @@
pegasus_server_impl::pegasus_server_impl(dsn::replication::replica *r)
});
// every replica has the same block cache
- tbl_opts.block_cache = _s_block_cache;
+ _tbl_opts.block_cache = _s_block_cache;
}
// FLAGS_rocksdb_limiter_max_write_megabytes_per_sec <= 0 means close the
rate limit.
@@ -520,7 +519,7 @@
pegasus_server_impl::pegasus_server_impl(dsn::replication::replica *r)
FLAGS_rocksdb_total_size_across_write_buffer);
_s_write_buffer_manager =
std::make_shared<rocksdb::WriteBufferManager>(
static_cast<size_t>(FLAGS_rocksdb_total_size_across_write_buffer),
- tbl_opts.block_cache);
+ _tbl_opts.block_cache);
});
_db_opts.write_buffer_manager = _s_write_buffer_manager;
}
@@ -541,33 +540,33 @@
pegasus_server_impl::pegasus_server_impl(dsn::replication::replica *r)
CHECK(index_type_item != INDEX_TYPE_STRING_MAP.end(),
"[pegasus.server]rocksdb_index_type should be one among
binary_search, "
"hash_search, two_level_index_search or
binary_search_with_first_key.");
- tbl_opts.index_type = index_type_item->second;
+ _tbl_opts.index_type = index_type_item->second;
LOG_INFO_PREFIX("rocksdb_index_type = {}", FLAGS_rocksdb_index_type);
- tbl_opts.partition_filters = FLAGS_rocksdb_partition_filters;
+ _tbl_opts.partition_filters = FLAGS_rocksdb_partition_filters;
// TODO(yingchun): clean up these useless log ?
- LOG_INFO_PREFIX("rocksdb_partition_filters = {}",
tbl_opts.partition_filters);
+ LOG_INFO_PREFIX("rocksdb_partition_filters = {}",
_tbl_opts.partition_filters);
- tbl_opts.metadata_block_size = FLAGS_rocksdb_metadata_block_size;
- LOG_INFO_PREFIX("rocksdb_metadata_block_size = {}",
tbl_opts.metadata_block_size);
+ _tbl_opts.metadata_block_size = FLAGS_rocksdb_metadata_block_size;
+ LOG_INFO_PREFIX("rocksdb_metadata_block_size = {}",
_tbl_opts.metadata_block_size);
- tbl_opts.cache_index_and_filter_blocks =
FLAGS_rocksdb_cache_index_and_filter_blocks;
+ _tbl_opts.cache_index_and_filter_blocks =
FLAGS_rocksdb_cache_index_and_filter_blocks;
LOG_INFO_PREFIX("rocksdb_cache_index_and_filter_blocks = {}",
- tbl_opts.cache_index_and_filter_blocks);
+ _tbl_opts.cache_index_and_filter_blocks);
- tbl_opts.pin_top_level_index_and_filter =
FLAGS_rocksdb_pin_top_level_index_and_filter;
+ _tbl_opts.pin_top_level_index_and_filter =
FLAGS_rocksdb_pin_top_level_index_and_filter;
LOG_INFO_PREFIX("rocksdb_pin_top_level_index_and_filter = {}",
- tbl_opts.pin_top_level_index_and_filter);
+ _tbl_opts.pin_top_level_index_and_filter);
- tbl_opts.cache_index_and_filter_blocks_with_high_priority =
+ _tbl_opts.cache_index_and_filter_blocks_with_high_priority =
FLAGS_rocksdb_cache_index_and_filter_blocks_with_high_priority;
LOG_INFO_PREFIX("rocksdb_cache_index_and_filter_blocks_with_high_priority
= {}",
- tbl_opts.cache_index_and_filter_blocks_with_high_priority);
+
_tbl_opts.cache_index_and_filter_blocks_with_high_priority);
- tbl_opts.pin_l0_filter_and_index_blocks_in_cache =
+ _tbl_opts.pin_l0_filter_and_index_blocks_in_cache =
FLAGS_rocksdb_pin_l0_filter_and_index_blocks_in_cache;
LOG_INFO_PREFIX("rocksdb_pin_l0_filter_and_index_blocks_in_cache = {}",
- tbl_opts.pin_l0_filter_and_index_blocks_in_cache);
+ _tbl_opts.pin_l0_filter_and_index_blocks_in_cache);
// Bloom filter configurations.
if (!FLAGS_rocksdb_disable_bloom_filter) {
@@ -584,8 +583,8 @@
pegasus_server_impl::pegasus_server_impl(dsn::replication::replica *r)
// 50 | 0.225453 |
~0.00003
// Recommend using no more than three decimal digits after the decimal
point, as in 6.667.
// More details:
https://github.com/facebook/rocksdb/wiki/RocksDB-Bloom-Filter
- tbl_opts.format_version = FLAGS_rocksdb_format_version;
- tbl_opts.filter_policy.reset(
+ _tbl_opts.format_version = FLAGS_rocksdb_format_version;
+ _tbl_opts.filter_policy.reset(
rocksdb::NewBloomFilterPolicy(FLAGS_rocksdb_bloom_filter_bits_per_key, false));
if (dsn::utils::equals(FLAGS_rocksdb_filter_type, "prefix")) {
@@ -596,8 +595,8 @@
pegasus_server_impl::pegasus_server_impl(dsn::replication::replica *r)
}
}
- _data_cf_opts.table_factory.reset(NewBlockBasedTableFactory(tbl_opts));
- _meta_cf_opts.table_factory.reset(NewBlockBasedTableFactory(tbl_opts));
+ _data_cf_opts.table_factory.reset(NewBlockBasedTableFactory(_tbl_opts));
+ _meta_cf_opts.table_factory.reset(NewBlockBasedTableFactory(_tbl_opts));
_key_ttl_compaction_filter_factory =
std::make_shared<KeyWithTTLCompactionFilterFactory>();
_data_cf_opts.compaction_filter_factory =
_key_ttl_compaction_filter_factory;
diff --git a/src/server/test/pegasus_server_impl_test.cpp
b/src/server/test/pegasus_server_impl_test.cpp
index 1363d8054..9776571ae 100644
--- a/src/server/test/pegasus_server_impl_test.cpp
+++ b/src/server/test/pegasus_server_impl_test.cpp
@@ -29,7 +29,9 @@
#include <stdint.h>
#include <map>
#include <memory>
+#include <set>
#include <string>
+#include <utility>
#include "pegasus_const.h"
#include "pegasus_server_test_base.h"
@@ -95,6 +97,50 @@ public:
ASSERT_EQ(before_count + test.expect_perf_counter_incr,
after_count);
}
}
+
+ void test_open_db_with_rocksdb_envs(bool is_restart)
+ {
+ struct create_test
+ {
+ std::string env_key;
+ std::string env_value;
+ std::string expect_value;
+ } tests[] = {
+ {"rocksdb.num_levels", "5", "5"}, {"rocksdb.write_buffer_size",
"33554432", "33554432"},
+ };
+
+ std::map<std::string, std::string> all_test_envs;
+ {
+ // Make sure all rocksdb options of ROCKSDB_DYNAMIC_OPTIONS and
ROCKSDB_STATIC_OPTIONS
+ // are tested.
+ for (const auto &test : tests) {
+ all_test_envs[test.env_key] = test.env_value;
+ }
+ for (const auto &option : pegasus::ROCKSDB_DYNAMIC_OPTIONS) {
+ ASSERT_TRUE(all_test_envs.find(option) != all_test_envs.end());
+ }
+ for (const auto &option : pegasus::ROCKSDB_STATIC_OPTIONS) {
+ ASSERT_TRUE(all_test_envs.find(option) != all_test_envs.end());
+ }
+ }
+
+ start(all_test_envs);
+ if (is_restart) {
+ _server->stop(false);
+ start();
+ }
+
+ std::map<std::string, std::string> query_envs;
+ _server->query_app_envs(query_envs);
+ for (const auto &test : tests) {
+ const auto &iter = query_envs.find(test.env_key);
+ if (iter != query_envs.end()) {
+ ASSERT_EQ(iter->second, test.expect_value);
+ } else {
+ ASSERT_TRUE(false) << fmt::format("query_app_envs not
supported {}", test.env_key);
+ }
+ }
+ }
};
TEST_F(pegasus_server_impl_test, test_table_level_slow_query)
@@ -137,6 +183,18 @@ TEST_F(pegasus_server_impl_test,
test_open_db_with_app_envs)
ASSERT_EQ(ROCKSDB_ENV_USAGE_SCENARIO_BULK_LOAD, _server->_usage_scenario);
}
+TEST_F(pegasus_server_impl_test, test_open_db_with_rocksdb_envs)
+{
+ // Hint: Verify the set_rocksdb_options_before_creating function by
boolean is_restart=false.
+ test_open_db_with_rocksdb_envs(false);
+}
+
+TEST_F(pegasus_server_impl_test, test_restart_db_with_rocksdb_envs)
+{
+ // Hint: Verify the reset_rocksdb_options function by boolean
is_restart=true.
+ test_open_db_with_rocksdb_envs(true);
+}
+
TEST_F(pegasus_server_impl_test, test_stop_db_twice)
{
start();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]