Solve the problem that CreateContext occupies 500 tenant memory

This commit is contained in:
obdev
2023-05-29 17:41:06 +00:00
committed by ob-robot
parent 17c75534d0
commit 76e17ac719
8 changed files with 36 additions and 17 deletions

View File

@ -27,7 +27,8 @@ namespace sql
int ObLCNodeFactory::create_cache_node(ObLibCacheNameSpace ns,
ObILibCacheNode*& node,
uint64_t tenant_id)
uint64_t tenant_id,
MemoryContext &parent_context)
{
int ret = OB_SUCCESS;
lib::MemoryContext entity = NULL;
@ -41,8 +42,8 @@ int ObLCNodeFactory::create_cache_node(ObLibCacheNameSpace ns,
ret = OB_INVALID_ARGUMENT;
LOG_WARN("out of the max type", K(ret), K(ns));
} else if (FALSE_IT(mem_attr.label_ = LC_NS_TYPE_LABELS[ns])) {
} else if (OB_FAIL(ROOT_CONTEXT->CREATE_CONTEXT(entity,
lib::ContextParam().set_mem_attr(mem_attr)))) {
} else if (OB_FAIL(parent_context->CREATE_CONTEXT(entity,
lib::ContextParam().set_mem_attr(mem_attr)))) {
LOG_WARN("create entity failed", K(ret), K(mem_attr));
} else if (OB_ISNULL(entity)) {
ret = OB_ERR_UNEXPECTED;

View File

@ -34,7 +34,8 @@ public:
void destroy_cache_node(ObILibCacheNode* node);
int create_cache_node(ObLibCacheNameSpace ns,
ObILibCacheNode*& node,
uint64_t tenant_id);
uint64_t tenant_id,
lib::MemoryContext &parent_context);
template<typename ClassT>
static int create(lib::MemoryContext &mem_ctx, ObILibCacheNode*& node, ObPlanCache *lib_cache);

View File

@ -45,7 +45,8 @@ int ObLCObjectManager::init(int64_t hash_bucket, uint64_t tenant_id)
int ObLCObjectManager::alloc(ObCacheObjGuard& guard,
ObLibCacheNameSpace ns,
uint64_t tenant_id)
uint64_t tenant_id,
MemoryContext &parent_context)
{
int ret = OB_SUCCESS;
lib::MemoryContext entity = NULL;
@ -60,7 +61,7 @@ int ObLCObjectManager::alloc(ObCacheObjGuard& guard,
ret = OB_INVALID_ARGUMENT;
LOG_WARN("out of the max type", K(ret), K(ns));
} else if (FALSE_IT(mem_attr.label_ = LC_NS_TYPE_LABELS[ns])) {
} else if (OB_FAIL(ROOT_CONTEXT->CREATE_CONTEXT(entity,
} else if (OB_FAIL(parent_context->CREATE_CONTEXT(entity,
lib::ContextParam().set_mem_attr(mem_attr)))) {
LOG_WARN("create entity failed", K(ret), K(mem_attr));
} else if (OB_ISNULL(entity)) {
@ -187,4 +188,3 @@ void ObLCObjectManager::inner_free(ObILibCacheObject *cache_obj)
} // namespace common
} // namespace oceanbase

View File

@ -29,12 +29,13 @@ class ObLCObjectManager
{
public:
typedef common::hash::ObHashMap<ObCacheObjID, ObILibCacheObject*> IdCacheObjectMap;
ObLCObjectManager() : object_id_(0) {}
int init(int64_t hash_bucket, uint64_t tenant_id);
int alloc(ObCacheObjGuard& guard,
ObLibCacheNameSpace ns,
uint64_t tenant_id);
uint64_t tenant_id,
lib::MemoryContext &parent_context);
int destroy_cache_obj(const bool is_leaked,
const uint64_t object_id);
void free(ObILibCacheObject *&obj, const CacheRefHandleID ref_handle)
@ -75,14 +76,14 @@ private:
* cache node
* | | |
* cache_obj cache_obj cache_obj
*
*
* In the library cache, each key corresponds to a cache node structure, which is very
* inconvenient when traversing the output of the virtual table, so a map of key-cache_obj
* is used to facilitate traversal.
*/
IdCacheObjectMap cache_obj_map_;
/**
*
*
* All cache_obj objects created by the alloc method will have their reference count incremented
* and added to alloc_cache_obj_map_. when the free method is called, if the reference count of the
* cache_obj object decreases to 0, it will be removed from alloc_cache_obj_map_. the role of

View File

@ -28,7 +28,6 @@ namespace oceanbase
namespace common
{
class ObIAllocator;
class MemoryContext;
}
namespace sql
{

View File

@ -322,6 +322,10 @@ void ObPlanCache::destroy()
if (OB_SUCCESS != (cache_evict_all_obj())) {
SQL_PC_LOG_RET(WARN, OB_ERROR, "fail to evict all lib cache cache");
}
if (root_context_ != NULL) {
DESTROY_CONTEXT(root_context_);
root_context_ = NULL;
}
inited_ = false;
}
}
@ -331,7 +335,13 @@ int ObPlanCache::init(int64_t hash_bucket, uint64_t tenant_id)
int ret = OB_SUCCESS;
if (!inited_) {
ObPCMemPctConf default_conf;
if (OB_FAIL(co_mgr_.init(hash_bucket, tenant_id))) {
ObMemAttr attr(tenant_id, "PlanCache", ObCtxIds::PLAN_CACHE_CTX_ID);
lib::ContextParam param;
param.set_properties(lib::ADD_CHILD_THREAD_SAFE | lib::ALLOC_THREAD_SAFE)
.set_mem_attr(attr);
if (OB_FAIL(ROOT_CONTEXT->CREATE_CONTEXT(root_context_, param))) {
SQL_PC_LOG(WARN, "failed to create context", K(ret));
} else if (OB_FAIL(co_mgr_.init(hash_bucket, tenant_id))) {
SQL_PC_LOG(WARN, "failed to init lib cache manager", K(ret));
} else if (OB_FAIL(cache_key_node_map_.create(hash::cal_next_prime(hash_bucket),
ObModIds::OB_HASH_BUCKET_PLAN_CACHE,
@ -358,6 +368,12 @@ int ObPlanCache::init(int64_t hash_bucket, uint64_t tenant_id)
ref_handle_mgr_.set_tenant_id(tenant_id_);
inited_ = true;
}
if (OB_FAIL(ret)) {
if (root_context_ != NULL) {
DESTROY_CONTEXT(root_context_);
root_context_ = NULL;
}
}
}
return ret;
}
@ -1306,8 +1322,9 @@ int ObPlanCache::create_node_and_add_cache_obj(ObILibCacheKey *cache_key,
ret = OB_INVALID_ARGUMENT;
SQL_PC_LOG(WARN, "invalid argument", K(ret), K(cache_key), K(cache_obj));
} else if (OB_FAIL(cn_factory_.create_cache_node(cache_key->namespace_,
cache_node,
tenant_id_))) {
cache_node,
tenant_id_,
root_context_))) {
SQL_PC_LOG(WARN, "failed to create cache node", K(ret), K_(cache_key->namespace), K_(tenant_id));
} else {
// reference count after constructing cache node
@ -1846,7 +1863,7 @@ int ObPlanCache::add_stat_for_cache_obj(ObILibCacheCtx &ctx, ObILibCacheObject *
int ObPlanCache::alloc_cache_obj(ObCacheObjGuard& guard, ObLibCacheNameSpace ns, uint64_t tenant_id)
{
int ret = OB_SUCCESS;
if (OB_FAIL(co_mgr_.alloc(guard, ns, tenant_id))) {
if (OB_FAIL(co_mgr_.alloc(guard, ns, tenant_id, root_context_))) {
LOG_WARN("failed to alloc cache obj", K(ret));
}
return ret;

View File

@ -441,6 +441,7 @@ private:
int64_t mem_low_pct_; // low water mark percentage
int64_t mem_used_; // mem used now
int64_t bucket_num_;
lib::MemoryContext root_context_;
common::ObMalloc inner_allocator_;
common::ObAddr host_;
ObPlanCacheStat pc_stat_;