Files
oceanbase/src/sql/plan_cache/ob_ps_cache.h
wangzelin.wzl 93a1074b0c patch 4.0
2022-10-24 17:57:12 +08:00

170 lines
6.3 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_SQL_PLAN_CACHE_OB_PS_CACHE_
#define OCEANBASE_SQL_PLAN_CACHE_OB_PS_CACHE_
#include "lib/hash/ob_hashmap.h"
#include "lib/atomic/ob_atomic.h"
#include "lib/allocator/page_arena.h"
#include "sql/plan_cache/ob_prepare_stmt_struct.h"
namespace oceanbase
{
namespace share
{
namespace schema
{
class ObSchemaGetterGuard;
}
}
using common::ObPsStmtId;
namespace sql
{
class ObPsCache
{
public:
//sql -> stmt_id
typedef common::hash::ObHashMap<ObPsSqlKey, ObPsStmtItem *, common::hash::SpinReadWriteDefendMode> PsStmtIdMap;
//stmt_id -> plan
typedef common::hash::ObHashMap<ObPsStmtId, ObPsStmtInfo *, common::hash::SpinReadWriteDefendMode> PsStmtInfoMap;
typedef common::hash::ObHashMap<ObPsStmtId, ObPsSessionInfo *, common::hash::SpinReadWriteDefendMode> PsSessionInfoMap;
typedef common::ObSEArray<std::pair<ObPsStmtId, int64_t>, 1024> PsIdClosedTimePairs;
ObPsCache();
virtual ~ObPsCache();
int init(const int64_t hash_bucket,
const common::ObAddr addr,
const uint64_t tenant_id);
bool is_inited() const { return inited_; }
bool is_valid() const { return valid_; }
void set_valid(bool valid) { valid_ = valid; }
int64_t inc_ref_count();
void dec_ref_count();
int64_t get_ref_count() const { return ref_count_; }
int set_mem_conf(const ObPCMemPctConf &conf);
public:
// always make sure stmt_id is inner_stmt_id!!!
int get_stmt_info_guard(const ObPsStmtId ps_stmt_id, ObPsStmtInfoGuard &guard);
int ref_stmt_item(const uint64_t db_id, const common::ObString &ps_sql, ObPsStmtItem *&stmt_item);
int ref_stmt_info(const ObPsStmtId stmt_id, ObPsStmtInfo *&ps_stmt_info);
int deref_stmt_info(const ObPsStmtId stmt_id);
int deref_all_ps_stmt(const ObIArray<ObPsStmtId> &ps_stmt_ids);
int ref_stmt_item(const ObPsSqlKey &ps_sql_key, ObPsStmtItem *&ps_stmt_item);
int deref_stmt_item(const ObPsSqlKey &ps_sql_key);
int deref_ps_stmt(const ObPsStmtId stmt_id, bool erase_item = false);
int get_or_add_stmt_item(const uint64_t db_id,
const common::ObString &ps_sql,
ObPsStmtItem *&ps_item_value);
int get_or_add_stmt_info(const ObResultSet &result,
const ObString &origin_sql,
const common::ObString &no_param_sql,
const ObIArray<ObPCParam*> &raw_params,
const common::ObIArray<int64_t> &raw_params_idx,
int64_t param_cnt,
ObSchemaGetterGuard &schema_guard,
stmt::StmtType stmt_type,
ObPsStmtItem *ps_item,
ObPsStmtInfo *&ref_ps_info,
int32_t returning_into_parm_num);
int cache_evict();
int cache_evict_all_ps();
void dump_ps_cache();
inline void inc_access_count() { ATOMIC_INC(&access_count_); }
inline uint64_t get_access_count() { return ATOMIC_LOAD(&access_count_); }
inline uint64_t get_hit_count() { return ATOMIC_LOAD(&hit_count_); }
inline void inc_access_and_hit_count()
{
ATOMIC_INC(&hit_count_);
ATOMIC_INC(&access_count_);
}
int mem_total(int64_t &mem_total) const;
inline int64_t get_stmt_id_map_size() { return stmt_id_map_.size(); }
inline int64_t get_stmt_info_map_size() { return stmt_info_map_.size(); }
int get_all_stmt_id(common::ObIArray<ObPsStmtId> *id_array);
int check_schema_version(ObSchemaGetterGuard &schema_guard,
ObPsStmtInfo &stmt_info,
bool &is_expired);
int erase_stmt_item(ObPsStmtId stmt_id, ObPsSqlKey &ps_key);
private:
int inner_cache_evict(bool is_evict_all);
int fill_ps_stmt_info(const ObResultSet &result,
int64_t param_cnt,
ObPsStmtInfo &ps_stmt_info,
int32_t returning_into_parm_num) const;
int add_stmt_info(const ObPsStmtItem &ps_item,
const ObPsStmtInfo &ps_info,
ObPsStmtInfo *&ref_ps_info);
inline ObPsStmtId gen_new_ps_stmt_id() { return __sync_add_and_fetch(&next_ps_stmt_id_, 1); }
int64_t get_mem_limit() const
{
const double PS_EVICT_PERCENT_ON_PC = 0.5;
const int64_t MAX_TENANT_MEM = ((int64_t)(1) << 40); // 1T
int64_t tenant_mem = lib::get_tenant_memory_limit(tenant_id_);
int64_t mem_limit = -1;
if (OB_UNLIKELY(0 >= tenant_mem || tenant_mem >= MAX_TENANT_MEM)) {
mem_limit = MAX_TENANT_MEM * PS_EVICT_PERCENT_ON_PC;
}
mem_limit = tenant_mem / 100
* get_mem_limit_pct() * PS_EVICT_PERCENT_ON_PC;
return mem_limit;
}
int64_t get_mem_high() const { return get_mem_limit()/100 * get_mem_high_pct(); }
inline int64_t get_mem_limit_pct() const { return ATOMIC_LOAD(&mem_limit_pct_); }
inline int64_t get_mem_high_pct() const { return ATOMIC_LOAD(&mem_high_pct_); }
inline int64_t get_mem_low_pct() const { return ATOMIC_LOAD(&mem_low_pct_); }
inline void set_mem_limit_pct(int64_t pct) { ATOMIC_STORE(&mem_limit_pct_, pct); }
inline void set_mem_high_pct(int64_t pct) { ATOMIC_STORE(&mem_high_pct_, pct); }
inline void set_mem_low_pct(int64_t pct) { ATOMIC_STORE(&mem_low_pct_, pct); }
private:
static const int64_t SLICE_SIZE = 1024;
ObPsStmtId next_ps_stmt_id_;
bool inited_;
bool valid_;
int64_t tenant_id_;
common::ObAddr host_;
volatile int64_t ref_count_;
PsStmtIdMap stmt_id_map_;
PsStmtInfoMap stmt_info_map_;
int64_t mem_limit_pct_;
int64_t mem_high_pct_; // high water mark percentage
int64_t mem_low_pct_; // low water mark percentage
uint64_t hit_count_;
uint64_t access_count_;
lib::ObMutex mutex_;
lib::MemoryContext mem_context_;
common::ObIAllocator *inner_allocator_;
};
} // end namespace sql
} // end namespace oceanbase
#endif // OCEANBASE_SQL_PLAN_CACHE_OB_PS_CACHE_