[OBKV][CP] patch config _obkv_feature_mode from 32x
This commit is contained in:
@ -30,6 +30,7 @@
|
||||
#include "ob_table_session_pool.h"
|
||||
#include "storage/tx/wrs/ob_weak_read_util.h"
|
||||
#include "ob_table_move_response.h"
|
||||
#include "share/table/ob_table_config_util.h"
|
||||
|
||||
using namespace oceanbase::observer;
|
||||
using namespace oceanbase::common;
|
||||
@ -997,7 +998,7 @@ bool oceanbase::observer::is_require_rerouting_err(const int err)
|
||||
{
|
||||
// rerouting: whether client should refresh location cache and retry
|
||||
// Now, following the same logic as in ../mysql/ob_query_retry_ctrl.cpp
|
||||
return (is_master_changed_error(err)
|
||||
bool is_err = is_master_changed_error(err)
|
||||
|| is_server_down_error(err)
|
||||
|| is_partition_change_error(err)
|
||||
|| is_server_status_error(err)
|
||||
@ -1005,5 +1006,7 @@ bool oceanbase::observer::is_require_rerouting_err(const int err)
|
||||
|| is_transaction_rpc_timeout_err(err)
|
||||
|| is_has_no_readable_replica_err(err)
|
||||
|| is_select_dup_follow_replic_err(err)
|
||||
|| is_trans_stmt_need_retry_error(err));
|
||||
|| is_trans_stmt_need_retry_error(err);
|
||||
|
||||
return is_err && ObKVFeatureModeUitl::is_rerouting_enable();
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "storage/tx_storage/ob_tenant_freezer.h"
|
||||
#include "observer/table/ttl/ob_table_ttl_task.h"
|
||||
#include "observer/table/ob_table_service.h"
|
||||
#include "share/table/ob_table_config_util.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -395,6 +396,10 @@ int ObTenantTabletTTLMgr::report_task_status(ObTTLTaskInfo& task_info, ObTTLTask
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("the tablet task ctx is null", KR(ret));
|
||||
} else {
|
||||
if (!ObKVFeatureModeUitl::is_ttl_enable()) {
|
||||
local_tenant_task_.ttl_continue_ = false;
|
||||
LOG_DEBUG("local_tenant_task mark continue is false");
|
||||
}
|
||||
// lock task ctx for update
|
||||
common::ObSpinLockGuard ctx_guard(ctx->lock_);
|
||||
ctx->last_modify_time_ = ObTimeUtility::current_time();
|
||||
@ -603,7 +608,10 @@ void OBTTLTimerPeriodicTask::runTimerTask()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCurTraceId::init(GCONF.self_addr_);
|
||||
if (common::ObTTLUtil::check_can_do_work()) {
|
||||
if (!ObKVFeatureModeUitl::is_ttl_enable()) {
|
||||
// do nothing
|
||||
LOG_DEBUG("ttl is disable");
|
||||
} else if (common::ObTTLUtil::check_can_do_work()) {
|
||||
if (OB_FAIL(tablet_ttl_mgr_.check_tenant_memory())) {
|
||||
LOG_WARN("fail to check all tenant memory", KR(ret));
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "share/ob_max_id_fetcher.h"
|
||||
#include "share/table/ob_ttl_util.h"
|
||||
#include "lib/oblog/ob_log_module.h"
|
||||
#include "share/table/ob_table_config_util.h"
|
||||
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::common;
|
||||
@ -30,7 +31,10 @@ void ObClearTTLHistoryTask::runTimerTask()
|
||||
{
|
||||
ObCurTraceId::init(GCONF.self_addr_);
|
||||
int ret = OB_SUCCESS;
|
||||
if (IS_NOT_INIT) {
|
||||
if (!ObKVFeatureModeUitl::is_ttl_enable()) {
|
||||
// do nothing
|
||||
LOG_DEBUG("ttl is disable");
|
||||
} else if (IS_NOT_INIT) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("ob clear ttl history task is not init", KR(ret));
|
||||
} else if (ObTTLUtil::check_can_do_work()) {
|
||||
@ -581,7 +585,10 @@ void ObTTLTaskScheduler::runTimerTask()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCurTraceId::init(GCONF.self_addr_);
|
||||
if (IS_NOT_INIT) {
|
||||
if (!ObKVFeatureModeUitl::is_ttl_enable()) {
|
||||
// do nothing
|
||||
LOG_DEBUG("ttl is disable");
|
||||
} else if (IS_NOT_INIT) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("ttl task mgr not init", KR(ret));
|
||||
} else if (OB_FAIL(reload_tenant_task())) {
|
||||
|
||||
@ -261,6 +261,7 @@ ob_set_subtarget(ob_share common_mixed
|
||||
detect/ob_detect_manager_utils.cpp
|
||||
table/ob_table_load_sql_statistics.cpp
|
||||
table/ob_ttl_util.cpp
|
||||
table/ob_table_config_util.cpp
|
||||
)
|
||||
|
||||
ob_set_subtarget(ob_share tablet
|
||||
|
||||
@ -1110,6 +1110,43 @@ int ObConfigLogArchiveOptionsItem::format_option_str(const char *src, int64_t sr
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
ObConfigModeItem::ObConfigModeItem(ObConfigContainer *container,
|
||||
Scope::ScopeInfo scope_info,
|
||||
const char *name,
|
||||
const char *def,
|
||||
ObConfigParser* parser,
|
||||
const char *info,
|
||||
const ObParameterAttr attr)
|
||||
:parser_(parser)
|
||||
{
|
||||
MEMSET(value_, 0, MAX_MODE_BYTES);
|
||||
if (OB_LIKELY(NULL != container)) {
|
||||
container->set_refactored(ObConfigStringKey(name), this, 1);
|
||||
}
|
||||
init(scope_info, name, def, info, attr);
|
||||
}
|
||||
|
||||
ObConfigModeItem::~ObConfigModeItem()
|
||||
{
|
||||
if (parser_ != NULL) {
|
||||
delete parser_;
|
||||
}
|
||||
}
|
||||
|
||||
bool ObConfigModeItem::set(const char *str)
|
||||
{
|
||||
bool valid = false;
|
||||
if (str == NULL || parser_ == NULL) {
|
||||
valid = false;
|
||||
OB_LOG_RET(WARN, OB_ERR_UNEXPECTED, "str or parser_ is NULL", K(str), K(parser_));
|
||||
} else {
|
||||
valid = parser_->parse(str, value_, MAX_MODE_BYTES);
|
||||
if (!valid) {
|
||||
OB_LOG_RET(WARN, OB_ERR_UNEXPECTED, "parse config item fail", K(str), K(parser_));
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
ObConfigVersionItem::ObConfigVersionItem(ObConfigContainer *container,
|
||||
Scope::ScopeInfo scope_info,
|
||||
|
||||
@ -47,6 +47,7 @@ enum ObConfigItemType{
|
||||
OB_CONF_ITEM_TYPE_CAPACITY = 9,
|
||||
OB_CONF_ITEM_TYPE_LOGARCHIVEOPT = 10,
|
||||
OB_CONF_ITEM_TYPE_VERSION = 11,
|
||||
OB_CONF_ITEM_TYPE_MODE = 12,
|
||||
};
|
||||
|
||||
enum class ObConfigRangeOpts {
|
||||
@ -1224,6 +1225,57 @@ private:
|
||||
common::ObSArray<ObConfigPair> config_array_;
|
||||
};
|
||||
|
||||
class ObConfigModeItem: public ObConfigItem
|
||||
{
|
||||
public:
|
||||
ObConfigModeItem(ObConfigContainer *container,
|
||||
Scope::ScopeInfo scope_info,
|
||||
const char *name,
|
||||
const char *def,
|
||||
ObConfigParser* parser,
|
||||
const char *info,
|
||||
const ObParameterAttr attr = ObParameterAttr());
|
||||
virtual ~ObConfigModeItem();
|
||||
// get_value() return the real-time value
|
||||
const uint8_t* get_value() const { return value_; }
|
||||
// get() return the real-time value if it does not need reboot, otherwise it return initial_value
|
||||
const uint8_t* get() const { return value_; }
|
||||
operator const uint8_t* () const { return value_; }
|
||||
|
||||
virtual ObConfigItemType get_config_item_type() const {
|
||||
return ObConfigItemType::OB_CONF_ITEM_TYPE_MODE;
|
||||
}
|
||||
protected:
|
||||
//use current value to do input operation
|
||||
bool set(const char *str);
|
||||
const char *value_ptr() const override
|
||||
{
|
||||
return value_str_;
|
||||
}
|
||||
const char *value_reboot_ptr() const override
|
||||
{
|
||||
return value_reboot_str_;
|
||||
}
|
||||
uint64_t value_len() const override
|
||||
{
|
||||
return sizeof(value_str_);
|
||||
}
|
||||
uint64_t value_reboot_len() const override
|
||||
{
|
||||
return sizeof(value_reboot_str_);
|
||||
}
|
||||
protected:
|
||||
static const uint64_t VALUE_BUF_SIZE = 65536UL;
|
||||
static const int64_t MAX_MODE_BYTES = 32;
|
||||
ObConfigParser *parser_;
|
||||
char value_str_[VALUE_BUF_SIZE];
|
||||
char value_reboot_str_[VALUE_BUF_SIZE];
|
||||
// max bits size: 8 * 32 = 256
|
||||
uint8_t value_[MAX_MODE_BYTES];
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObConfigModeItem);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
#include "share/ob_resource_limit.h"
|
||||
#include "share/table/ob_ttl_util.h"
|
||||
#include "src/observer/ob_server.h"
|
||||
|
||||
#include "share/table/ob_table_config_util.h"
|
||||
#include "share/config/ob_config_mode_name_def.h"
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace share;
|
||||
@ -875,5 +876,147 @@ bool ObConfigSQLTlsVersionChecker::check(const ObConfigItem &t) const
|
||||
0 == tmp_str.case_compare("TLSV1.3");
|
||||
}
|
||||
|
||||
int ObModeConfigParserUitl::parse_item_to_kv(char *item, ObString &key, ObString &value)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(item)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
OB_LOG(WARN, "item is NULL", K(ret));
|
||||
} else {
|
||||
// key
|
||||
char *save_ptr = NULL;
|
||||
char *key_ptr = STRTOK_R(item, "=", &save_ptr);
|
||||
ObString tmp_key(key_ptr);
|
||||
key = tmp_key.trim();
|
||||
// value
|
||||
ObString tmp_value(save_ptr);
|
||||
value = tmp_value.trim();
|
||||
if (value.case_compare("on") != 0 && value.case_compare("off") != 0) {
|
||||
ret = OB_INVALID_CONFIG;
|
||||
OB_LOG(WARN, "item value is invalid", K(ret), K(value));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObModeConfigParserUitl::format_mode_str(const char *src, int64_t src_len, char *dst, int64_t dst_len)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(src) || OB_UNLIKELY(src_len <=0)
|
||||
|| OB_ISNULL(dst) || dst_len < (3 * src_len)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
OB_LOG(WARN, "invalid arguments", KR(ret), KP(src), KP(dst), K(src_len), K(dst_len));
|
||||
} else {
|
||||
const char *source_str = src;
|
||||
const char *locate_str = NULL;
|
||||
int64_t source_left_len = src_len;
|
||||
int32_t locate = -1;
|
||||
int64_t pos = 0;
|
||||
while (OB_SUCC(ret) && (source_left_len > 0)
|
||||
&& (NULL != (locate_str = STRCHR(source_str, ',')))) {
|
||||
locate = static_cast<int32_t>(locate_str - source_str);
|
||||
if (OB_FAIL(databuff_printf(dst, dst_len, pos, "%.*s , ", locate, source_str))) {
|
||||
OB_LOG(WARN, "failed to databuff_print", K(ret), K(dst), K(locate), K(source_str));
|
||||
} else {
|
||||
source_str = locate_str + 1;
|
||||
source_left_len -= (locate + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && source_left_len > 0) {
|
||||
if (OB_FAIL(databuff_printf(dst, dst_len, pos, "%s", source_str))) {
|
||||
OB_LOG(WARN, "failed to databuff_print", KR(ret), K(dst), K(pos));
|
||||
}
|
||||
}
|
||||
OB_LOG(DEBUG, "format_option_str", K(ret), K(src), K(dst));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObModeConfigParserUitl::get_kv_list(char *str, ObIArray<std::pair<ObString, ObString>> &kv_list)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(str)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
OB_LOG(WARN, "item is NULL", K(ret));
|
||||
} else {
|
||||
ObString key;
|
||||
ObString value;
|
||||
char *save_ptr = NULL;
|
||||
char *token = STRTOK_R(str, ",", &save_ptr);
|
||||
while (OB_SUCC(ret) && OB_NOT_NULL(token)) {
|
||||
// trim left space
|
||||
while (*token == ' ') token++;
|
||||
// trim right space
|
||||
uint64_t len = strlen(token);
|
||||
while (len > 0 && token[len - 1] == ' ') token[--len] = '\0';
|
||||
// check and set mode
|
||||
if (OB_FAIL(parse_item_to_kv(token, key, value))) {
|
||||
OB_LOG(WARN, "fail to check config item", K(ret));
|
||||
} else if (OB_FAIL(kv_list.push_back(std::make_pair(key, value)))) {
|
||||
OB_LOG(WARN, "fail to push back key and value pair", K(ret), K(key), K(value));
|
||||
} else {
|
||||
token = STRTOK_R(NULL, ",", &save_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObKvFeatureModeParser::parse(const char *str, uint8_t *arr, int64_t len)
|
||||
{
|
||||
bool bret = true;
|
||||
if (str == NULL || arr == NULL) {
|
||||
bret = false;
|
||||
OB_LOG_RET(WARN, OB_ERR_UNEXPECTED, "Get mode config item fail, str or value arr is NULL!");
|
||||
} else if (strlen(str) == 0) {
|
||||
bret = true;
|
||||
OB_LOG_RET(DEBUG, OB_SUCCESS, "strlen is 0");
|
||||
} else {
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
ObSEArray<std::pair<ObString, ObString>, 8> kv_list;
|
||||
int64_t str_len = strlen(str);
|
||||
const int64_t buf_len = 3 * str_len; // need replace ',' to ' , '
|
||||
char buf[buf_len];
|
||||
MEMSET(buf, 0, sizeof(buf));
|
||||
MEMCPY(buf, str, str_len);
|
||||
if (OB_SUCCESS != (tmp_ret = ObModeConfigParserUitl::format_mode_str(str, str_len, buf, buf_len))) {
|
||||
bret = false;
|
||||
OB_LOG_RET(WARN, tmp_ret, "fail to format mode str", K(str));
|
||||
} else if (OB_SUCCESS != (tmp_ret = ObModeConfigParserUitl::get_kv_list(buf, kv_list))) {
|
||||
bret = false;
|
||||
OB_LOG_RET(WARN, tmp_ret, "fail to get kv list", K(str));
|
||||
} else {
|
||||
ObKVFeatureMode kv_mode;
|
||||
for (int64_t i = 0; i < kv_list.count() && bret; i++) {
|
||||
uint8_t mode = MODE_DEFAULT;
|
||||
if (kv_list.at(i).second.case_compare(MODE_VAL_ON) == 0) {
|
||||
mode = MODE_ON;
|
||||
} else if (kv_list.at(i).second.case_compare(MODE_VAL_OFF) == 0) {
|
||||
mode = MODE_OFF;
|
||||
} else {
|
||||
bret = false;
|
||||
OB_LOG_RET(WARN, OB_INVALID_CONFIG, "unknown mode type", K(kv_list.at(i).second));
|
||||
}
|
||||
if (!bret) {
|
||||
} else if (kv_list.at(i).first.case_compare(MODE_NAME_TTL) == 0) {
|
||||
kv_mode.set_ttl_mode(mode);
|
||||
} else if (kv_list.at(i).first.case_compare(MODE_NAME_REROUTING) == 0) {
|
||||
kv_mode.set_rerouting_mode(mode);
|
||||
} else if (kv_list.at(i).first.case_compare(MODE_NAME_HOTKEY) == 0) {
|
||||
kv_mode.set_hotkey_mode(mode);
|
||||
} else {
|
||||
bret = false;
|
||||
OB_LOG_RET(WARN, OB_INVALID_CONFIG, "unknown mode name", K(kv_list.at(i).first));
|
||||
}
|
||||
} // end for
|
||||
if (bret) {
|
||||
arr[0] = kv_mode.get_value();
|
||||
}
|
||||
}
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
} // end of namepace common
|
||||
} // end of namespace oceanbase
|
||||
|
||||
@ -635,6 +635,40 @@ public:
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObConfigSQLTlsVersionChecker);
|
||||
};
|
||||
|
||||
class ObModeConfigParserUitl
|
||||
{
|
||||
public:
|
||||
// parse config item like: "xxx=yyy"
|
||||
static int parse_item_to_kv(char *item, ObString &key, ObString &value);
|
||||
static int get_kv_list(char *str, ObIArray<std::pair<ObString, ObString>> &kv_list);
|
||||
// format str for split config item
|
||||
static int format_mode_str(const char *src, int64_t src_len, char *dst, int64_t dst_len);
|
||||
};
|
||||
|
||||
class ObConfigParser
|
||||
{
|
||||
public:
|
||||
ObConfigParser() {}
|
||||
virtual ~ObConfigParser() {}
|
||||
virtual bool parse(const char *str, uint8_t *arr, int64_t len) = 0;
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObConfigParser);
|
||||
};
|
||||
|
||||
class ObKvFeatureModeParser : public ObConfigParser
|
||||
{
|
||||
public:
|
||||
ObKvFeatureModeParser() {}
|
||||
virtual ~ObKvFeatureModeParser() {}
|
||||
virtual bool parse(const char *str, uint8_t *arr, int64_t len) override;
|
||||
public:
|
||||
static const int8_t MODE_DEFAULT = 0b00;
|
||||
static const int8_t MODE_ON = 0b01;
|
||||
static const int8_t MODE_OFF = 0b10;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObKvFeatureModeParser);
|
||||
};
|
||||
|
||||
typedef __ObConfigContainer<ObConfigStringKey,
|
||||
ObConfigItem, OB_MAX_CONFIG_NUMBER> ObConfigContainer;
|
||||
} // namespace common
|
||||
|
||||
28
src/share/config/ob_config_mode_name_def.h
Normal file
28
src/share/config/ob_config_mode_name_def.h
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2023 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SHARE_CONFIG_OB_CONFIG_MODE_NAME_DEF_H_
|
||||
#define OCEANBASE_SHARE_CONFIG_OB_CONFIG_MODE_NAME_DEF_H_
|
||||
// _obkv_feature_mode
|
||||
#define MODE_NAME_TTL "ttl"
|
||||
#define MODE_NAME_REROUTING "rerouting"
|
||||
#define MODE_NAME_HOTKEY "hotkey"
|
||||
|
||||
#define MODE_DEFAULT_VAL_TTL true
|
||||
#define MODE_DEFAULT_VAL_REROUTING false
|
||||
#define MODE_DEFAULT_VAL_HOTKEY false
|
||||
|
||||
// mode value
|
||||
#define MODE_VAL_ON "on"
|
||||
#define MODE_VAL_OFF "off"
|
||||
|
||||
#endif //
|
||||
@ -26,7 +26,8 @@
|
||||
SCOPE(_DEF_PARAMETER_RANGE_EASY(access_specifier, param, _ ## SCOPE, name, args))
|
||||
#define _DEF_PARAMETER_SCOPE_CHECKER_EASY(access_specifier, param, name, SCOPE, args...) \
|
||||
SCOPE(_DEF_PARAMETER_CHECKER_EASY(access_specifier, param, _ ## SCOPE, name, args))
|
||||
|
||||
#define _DEF_PARAMETER_SCOPE_PARSER_EASY(access_specifier, param, name, SCOPE, args...) \
|
||||
SCOPE(_DEF_PARAMETER_PARSER_EASY(access_specifier, param, _ ## SCOPE, name, args))
|
||||
#define _DEF_PARAMETER_SCOPE_IP_EASY(access_specifier, param, name, SCOPE, def, args...) \
|
||||
SCOPE(_DEF_PARAMETER_CHECKER_EASY(access_specifier, param, _ ## SCOPE, name, def, \
|
||||
common::ObConfigIpChecker, args))
|
||||
@ -94,6 +95,18 @@ access_specifier:
|
||||
} \
|
||||
} name;
|
||||
|
||||
#define _DEF_PARAMETER_PARSER_EASY(access_specifier, param, scope, name, def, parser, args...) \
|
||||
access_specifier: \
|
||||
class ObConfig ## param ## Item ## _ ## name \
|
||||
: public common::ObConfig ## param ## Item \
|
||||
{ \
|
||||
public: \
|
||||
ObConfig ## param ## Item ## _ ## name() \
|
||||
: common::ObConfig ## param ## Item( \
|
||||
local_container(), scope, #name, def, \
|
||||
new (std::nothrow) parser(), args) {} \
|
||||
} name;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define DEF_INT(args...) \
|
||||
_DEF_PARAMETER_SCOPE_RANGE_EASY(public, Int, args)
|
||||
@ -140,6 +153,9 @@ access_specifier:
|
||||
#define DEF_STR_LIST(args...) \
|
||||
_DEF_PARAMETER_SCOPE_EASY(public, StrList, args)
|
||||
|
||||
#define DEF_MODE_WITH_PARSER(args...) \
|
||||
_DEF_PARAMETER_SCOPE_PARSER_EASY(public, Mode, args)
|
||||
|
||||
#define DEF_LOG_ARCHIVE_OPTIONS_WITH_CHECKER(args...) \
|
||||
_DEF_PARAMETER_SCOPE_CHECKER_EASY(public, LogArchiveOptions, args)
|
||||
#define DEF_LOG_LEVEL(args...) \
|
||||
|
||||
@ -1628,3 +1628,7 @@ DEF_STR_WITH_CHECKER(sql_protocol_min_tls_version, OB_CLUSTER_PARAMETER, "none",
|
||||
"SQL SSL control options, used to specify the minimum SSL/TLS version number. "
|
||||
"values: none, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
// obkv
|
||||
DEF_MODE_WITH_PARSER(_obkv_feature_mode, OB_CLUSTER_PARAMETER, "", common::ObKvFeatureModeParser,
|
||||
"_obkv_feature_mode is a option list to control specified OBKV features on/off.",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
||||
140
src/share/table/ob_table_config_util.cpp
Normal file
140
src/share/table/ob_table_config_util.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Copyright (c) 2023 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SHARE
|
||||
#include "ob_table_config_util.h"
|
||||
#include "lib/container/ob_se_array.h"
|
||||
#include "share/config/ob_config_helper.h"
|
||||
#include "share/config/ob_config_mode_name_def.h"
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
ObKVFeatureMode::ObKVFeatureMode(const uint8_t *values)
|
||||
{
|
||||
if (OB_UNLIKELY(values == NULL)) {
|
||||
value_ = 0;
|
||||
is_valid_ = false;
|
||||
} else {
|
||||
value_ = values[0];
|
||||
is_valid_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ObKVFeatureMode::set_ttl_mode(uint8_t mode)
|
||||
{
|
||||
is_valid_ = check_mode_valid(mode);
|
||||
if (is_valid_) {
|
||||
ttl_mode_ = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void ObKVFeatureMode::set_rerouting_mode(uint8_t mode)
|
||||
{
|
||||
is_valid_ = check_mode_valid(mode);
|
||||
if (is_valid_) {
|
||||
rerouting_mode_ = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void ObKVFeatureMode::set_hotkey_mode(uint8_t mode)
|
||||
{
|
||||
is_valid_ = check_mode_valid(mode);
|
||||
if (is_valid_) {
|
||||
hotkey_mode_ = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void ObKVFeatureMode::set_value(uint8_t value)
|
||||
{
|
||||
if ((value & 0b11) == 0b11 || ((value >> 2) & 0b11) == 0b11 || ((value >> 4) & 0b11) == 0b11) {
|
||||
is_valid_ = false;
|
||||
} else {
|
||||
is_valid_ = true;
|
||||
value_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ObKVFeatureMode::is_ttl_enable() {
|
||||
bool mode = MODE_DEFAULT_VAL_TTL;
|
||||
if (ttl_mode_ == ObKvFeatureModeParser::MODE_ON) {
|
||||
mode = true;
|
||||
} else if (ttl_mode_ == ObKvFeatureModeParser::MODE_OFF) {
|
||||
mode = false;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
bool ObKVFeatureMode::is_rerouting_enable() {
|
||||
bool mode = MODE_DEFAULT_VAL_REROUTING;
|
||||
if (rerouting_mode_ == ObKvFeatureModeParser::MODE_ON) {
|
||||
mode = true;
|
||||
} else if (rerouting_mode_ == ObKvFeatureModeParser::MODE_ON) {
|
||||
mode = false;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
bool ObKVFeatureMode::is_hotkey_enable() {
|
||||
bool mode = MODE_DEFAULT_VAL_HOTKEY;
|
||||
if (hotkey_mode_ == ObKvFeatureModeParser::MODE_ON) {
|
||||
mode = true;
|
||||
} else if (hotkey_mode_ == ObKvFeatureModeParser::MODE_ON) {
|
||||
mode = false;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
bool ObKVFeatureModeUitl::is_obkv_feature_enable(ObKVFeatureType feat_type)
|
||||
{
|
||||
bool bret = false;
|
||||
ObKVFeatureMode cfg(GCONF._obkv_feature_mode);
|
||||
if (!cfg.is_valid()) {
|
||||
bret = false;
|
||||
OB_LOG_RET(WARN, OB_INVALID_ARGUMENT, "unexpected, cfg is invalid");
|
||||
} else {
|
||||
switch (feat_type) {
|
||||
case ObKVFeatureType::TTL:
|
||||
bret = cfg.is_ttl_enable();
|
||||
break;
|
||||
case ObKVFeatureType::REROUTING:
|
||||
bret = cfg.is_rerouting_enable();
|
||||
break;
|
||||
case ObKVFeatureType::HOTKEY:
|
||||
bret = cfg.is_hotkey_enable();
|
||||
break;
|
||||
default:
|
||||
OB_LOG_RET(WARN, OB_INVALID_ARGUMENT, "unexpected feature type", K(feat_type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
bool ObKVFeatureModeUitl::is_ttl_enable()
|
||||
{
|
||||
return is_obkv_feature_enable(ObKVFeatureType::TTL);
|
||||
}
|
||||
|
||||
bool ObKVFeatureModeUitl::is_rerouting_enable()
|
||||
{
|
||||
return is_obkv_feature_enable(ObKVFeatureType::REROUTING);
|
||||
}
|
||||
|
||||
bool ObKVFeatureModeUitl::is_hotkey_enable()
|
||||
{
|
||||
return is_obkv_feature_enable(ObKVFeatureType::HOTKEY);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
71
src/share/table/ob_table_config_util.h
Normal file
71
src/share/table/ob_table_config_util.h
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2023 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_OB_TABLE_CONFIG_UTIL_H_
|
||||
#define OCEANBASE_OB_TABLE_CONFIG_UTIL_H_
|
||||
#include "lib/utility/ob_macro_utils.h"
|
||||
#include "lib/utility/ob_print_utils.h"
|
||||
#include "share/config/ob_server_config.h"
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
enum ObKVFeatureType {
|
||||
INVALIDTYPE,
|
||||
TTL,
|
||||
REROUTING,
|
||||
HOTKEY,
|
||||
MAXTYPE
|
||||
};
|
||||
|
||||
class ObKVFeatureMode final
|
||||
{
|
||||
public:
|
||||
ObKVFeatureMode(): is_valid_(false), value_(0) {}
|
||||
ObKVFeatureMode(const uint8_t *values);
|
||||
bool is_valid() { return is_valid_; }
|
||||
bool check_mode_valid(uint8_t mode) { return mode > 2 ? false : true; }
|
||||
bool is_ttl_enable();
|
||||
bool is_rerouting_enable();
|
||||
bool is_hotkey_enable();
|
||||
void set_ttl_mode(uint8_t mode);
|
||||
void set_rerouting_mode(uint8_t mode);
|
||||
void set_hotkey_mode(uint8_t mode);
|
||||
void set_value(uint8_t value);
|
||||
int8_t get_value() const { return value_; }
|
||||
private:
|
||||
bool is_valid_;
|
||||
union {
|
||||
uint8_t value_;
|
||||
struct {
|
||||
uint8_t ttl_mode_ : 2;
|
||||
uint8_t rerouting_mode_ : 2;
|
||||
uint8_t hotkey_mode_ : 2;
|
||||
uint8_t reserver_mode_ :2;
|
||||
};
|
||||
};
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObKVFeatureMode);
|
||||
};
|
||||
|
||||
class ObKVFeatureModeUitl
|
||||
{
|
||||
public:
|
||||
static bool is_obkv_feature_enable(ObKVFeatureType feat_type);
|
||||
static bool is_ttl_enable();
|
||||
static bool is_rerouting_enable();
|
||||
static bool is_hotkey_enable();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -44,6 +44,7 @@
|
||||
#include "observer/mysql/ob_query_response_time.h"
|
||||
#include "rootserver/ob_rs_job_table_operator.h" //ObRsJobType
|
||||
#include "sql/resolver/cmd/ob_kill_stmt.h"
|
||||
#include "share/table/ob_table_config_util.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -4327,6 +4328,10 @@ int ObTableTTLResolver::resolve(const ParseNode& parse_tree)
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("TTL command is not supported in data version less than 4.2.1", K(ret), K(tenant_data_version));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "TTL command is not supported in data version less than 4.2.1");
|
||||
} else if (!ObKVFeatureModeUitl::is_ttl_enable()) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("ttl is disable", K(ret));
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "ttl is disable, set by config item _obkv_feature_mode");
|
||||
} else if (OB_UNLIKELY(T_TABLE_TTL != parse_tree.type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("type is not T_TABLE_TTL", "type", get_type_name(parse_tree.type_));
|
||||
|
||||
@ -316,6 +316,7 @@ _minor_compaction_amplification_factor
|
||||
_min_malloc_sample_interval
|
||||
_mvcc_gc_using_min_txn_snapshot
|
||||
_nested_loop_join_enabled
|
||||
_obkv_feature_mode
|
||||
_ob_ddl_timeout
|
||||
_ob_elr_fast_freeze_threshold
|
||||
_ob_enable_direct_load
|
||||
|
||||
@ -5,6 +5,7 @@ storage_unittest(test_create_executor table/test_create_executor.cpp)
|
||||
storage_unittest(test_table_aggregation table/test_table_aggregation.cpp)
|
||||
storage_unittest(test_table_sess_pool table/test_table_sess_pool.cpp)
|
||||
storage_unittest(test_ingress_bw_alloc_manager net/test_ingress_bw_alloc_manager.cpp)
|
||||
ob_unittest(test_obkv_config tableapi/test_obkv_config.cpp)
|
||||
ob_unittest(test_uniq_task_queue)
|
||||
|
||||
add_subdirectory(rpc EXCLUDE_FROM_ALL)
|
||||
|
||||
156
unittest/observer/tableapi/test_obkv_config.cpp
Normal file
156
unittest/observer/tableapi/test_obkv_config.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
#include "share/table/ob_table_config_util.h"
|
||||
#include "lib/time/ob_time_utility.h"
|
||||
#include "share/parameter/ob_parameter_macro.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace share;
|
||||
namespace common
|
||||
{
|
||||
ObConfigContainer l_container;
|
||||
static ObConfigContainer *local_container()
|
||||
{
|
||||
return &l_container;
|
||||
}
|
||||
class TestObKvConfig : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
#undef OB_CLUSTER_PARAMETER
|
||||
#define OB_CLUSTER_PARAMETER(args...) args
|
||||
DEF_MODE_WITH_PARSER(_obkv_feature_mode, OB_CLUSTER_PARAMETER, "", common::ObKvFeatureModeParser,
|
||||
"_obkv_feature_mode is a option list to control specified OBKV features on/off.",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
#undef OB_CLUSTER_PARAMETER
|
||||
};
|
||||
|
||||
TEST_F(TestObKvConfig, test_process_item)
|
||||
{
|
||||
ObString key;
|
||||
ObString value;
|
||||
char str1[100] = {"ttl=off"};
|
||||
ASSERT_EQ(OB_SUCCESS, ObModeConfigParserUitl::parse_item_to_kv(str1, key, value));
|
||||
ASSERT_EQ(key, ObString("ttl"));
|
||||
ASSERT_EQ(value, ObString("off"));
|
||||
|
||||
char str2[100] = {" ttl = off "};
|
||||
ASSERT_EQ(OB_SUCCESS, ObModeConfigParserUitl::parse_item_to_kv(str2, key, value));
|
||||
ASSERT_EQ(key, ObString("ttl"));
|
||||
ASSERT_EQ(value, ObString("off"));
|
||||
|
||||
char str3[100] = {" rerouting =off "};
|
||||
ASSERT_EQ(OB_SUCCESS, ObModeConfigParserUitl::parse_item_to_kv(str3, key, value));
|
||||
ASSERT_EQ(key, ObString("rerouting"));
|
||||
ASSERT_EQ(value, ObString("off"));
|
||||
|
||||
char str4[100] = {"ttl=on, rerouting=off"};
|
||||
common::ObSEArray<std::pair<ObString, ObString>, 8> kv_list;
|
||||
ASSERT_EQ(OB_SUCCESS, ObModeConfigParserUitl::get_kv_list(str4, kv_list));
|
||||
ASSERT_EQ(2, kv_list.count());
|
||||
ASSERT_EQ(kv_list.at(0).first, ObString("ttl"));
|
||||
ASSERT_EQ(kv_list.at(0).second, ObString("on"));
|
||||
ASSERT_EQ(kv_list.at(1).first, ObString("rerouting"));
|
||||
ASSERT_EQ(kv_list.at(1).second, ObString("off"));
|
||||
}
|
||||
|
||||
|
||||
TEST_F(TestObKvConfig, test_parse)
|
||||
{
|
||||
ObKvFeatureModeParser parser;
|
||||
uint8_t arr[32];
|
||||
ASSERT_EQ(true, parser.parse("ttl=on, rerouting=off", arr, 32));
|
||||
ASSERT_EQ(arr[0], 0b00001001);
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(true, parser.parse("ttl=on, ttl=off, rerouting=on", arr, 32));
|
||||
ASSERT_EQ(arr[0], 0b0000110);
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(true, parser.parse("ttl=on, ttl=off", arr, 32));
|
||||
ASSERT_EQ(arr[0], 0b00000010);
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(true, parser.parse("ttl=on, hotkey=on, rerouting=on", arr, 32));
|
||||
ASSERT_EQ(arr[0], 0b00010101);
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(false, parser.parse("ttl=on, ttt=off", arr, 32));
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(false, parser.parse("ttl=on, rerouting=default", arr, 32));
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(true, parser.parse("", arr, 32));
|
||||
ASSERT_EQ(arr[0], 0);
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(false, parser.parse("ttl=on, ttt=off, ", arr, 32));
|
||||
|
||||
MEMSET(arr, 0, 32);
|
||||
ASSERT_EQ(false, parser.parse("ttl=on, ttt=off,", arr, 32));
|
||||
}
|
||||
|
||||
TEST_F(TestObKvConfig, test_obkv_feature_mode)
|
||||
{
|
||||
const uint8_t *value = _obkv_feature_mode;
|
||||
ASSERT_NE((void*)NULL, (void*)value);
|
||||
ASSERT_EQ(value[0], 0);
|
||||
ASSERT_EQ(true, _obkv_feature_mode.set_value("ttl=off, rerouting=on, hotkey=on"));
|
||||
const uint8_t *value1 = _obkv_feature_mode.get();
|
||||
ASSERT_NE((void*)NULL, (void*)value1);
|
||||
ASSERT_EQ(value1[0], 0b00010110);
|
||||
// bad case
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value("hotkey=off="));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value("=off"));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value(","));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value(" , "));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value(" ,hotkey=off"));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value(",hotkey=off"));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value("ttl=off,, hotkey=off"));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value("ttl=off, , hotkey=off"));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value("ttl=off, rerouting=on, "));
|
||||
ASSERT_EQ(false, _obkv_feature_mode.set_value("ttl=off, rerouting=on,"));
|
||||
}
|
||||
|
||||
TEST_F(TestObKvConfig, testObKVFeatureMode)
|
||||
{
|
||||
// rerouting=off, ttl=on
|
||||
uint8_t values[1] = {0b001001};
|
||||
ObKVFeatureMode kv_mode(values);
|
||||
ASSERT_EQ(true, kv_mode.is_ttl_enable());
|
||||
ASSERT_EQ(false, kv_mode.is_rerouting_enable());
|
||||
// default
|
||||
ObKVFeatureMode kv_mode_1;
|
||||
ASSERT_EQ(false, kv_mode_1.is_valid());
|
||||
kv_mode_1.set_ttl_mode(0b10);
|
||||
kv_mode_1.set_rerouting_mode(0b01);
|
||||
kv_mode_1.set_hotkey_mode(0b01);
|
||||
ASSERT_EQ(true, kv_mode_1.is_valid());
|
||||
ASSERT_EQ(false, kv_mode_1.is_ttl_enable());
|
||||
ASSERT_EQ(true, kv_mode_1.is_rerouting_enable());
|
||||
ASSERT_EQ(true, kv_mode_1.is_hotkey_enable());
|
||||
kv_mode_1.set_value(0b11101001);
|
||||
ASSERT_EQ(true, kv_mode_1.is_valid());
|
||||
ASSERT_EQ(true, kv_mode_1.is_ttl_enable());
|
||||
ASSERT_EQ(false, kv_mode_1.is_rerouting_enable());
|
||||
ASSERT_EQ(false, kv_mode_1.is_hotkey_enable());
|
||||
// bad case
|
||||
kv_mode_1.set_ttl_mode(0b11);
|
||||
ASSERT_EQ(false, kv_mode_1.is_valid());
|
||||
kv_mode_1.set_hotkey_mode(0b11);
|
||||
ASSERT_EQ(false, kv_mode_1.is_valid());
|
||||
kv_mode_1.set_rerouting_mode(0b11);
|
||||
ASSERT_EQ(false, kv_mode_1.is_valid());
|
||||
kv_mode_1.set_value(0b00111111);
|
||||
ASSERT_EQ(false, kv_mode_1.is_valid());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user