patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -16,182 +16,69 @@
#include "sql/engine/ob_physical_plan.h"
#include "sql/ob_sql.h"
#include "sql/plan_cache/ob_plan_cache.h"
#include "pl/ob_pl.h"
#include "pl/ob_pl_package.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 {
namespace oceanbase
{
using namespace common;
using namespace pl;
using namespace lib;
namespace sql {
namespace sql
{
int ObCacheObjectFactory::alloc(ObPhysicalPlan*& plan, const CacheRefHandleID ref_handle, uint64_t tenant_id)
int ObCacheObjectFactory::alloc(ObCacheObjGuard& guard, ObLibCacheNameSpace ns, 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)) {
ObPlanCache *lib_cache = get_plan_cache(tenant_id);
if (OB_ISNULL(lib_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));
LOG_WARN("invalid null plan cache", K(ret));
} else if (OB_FAIL(lib_cache->alloc_cache_obj(guard, ns, tenant_id))) {
LOG_WARN("failed to alloc cache obj", K(ret), K(ns));
}
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 (!plan_cache->is_valid()) {
// do nothing
} else 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;
if (NULL != lib_cache) {
lib_cache->dec_ref_count();
lib_cache = NULL;
}
return ret;
}
void ObCacheObjectFactory::common_free(ObCacheObject* cache_obj, const CacheRefHandleID ref_handle)
void ObCacheObjectFactory::inner_free(ObILibCacheObject *&cache_obj,
const CacheRefHandleID ref_handle)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(cache_obj)) {
// nothing to do
uint64_t tenant_id = cache_obj->get_tenant_id();
ObPlanCache *lib_cache = get_plan_cache(tenant_id);
if (OB_ISNULL(lib_cache)) {
LOG_WARN("invalid null plan cache");
} 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));
}
lib_cache->free_cache_obj(cache_obj, ref_handle);
}
if (NULL != lib_cache) {
lib_cache->dec_ref_count();
lib_cache = NULL;
}
}
void ObCacheObjectFactory::inner_free(ObCacheObject* cache_obj)
void ObCacheObjectFactory::inner_free(ObPlanCache *pc,
ObILibCacheObject *&cache_obj,
const CacheRefHandleID ref_handle)
{
int ret = OB_SUCCESS;
MemoryContext entity = cache_obj->get_mem_context();
WITH_CONTEXT(entity)
{
cache_obj->~ObCacheObject();
if (OB_ISNULL(pc)) {
LOG_WARN("invalid null plan cache");
} else {
pc->free_cache_obj(cache_obj, ref_handle);
}
cache_obj = NULL;
DESTROY_CONTEXT(entity);
}
ObPlanCache* ObCacheObjectFactory::get_plan_cache(const uint64_t tenant_id)
ObPlanCache *ObCacheObjectFactory::get_plan_cache(const uint64_t tenant_id)
{
ObPlanCache* ret_pc = NULL;
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) {
@ -200,32 +87,40 @@ ObPlanCache* ObCacheObjectFactory::get_plan_cache(const uint64_t 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);
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 ObCacheObjectFactory::destroy_cache_obj(const bool is_leaked,
const uint64_t obj_id,
ObPlanCache *lib_cache)
{
int ret = OB_SUCCESS;
ObCacheObject* to_del_obj;
if (OB_ISNULL(plan_cache)) {
if (OB_ISNULL(lib_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);
LOG_WARN("invalid null plan cache", K(ret));
} else if (OB_FAIL(lib_cache->destroy_cache_obj(is_leaked, obj_id))) {
LOG_WARN("failed to destory cache obj", K(ret), K(is_leaked), K(obj_id));
}
return ret;
}
} // end namespace sql
} // namespace oceanbase
int ObCacheObjGuard::force_early_release(ObPlanCache *plan_cache)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(cache_obj_)) {
// do nothing
} else if (OB_ISNULL(plan_cache)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("is null", K(ret));
} else {
ObCacheObjectFactory::free(plan_cache, cache_obj_, ref_handle_);
cache_obj_ = NULL;
}
return ret;
}
} //end namespace sql
} //namespace oceanbase