fix bug: plan cache core is caused by the plan cache diagnostic view.
This commit is contained in:
		@ -209,7 +209,7 @@ int ObAllPlanCacheStat::fill_cells(ObPlanCache &plan_cache)
 | 
				
			|||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case GV_SQL: {
 | 
					    case GV_SQL: {
 | 
				
			||||||
      SET_REF_HANDLE_COL(GV_SQL_HANDLE);
 | 
					      SET_REF_HANDLE_COL(PC_DIAG_HANDLE);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    case PL_ANON: {
 | 
					    case PL_ANON: {
 | 
				
			||||||
 | 
				
			|||||||
@ -557,11 +557,11 @@ int ObAllVirtualSqlPlan::prepare_next_plan()
 | 
				
			|||||||
    // !!!引用plan cache资源之前必须加ObReqTimeGuard
 | 
					    // !!!引用plan cache资源之前必须加ObReqTimeGuard
 | 
				
			||||||
    ObReqTimeGuard req_timeinfo_guard;
 | 
					    ObReqTimeGuard req_timeinfo_guard;
 | 
				
			||||||
    ObPlanCache *plan_cache = NULL;
 | 
					    ObPlanCache *plan_cache = NULL;
 | 
				
			||||||
    ObCacheObjGuard guard(SQL_PLAN_HANDLE);
 | 
					    ObCacheObjGuard guard(PC_DIAG_HANDLE);
 | 
				
			||||||
    int tmp_ret = OB_SUCCESS;
 | 
					    int tmp_ret = OB_SUCCESS;
 | 
				
			||||||
    MTL_SWITCH(tenant_id_) {
 | 
					    MTL_SWITCH(tenant_id_) {
 | 
				
			||||||
      plan_cache = MTL(ObPlanCache*);
 | 
					      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
 | 
					        // should not panic
 | 
				
			||||||
      } else if (FALSE_IT(plan = static_cast<ObPhysicalPlan*>(guard.get_cache_obj()))) {
 | 
					      } else if (FALSE_IT(plan = static_cast<ObPhysicalPlan*>(guard.get_cache_obj()))) {
 | 
				
			||||||
        // do nothing
 | 
					        // do nothing
 | 
				
			||||||
 | 
				
			|||||||
@ -83,7 +83,7 @@ int ObGVSql::get_row_from_specified_tenant(uint64_t tenant_id, bool &is_end)
 | 
				
			|||||||
    plan_cache_ = MTL(ObPlanCache*);
 | 
					    plan_cache_ = MTL(ObPlanCache*);
 | 
				
			||||||
    NG_TRACE(trav_ps_map_start);
 | 
					    NG_TRACE(trav_ps_map_start);
 | 
				
			||||||
    ObGetAllCacheIdOp plan_id_op(&plan_id_array_);
 | 
					    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");
 | 
					      SERVER_LOG(WARN, "fail to traverse id2stat_map");
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      plan_id_array_idx_ = 0;
 | 
					      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;
 | 
					        is_end = false;
 | 
				
			||||||
        uint64_t plan_id= plan_id_array_.at(plan_id_array_idx_);
 | 
					        uint64_t plan_id= plan_id_array_.at(plan_id_array_idx_);
 | 
				
			||||||
        ++plan_id_array_idx_;
 | 
					        ++plan_id_array_idx_;
 | 
				
			||||||
        ObCacheObjGuard guard(GV_SQL_HANDLE);
 | 
					        ObCacheObjGuard guard(PC_DIAG_HANDLE);
 | 
				
			||||||
        int tmp_ret = plan_cache_->ref_cache_obj(plan_id, guard); //plan引用计数加1
 | 
					        int tmp_ret = plan_cache_->ref_alloc_obj(plan_id, guard); //plan引用计数加1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //如果当前plan_id对应的plan已被淘汰, 则忽略继续获取下一个plan
 | 
					        //如果当前plan_id对应的plan已被淘汰, 则忽略继续获取下一个plan
 | 
				
			||||||
        if (OB_HASH_NOT_EXIST == tmp_ret) {
 | 
					        if (OB_HASH_NOT_EXIST == tmp_ret) {
 | 
				
			||||||
 | 
				
			|||||||
@ -132,7 +132,7 @@ void ObLCObjectManager::common_free(ObILibCacheObject *cache_obj,
 | 
				
			|||||||
  if (OB_ISNULL(cache_obj)) {
 | 
					  if (OB_ISNULL(cache_obj)) {
 | 
				
			||||||
    // do nothing
 | 
					    // do nothing
 | 
				
			||||||
  } else {
 | 
					  } 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());
 | 
					        cache_obj->set_logical_del_time(ObTimeUtility::current_monotonic_time());
 | 
				
			||||||
        LOG_WARN("set logical del time", K(cache_obj->get_logical_del_time()),
 | 
					        LOG_WARN("set logical del time", K(cache_obj->get_logical_del_time()),
 | 
				
			||||||
                                         K(cache_obj->added_lc()),
 | 
					                                         K(cache_obj->added_lc()),
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,8 @@ const char* ObCacheRefHandleMgr::handle_name(const CacheRefHandleID handle_id)
 | 
				
			|||||||
    "plan_baseline_handle",
 | 
					    "plan_baseline_handle",
 | 
				
			||||||
    "tableapi_node_handle",
 | 
					    "tableapi_node_handle",
 | 
				
			||||||
    "sql_plan_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");
 | 
					  static_assert(sizeof(handle_names)/sizeof(const char*) == MAX_HANDLE, "invalid handle name array");
 | 
				
			||||||
  if (handle_id < MAX_HANDLE) {
 | 
					  if (handle_id < MAX_HANDLE) {
 | 
				
			||||||
 | 
				
			|||||||
@ -130,6 +130,7 @@ enum CacheRefHandleID
 | 
				
			|||||||
  TABLEAPI_NODE_HANDLE,
 | 
					  TABLEAPI_NODE_HANDLE,
 | 
				
			||||||
  SQL_PLAN_HANDLE,
 | 
					  SQL_PLAN_HANDLE,
 | 
				
			||||||
  CALLSTMT_HANDLE,
 | 
					  CALLSTMT_HANDLE,
 | 
				
			||||||
 | 
					  PC_DIAG_HANDLE,
 | 
				
			||||||
  MAX_HANDLE
 | 
					  MAX_HANDLE
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1707,7 +1707,7 @@ int ObPlanCache::ref_cache_obj(const ObCacheObjID obj_id, ObCacheObjGuard& guard
 | 
				
			|||||||
  int ret = OB_SUCCESS;
 | 
					  int ret = OB_SUCCESS;
 | 
				
			||||||
  ObCacheObjAtomicOp op(guard.ref_handle_);
 | 
					  ObCacheObjAtomicOp op(guard.ref_handle_);
 | 
				
			||||||
  ObGlobalReqTimeService::check_req_timeinfo();
 | 
					  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));
 | 
					    SQL_PC_LOG(WARN, "failed to get update plan statistic", K(obj_id), K(ret));
 | 
				
			||||||
  } else if (NULL == op.get_value()) {
 | 
					  } else if (NULL == op.get_value()) {
 | 
				
			||||||
    ret = OB_HASH_NOT_EXIST;
 | 
					    ret = OB_HASH_NOT_EXIST;
 | 
				
			||||||
@ -1736,6 +1736,40 @@ int ObPlanCache::ref_plan(const ObCacheObjID plan_id, ObCacheObjGuard& guard)
 | 
				
			|||||||
  return ret;
 | 
					  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 ObPlanCache::add_cache_obj_stat(ObILibCacheCtx &ctx, ObILibCacheObject *cache_obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					  int ret = OB_SUCCESS;
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,11 @@
 | 
				
			|||||||
#include "sql/plan_cache/ob_lib_cache_object_manager.h"
 | 
					#include "sql/plan_cache/ob_lib_cache_object_manager.h"
 | 
				
			||||||
namespace oceanbase
 | 
					namespace oceanbase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					namespace observer
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  class ObGVSql;
 | 
				
			||||||
 | 
					  class ObAllVirtualSqlPlan;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
namespace rpc
 | 
					namespace rpc
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  class ObLoadBaselineArg;
 | 
					  class ObLoadBaselineArg;
 | 
				
			||||||
@ -221,6 +226,8 @@ class ObPlanCache
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
friend class ObCacheObjectFactory;
 | 
					friend class ObCacheObjectFactory;
 | 
				
			||||||
friend class ObPlanCacheEliminationTask;
 | 
					friend class ObPlanCacheEliminationTask;
 | 
				
			||||||
 | 
					friend class observer::ObAllVirtualSqlPlan;
 | 
				
			||||||
 | 
					friend class observer::ObGVSql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  static const int64_t MAX_PLAN_SIZE = 20*1024*1024; //20M
 | 
					  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_lib_cache_by_ns(const ObLibCacheNameSpace ns);
 | 
				
			||||||
  int flush_pl_cache();
 | 
					  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:
 | 
					private:
 | 
				
			||||||
  DISALLOW_COPY_AND_ASSIGN(ObPlanCache);
 | 
					  DISALLOW_COPY_AND_ASSIGN(ObPlanCache);
 | 
				
			||||||
  int add_plan_cache(ObILibCacheCtx &ctx,
 | 
					  int add_plan_cache(ObILibCacheCtx &ctx,
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user