diff --git a/src/sql/plan_cache/ob_ps_cache.cpp b/src/sql/plan_cache/ob_ps_cache.cpp index 36d04ce7a4ebd62113196edc26d8d9ff67bc3b96..140a9aaa14165effd03f8181be3d96023284fc4d 100644 --- a/src/sql/plan_cache/ob_ps_cache.cpp +++ b/src/sql/plan_cache/ob_ps_cache.cpp @@ -39,6 +39,7 @@ ObPsCache::ObPsCache() mem_low_pct_(0), hit_count_(0), access_count_(0), + mutex_(), mem_context_(NULL), inner_allocator_(NULL) {} @@ -46,8 +47,6 @@ ObPsCache::ObPsCache() ObPsCache::~ObPsCache() { int ret = OB_SUCCESS; - // ps_stmt_id和ps_stmt_info创建时,会给其增加引用计数 - // 现在PsCache要析构了,对所有内部对象减去1,如果引用计数到0,会显式free内存 cache_evict_all_ps(); if (NULL != mem_context_) { @@ -709,6 +708,12 @@ int ObPsCache::cache_evict_all_ps() int ObPsCache::inner_cache_evict(bool is_evict_all) { int ret = OB_SUCCESS; + // There is a concurrency problem between the regularly triggered ps cache evict task and + // the manually triggered flush ps cache evict task. There is also a concurrency problem between + // the flush ps cache evict tasks triggered at the same time in different sessions. + // The same ps stmt may be added to the closed list by different ps cache evict tasks + // at the same time, so mutex is used here to make all flush ps cache evict tasks execute serially + lib::ObMutexGuard guard(mutex_); PsIdClosedTimePairs expired_stmt_ids; PsIdClosedTimePairs closed_stmt_ids; ObGetClosedStmtIdOp op(&expired_stmt_ids, &closed_stmt_ids); diff --git a/src/sql/plan_cache/ob_ps_cache.h b/src/sql/plan_cache/ob_ps_cache.h index d9e4f04dd4a48e5f9bea9ff4e0b96980fa82989a..ad0861ae9466d1a2bf6929fd3ccb8dc75187e021 100644 --- a/src/sql/plan_cache/ob_ps_cache.h +++ b/src/sql/plan_cache/ob_ps_cache.h @@ -187,6 +187,7 @@ private: uint64_t hit_count_; uint64_t access_count_; + lib::ObMutex mutex_; lib::MemoryContext mem_context_; common::ObIAllocator* inner_allocator_; };