diff --git a/src/sql/plan_cache/ob_i_lib_cache_node.h b/src/sql/plan_cache/ob_i_lib_cache_node.h index 6dfebc836b..d404fa0abf 100644 --- a/src/sql/plan_cache/ob_i_lib_cache_node.h +++ b/src/sql/plan_cache/ob_i_lib_cache_node.h @@ -154,7 +154,7 @@ public: int unlock() { return rwlock_.unlock(); } int64_t inc_ref_count(const CacheRefHandleID ref_handle); int64_t dec_ref_count(const CacheRefHandleID ref_handle); - int64_t get_ref_count() const { return ref_count_; } + int64_t get_ref_count() const { return ATOMIC_LOAD(&ref_count_); } common::ObIAllocator *get_allocator() { return &allocator_; } common::ObIAllocator &get_allocator_ref() { return allocator_; } lib::MemoryContext &get_mem_context() { return mem_context_; } diff --git a/src/sql/plan_cache/ob_plan_cache.cpp b/src/sql/plan_cache/ob_plan_cache.cpp index 4959379d30..35a82be84d 100644 --- a/src/sql/plan_cache/ob_plan_cache.cpp +++ b/src/sql/plan_cache/ob_plan_cache.cpp @@ -1187,6 +1187,8 @@ int ObPlanCache::ref_cache_obj(const ObCacheObjID obj_id, ObCacheObjGuard& guard 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(); } diff --git a/src/sql/plan_cache/ob_plan_cache_callback.cpp b/src/sql/plan_cache/ob_plan_cache_callback.cpp index 9df45d392d..4d42ff5dfd 100644 --- a/src/sql/plan_cache/ob_plan_cache_callback.cpp +++ b/src/sql/plan_cache/ob_plan_cache_callback.cpp @@ -49,11 +49,26 @@ int ObLibCacheAtomicOp::get_value(ObILibCacheNode *&cache_node) return ret; } +/* +worker thread: | evict thread + | get all plan id array(contains plan id x) +deleting .... remove plan id x | +from map | +dec ref cnt => ref_cnt=0 | + | ref plan id x. inc_ref=1 +deleting plan x | + | acess plan x --> cause core! +*/ + void ObCacheObjAtomicOp::operator()(ObjKV &entry) { if (NULL != entry.second) { - cache_obj_ = entry.second; - cache_obj_->inc_ref_count(ref_handle_); + if (0 == entry.second->get_ref_count()) { + // do nothing + } else { + cache_obj_ = entry.second; + cache_obj_->inc_ref_count(ref_handle_); + } SQL_PC_LOG(DEBUG, "succ to get plan", "ref_count", cache_obj_->get_ref_count()); } else { // do nothing