patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -19,37 +19,36 @@
#include "share/config/ob_server_config.h"
#include "observer/ob_req_time_service.h"
#include "observer/omt/ob_tenant_config_mgr.h"
#include "pl/ob_pl.h"
#include "sql/plan_cache/ob_cache_object_factory.h"
namespace oceanbase {
namespace sql {
int ObPlanCacheManager::init(share::ObIPartitionLocationCache* plc, common::ObAddr addr)
namespace oceanbase
{
namespace sql
{
int ObPlanCacheManager::init(common::ObAddr addr)
{
int ret = OB_SUCCESS;
if (!inited_) {
if (OB_ISNULL(plc)) {
ret = OB_INVALID_ARGUMENT;
SQL_PC_LOG(WARN, "invalid argument", K(plc), K(ret));
if (OB_FAIL(pcm_.create(hash::cal_next_prime(512),
ObModIds::OB_HASH_BUCKET_PLAN_CACHE,
ObModIds::OB_HASH_NODE_PLAN_CACHE))) {
SQL_PC_LOG(WARN, "Failed to init plan cache manager", K(ret));
} else if (OB_FAIL(ps_pcm_.create(hash::cal_next_prime(512),
ObModIds::OB_HASH_BUCKET_PLAN_CACHE,
ObModIds::OB_HASH_NODE_PS_CACHE))) {
SQL_PC_LOG(WARN, "Failed to init ps plan cache manager", K(ret));
} else if (OB_FAIL(TG_CREATE(lib::TGDefIDs::PlanCacheEvict, tg_id_))) {
SQL_PC_LOG(WARN, "tg create failed", K(ret));
} else if (OB_FAIL(TG_START(tg_id_))) {
//TODO shengle, maybe exist memory leak
SQL_PC_LOG(WARN, "Failed to init timer", K(ret));
} else {
if (OB_FAIL(pcm_.create(
hash::cal_next_prime(512), ObModIds::OB_HASH_BUCKET_PLAN_CACHE, ObModIds::OB_HASH_NODE_PLAN_CACHE))) {
SQL_PC_LOG(WARN, "Failed to init plan cache manager", K(ret));
} else if (OB_FAIL(ps_pcm_.create(hash::cal_next_prime(512),
ObModIds::OB_HASH_BUCKET_PLAN_CACHE,
ObModIds::OB_HASH_NODE_PS_CACHE))) {
SQL_PC_LOG(WARN, "Failed to init ps plan cache manager", K(ret));
} else if (OB_FAIL(TG_CREATE(lib::TGDefIDs::PlanCacheEvict, tg_id_))) {
SQL_PC_LOG(WARN, "tg create failed", K(ret));
} else if (OB_FAIL(TG_START(tg_id_))) {
// TODO, maybe exist memory leak
SQL_PC_LOG(WARN, "Failed to init timer", K(ret));
} else {
partition_location_cache_ = plc;
self_addr_ = addr;
elimination_task_.plan_cache_manager_ = this;
if (OB_FAIL(TG_SCHEDULE(tg_id_, elimination_task_, GCONF.plan_cache_evict_interval, false))) {
SQL_PC_LOG(WARN, "Failed to schedule cache elimination task", K(ret));
}
self_addr_ = addr;
elimination_task_.plan_cache_manager_ = this;
if (OB_FAIL(TG_SCHEDULE(tg_id_, elimination_task_,
GCONF.plan_cache_evict_interval, false))) {
SQL_PC_LOG(WARN, "Failed to schedule cache elimination task", K(ret));
}
}
}
@ -67,7 +66,9 @@ void ObPlanCacheManager::destroy()
inited_ = false;
observer::ObReqTimeGuard req_timeinfo_guard;
TG_DESTROY(tg_id_);
for (PlanCacheMap::iterator it = pcm_.begin(); it != pcm_.end(); it++) {
for (PlanCacheMap::iterator it = pcm_.begin();
it != pcm_.end();
it++) {
if (OB_ISNULL(it->second)) {
BACKTRACE(ERROR, true, "plan_cache is null");
} else {
@ -77,9 +78,9 @@ void ObPlanCacheManager::destroy()
}
}
ObPlanCache* ObPlanCacheManager::get_plan_cache(uint64_t tenant_id)
ObPlanCache *ObPlanCacheManager::get_plan_cache(uint64_t tenant_id)
{
ObPlanCache* pc = NULL;
ObPlanCache *pc = NULL;
if (!destroyed_) {
ObPlanCacheManagerAtomic op;
int ret = pcm_.atomic_refactored(tenant_id, op);
@ -93,9 +94,9 @@ ObPlanCache* ObPlanCacheManager::get_plan_cache(uint64_t tenant_id)
return pc;
}
ObPsCache* ObPlanCacheManager::get_ps_cache(const uint64_t tenant_id)
ObPsCache *ObPlanCacheManager::get_ps_cache(const uint64_t tenant_id)
{
ObPsCache* ps_cache = NULL;
ObPsCache *ps_cache = NULL;
if (!destroyed_) {
ObPsCacheManagerAtomic op;
int ret = ps_pcm_.atomic_refactored(tenant_id, op);
@ -109,20 +110,6 @@ ObPsCache* ObPlanCacheManager::get_ps_cache(const uint64_t tenant_id)
return ps_cache;
}
int ObPlanCacheManager::validate_plan_cache(const uint64_t& tenant_id)
{
int ret = OB_SUCCESS;
ObPlanCache* plan_cache = get_plan_cache(tenant_id);
if (OB_ISNULL(plan_cache)) {
// do nothing, and others will create this later.
} else {
plan_cache->set_valid(true);
}
return ret;
}
// maybe get plan_cache = NULL;
// this thread other thread
//
@ -134,9 +121,9 @@ int ObPlanCacheManager::validate_plan_cache(const uint64_t& tenant_id)
// erase tenand_id->plan_cache
// get but not exist
// return NULL
ObPlanCache* ObPlanCacheManager::get_or_create_plan_cache(uint64_t tenant_id, const ObPCMemPctConf& pc_mem_conf)
ObPlanCache *ObPlanCacheManager::get_or_create_plan_cache(uint64_t tenant_id, const ObPCMemPctConf &pc_mem_conf)
{
ObPlanCache* pc = NULL;
ObPlanCache *pc = NULL;
if (!destroyed_) {
ObPlanCacheManagerAtomic op;
int ret = pcm_.read_atomic(tenant_id, op);
@ -145,15 +132,18 @@ ObPlanCache* ObPlanCacheManager::get_or_create_plan_cache(uint64_t tenant_id, co
SQL_PC_LOG(DEBUG, "Get Plan Cache Success", K(tenant_id), K(pc));
} else if (OB_HASH_NOT_EXIST == ret) {
// create plan cache
void* buff = ob_malloc(sizeof(ObPlanCache), ObNewModIds::OB_SQL_PLAN_CACHE);
void *buff = ob_malloc(sizeof(ObPlanCache), ObNewModIds::OB_SQL_PLAN_CACHE);
if (OB_ISNULL(buff)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
SQL_PC_LOG(ERROR, "Alloc mem for plan cache failed");
} else if (NULL == (pc = new (buff) ObPlanCache())) {
} else if (NULL == (pc = new(buff)ObPlanCache())) {
ret = OB_NOT_INIT;
SQL_PC_LOG(WARN, "fail to constructor plan cache");
} else {
if (OB_FAIL(pc->init(common::OB_PLAN_CACHE_BUCKET_NUMBER, self_addr_, partition_location_cache_, tenant_id))) {
if (OB_FAIL(pc->init(common::OB_PLAN_CACHE_BUCKET_NUMBER,
self_addr_,
tenant_id,
&pcm_))) {
SQL_PC_LOG(WARN, "init plan cache fail", K(tenant_id));
} else if (OB_FAIL(pc->set_mem_conf(pc_mem_conf))) {
SQL_PC_LOG(WARN, "fail to set plan cache memory conf", K(ret));
@ -165,9 +155,9 @@ ObPlanCache* ObPlanCacheManager::get_or_create_plan_cache(uint64_t tenant_id, co
ob_free(buff);
buff = NULL;
pc = NULL;
} else if (OB_SUCCESS == ret) { // add new plan cache to sql engine
pc->inc_ref_count(); // hash table reference count
pc->inc_ref_count(); // external code reference count
} else if (OB_SUCCESS == ret) {// add new plan cache to sql engine
pc->inc_ref_count(); //hash表引用计数
pc->inc_ref_count(); //外部代码引用计数
ret = pcm_.set_refactored(tenant_id, pc);
if (OB_SUCC(ret)) {
SQL_PC_LOG(DEBUG, "Add Plan Cache Success", K(tenant_id), K(pc));
@ -182,8 +172,8 @@ ObPlanCache* ObPlanCacheManager::get_or_create_plan_cache(uint64_t tenant_id, co
pc = op.get_plan_cache();
SQL_PC_LOG(DEBUG, "Get Plan Cache Success", K(tenant_id), K(pc));
} else {
// this case is describle on function name;
SQL_PC_LOG(DEBUG, "tenant erase by others", K(tenant_id), K(ret));
//this case is describle on function name;
SQL_PC_LOG(DEBUG, "tenant erase by others",K(tenant_id), K(ret));
}
}
}
@ -196,9 +186,10 @@ ObPlanCache* ObPlanCacheManager::get_or_create_plan_cache(uint64_t tenant_id, co
return pc;
}
ObPsCache* ObPlanCacheManager::get_or_create_ps_cache(const uint64_t tenant_id, const ObPCMemPctConf& pc_mem_conf)
ObPsCache *ObPlanCacheManager::get_or_create_ps_cache(
const uint64_t tenant_id, const ObPCMemPctConf &pc_mem_conf)
{
ObPsCache* ps_cache = NULL;
ObPsCache *ps_cache = NULL;
if (!destroyed_) {
ObPsCacheManagerAtomic op;
int ret = ps_pcm_.atomic_refactored(tenant_id, op);
@ -207,16 +198,17 @@ ObPsCache* ObPlanCacheManager::get_or_create_ps_cache(const uint64_t tenant_id,
SQL_PC_LOG(DEBUG, "Get ps Plan Cache Success", K(tenant_id), K(ps_cache));
} else if (OB_HASH_NOT_EXIST == ret) {
// create ps plan cache
void* buff = ob_malloc(sizeof(ObPsCache), ObModIds::OB_SQL_PS_CACHE);
void *buff = ob_malloc(sizeof(ObPsCache), ObModIds::OB_SQL_PS_CACHE);
if (OB_ISNULL(buff)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
SQL_PC_LOG(ERROR, "Alloc mem for ps plan cache failed");
} else if (NULL == (ps_cache = new (buff) ObPsCache())) {
} else if (NULL == (ps_cache = new(buff)ObPsCache())) {
ret = OB_NOT_INIT;
SQL_PC_LOG(WARN, "fail to constructor ps plan cache");
} else {
if (OB_SUCC(ps_cache->init(
common::OB_PLAN_CACHE_BUCKET_NUMBER, self_addr_, partition_location_cache_, tenant_id))) {
if (OB_SUCC(ps_cache->init(common::OB_PLAN_CACHE_BUCKET_NUMBER,
self_addr_,
tenant_id))) {
SQL_PC_LOG(INFO, "Init Ps Plan Cache Success", K(tenant_id));
} else if (OB_FAIL(ps_cache->set_mem_conf(pc_mem_conf))) {
SQL_PC_LOG(WARN, "fail to set plan cache memory conf", K(ret));
@ -230,12 +222,12 @@ ObPsCache* ObPlanCacheManager::get_or_create_ps_cache(const uint64_t tenant_id,
// add new plan cache to sql engine
if (OB_SUCCESS == ret && NULL != ps_cache) {
ps_cache->inc_ref_count(); // hash table reference count
ps_cache->inc_ref_count(); // external code reference count
ps_cache->inc_ref_count(); //hash表引用计数
ps_cache->inc_ref_count(); //外部代码引用计数
ret = ps_pcm_.set_refactored(tenant_id, ps_cache);
if (OB_SUCC(ret)) {
SQL_PC_LOG(
INFO, "Add ps Plan Cache Success", K(tenant_id), K(ps_cache), "ref_count", ps_cache->get_ref_count());
SQL_PC_LOG(INFO, "Add ps Plan Cache Success", K(tenant_id), K(ps_cache),
"ref_count", ps_cache->get_ref_count());
} else {
// someone else add plan cache already
// or error when add plan cache to hashmap
@ -247,8 +239,8 @@ ObPsCache* ObPlanCacheManager::get_or_create_ps_cache(const uint64_t tenant_id,
ps_cache = op.get_ps_cache();
SQL_PC_LOG(DEBUG, "Get Ps Plan Cache Success", K(tenant_id), K(ps_cache));
} else {
// this case is describle on function name;
SQL_PC_LOG(INFO, "tenant erase by others", K(tenant_id), K(ret));
//this case is describle on function name;
SQL_PC_LOG(INFO, "tenant erase by others",K(tenant_id), K(ret));
}
}
}
@ -260,22 +252,25 @@ ObPsCache* ObPlanCacheManager::get_or_create_ps_cache(const uint64_t tenant_id,
return ps_cache;
}
int ObPlanCacheManager::revert_plan_cache(const uint64_t& tenant_id)
int ObPlanCacheManager::revert_plan_cache(const uint64_t &tenant_id)
{
int ret = OB_SUCCESS;
ObPlanCache* ppc = NULL;
ObPlanCache *ppc = NULL;
observer::ObReqTimeGuard req_timeinfo_guard;
int tmp_ret = pcm_.get_refactored(tenant_id, ppc);
if (OB_SUCCESS == tmp_ret && NULL != ppc) {
SQL_PC_LOG(INFO, "plan_cache_manager revert plan cache", "pc ref_count", ppc->get_ref_count(), K(tenant_id));
// cancel scheduled task
SQL_PC_LOG(INFO, "plan_cache_manager revert plan cache",
"pc ref_count", ppc->get_ref_count(),
K(tenant_id));
//cancel scheduled task
ppc->set_valid(false);
ppc->dec_ref_count();
} else if (OB_HASH_NOT_EXIST == tmp_ret) { // maybe erase by other thread
} else if (OB_HASH_NOT_EXIST == tmp_ret) { // maybe erase by other thread
SQL_PC_LOG(INFO, "Plan Cache not exist", K(tenant_id));
} else {
ret = tmp_ret;
SQL_PC_LOG(ERROR, "unexpected error when erase plan cache", K(tenant_id), K(ppc), K(ret));
SQL_PC_LOG(ERROR, "unexpected error when erase plan cache",
K(tenant_id), K(ppc), K(ret));
}
return ret;
}
@ -288,20 +283,24 @@ void ObPlanCacheManager::ObPlanCacheEliminationTask::runTimerTask()
SQL_PC_LOG(WARN, "plan_cache_manager not inited", K(ret));
} else {
{
// Guard must be defined before referencing plan resources before calling the plan cache interface
// 在调用plan cache接口前引用plan资源前必须定义guard
observer::ObReqTimeGuard req_timeinfo_guard;
run_plan_cache_task();
run_ps_cache_task();
SQL_PC_LOG(INFO, "schedule next cache evict task", "evict_interval", (int64_t)(GCONF.plan_cache_evict_interval));
SQL_PC_LOG(INFO, "schedule next cache evict task",
"evict_interval", (int64_t)(GCONF.plan_cache_evict_interval));
}
// free cache obj in deleted map
if (get_plan_cache_gc_strategy() > 0) {
observer::ObReqTimeGuard req_timeinfo_guard;
run_free_cache_obj_task();
}
SQL_PC_LOG(INFO, "schedule next cache evict task", "evict_interval", (int64_t)(GCONF.plan_cache_evict_interval));
if (OB_FAIL(TG_SCHEDULE(plan_cache_manager_->tg_id_, *this, GCONF.plan_cache_evict_interval, false))) {
SQL_PC_LOG(INFO, "schedule next cache evict task",
"evict_interval", (int64_t)(GCONF.plan_cache_evict_interval));
if (OB_FAIL(TG_SCHEDULE(plan_cache_manager_->tg_id_, *this,
GCONF.plan_cache_evict_interval,
false))) {
SQL_PC_LOG(WARN, "Schedule new elimination failed", K(ret));
}
}
@ -318,27 +317,29 @@ void ObPlanCacheManager::ObPlanCacheEliminationTask::run_plan_cache_task()
} else if (OB_FAIL(plan_cache_manager_->pcm_.foreach_refactored(op))) {
SQL_PC_LOG(ERROR, "fail to traverse pcm", K(ret));
} else {
for (int64_t i = 0; i < tenant_id_array.count(); i++) { // ignore error
for (int64_t i = 0; i < tenant_id_array.count(); i++) { //循环忽略错误码,保证所有plan cache启动淘汰
uint64_t tenant_id = tenant_id_array.at(i);
bool is_dropped = true;
MAKE_TENANT_SWITCH_SCOPE_GUARD(guard);
if (OB_ISNULL(GCTX.schema_service_)) {
ret = OB_INVALID_ARGUMENT;
OB_LOG(WARN, "invalid argument", K(GCTX.schema_service_));
} else if (OB_FAIL(GCTX.schema_service_->check_if_tenant_has_been_dropped(tenant_id, is_dropped))) {
OB_LOG(WARN, "fail to check if tenant has been dropped", K(ret), K(tenant_id));
} else if (is_dropped) {
// if the tanent has been dropped, do nothing......
// 由于 tenat_id_array的tenant移除 与 drop tenant存在一定时延。因此,在这里需要检查一下tenant是否存在。
// bug fix: https://work.aone.alibaba-inc.com/issue/31275377
if (!GCTX.omt_->is_available_tenant(tenant_id)) {
// do nothing
} else if (OB_FAIL(guard.switch_to(tenant_id))) {
ret = OB_SUCCESS;
LOG_DEBUG("switch tenant fail", K(tenant_id));
} else {
ObPlanCache* plan_cache = plan_cache_manager_->get_plan_cache(tenant_id);
ObPlanCache *plan_cache = plan_cache_manager_->get_plan_cache(tenant_id);
if (NULL != plan_cache) {
// If it fails, the settings will not be updated and other processes will not be affected
if (OB_FAIL(plan_cache->update_memory_conf())) {
if (OB_FAIL(plan_cache->update_memory_conf())) { //如果失败, 则不更新设置, 也不影响其他流程
SQL_PC_LOG(WARN, "fail to update plan cache memory sys val", K(ret));
}
if (OB_FAIL(plan_cache->cache_evict())) {
SQL_PC_LOG(ERROR, "Plan cache evict failed, please check", K(ret));
}
if (OB_FAIL(plan_cache->asyn_update_baseline())) {
SQL_PC_LOG(ERROR, "asyn replace plan baseline failed", K(ret), K(tenant_id));
}
plan_cache->dec_ref_count();
}
}
@ -357,11 +358,11 @@ void ObPlanCacheManager::ObPlanCacheEliminationTask::run_ps_cache_task()
} else if (OB_FAIL(plan_cache_manager_->ps_pcm_.foreach_refactored(op))) {
SQL_PC_LOG(ERROR, "fail to traverse pcm", K(ret));
} else {
for (int64_t i = 0; i < tenant_id_array.count(); i++) { // ignore error
for (int64_t i = 0; i < tenant_id_array.count(); i++) { //循环忽略错误码,保证所有ps cache启动淘汰
uint64_t tenant_id = tenant_id_array.at(i);
ObPCMemPctConf conf;
ObPsCache* ps_cache = plan_cache_manager_->get_ps_cache(tenant_id); // inc ps_cache ref
ObPlanCache* plan_cache = plan_cache_manager_->get_plan_cache(tenant_id);
ObPsCache *ps_cache = plan_cache_manager_->get_ps_cache(tenant_id); // inc ps_cache ref
ObPlanCache *plan_cache = plan_cache_manager_->get_plan_cache(tenant_id);
if (NULL != plan_cache) {
conf.limit_pct_ = plan_cache->get_mem_limit_pct();
conf.high_pct_ = plan_cache->get_mem_high_pct();
@ -388,44 +389,47 @@ void ObPlanCacheManager::ObPlanCacheEliminationTask::run_free_cache_obj_task()
SQL_PC_LOG(WARN, "plan_cache_manager not inited", K(ret));
} else if (OB_FAIL(plan_cache_manager_->pcm_.foreach_refactored(op))) {
SQL_PC_LOG(ERROR, "failed to traverse pcm", K(ret));
} else if (observer::ObGlobalReqTimeService::get_instance().get_global_safe_timestamp(safe_timestamp)) {
} else if (observer::ObGlobalReqTimeService::get_instance()
.get_global_safe_timestamp(safe_timestamp)) {
SQL_PC_LOG(ERROR, "failed to get global safe timestamp", K(ret));
} else {
for (int i = 0; i < tenant_id_array.count(); i++) {
uint64_t tenant_id = tenant_id_array.at(i);
// inc plan cache ref
ObPlanCache* plan_cache = plan_cache_manager_->get_plan_cache(tenant_id);
ObPlanCache *plan_cache = plan_cache_manager_->get_plan_cache(tenant_id);
if (NULL != plan_cache) {
ObArray<DeletedCacheObjInfo> deleted_objs;
if (OB_FAIL(plan_cache->dump_deleted_objs<DUMP_ALL>(deleted_objs, safe_timestamp))) {
ObArray<AllocCacheObjInfo> deleted_objs;
MAKE_TENANT_SWITCH_SCOPE_GUARD(guard);
if (!GCTX.omt_->is_available_tenant(tenant_id)) {
// do nothing
} else if (OB_FAIL(guard.switch_to(tenant_id))) {
ret = OB_SUCCESS;
LOG_DEBUG("switch tenant fail", K(tenant_id));
} else if (OB_FAIL(plan_cache->dump_deleted_objs<DUMP_ALL>(deleted_objs, safe_timestamp))) {
SQL_PC_LOG(WARN, "failed to traverse hashmap", K(ret));
} else {
int64_t tot_mem_used = 0;
for (int k = 0; k < deleted_objs.count(); k++) {
tot_mem_used += deleted_objs.at(k).mem_used_;
} // end for
} // end for
if (tot_mem_used >= ((plan_cache->get_mem_limit() / 100) * 30)) {
LOG_ERROR("Cache Object Memory Leaked Much!!!",
K(deleted_objs),
K(tenant_id),
K(safe_timestamp),
K(plan_cache->get_mem_limit()));
LOG_ERROR("Cache Object Memory Leaked Much!!!", K(tot_mem_used),
K(plan_cache->get_mem_limit()), K(deleted_objs),
K(tenant_id), K(safe_timestamp));
} else if (deleted_objs.count() > 0) {
LOG_WARN("Cache Object Memory Leaked Much!!!",
K(deleted_objs),
K(tenant_id),
K(safe_timestamp),
K(plan_cache->get_mem_limit()));
LOG_WARN("Cache Object Memory Leaked Much!!!", K(deleted_objs), K(tenant_id),
K(safe_timestamp), K(plan_cache->get_mem_limit()));
}
int tmp_ret = OB_SUCCESS;
#if defined(NDEBUG)
LOG_DEBUG("AUTO Mode is not active for now");
#else
if (AUTO == get_plan_cache_gc_strategy()) {
ObCacheObject* to_del_obj = NULL;
for (int j = 0; j < deleted_objs.count(); j++) {
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true, deleted_objs.at(j).obj_id_, plan_cache))) {
LOG_WARN("failed to destroy cache obj", K(ret));
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true,
deleted_objs.at(j).obj_id_,
plan_cache))) {
LOG_WARN("failde to destroy cache obj", K(ret));
}
} // end inner loop
}
@ -436,12 +440,12 @@ void ObPlanCacheManager::ObPlanCacheEliminationTask::run_free_cache_obj_task()
LOG_WARN("failed to dump deleted map", K(ret));
}
#endif
if (NULL != plan_cache) {
if(NULL != plan_cache) {
plan_cache->dec_ref_count();
plan_cache = NULL;
}
}
} // end outter loop
} // end outter loop
}
}
@ -455,7 +459,7 @@ int ObPlanCacheManager::flush_plan_cache_by_sql_id(uint64_t tenant_id,
if (OB_FAIL(plan_cache->cache_evict_plan_by_sql_id(db_id, sql_id))) {
SQL_PC_LOG(ERROR, "Plan cache evict failed, please check", K(ret));
}
ObArray<DeletedCacheObjInfo> deleted_objs;
ObArray<AllocCacheObjInfo> deleted_objs;
int64_t safe_timestamp = INT64_MAX;
if (OB_FAIL(ret)) {
// do nothing
@ -465,7 +469,6 @@ int ObPlanCacheManager::flush_plan_cache_by_sql_id(uint64_t tenant_id,
} else if (OB_FAIL(plan_cache->dump_deleted_objs<DUMP_SQL>(deleted_objs, safe_timestamp))) {
SQL_PC_LOG(WARN, "failed to get deleted sql objs", K(ret));
} else {
ObCacheObject *to_del_obj = NULL;
LOG_INFO("Deleted Cache Objs", K(deleted_objs));
for (int64_t i = 0; i < deleted_objs.count(); i++) { // ignore error code and continue
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true,
@ -489,7 +492,7 @@ int ObPlanCacheManager::flush_all_plan_cache()
if (OB_FAIL(pcm_.foreach_refactored(op))) {
SQL_PC_LOG(ERROR, "fail to traverse pcm", K(ret));
}
for (int64_t i = 0; i < tenant_id_array.count(); i++) { // ignore ret
for (int64_t i = 0; i < tenant_id_array.count(); i ++) { //ignore ret
uint64_t tenant_id = tenant_id_array.at(i);
if (OB_FAIL(flush_plan_cache(tenant_id))) {
SQL_PC_LOG(ERROR, "plan cache evict failed", K(tenant_id), K(ret));
@ -498,6 +501,45 @@ int ObPlanCacheManager::flush_all_plan_cache()
return ret;
}
int ObPlanCacheManager::flush_all_lib_cache()
{
int ret = OB_SUCCESS;
observer::ObReqTimeGuard req_timeinfo_guard;
ObArray<uint64_t> tenant_id_array;
ObGetAllCacheKeyOp op(&tenant_id_array);
if (OB_FAIL(pcm_.foreach_refactored(op))) {
SQL_PC_LOG(ERROR, "fail to traverse pcm", K(ret));
}
for (int64_t i = 0; i < tenant_id_array.count(); i ++) { //ignore ret
uint64_t tenant_id = tenant_id_array.at(i);
if (OB_FAIL(flush_lib_cache(tenant_id))) {
SQL_PC_LOG(ERROR, "lib cache evict failed", K(tenant_id), K(ret));
}
}
return ret;
}
int ObPlanCacheManager::flush_all_lib_cache_by_ns(ObLibCacheNameSpace ns)
{
int ret = OB_SUCCESS;
observer::ObReqTimeGuard req_timeinfo_guard;
ObArray<uint64_t> tenant_id_array;
ObGetAllCacheKeyOp op(&tenant_id_array);
if (ns <= ObLibCacheNameSpace::NS_INVALID || ns >= ObLibCacheNameSpace::NS_MAX) {
ret = OB_ERR_UNEXPECTED;
SQL_PC_LOG(ERROR, "invalid namespace type", K(ns));
} else if (OB_FAIL(pcm_.foreach_refactored(op))) {
SQL_PC_LOG(ERROR, "fail to traverse pcm", K(ret));
}
for (int64_t i = 0; i < tenant_id_array.count(); i ++) { //ignore ret
uint64_t tenant_id = tenant_id_array.at(i);
if (OB_FAIL(flush_lib_cache_by_ns(tenant_id, ns))) {
SQL_PC_LOG(ERROR, "lib cache evict failed", K(tenant_id), K(ret));
}
}
return ret;
}
int ObPlanCacheManager::flush_all_pl_cache()
{
int ret = OB_SUCCESS;
@ -520,21 +562,23 @@ int ObPlanCacheManager::flush_pl_cache(const uint64_t tenant_id)
{
int ret = OB_SUCCESS;
observer::ObReqTimeGuard req_timeinfo_guard;
ObPlanCache* plan_cache = get_plan_cache(tenant_id);
ObPlanCache *plan_cache = get_plan_cache(tenant_id);
int64_t safe_timestamp = INT64_MAX;
ObArray<DeletedCacheObjInfo> deleted_objs;
ObArray<AllocCacheObjInfo> deleted_objs;
if (NULL != plan_cache) {
if (OB_FAIL(plan_cache->cache_evict_all_pl())) {
SQL_PC_LOG(ERROR, "PL cache evict failed, please check", K(ret));
} else if (OB_FAIL(observer::ObGlobalReqTimeService::get_instance().get_global_safe_timestamp(safe_timestamp))) {
} else if (OB_FAIL(observer::ObGlobalReqTimeService::get_instance()
.get_global_safe_timestamp(safe_timestamp))) {
SQL_PC_LOG(ERROR, "failed to get global safe timestamp", K(ret));
} else if (OB_FAIL(plan_cache->dump_deleted_objs<DUMP_PL>(deleted_objs, safe_timestamp))) {
SQL_PC_LOG(ERROR, "failed to dump deleted pl objs", K(ret));
} else {
ObCacheObject* to_del_obj = NULL;
LOG_INFO("Deleted Cache Objs", K(deleted_objs));
for (int i = 0; i < deleted_objs.count(); i++) { // ignore error code and continue
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true, deleted_objs.at(i).obj_id_, plan_cache))) {
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true,
deleted_objs.at(i).obj_id_,
plan_cache))) {
LOG_WARN("failed to destroy cache obj", K(ret));
}
}
@ -561,43 +605,41 @@ int ObPlanCacheManager::flush_all_ps_cache()
return ret;
}
int ObPlanCacheManager::flush_ps_cache(const uint64_t tenant_id)
int ObPlanCacheManager::flush_ps_cache(const uint64_t tenant_id)
{
int ret = OB_SUCCESS;
ObPsCache* ps_cache = get_ps_cache(tenant_id);
int64_t safe_timestamp = INT64_MAX;
ObPsCache *ps_cache = get_ps_cache(tenant_id);
if (NULL != ps_cache) {
if (OB_FAIL(ps_cache->cache_evict_all_ps())) {
SQL_PC_LOG(ERROR, "ps cache evict failed, please check", K(ret));
SQL_PC_LOG(ERROR, "ps cache evict failed, please check", K(ret));
}
ps_cache->dec_ref_count();
ps_cache->dec_ref_count();
}
return ret;
}
int ObPlanCacheManager::flush_plan_cache(const uint64_t tenant_id)
int ObPlanCacheManager::flush_lib_cache_by_ns(const uint64_t tenant_id, const ObLibCacheNameSpace ns)
{
int ret = OB_SUCCESS;
observer::ObReqTimeGuard req_timeinfo_guard;
ObPlanCache* plan_cache = get_plan_cache(tenant_id);
ObPlanCache *plan_cache = get_plan_cache(tenant_id);
int64_t safe_timestamp = INT64_MAX;
ObArray<AllocCacheObjInfo> deleted_objs;
if (NULL != plan_cache) {
if (OB_FAIL(plan_cache->cache_evict_all_plan())) {
SQL_PC_LOG(ERROR, "Plan cache evict failed, please check", K(ret));
}
ObArray<DeletedCacheObjInfo> deleted_objs;
int64_t safe_timestamp = INT64_MAX;
if (OB_FAIL(ret)) {
// do nothing
} else if (OB_FAIL(observer::ObGlobalReqTimeService::get_instance().get_global_safe_timestamp(safe_timestamp))) {
if (OB_FAIL(plan_cache->cache_evict_by_ns(ns))) {
SQL_PC_LOG(ERROR, "cache evict by ns failed, please check", K(ret));
} else if (OB_FAIL(observer::ObGlobalReqTimeService::get_instance()
.get_global_safe_timestamp(safe_timestamp))) {
SQL_PC_LOG(ERROR, "failed to get global safe timestamp", K(ret));
} else if (OB_FAIL(plan_cache->dump_deleted_objs<DUMP_SQL>(deleted_objs, safe_timestamp))) {
SQL_PC_LOG(WARN, "failed to get deleted sql objs", K(ret));
} else if (OB_FAIL(plan_cache->dump_deleted_objs_by_ns(deleted_objs, safe_timestamp, ns))) {
SQL_PC_LOG(ERROR, "failed to dump deleted objs by ns", K(ret));
} else {
ObCacheObject* to_del_obj = NULL;
LOG_INFO("Deleted Cache Objs", K(deleted_objs));
for (int64_t i = 0; i < deleted_objs.count(); i++) { // ignore error code and continue
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true, deleted_objs.at(i).obj_id_, plan_cache))) {
for (int i = 0; i < deleted_objs.count(); i++) { // ignore error code and continue
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true,
deleted_objs.at(i).obj_id_,
plan_cache))) {
LOG_WARN("failed to destroy cache obj", K(ret));
}
}
@ -607,22 +649,90 @@ int ObPlanCacheManager::flush_plan_cache(const uint64_t tenant_id)
return ret;
}
int ObPlanCacheManager::revert_ps_cache(const uint64_t& tenant_id)
int ObPlanCacheManager::flush_lib_cache(const uint64_t tenant_id)
{
int ret = OB_SUCCESS;
ObPsCache* ppc = NULL;
observer::ObReqTimeGuard req_timeinfo_guard;
ObPlanCache *plan_cache = get_plan_cache(tenant_id);
if (NULL != plan_cache) {
if (OB_FAIL(plan_cache->cache_evict_all_obj())) {
SQL_PC_LOG(ERROR, "lib cache evict failed, please check", K(ret));
}
ObArray<AllocCacheObjInfo> deleted_objs;
int64_t safe_timestamp = INT64_MAX;
if (OB_FAIL(ret)) {
// do nothing
} else if (OB_FAIL(observer::ObGlobalReqTimeService::get_instance().get_global_safe_timestamp(safe_timestamp))) {
SQL_PC_LOG(ERROR, "failed to get global safe timestamp", K(ret));
} else if (OB_FAIL(plan_cache->dump_deleted_objs<DUMP_ALL>(deleted_objs, safe_timestamp))) {
SQL_PC_LOG(WARN, "failed to get deleted sql objs", K(ret));
} else {
LOG_INFO("Deleted Cache Objs", K(deleted_objs));
for (int64_t i = 0; i < deleted_objs.count(); i++) { // ignore error code and continue
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true,
deleted_objs.at(i).obj_id_,
plan_cache))) {
LOG_WARN("failed to destroy cache obj", K(ret));
}
}
}
plan_cache->dec_ref_count();
}
return ret;
}
int ObPlanCacheManager::flush_plan_cache(const uint64_t tenant_id)
{
int ret = OB_SUCCESS;
observer::ObReqTimeGuard req_timeinfo_guard;
ObPlanCache *plan_cache = get_plan_cache(tenant_id);
if (NULL != plan_cache) {
if (OB_FAIL(plan_cache->cache_evict_all_plan())) {
SQL_PC_LOG(ERROR, "Plan cache evict failed, please check", K(ret));
}
ObArray<AllocCacheObjInfo> deleted_objs;
int64_t safe_timestamp = INT64_MAX;
if (OB_FAIL(ret)) {
// do nothing
} else if (OB_FAIL(observer::ObGlobalReqTimeService::get_instance().get_global_safe_timestamp(safe_timestamp))) {
SQL_PC_LOG(ERROR, "failed to get global safe timestamp", K(ret));
} else if (OB_FAIL(plan_cache->dump_deleted_objs<DUMP_SQL>(deleted_objs, safe_timestamp))) {
SQL_PC_LOG(WARN, "failed to get deleted sql objs", K(ret));
} else {
LOG_INFO("Deleted Cache Objs", K(deleted_objs));
for (int64_t i = 0; i < deleted_objs.count(); i++) { // ignore error code and continue
if (OB_FAIL(ObCacheObjectFactory::destroy_cache_obj(true,
deleted_objs.at(i).obj_id_,
plan_cache))) {
LOG_WARN("failed to destroy cache obj", K(ret));
}
}
}
plan_cache->dec_ref_count();
}
return ret;
}
int ObPlanCacheManager::revert_ps_cache(const uint64_t &tenant_id)
{
int ret = OB_SUCCESS;
ObPsCache *ppc = NULL;
observer::ObReqTimeGuard req_timeinfo_guard;
int tmp_ret = ps_pcm_.erase_refactored(tenant_id, &ppc);
if (OB_SUCCESS == tmp_ret && NULL != ppc) {
SQL_PC_LOG(INFO, "plan_cache_manager revert ps plan cache", "pc ref_count", ppc->get_ref_count(), K(tenant_id));
// cancel scheduled task
SQL_PC_LOG(INFO, "plan_cache_manager revert ps plan cache",
"pc ref_count", ppc->get_ref_count(),
K(tenant_id));
//cancel scheduled task
ppc->dec_ref_count();
ppc->set_valid(false);
} else if (OB_HASH_NOT_EXIST == tmp_ret) { // maybe erase by other thread
} else if (OB_HASH_NOT_EXIST == tmp_ret) { // maybe erase by other thread
SQL_PC_LOG(INFO, "PS Plan Cache not exist", K(tenant_id));
} else {
ret = tmp_ret;
SQL_PC_LOG(ERROR, "unexpected error when erase plan cache", K(tenant_id), K(ppc), K(ret));
SQL_PC_LOG(ERROR, "unexpected error when erase plan cache",
K(tenant_id), K(ppc), K(ret));
}
return ret;
}
@ -631,12 +741,13 @@ int ObPlanCacheManager::get_plan_cache_gc_strategy()
{
PlanCacheGCStrategy strategy = INVALID;
for (int i = 0; i < ARRAYSIZEOF(plan_cache_gc_confs) && strategy == INVALID; i++) {
if (0 == ObString::make_string(plan_cache_gc_confs[i]).case_compare(GCONF._ob_plan_cache_gc_strategy)) {
if (0 == ObString::make_string(plan_cache_gc_confs[i])
.case_compare(GCONF._ob_plan_cache_gc_strategy)) {
strategy = static_cast<PlanCacheGCStrategy>(i);
}
}
return strategy;
}
} // end of namespace sql
} // end of namespace oceanbase
} // end of namespace sql
} // end of namespace oceanbase