[OBKV][CP] patch config _obkv_feature_mode from 32x

This commit is contained in:
GroundWu
2023-09-09 11:40:26 +00:00
committed by ob-robot
parent e6dee1493e
commit e1081698d6
17 changed files with 721 additions and 14 deletions

View File

@ -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,13 +998,15 @@ 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)
|| is_server_down_error(err)
|| is_partition_change_error(err)
|| is_server_status_error(err)
|| is_unit_migrate(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));
bool is_err = is_master_changed_error(err)
|| is_server_down_error(err)
|| is_partition_change_error(err)
|| is_server_status_error(err)
|| is_unit_migrate(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);
return is_err && ObKVFeatureModeUitl::is_rerouting_enable();
}

View File

@ -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));
}

View File

@ -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())) {

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View 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 //

View File

@ -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...) \

View File

@ -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));

View 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);
}
}
}

View 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

View File

@ -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_));

View File

@ -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

View File

@ -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)

View 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();
}