init push

This commit is contained in:
oceanbase-admin
2021-05-31 22:56:52 +08:00
commit cea7de1475
7020 changed files with 5689869 additions and 0 deletions

View File

@ -0,0 +1,229 @@
/**
* Copyright (c) 2021 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 SQL_PC
#include "sql/plan_cache/ob_cache_object_factory.h"
#include "sql/engine/ob_physical_plan.h"
#include "sql/ob_sql.h"
#include "sql/plan_cache/ob_plan_cache.h"
#include "lib/alloc/malloc_hook.h"
#include "lib/allocator/page_arena.h"
#include "lib/allocator/ob_malloc.h"
#include "observer/ob_server_struct.h"
#include "observer/ob_req_time_service.h"
namespace oceanbase {
using namespace common;
using namespace lib;
namespace sql {
int ObCacheObjectFactory::alloc(ObPhysicalPlan*& plan, const CacheRefHandleID ref_handle, uint64_t tenant_id)
{
int ret = OB_SUCCESS;
ObCacheObject* cache_obj = NULL;
if (OB_FAIL(alloc(cache_obj, ref_handle, T_CO_SQL_CRSR, tenant_id))) {
LOG_WARN("alloc physical plan failed", K(ret), K(tenant_id));
} else if (OB_ISNULL(cache_obj) || OB_UNLIKELY(!cache_obj->is_sql_crsr())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("cache object is invalid", KPC(cache_obj));
} else {
plan = static_cast<ObPhysicalPlan*>(cache_obj);
}
if (OB_FAIL(ret) && cache_obj != NULL) {
ObCacheObjectFactory::free(cache_obj, ref_handle);
cache_obj = NULL;
}
return ret;
}
int ObCacheObjectFactory::alloc(
ObCacheObject*& cache_obj, const CacheRefHandleID ref_handle, ObCacheObjType co_type, uint64_t tenant_id)
{
int ret = OB_SUCCESS;
void* buf = NULL;
observer::ObGlobalReqTimeService::check_req_timeinfo();
ObMemAttr mem_attr;
mem_attr.tenant_id_ = tenant_id;
ObPlanCache* plan_cache = get_plan_cache(tenant_id);
if (T_CO_PRCR == co_type || T_CO_PKG == co_type || T_CO_ANON == co_type) {
mem_attr.label_ = ObNewModIds::OB_SQL_PHY_PL_OBJ;
} else {
mem_attr.label_ = ObNewModIds::OB_SQL_PHY_PLAN;
}
mem_attr.ctx_id_ = ObCtxIds::PLAN_CACHE_CTX_ID;
MemoryContext* entity = NULL;
if (OB_UNLIKELY(co_type < T_CO_SQL_CRSR) || OB_UNLIKELY(co_type >= T_CO_MAX) || OB_ISNULL(plan_cache)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("co_type is invalid", K(co_type), K(plan_cache), K(tenant_id));
} else if (OB_FAIL(ROOT_CONTEXT.CREATE_CONTEXT(entity, lib::ContextParam().set_mem_attr(mem_attr)))) {
LOG_WARN("create entity failed", K(ret), K(mem_attr));
} else if (NULL == entity) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("NULL memory entity", K(ret));
}
if (OB_SUCC(ret)) {
WITH_CONTEXT(entity)
{
switch (co_type) {
case T_CO_SQL_CRSR:
if (NULL != (buf = entity->get_arena_allocator().alloc(sizeof(ObPhysicalPlan)))) {
cache_obj = new (buf) ObPhysicalPlan(*entity);
}
break;
case T_CO_ANON:
case T_CO_PRCR:
case T_CO_PKG:
default:
break;
}
}
}
if (OB_SUCC(ret)) {
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
OB_LOG(ERROR, "fail to alloc cache obj", K(ret), KP(buf), K(co_type));
} else {
cache_obj->set_tenant_id(tenant_id);
uint64_t cache_obj_id = plan_cache->allocate_plan_id();
cache_obj->object_id_ = cache_obj_id;
cache_obj->inc_ref_count(ref_handle);
/*
* to deconstruct the CacheObject object, you must first remove the corresponding kv pair from the deleted_map,
* then the atomicity of hashmap can ensure that only one thread does the removal action, and
* only this thread gets the CacheObject pointer to do subsequent destructuring
*/
if (OB_FAIL(plan_cache->get_deleted_map().set_refactored(cache_obj_id, cache_obj))) {
LOG_WARN("failed to add element to hashmap", K(ret));
inner_free(cache_obj);
cache_obj = NULL;
entity = NULL;
}
}
}
if (OB_FAIL(ret) && NULL != entity) {
DESTROY_CONTEXT(entity);
entity = NULL;
}
if (NULL != plan_cache) {
plan_cache->dec_ref_count();
plan_cache = NULL;
}
return ret;
}
void ObCacheObjectFactory::common_free(ObCacheObject* cache_obj, const CacheRefHandleID ref_handle)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(cache_obj)) {
// nothing to do
} else {
int64_t ref_count = cache_obj->dec_ref_count(ref_handle);
if (ref_count > 0) {
if (!cache_obj->added_pc()) {
cache_obj->set_logical_del_time(ObTimeUtility::current_monotonic_time());
LOG_WARN("set logical del time",
K(cache_obj->get_logical_del_time()),
K(cache_obj->added_pc()),
K(cache_obj->get_object_id()),
K(cache_obj->get_tenant_id()),
K(lbt()));
}
} else if (ref_count == 0) {
uint64_t tenant_id = cache_obj->get_tenant_id();
ObPlanCache* plan_cache = get_plan_cache(tenant_id);
if (cache_obj->get_pre_calc_expr_handler() != NULL) {
LOG_DEBUG("dec pre calculabe expression.",
KP(cache_obj->get_pre_calc_expr_handler()),
KP(cache_obj),
K(cache_obj->get_pre_expr_ref_count()));
}
// decrease reference and remove it when reference count is ZERO.
cache_obj->dec_pre_expr_ref_count();
if (OB_FAIL(ret)) {
// do nothing
} else if (OB_ISNULL(plan_cache)) {
// if plan cache is marked by destroyed_, this is not a ERROR.
LOG_WARN("invalid null plan cache", K(ret), K(tenant_id));
} else if (OB_FAIL(destroy_cache_obj(false, cache_obj->get_object_id(), plan_cache))) {
LOG_WARN("failed to destroy cache obj", K(ret));
}
if (NULL != plan_cache) {
plan_cache->dec_ref_count();
plan_cache = NULL;
}
} else {
LOG_ERROR("invalid plan ref count", K(ref_count), KP(cache_obj));
}
}
}
void ObCacheObjectFactory::inner_free(ObCacheObject* cache_obj)
{
int ret = OB_SUCCESS;
MemoryContext& entity = cache_obj->get_mem_context();
WITH_CONTEXT(&entity)
{
cache_obj->~ObCacheObject();
}
cache_obj = NULL;
DESTROY_CONTEXT(&entity);
}
ObPlanCache* ObCacheObjectFactory::get_plan_cache(const uint64_t tenant_id)
{
ObPlanCache* ret_pc = NULL;
uint64_t used_tenant_id = tenant_id;
ObPCMemPctConf default_conf;
if (tenant_id > OB_SYS_TENANT_ID && tenant_id <= OB_MAX_RESERVED_TENANT_ID) {
used_tenant_id = OB_SYS_TENANT_ID;
}
if (OB_ISNULL(GCTX.sql_engine_) || OB_ISNULL(GCTX.sql_engine_->get_plan_cache_manager())) {
LOG_WARN("invalid null sql engine", K(GCTX.sql_engine_));
} else {
ret_pc = GCTX.sql_engine_->get_plan_cache_manager()->get_or_create_plan_cache(used_tenant_id, default_conf);
}
return ret_pc;
}
int ObCacheObjectFactory::destroy_cache_obj(const bool is_leaked, const uint64_t obj_id, ObPlanCache* plan_cache)
{
int ret = OB_SUCCESS;
ObCacheObject* to_del_obj;
if (OB_ISNULL(plan_cache)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(plan_cache));
} else if (OB_FAIL(plan_cache->get_deleted_map().erase_refactored(obj_id, &to_del_obj))) {
if (OB_HASH_NOT_EXIST == ret) {
ret = OB_SUCCESS;
} else {
LOG_WARN("failed to erase element from deleted map", K(obj_id), K(ret));
}
} else if (OB_ISNULL(to_del_obj)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid cache obj", K(to_del_obj));
} else {
to_del_obj->dump_deleted_log_info(!is_leaked);
inner_free(to_del_obj);
}
return ret;
}
} // end namespace sql
} // namespace oceanbase