diff --git a/src/observer/virtual_table/ob_all_plan_cache_stat.cpp b/src/observer/virtual_table/ob_all_plan_cache_stat.cpp index 26f038c672..90dd044273 100644 --- a/src/observer/virtual_table/ob_all_plan_cache_stat.cpp +++ b/src/observer/virtual_table/ob_all_plan_cache_stat.cpp @@ -209,7 +209,7 @@ int ObAllPlanCacheStat::fill_cells(ObPlanCache &plan_cache) break; } case GV_SQL: { - SET_REF_HANDLE_COL(GV_SQL_HANDLE); + SET_REF_HANDLE_COL(PC_DIAG_HANDLE); break; } case PL_ANON: { diff --git a/src/observer/virtual_table/ob_all_virtual_sql_plan.cpp b/src/observer/virtual_table/ob_all_virtual_sql_plan.cpp index ce4d189d4d..9c9e3a1638 100644 --- a/src/observer/virtual_table/ob_all_virtual_sql_plan.cpp +++ b/src/observer/virtual_table/ob_all_virtual_sql_plan.cpp @@ -557,11 +557,11 @@ int ObAllVirtualSqlPlan::prepare_next_plan() // !!!引用plan cache资源之前必须加ObReqTimeGuard ObReqTimeGuard req_timeinfo_guard; ObPlanCache *plan_cache = NULL; - ObCacheObjGuard guard(SQL_PLAN_HANDLE); + ObCacheObjGuard guard(PC_DIAG_HANDLE); int tmp_ret = OB_SUCCESS; MTL_SWITCH(tenant_id_) { plan_cache = MTL(ObPlanCache*); - if (OB_SUCCESS != (tmp_ret = plan_cache->ref_plan(plan_id_, guard))) { + if (OB_SUCCESS != (tmp_ret = plan_cache->ref_alloc_plan(plan_id_, guard))) { // should not panic } else if (FALSE_IT(plan = static_cast(guard.get_cache_obj()))) { // do nothing diff --git a/src/observer/virtual_table/ob_gv_sql.cpp b/src/observer/virtual_table/ob_gv_sql.cpp index 1d3cac473f..efa0279acd 100644 --- a/src/observer/virtual_table/ob_gv_sql.cpp +++ b/src/observer/virtual_table/ob_gv_sql.cpp @@ -83,7 +83,7 @@ int ObGVSql::get_row_from_specified_tenant(uint64_t tenant_id, bool &is_end) plan_cache_ = MTL(ObPlanCache*); NG_TRACE(trav_ps_map_start); ObGetAllCacheIdOp plan_id_op(&plan_id_array_); - if (OB_FAIL(plan_cache_->foreach_cache_obj(plan_id_op))) { + if (OB_FAIL(plan_cache_->foreach_alloc_cache_obj(plan_id_op))) { SERVER_LOG(WARN, "fail to traverse id2stat_map"); } else { plan_id_array_idx_ = 0; @@ -113,8 +113,8 @@ int ObGVSql::get_row_from_specified_tenant(uint64_t tenant_id, bool &is_end) is_end = false; uint64_t plan_id= plan_id_array_.at(plan_id_array_idx_); ++plan_id_array_idx_; - ObCacheObjGuard guard(GV_SQL_HANDLE); - int tmp_ret = plan_cache_->ref_cache_obj(plan_id, guard); //plan引用计数加1 + ObCacheObjGuard guard(PC_DIAG_HANDLE); + int tmp_ret = plan_cache_->ref_alloc_obj(plan_id, guard); //plan引用计数加1 //如果当前plan_id对应的plan已被淘汰, 则忽略继续获取下一个plan if (OB_HASH_NOT_EXIST == tmp_ret) { diff --git a/src/sql/plan_cache/ob_lib_cache_object_manager.cpp b/src/sql/plan_cache/ob_lib_cache_object_manager.cpp index fe3024b495..5cce6650f8 100644 --- a/src/sql/plan_cache/ob_lib_cache_object_manager.cpp +++ b/src/sql/plan_cache/ob_lib_cache_object_manager.cpp @@ -132,7 +132,7 @@ void ObLCObjectManager::common_free(ObILibCacheObject *cache_obj, if (OB_ISNULL(cache_obj)) { // do nothing } else { - if (!cache_obj->added_lc()) { + if (ref_handle != PC_DIAG_HANDLE && !cache_obj->added_lc()) { 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_lc()), diff --git a/src/sql/plan_cache/ob_pc_ref_handle.cpp b/src/sql/plan_cache/ob_pc_ref_handle.cpp index 342d6c4ce3..636fd0e99a 100644 --- a/src/sql/plan_cache/ob_pc_ref_handle.cpp +++ b/src/sql/plan_cache/ob_pc_ref_handle.cpp @@ -65,7 +65,8 @@ const char* ObCacheRefHandleMgr::handle_name(const CacheRefHandleID handle_id) "plan_baseline_handle", "tableapi_node_handle", "sql_plan_handle", - "callstmt_handle" + "callstmt_handle", + "pc_diag_handle" }; static_assert(sizeof(handle_names)/sizeof(const char*) == MAX_HANDLE, "invalid handle name array"); if (handle_id < MAX_HANDLE) { diff --git a/src/sql/plan_cache/ob_pc_ref_handle.h b/src/sql/plan_cache/ob_pc_ref_handle.h index 7148f5e026..da78b6bade 100644 --- a/src/sql/plan_cache/ob_pc_ref_handle.h +++ b/src/sql/plan_cache/ob_pc_ref_handle.h @@ -130,6 +130,7 @@ enum CacheRefHandleID TABLEAPI_NODE_HANDLE, SQL_PLAN_HANDLE, CALLSTMT_HANDLE, + PC_DIAG_HANDLE, MAX_HANDLE }; diff --git a/src/sql/plan_cache/ob_plan_cache.cpp b/src/sql/plan_cache/ob_plan_cache.cpp index 96a8020a15..b260fbee93 100644 --- a/src/sql/plan_cache/ob_plan_cache.cpp +++ b/src/sql/plan_cache/ob_plan_cache.cpp @@ -1707,7 +1707,7 @@ int ObPlanCache::ref_cache_obj(const ObCacheObjID obj_id, ObCacheObjGuard& guard int ret = OB_SUCCESS; ObCacheObjAtomicOp op(guard.ref_handle_); ObGlobalReqTimeService::check_req_timeinfo(); - if (OB_FAIL(co_mgr_.atomic_get_alloc_cache_obj(obj_id, op))) { + if (OB_FAIL(co_mgr_.atomic_get_cache_obj(obj_id, op))) { SQL_PC_LOG(WARN, "failed to get update plan statistic", K(obj_id), K(ret)); } else if (NULL == op.get_value()) { ret = OB_HASH_NOT_EXIST; @@ -1736,6 +1736,40 @@ int ObPlanCache::ref_plan(const ObCacheObjID plan_id, ObCacheObjGuard& guard) return ret; } +int ObPlanCache::ref_alloc_obj(const ObCacheObjID obj_id, ObCacheObjGuard& guard) +{ + int ret = OB_SUCCESS; + ObCacheObjAtomicOp op(guard.ref_handle_); + ObGlobalReqTimeService::check_req_timeinfo(); + if (OB_FAIL(co_mgr_.atomic_get_alloc_cache_obj(obj_id, op))) { + SQL_PC_LOG(WARN, "failed to get update plan statistic", K(obj_id), K(ret)); + } else if (NULL == op.get_value()) { + ret = OB_HASH_NOT_EXIST; + } else { + guard.cache_obj_ = op.get_value(); + } + return ret; +} + +int ObPlanCache::ref_alloc_plan(const ObCacheObjID plan_id, ObCacheObjGuard& guard) +{ + int ret = OB_SUCCESS; + ObILibCacheObject *cache_obj = NULL; + ObGlobalReqTimeService::check_req_timeinfo(); + if (OB_FAIL(ref_alloc_obj(plan_id, guard))) { // inc ref count by 1 + LOG_WARN("failed to ref cache obj", K(ret)); + } else if (FALSE_IT(cache_obj = guard.cache_obj_)) { + // do nothing + } else if (OB_ISNULL(cache_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null cache object", K(ret)); + } else if (ObLibCacheNameSpace::NS_CRSR != cache_obj->get_ns()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("this cache object is not a plan.", K(ret), K(cache_obj->get_ns())); + } + return ret; +} + int ObPlanCache::add_cache_obj_stat(ObILibCacheCtx &ctx, ObILibCacheObject *cache_obj) { int ret = OB_SUCCESS; diff --git a/src/sql/plan_cache/ob_plan_cache.h b/src/sql/plan_cache/ob_plan_cache.h index da99972751..b30c83a4f1 100644 --- a/src/sql/plan_cache/ob_plan_cache.h +++ b/src/sql/plan_cache/ob_plan_cache.h @@ -26,6 +26,11 @@ #include "sql/plan_cache/ob_lib_cache_object_manager.h" namespace oceanbase { +namespace observer +{ + class ObGVSql; + class ObAllVirtualSqlPlan; +} namespace rpc { class ObLoadBaselineArg; @@ -221,6 +226,8 @@ class ObPlanCache { friend class ObCacheObjectFactory; friend class ObPlanCacheEliminationTask; +friend class observer::ObAllVirtualSqlPlan; +friend class observer::ObGVSql; public: static const int64_t MAX_PLAN_SIZE = 20*1024*1024; //20M @@ -421,6 +428,10 @@ public: int flush_lib_cache_by_ns(const ObLibCacheNameSpace ns); int flush_pl_cache(); +protected: + int ref_alloc_obj(const ObCacheObjID obj_id, ObCacheObjGuard& guard); + int ref_alloc_plan(const ObCacheObjID obj_id, ObCacheObjGuard& guard); + private: DISALLOW_COPY_AND_ASSIGN(ObPlanCache); int add_plan_cache(ObILibCacheCtx &ctx,