release tenant memory in resource manager when drop tenant

This commit is contained in:
obdev 2023-02-14 07:11:54 +00:00 committed by ob-robot
parent 454158d35e
commit 8813e31143
7 changed files with 320 additions and 128 deletions

View File

@ -720,6 +720,8 @@ int ObTenant::init(const ObTenantMeta &meta)
if (OB_SUCC(ret) && !is_virtual_tenant_id(id_)) {
if (OB_FAIL(OB_PX_TARGET_MGR.add_tenant(id_))) {
LOG_WARN("add tenant into px target mgr failed", K(ret), K(id_));
} else if (OB_FAIL(G_RES_MGR.get_col_mapping_rule_mgr().add_tenant(id_))) {
LOG_WARN("add tenant into res col maping rule mgr failed", K(ret), K(id_));
}
}
@ -962,6 +964,7 @@ void ObTenant::wait()
ObTenantSwitchGuard guard(this);
ObTenantBase::stop_mtl_module();
OB_PX_TARGET_MGR.delete_tenant(id_);
G_RES_MGR.get_col_mapping_rule_mgr().drop_tenant(id_);
ObTenantBase::wait_mtl_module();
wait_mtl_finished_ = true;
}

View File

@ -17,176 +17,318 @@
using namespace oceanbase::common;
using namespace oceanbase::share;
int ObResourceColMappingRuleManager::init()
int ObTenantResColMappingInfo::init(uint64_t tenant_id)
{
int ret = OB_SUCCESS;
// number of columns with mapping rule.
int rule_bucket_size = 4096;
int rule_group_bucket_size = 40960;
int tenant_bucket_size = 100;
int rule_bucket_size = 128;
int rule_group_bucket_size = 128;
tenant_id_ = tenant_id;
allocator_.set_label("ResKeyName");
allocator_.set_tenant_id(tenant_id);
ObMemAttr attr1(tenant_id, "ResRuleIdMap");
ObMemAttr attr2(tenant_id, "ResGrpIdMap");
if (OB_UNLIKELY(rule_id_map_.created() || group_id_map_.created())) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (OB_FAIL(rule_id_map_.create(rule_bucket_size, "ColRuleMap", "ColRuleMapNode"))) {
} else if (OB_FAIL(rule_id_map_.create(rule_bucket_size, attr1, attr1))) {
LOG_WARN("fail create rule map", K(ret));
} else if (OB_FAIL(group_id_map_.create(rule_group_bucket_size, "RuleGrpIdMap", "RuleGrpIdNode"))) {
LOG_WARN("fail create group map", K(ret));
} else if (OB_FAIL(tenant_version_.create(tenant_bucket_size, "RuleVersionMap", "RuleVersionNode"))) {
} else if (OB_FAIL(group_id_map_.create(rule_group_bucket_size, attr2, attr2))) {
LOG_WARN("fail create group map", K(ret));
}
LOG_INFO("init resource column mapping rule manager", K(ret));
return ret;
}
int ObResourceColMappingRuleManager::refresh_resource_column_mapping_rule(uint64_t tenant_id,
sql::ObPlanCache *plan_cache,
const common::ObString &plan)
int ObTenantResColMappingInfo::refresh(sql::ObPlanCache *plan_cache, const common::ObString &plan)
{
int ret = OB_SUCCESS;
ObResourceManagerProxy proxy;
int64_t inner_table_version = 0;
int64_t cache_version = get_column_mapping_version(tenant_id);
if (OB_FAIL(proxy.get_resource_mapping_version(tenant_id, inner_table_version))) {
if (OB_FAIL(proxy.get_resource_mapping_version(tenant_id_, inner_table_version))) {
LOG_WARN("get resource mapping version failed", K(ret));
} else if (cache_version >= inner_table_version) {
LOG_TRACE("local version is latest, don't need refresh", K(tenant_id), K(cache_version), K(inner_table_version));
} else if (version_ >= inner_table_version) {
LOG_TRACE("local version is latest, don't need refresh", K(tenant_id_),
K(version_), K(inner_table_version));
} else if (OB_ISNULL(plan_cache)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("get plan cache failed", K(ret), K(tenant_id));
LOG_WARN("get plan cache failed", K(ret));
} else if (lock_.trylock()) {
LOG_INFO("local version is not latest, need refresh", K(tenant_id), K(cache_version), K(inner_table_version));
LOG_INFO("local version is not latest, need refresh", K(tenant_id_),
K(version_), K(inner_table_version));
// update cache
ObArray<ObResourceColumnMappingRule> rules;
if (OB_ISNULL(GCTX.cgroup_ctrl_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("cgroup ctrl is null", K(ret));
} else if (!GCTX.cgroup_ctrl_->is_valid()) {
ret = OB_EAGAIN;
// cgroup ctrl 没有初始化成功,可能是没有 cgroup fs、没有权限等原因
// 此时不再继续后继资源隔离操作
} else if (OB_FAIL(proxy.get_all_resource_mapping_rules_by_column(tenant_id, plan, rules))) {
LOG_WARN("fail get resource mapping rules by column", K(tenant_id), K(ret));
} else if (OB_FAIL(proxy.get_all_resource_mapping_rules_by_column(tenant_id_, plan,
allocator_, rules))) {
LOG_WARN("fail get resource mapping rules by column", K(tenant_id_), K(ret));
} else {
//TODO: remove elements not in the array which means not in inner table.
uint64_t current_time = static_cast<uint64_t>(ObTimeUtility::current_time());
for (int64_t i = 0; i < rules.count() && OB_SUCC(ret); ++i) {
ObResourceColumnMappingRule &rule = rules.at(i);
uint64_t rule_id = 0;
if (OB_FAIL(rule_id_map_.get_refactored(
ColumnNameKey(tenant_id, rule.database_id_, rule.table_name_, rule.column_name_, rule.case_mode_),
rule_id))) {
bool rule_id_map_inserted = false;
bool group_id_map_inserted = false;
if (OB_FAIL(rule_id_map_.get_refactored(ColumnNameKey(tenant_id_, rule.database_id_,
rule.table_name_, rule.column_name_, rule.case_mode_), rule_id))) {
if (OB_HASH_NOT_EXIST == ret) {
//use current_time as new rule id and insert into rule_id_map_.
rule_id = current_time;
current_time++;
if (OB_FAIL(rule_id_map_.set_refactored(
ColumnNameKey(tenant_id, rule.database_id_, rule.table_name_, rule.column_name_, rule.case_mode_),
rule_id))) {
rule.reset();
if (OB_FAIL(rule_id_map_.set_refactored(ColumnNameKey(tenant_id_, rule.database_id_,
rule.table_name_, rule.column_name_, rule.case_mode_), rule_id))) {
LOG_WARN("rule id map set refactored failed", K(ret));
} else if (OB_FAIL(plan_cache->evict_plan_by_table_name(rule.database_id_, rule.table_name_))) {
ret = OB_SUCCESS;
LOG_ERROR("evict plan by table name failed", K(ret), K(tenant_id),
K(rule.database_id_), K(rule.table_name_));
} else {
rule_id_map_inserted = true;
if (OB_FAIL(plan_cache->evict_plan_by_table_name(rule.database_id_, rule.table_name_))) {
ret = OB_SUCCESS;
LOG_ERROR("evict plan by table name failed", K(ret), K(tenant_id_), K(rule));
}
}
} else {
rule.reset();
LOG_WARN("get refactored from rule id map failed", K(ret));
}
} else {
rule.reset_table_column_name();
}
RuleValue rule_value;
if (OB_FAIL(ret)) {
} else if (OB_FAIL(group_id_map_.get_refactored(
RuleValueKey(tenant_id, rule_id, rule.user_name_, rule.literal_value_),
RuleValueKey(rule_id, rule.user_name_, rule.literal_value_),
rule_value))) {
if (OB_HASH_NOT_EXIST == ret) {
if (OB_FAIL(group_id_map_.set_refactored(
RuleValueKey(tenant_id, rule_id, rule.user_name_, rule.literal_value_),
RuleValueKey(rule_id, rule.user_name_, rule.literal_value_),
RuleValue(rule.group_id_, rule.user_name_, rule.literal_value_)))) {
rule.reset_user_name_literal();
LOG_WARN("group id map set refactored failed", K(ret));
} else {
group_id_map_inserted = true;
}
} else {
rule.reset_user_name_literal();
LOG_WARN("group id map set refactored failed", K(ret));
}
} else if (rule_value.group_id_ == rule.group_id_) {
//not updated, just ignore.
// release memory of user_name and literal_value in ObResourceColumnMappingRule
rule.reset_user_name_literal();
} else if (OB_FAIL(group_id_map_.set_refactored(
RuleValueKey(tenant_id, rule_id, rule.user_name_, rule.literal_value_),
RuleValueKey(rule_id, rule.user_name_, rule.literal_value_),
RuleValue(rule.group_id_, rule.user_name_, rule.literal_value_),
1 /* overwrite*/, 0, 0 /* overwrite_key*/))) {
LOG_WARN("group id map set refactored failed", K(ret));
} else {
group_id_map_inserted = true;
// parameter overwrite_key of set_refactored is unused, key is always overwrited when value is overwrited.
// So we record ptrs in value, and free ptrs recorded in original value when overwrite key and value.
rule_value.release_memory();
rule_value.release_memory(allocator_);
}
if (!rule_id_map_inserted) {
rule.reset_table_column_name(allocator_);
}
if (!group_id_map_inserted) {
rule.reset_user_name_literal(allocator_);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(tenant_version_.set_refactored(tenant_id, inner_table_version, 1))) {
LOG_WARN("update tenant cache version failed", K(ret));
}
version_ = inner_table_version;
}
LOG_INFO("refresh_resource_column_mapping_rule",
K(ret), K(tenant_id), K(inner_table_version),
K(ret), K(tenant_id_), K(inner_table_version),
K(plan), K(rules), "rule_count", group_id_map_.size());
}
lock_.unlock();
} else {
LOG_ERROR("get lock of resource mapping rule cache failed.", K(tenant_id));
LOG_ERROR("get lock of resource mapping rule cache failed.", K(tenant_id_));
}
return ret;
}
int ObTenantResColMappingInfo::get_rule_id(uint64_t tenant_id,
uint64_t database_id,
const common::ObString &table_name,
const common::ObString &column_name,
common::ObNameCaseMode case_mode,
uint64_t &rule_id)
{
int ret = OB_SUCCESS;
rule_id = OB_INVALID_ID;
if (OB_FAIL(rule_id_map_.get_refactored(
ColumnNameKey(tenant_id, database_id, table_name, column_name, case_mode), rule_id))) {
if (OB_HASH_NOT_EXIST != ret) {
LOG_WARN("get rule id failed", K(ret));
} else {
ret = OB_SUCCESS;
}
}
return ret;
}
int ObTenantResColMappingInfo::get_group_id(uint64_t rule_id, const ObString &user_name,
const common::ObString &literal_value,
uint64_t &group_id)
{
int ret = OB_SUCCESS;
RuleValue rule_value;
group_id = OB_INVALID_ID;
if (OB_FAIL(group_id_map_.get_refactored(
RuleValueKey(rule_id, user_name, literal_value), rule_value))) {
if (OB_HASH_NOT_EXIST == ret) {
ret = group_id_map_.get_refactored(
RuleValueKey(rule_id, ObString(), literal_value), rule_value);
}
}
if (OB_SUCC(ret)) {
group_id = rule_value.group_id_;
} else if (OB_HASH_NOT_EXIST == ret) {
ret = OB_SUCCESS;
} else {
LOG_WARN("get group id failed", K(ret));
}
LOG_TRACE("get_column_mapping_group_id", K(tenant_id_), K(rule_id), K(user_name),
K(literal_value), K(rule_value.group_id_));
return ret;
}
int ObResourceColMappingRuleManager::init()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(inited_)) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (OB_FAIL(tenant_rule_infos_.init("ResRuleInfoMap"))) {
LOG_WARN("create map failed", K(ret));
} else {
inited_ = true;
}
return ret;
}
int ObResourceColMappingRuleManager::add_tenant(uint64_t tenant_id)
{
int ret = OB_SUCCESS;
ObTenantResColMappingInfo *res_info = NULL;
void *buf = NULL;
ObMemAttr attr(tenant_id, "ResRuleInfo");
ObResTenantId res_tenant_id(tenant_id);
if (is_virtual_tenant_id(tenant_id)) {
// do nothing
} else if (OB_UNLIKELY(!inited_)) {
LOG_ERROR("resource column mapping rule manager not init", K(ret));
} else if (OB_FAIL(tenant_rule_infos_.contains_key(res_tenant_id))) {
if (OB_ENTRY_EXIST == ret) {
ret = OB_SUCCESS;
} else if (OB_ENTRY_NOT_EXIST != ret) {
LOG_WARN("check map contain key failed", K(ret));
} else if (OB_ISNULL(buf = ob_malloc(sizeof(ObTenantResColMappingInfo), attr))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret), K(sizeof(ObTenantResColMappingInfo)));
} else {
res_info = new (buf)ObTenantResColMappingInfo();
if (OB_FAIL(res_info->init(tenant_id))) {
LOG_WARN("init resource column mapping info failed", K(ret));
} else if (OB_FAIL(tenant_rule_infos_.insert_and_get(res_tenant_id, res_info))) {
LOG_WARN("insert failed", K(ret));
} else {
tenant_rule_infos_.revert(res_info);
}
if (OB_FAIL(ret)) {
res_info->~ObTenantResColMappingInfo();
ob_free(res_info);
res_info = NULL;
}
}
}
LOG_INFO("add resource column mapping rule info", K(ret), K(tenant_id));
return ret;
}
int ObResourceColMappingRuleManager::drop_tenant(uint64_t tenant_id)
{
int ret = OB_SUCCESS;
ObResTenantId res_tenant_id(tenant_id);
if (is_virtual_tenant_id(tenant_id)) {
// do nothing
} else if (OB_FAIL(tenant_rule_infos_.del(res_tenant_id))) {
if (OB_ENTRY_NOT_EXIST != ret) {
LOG_WARN("drop tenant failed", K(ret));
} else {
ret = OB_SUCCESS;
}
}
LOG_INFO("drop resource column mapping rule info", K(ret), K(tenant_id));
return ret;
}
int ObResourceColMappingRuleManager::refresh_resource_column_mapping_rule(uint64_t tenant_id,
sql::ObPlanCache *plan_cache,
const common::ObString &plan)
{
int ret = OB_SUCCESS;
ObTenantResColMappingInfo *res_info = NULL;
ObResTenantId res_tenant_id(tenant_id);
if (OB_FAIL(tenant_rule_infos_.get(res_tenant_id, res_info))) {
LOG_WARN("get tenant rule infos failed", K(ret));
} else if (OB_FAIL(res_info->refresh(plan_cache, plan))) {
LOG_WARN("refresh res col mapping info failed", K(ret), K(tenant_id));
}
tenant_rule_infos_.revert(res_info);
return ret;
}
uint64_t ObResourceColMappingRuleManager::get_column_mapping_rule_id(uint64_t tenant_id,
uint64_t database_id,
const common::ObString &table_name,
const common::ObString &column_name,
common::ObNameCaseMode case_mode) const
common::ObNameCaseMode case_mode)
{
int ret = common::OB_SUCCESS;
int ret = OB_SUCCESS;
uint64_t rule_id = OB_INVALID_ID;
if (OB_FAIL(rule_id_map_.get_refactored(
ColumnNameKey(tenant_id, database_id, table_name, column_name, case_mode), rule_id))) {
rule_id = OB_INVALID_ID;
ObTenantResColMappingInfo *res_info = NULL;
ObResTenantId res_tenant_id(tenant_id);
if (OB_FAIL(tenant_rule_infos_.get(res_tenant_id, res_info))) {
LOG_WARN("get tenant rule info failed", K(ret));
} else if (OB_FAIL(res_info->get_rule_id(tenant_id, database_id, table_name, column_name,
case_mode, rule_id))) {
LOG_WARN("get rule id failed", K(ret));
}
LOG_TRACE("get_column_mapping_rule_id", K(tenant_id), K(database_id), K(table_name), K(column_name), K(case_mode), K(rule_id));
tenant_rule_infos_.revert(res_info);
LOG_TRACE("get_column_mapping_rule_id", K(tenant_id), K(database_id), K(table_name),
K(column_name), K(case_mode), K(rule_id));
return rule_id;
}
uint64_t ObResourceColMappingRuleManager::get_column_mapping_group_id(uint64_t tenant_id,
uint64_t rule_id, const ObString &user_name,
const common::ObString &literal_value)
{
int ret = common::OB_SUCCESS;
RuleValue rule_value;
if (OB_FAIL(group_id_map_.get_refactored(
RuleValueKey(tenant_id, rule_id, user_name, literal_value), rule_value))) {
if (OB_HASH_NOT_EXIST == ret) {
if (OB_FAIL(group_id_map_.get_refactored(
RuleValueKey(tenant_id, rule_id, ObString(), literal_value), rule_value))) {
// return invalid group id if not found, and then use current thread execute this query.
rule_value.group_id_ = OB_INVALID_ID;
}
} else {
rule_value.group_id_ = OB_INVALID_ID;
}
int ret = OB_SUCCESS;
ObTenantResColMappingInfo *res_info = NULL;
uint64_t group_id = OB_INVALID_ID;
ObResTenantId res_tenant_id(tenant_id);
if (OB_FAIL(tenant_rule_infos_.get(res_tenant_id, res_info))) {
LOG_WARN("get tenant rule info failed", K(ret));
} else if (OB_FAIL(res_info->get_group_id(rule_id, user_name, literal_value, group_id))) {
LOG_WARN("get group id failed", K(ret));
}
LOG_TRACE("get_column_mapping_group_id", K(tenant_id), K(rule_id), K(user_name), K(literal_value), K(rule_value.group_id_));
return rule_value.group_id_;
tenant_rule_infos_.revert(res_info);
LOG_TRACE("get_column_mapping_group_id", K(tenant_id), K(rule_id), K(user_name), K(literal_value),
K(group_id));
return group_id;
}
int64_t ObResourceColMappingRuleManager::get_column_mapping_version(uint64_t tenant_id)
{
int ret = OB_SUCCESS;
int64_t version = 0;
if (OB_FAIL(tenant_version_.get_refactored(tenant_id, version))) {
LOG_WARN("get tenant column mapping version failed", K(tenant_id), K(ret));
version = 0;
ObResTenantId res_tenant_id(tenant_id);
ObTenantResColMappingInfo *res_info = NULL;
if (OB_FAIL(tenant_rule_infos_.get(res_tenant_id, res_info))) {
LOG_TRACE("get tenant column mapping version failed", K(tenant_id), K(ret));
} else {
version = res_info->get_version();
}
tenant_rule_infos_.revert(res_info);
return version;
}

View File

@ -30,7 +30,11 @@ class ObPlanCache;
}
namespace share
{
class ObResourceColMappingRuleManager
typedef common::ObIntWarp ObResTenantId;
typedef common::LinkHashNode<ObResTenantId> ObResColMapInfoNode;
typedef common::LinkHashValue<ObResTenantId> ObResColMapInfoValue;
class ObResourceManagerProxy;
class ObTenantResColMappingInfo : public ObResColMapInfoValue
{
private:
struct TableNameHashWrapper
@ -96,49 +100,45 @@ private:
struct ColumnNameKey
{
ColumnNameKey() : tenant_id_(0), database_id_(0), table_name_(), column_name_() {}
ColumnNameKey() : database_id_(0), table_name_(), column_name_() {}
ColumnNameKey(uint64_t tenant_id, uint64_t database_id,
common::ObString table_name, common::ObString column_name,
common::ObNameCaseMode name_case_mode) :
tenant_id_(tenant_id), database_id_(database_id),
table_name_(tenant_id_, database_id_, name_case_mode, table_name),
database_id_(database_id),
table_name_(tenant_id, database_id, name_case_mode, table_name),
column_name_(column_name)
{ }
uint64_t tenant_id_;
uint64_t database_id_;
TableNameHashWrapper table_name_;
ColumnNameHashWrapper column_name_;
inline uint64_t hash() const
{
uint64_t hash_val = (tenant_id_ << 32) | database_id_;
uint64_t hash_val = database_id_;
hash_val = table_name_.hash(hash_val);
hash_val = column_name_.hash(hash_val);
return hash_val;
}
inline bool operator==(const ColumnNameKey& key) const
{
return tenant_id_ == key.tenant_id_
&& database_id_ == key.database_id_
return database_id_ == key.database_id_
&& table_name_ == key.table_name_
&& column_name_ == key.column_name_;
}
TO_STRING_KV(K(tenant_id_), K(database_id_), K(table_name_), K(column_name_));
TO_STRING_KV(K(database_id_), K(table_name_), K(column_name_));
};
struct RuleValueKey
{
RuleValueKey() : tenant_id_(common::OB_INVALID_ID), rule_id_(common::OB_INVALID_ID),
user_name_(), literal_value_() {}
RuleValueKey(uint64_t tenant_id, uint64_t rule_id, common::ObString user_name, common::ObString literal_value) :
tenant_id_(tenant_id), rule_id_(rule_id), user_name_(user_name), literal_value_(literal_value)
RuleValueKey() : rule_id_(common::OB_INVALID_ID), user_name_(), literal_value_() {}
RuleValueKey(uint64_t rule_id, common::ObString user_name, common::ObString literal_value) :
rule_id_(rule_id), user_name_(user_name), literal_value_(literal_value)
{ }
uint64_t tenant_id_;
uint64_t rule_id_;
// user name is case sensitive.
common::ObString user_name_;
common::ObString literal_value_;
inline uint64_t hash() const
{
uint64_t hash_val = tenant_id_;
uint64_t hash_val = 0;
hash_val = common::murmurhash(&rule_id_, sizeof(uint64_t), hash_val);
hash_val = common::murmurhash(user_name_.ptr(), user_name_.length(), hash_val);
hash_val = common::murmurhash(literal_value_.ptr(), literal_value_.length(), hash_val);
@ -146,12 +146,11 @@ private:
}
inline bool operator==(const RuleValueKey& key) const
{
return tenant_id_ == key.tenant_id_
&& rule_id_ == key.rule_id_
return rule_id_ == key.rule_id_
&& 0 == user_name_.compare(key.user_name_)
&& 0 == literal_value_.compare(key.literal_value_);
}
TO_STRING_KV(K(tenant_id_), K(rule_id_), K(user_name_), K(literal_value_));
TO_STRING_KV(K(rule_id_), K(user_name_), K(literal_value_));
};
struct RuleValue
{
@ -159,14 +158,14 @@ private:
RuleValue(uint64_t group_id, common::ObString user_name, common::ObString literal_value) :
group_id_(group_id), user_name_ptr_(user_name.ptr()), literal_value_ptr_(literal_value.ptr())
{ }
void release_memory()
void release_memory(common::ObIAllocator &allocator)
{
if (NULL != user_name_ptr_) {
ob_free(user_name_ptr_);
allocator.free(user_name_ptr_);
user_name_ptr_ = NULL;
}
if (OB_NOT_NULL(literal_value_ptr_)) {
ob_free(literal_value_ptr_);
allocator.free(literal_value_ptr_);
literal_value_ptr_ = NULL;
}
}
@ -175,31 +174,76 @@ private:
char *literal_value_ptr_;
TO_STRING_KV(K(group_id_), KP(user_name_ptr_), KP(literal_value_ptr_));
};
public:
ObTenantResColMappingInfo()
{}
int init(uint64_t tenant_id);
int refresh(sql::ObPlanCache *plan_cache, const common::ObString &plan);
int get_rule_id(uint64_t tenant_id, uint64_t database_id, const common::ObString &table_name,
const common::ObString &column_name, common::ObNameCaseMode case_mode,
uint64_t &rule_id);
int get_group_id(uint64_t rule_id, const ObString &user_name,
const common::ObString &literal_value, uint64_t &group_id);
int64_t get_version() { return version_; }
private:
uint64_t tenant_id_;
//avoid concurrent modification on maps.
obutil::Mutex lock_;
ObArenaAllocator allocator_;
common::hash::ObHashMap<ColumnNameKey, uint64_t> rule_id_map_;
common::hash::ObHashMap<RuleValueKey, RuleValue> group_id_map_;
int64_t version_;
};
class ObResourceColMappingRuleManager
{
private:
class AllocHandle
{
public:
static ObTenantResColMappingInfo *alloc_value() { return NULL; }
static void free_value(ObTenantResColMappingInfo *info)
{
if (NULL != info) {
info->~ObTenantResColMappingInfo();
ob_free(info);
info = NULL;
}
}
static ObResColMapInfoNode *alloc_node(ObTenantResColMappingInfo *p)
{
UNUSED(p);
return OB_NEW(ObResColMapInfoNode, "ResRuleInfoMap");
}
static void free_node(ObResColMapInfoNode *node)
{
if (NULL != node) {
OB_DELETE(ObResColMapInfoNode, "ResRuleInfoMap", node);
node = NULL;
}
}
};
public:
ObResourceColMappingRuleManager(): inited_(false)
{ }
virtual ~ObResourceColMappingRuleManager() = default;
int init();
int add_tenant(uint64_t tenant_id);
int drop_tenant(uint64_t tenant_id);
int refresh_resource_column_mapping_rule(uint64_t tenant_id,
sql::ObPlanCache *plan_cache,
const common::ObString &plan);
uint64_t get_column_mapping_rule_id(uint64_t tenant_id, uint64_t database_id,
const common::ObString &table_name,
const common::ObString &column_name,
common::ObNameCaseMode case_mode) const;
common::ObNameCaseMode case_mode);
uint64_t get_column_mapping_group_id(uint64_t tenant_id, uint64_t rule_id,
const common::ObString &user_name,
const common::ObString &literal_value);
int64_t get_column_mapping_version(uint64_t tenant_id);
private:
// get version of inner table data in __all_sys_stat.
int query_inner_table_version(int64_t &current_version);
private:
//avoid concurrent modification on maps.
obutil::Mutex lock_;
common::hash::ObHashMap<ColumnNameKey, uint64_t> rule_id_map_;
common::hash::ObHashMap<RuleValueKey, RuleValue> group_id_map_;
common::hash::ObHashMap<uint64_t, int64_t> tenant_version_;
common::ObLinkHashMap<ObResTenantId, ObTenantResColMappingInfo, AllocHandle> tenant_rule_infos_;
bool inited_;
DISALLOW_COPY_AND_ASSIGN(ObResourceColMappingRuleManager);

View File

@ -1937,6 +1937,7 @@ int ObResourceManagerProxy::parse_column_mapping_rule(ObString &value,
int ObResourceManagerProxy::get_all_resource_mapping_rules_by_column(
uint64_t tenant_id,
const common::ObString &plan,
ObIAllocator &allocator,
common::ObIArray<ObResourceColumnMappingRule> &rules)
{
int ret = OB_SUCCESS;
@ -1999,11 +2000,11 @@ int ObResourceManagerProxy::get_all_resource_mapping_rules_by_column(
LOG_WARN("get database_id", K(ret));
} else if (OB_INVALID_ID == database_id) {
// do nothing
} else if (OB_FAIL(rule.write_string_values(tenant_id, table_name, column_name,
literal_value, user_name))) {
LOG_WARN("write string values failed", K(ret));
} else if (OB_FAIL(schema_guard.get_tenant_name_case_mode(tenant_id, case_mode))) {
LOG_WARN("get tenant name case mode failed", K(ret));
} else if (OB_FAIL(rule.write_string_values(tenant_id, table_name, column_name,
literal_value, user_name, allocator))) {
LOG_WARN("write string values failed", K(ret));
} else {
rule.set_database_id(database_id);
// get and set case mode in oracle mode is ok. When TableNameHashWrapper compare
@ -2011,7 +2012,7 @@ int ObResourceManagerProxy::get_all_resource_mapping_rules_by_column(
rule.set_case_mode(case_mode);
if (OB_FAIL(rules.push_back(rule))) {
LOG_WARN("fail push back rules", K(rule), K(ret));
rule.reset();
rule.reset(allocator);
}
}
}

View File

@ -152,6 +152,7 @@ public:
int get_all_resource_mapping_rules_by_column(
uint64_t tenant_id,
const common::ObString &plan,
ObIAllocator &allocator,
common::ObIArray<ObResourceColumnMappingRule> &rules);
int get_next_element(
const common::ObString &value,

View File

@ -111,55 +111,55 @@ int ObResourceColumnMappingRule::assign(const ObResourceColumnMappingRule &other
return OB_SUCCESS;
}
void ObResourceColumnMappingRule::reset_table_column_name()
void ObResourceColumnMappingRule::reset_table_column_name(ObIAllocator &allocator)
{
if (OB_NOT_NULL(table_name_.ptr())) {
ob_free(table_name_.ptr());
allocator.free(table_name_.ptr());
table_name_.reset();
}
if (OB_NOT_NULL(column_name_.ptr())) {
ob_free(column_name_.ptr());
allocator.free(column_name_.ptr());
column_name_.reset();
}
}
void ObResourceColumnMappingRule::reset_user_name_literal()
void ObResourceColumnMappingRule::reset_user_name_literal(ObIAllocator &allocator)
{
if (OB_NOT_NULL(literal_value_.ptr())) {
ob_free(literal_value_.ptr());
allocator.free(literal_value_.ptr());
literal_value_.reset();
}
if (OB_NOT_NULL(user_name_.ptr())) {
ob_free(user_name_.ptr());
allocator.free(user_name_.ptr());
user_name_.reset();
}
}
int ObResourceColumnMappingRule::write_string_values(uint64_t tenant_id,
common::ObString table_name, common::ObString column_name,
common::ObString literal_value, common::ObString user_name)
common::ObString literal_value, common::ObString user_name,
ObIAllocator &allocator)
{
int ret = OB_SUCCESS;
ObMemAttr attr(tenant_id, "ResColMapRule");
void *table_name_buf = ob_malloc(table_name.length(), attr);
void *column_name_buf = ob_malloc(column_name.length(), attr);
void *literal_value_buf = ob_malloc(literal_value.length(), attr);
void *user_name_buf = user_name.empty() ? NULL : ob_malloc(user_name.length(), attr);
void *table_name_buf = allocator.alloc(table_name.length());
void *column_name_buf = allocator.alloc(column_name.length());
void *literal_value_buf = allocator.alloc(literal_value.length());
void *user_name_buf = user_name.empty() ? NULL : allocator.alloc(user_name.length());
if (OB_ISNULL(table_name_buf) || OB_ISNULL(column_name_buf)
|| OB_ISNULL(literal_value_buf)
|| (!user_name.empty() && OB_ISNULL(user_name_buf))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret), K(literal_value));
if (NULL != table_name_buf) {
ob_free(table_name_buf);
allocator.free(table_name_buf);
}
if (NULL != column_name_buf) {
ob_free(column_name_buf);
allocator.free(column_name_buf);
}
if (NULL != literal_value_buf) {
ob_free(literal_value_buf);
allocator.free(literal_value_buf);
}
if (NULL != user_name_buf) {
ob_free(user_name_buf);
allocator.free(user_name_buf);
}
} else {
MEMCPY(table_name_buf, table_name.ptr(), table_name.length());

View File

@ -419,13 +419,14 @@ public:
void set_case_mode(common:: ObNameCaseMode case_mode) { case_mode_ = case_mode; }
int write_string_values(uint64_t tenant_id,
common::ObString table_name, common::ObString column_name,
common::ObString literal_value, common::ObString user_name);
void reset_table_column_name();
void reset_user_name_literal();
void reset()
common::ObString literal_value, common::ObString user_name,
ObIAllocator &allocator);
void reset_table_column_name(ObIAllocator &allocator);
void reset_user_name_literal(ObIAllocator &allocator);
void reset(ObIAllocator &allocator)
{
reset_table_column_name();
reset_user_name_literal();
reset_table_column_name(allocator);
reset_user_name_literal(allocator);
}
int assign(const ObResourceColumnMappingRule &other);
TO_STRING_KV(K_(tenant_id), K_(database_id), K_(table_name), K_(column_name),