diff --git a/src/sql/plan_cache/ob_prepare_stmt_struct.cpp b/src/sql/plan_cache/ob_prepare_stmt_struct.cpp index f6b0b4fc74..25a538d3ee 100644 --- a/src/sql/plan_cache/ob_prepare_stmt_struct.cpp +++ b/src/sql/plan_cache/ob_prepare_stmt_struct.cpp @@ -316,7 +316,8 @@ ObPsStmtInfo::ObPsStmtInfo(ObIAllocator *inner_allocator, raw_sql_(), raw_params_(inner_allocator), raw_params_idx_(inner_allocator), - literal_stmt_type_(stmt::T_NONE) + literal_stmt_type_(stmt::T_NONE), + erased_(false) { } @@ -462,6 +463,7 @@ int ObPsStmtInfo::deep_copy(const ObPsStmtInfo &other) is_expired_ = other.is_expired_; is_expired_evicted_ = other.is_expired_evicted_; literal_stmt_type_ = other.literal_stmt_type_; + erased_ = other.erased_; if (other.get_dep_objs_cnt() > 0) { dep_objs_cnt_ = other.get_dep_objs_cnt(); if (NULL == (dep_objs_ = reinterpret_cast diff --git a/src/sql/plan_cache/ob_prepare_stmt_struct.h b/src/sql/plan_cache/ob_prepare_stmt_struct.h index dc0cc131ae..9d0818c5c9 100644 --- a/src/sql/plan_cache/ob_prepare_stmt_struct.h +++ b/src/sql/plan_cache/ob_prepare_stmt_struct.h @@ -251,6 +251,7 @@ public: void set_is_expired() { ATOMIC_STORE(&is_expired_, true); } bool is_expired() { return ATOMIC_LOAD(&is_expired_); } bool *get_is_expired_evicted_ptr() { return &is_expired_evicted_; } + bool try_set_erase_flag() { return ATOMIC_BCAS(&erased_, false, true); } DECLARE_VIRTUAL_TO_STRING; @@ -292,6 +293,7 @@ private: ObFixedArray raw_params_; ObFixedArray raw_params_idx_; stmt::StmtType literal_stmt_type_; + volatile bool erased_; }; struct TypeInfo { diff --git a/src/sql/plan_cache/ob_ps_cache.cpp b/src/sql/plan_cache/ob_ps_cache.cpp index b28b42a0a8..64a03cf4ee 100644 --- a/src/sql/plan_cache/ob_ps_cache.cpp +++ b/src/sql/plan_cache/ob_ps_cache.cpp @@ -152,6 +152,9 @@ int ObPsCache::deref_ps_stmt(const ObPsStmtId stmt_id, bool erase_item/*=false*/ if (erase_item) { // dec cached ref if (OB_FAIL(erase_stmt_item(stmt_id, ps_sql_key))) { LOG_WARN("fail to erase stmt", K(ret)); + } else if (ps_info->try_set_erase_flag() && OB_SUCCESS != (tmp_ret = deref_stmt_info(stmt_id))) { + ret = tmp_ret; + LOG_WARN("deref stmt info failed", K(ret), K(stmt_id), K(ps_sql_key)); } } else { // dec session ref if (OB_ISNULL(ps_info->get_ps_item())) { @@ -160,13 +163,12 @@ int ObPsCache::deref_ps_stmt(const ObPsStmtId stmt_id, bool erase_item/*=false*/ } else { ps_info->get_ps_item()->dec_ref_count_check_erase(); } - } - - if (OB_SUCCESS != (tmp_ret = deref_stmt_info(stmt_id))) { - ret = tmp_ret; //previous ret ignore - LOG_WARN("deref stmt info failed", K(ret), K(stmt_id), K(ps_sql_key)); - } else { - LOG_TRACE("deref stmt info success", K(stmt_id), K(ps_sql_key), K(ret)); + if (OB_SUCCESS != (tmp_ret = deref_stmt_info(stmt_id))) { + ret = tmp_ret; //previous ret ignore + LOG_WARN("deref stmt info failed", K(ret), K(stmt_id), K(ps_sql_key)); + } else { + LOG_TRACE("deref stmt info success", K(stmt_id), K(ps_sql_key), K(ret)); + } } } return ret;