diff --git a/src/objit/include/objit/ob_llvm_helper.h b/src/objit/include/objit/ob_llvm_helper.h index 2cc8af595..4bb341d78 100644 --- a/src/objit/include/objit/ob_llvm_helper.h +++ b/src/objit/include/objit/ob_llvm_helper.h @@ -43,6 +43,7 @@ namespace oceanbase { namespace jit { +enum class ObPLOptLevel : int; namespace core { class JitContext; @@ -360,7 +361,7 @@ public: int init(); void final(); static int initialize(); - void compile_module(bool optimization = true); + int compile_module(jit::ObPLOptLevel optimization); void dump_module(); void dump_debuginfo(); int verify_function(ObLLVMFunction &function); diff --git a/src/objit/src/core/ob_orc_jit.cpp b/src/objit/src/core/ob_orc_jit.cpp index 8b0ca4b73..5d5eb4c80 100644 --- a/src/objit/src/core/ob_orc_jit.cpp +++ b/src/objit/src/core/ob_orc_jit.cpp @@ -178,6 +178,28 @@ void ObOrcJit::add_compiled_object(size_t length, const char *ptr) ObModuleKeys.push_back(Key); } +int ObOrcJit::set_optimize_level(ObPLOptLevel level) +{ + int ret = OB_SUCCESS; + + if (level <= ObPLOptLevel::INVALID || level > ObPLOptLevel::O3) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected PLSQL_OPTIMIZE_LEVEL", K(ret), K(level), K(lbt())); + } + + if (OB_SUCC(ret) && OB_ISNULL(ObTM)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected NULL TM", K(ret), K(ObTM.get()), K(lbt())); + } + + if (OB_SUCC(ret) && level == ObPLOptLevel::O0) { + ObTM->setOptLevel(CodeGenOpt::Level::None); + ObTM->setFastISel(true); + } + + return ret; +} + } // namespace core } // objit } // oceanbase diff --git a/src/objit/src/core/ob_orc_jit.h b/src/objit/src/core/ob_orc_jit.h index 4667cf269..836121958 100644 --- a/src/objit/src/core/ob_orc_jit.h +++ b/src/objit/src/core/ob_orc_jit.h @@ -31,6 +31,16 @@ namespace oceanbase { namespace jit { + +enum class ObPLOptLevel : int +{ + INVALID = -1, + O0 = 0, + O1 = 1, + O2 = 2, + O3 = 3 +}; + namespace core { using namespace llvm; @@ -85,6 +95,8 @@ public: const ObString& get_compiled_object() const { return SoObject; } + int set_optimize_level(ObPLOptLevel level); + private: std::string mangle(const std::string &Name) { diff --git a/src/objit/src/ob_llvm_helper.cpp b/src/objit/src/ob_llvm_helper.cpp index f81115d03..cfe2eb7a5 100644 --- a/src/objit/src/ob_llvm_helper.cpp +++ b/src/objit/src/ob_llvm_helper.cpp @@ -597,22 +597,30 @@ int ObLLVMHelper::init_llvm() { OZ (helper.get_int64(OB_SUCCESS, magic)); OZ (helper.create_ret(magic)); - OX (helper.compile_module()); + OZ (helper.compile_module(jit::ObPLOptLevel::O2)); OX (helper.get_function_address(init_func_name)); return ret; } -void ObLLVMHelper::compile_module(bool optimization) +int ObLLVMHelper::compile_module(jit::ObPLOptLevel optimization) { - if (optimization) { - OB_LLVM_MALLOC_GUARD(GET_PL_MOD_STRING(pl::OB_PL_CODE_GEN)); - jc_->optimize(); - LOG_INFO("================Optimized LLVM Module================"); - dump_module(); + int ret = OB_SUCCESS; + + if (OB_FAIL(jit_->set_optimize_level(optimization))) { + LOG_WARN("failed to set backend optimize level", K(ret), K(optimization)); + } else { + if (optimization >= jit::ObPLOptLevel::O2) { + OB_LLVM_MALLOC_GUARD(GET_PL_MOD_STRING(pl::OB_PL_CODE_GEN)); + jc_->optimize(); + LOG_INFO("================Optimized LLVM Module================"); + dump_module(); + } + OB_LLVM_MALLOC_GUARD(GET_PL_MOD_STRING(pl::OB_PL_JIT)); + jc_->compile(); } - OB_LLVM_MALLOC_GUARD(GET_PL_MOD_STRING(pl::OB_PL_JIT)); - jc_->compile(); + + return ret; } void ObLLVMHelper::dump_module() diff --git a/src/pl/ob_pl.cpp b/src/pl/ob_pl.cpp index 27292cfd8..7d9a1b7a6 100644 --- a/src/pl/ob_pl.cpp +++ b/src/pl/ob_pl.cpp @@ -188,7 +188,8 @@ int ObPL::init(common::ObMySQLProxy &sql_proxy) sql_proxy_ = &sql_proxy; OZ (codegen_lock_.init(1024)); - OZ (jit_lock_.init(32)); + OZ (jit_lock_.first.init(1024)); + OZ (jit_lock_.second.init(1024)); OZ (interface_service_.init()); OX (serialize_composite_callback = ObUserDefinedType::serialize_obj); OX (deserialize_composite_callback = ObUserDefinedType::deserialize_obj); diff --git a/src/pl/ob_pl.h b/src/pl/ob_pl.h index 87eb68605..a870f22be 100644 --- a/src/pl/ob_pl.h +++ b/src/pl/ob_pl.h @@ -1192,7 +1192,7 @@ public: static int check_trigger_arg(const ParamStore ¶ms, const ObPLFunction &func); - ObBucketLock& get_jit_lock() { return jit_lock_; } + std::pair& get_jit_lock() { return jit_lock_; } static int check_session_alive(const ObBasicSessionInfo &session); @@ -1201,7 +1201,9 @@ private: ObPLPackageManager package_manager_; ObPLInterfaceService interface_service_; common::ObBucketLock codegen_lock_; - common::ObBucketLock jit_lock_; + + // first bucket is for deduplication, second bucket is for concurrency control + std::pair jit_lock_; }; class LinkPLStackGuard diff --git a/src/pl/ob_pl_code_generator.cpp b/src/pl/ob_pl_code_generator.cpp index 4f5b72272..2be89c07c 100644 --- a/src/pl/ob_pl_code_generator.cpp +++ b/src/pl/ob_pl_code_generator.cpp @@ -8301,8 +8301,12 @@ int ObPLCodeGenerator::generate(ObPLPackage &pl_package) LOG_INFO("================Original LLVM Module================", K(debug_mode_)); helper_.dump_module(); #endif + + // set optimize_level to 0 if in debug mode, otherwise use PLSQL_OPTIMIZE_LEVEL in exec_env + int64_t optimize_level = debug_mode_ ? 0 : pl_package.get_exec_env().get_plsql_optimize_level(); + OZ (helper_.verify_module(), pl_package); - OX (helper_.compile_module(!debug_mode_)); + OZ (helper_.compile_module(static_cast(optimize_level))); } OZ (final_expression(pl_package)); @@ -8446,8 +8450,12 @@ int ObPLCodeGenerator::generate_normal(ObPLFunction &pl_func) LOG_INFO("================Original================", K(pl_func), K(debug_mode_)); helper_.dump_module(); #endif + + // set optimize_level to 0 if in debug mode, otherwise use PLSQL_OPTIMIZE_LEVEL in exec_env + int64_t optimize_level = debug_mode_ ? 0 : pl_func.get_exec_env().get_plsql_optimize_level(); + OZ (helper_.verify_module(), pl_func); -OX (helper_.compile_module(!debug_mode_)); + OZ (helper_.compile_module(static_cast(optimize_level))); } if (OB_SUCC(ret)) { diff --git a/src/pl/ob_pl_compile.cpp b/src/pl/ob_pl_compile.cpp index 4abee50e8..4e1c7c6d7 100644 --- a/src/pl/ob_pl_compile.cpp +++ b/src/pl/ob_pl_compile.cpp @@ -233,7 +233,11 @@ int ObPLCompiler::compile( #endif lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(MTL_ID(), GET_PL_MOD_STRING(pl::OB_PL_CODE_GEN))); uint64_t lock_idx = stmt_id != OB_INVALID_ID ? stmt_id : murmurhash(block->str_value_, block->str_len_, 0); - ObBucketHashWLockGuard compile_guard(GCTX.pl_engine_->get_jit_lock(), lock_idx); + + // latch_id = (bucket_id % bucket_cnt_) / 8, so it is needed to multiply 8 to avoid consecutive ids being mapped to the same latch + ObBucketHashWLockGuard compile_id_guard(GCTX.pl_engine_->get_jit_lock().first, lock_idx * 8); + ObBucketHashWLockGuard compile_num_guard(GCTX.pl_engine_->get_jit_lock().second, (lock_idx % GCONF._ob_pl_compile_max_concurrency) * 8); + // check session status after get lock if (OB_FAIL(ObPL::check_session_alive(session_info_))) { LOG_WARN("query or session is killed after get PL jit lock", K(ret)); @@ -476,7 +480,9 @@ int ObPLCompiler::compile( OZ (cg.init()); OZ (read_dll_from_disk(enable_persistent, routine_storage, func_ast, cg, routine, func, op)); if (OB_SUCC(ret) && 0 == func.get_action()) { // not in disk - ObBucketHashWLockGuard compile_guard(GCTX.pl_engine_->get_jit_lock(), routine.get_routine_id()); + // latch_id = (bucket_id % bucket_cnt_) / 8, so it is needed to multiply 8 to avoid consecutive ids being mapped to the same latch + ObBucketHashWLockGuard compile_id_guard(GCTX.pl_engine_->get_jit_lock().first, routine.get_routine_id() * 8); + ObBucketHashWLockGuard compile_num_guard(GCTX.pl_engine_->get_jit_lock().second, (routine.get_routine_id() % GCONF._ob_pl_compile_max_concurrency) * 8); OZ (ObPL::check_session_alive(session_info_)); OZ (read_dll_from_disk(enable_persistent, routine_storage, func_ast, cg, routine, func, op)); // has lock, try read dll again if (OB_SUCC(ret) && 0 == func.get_action()) { // nobody code gen yet! do real code generate @@ -740,7 +746,10 @@ int ObPLCompiler::generate_package(const ObString &exec_env, ObPLPackageAST &pac if (op == ObRoutinePersistentInfo::ObPLOperation::SUCC) { //do nothing } else { - ObBucketHashWLockGuard compile_guard(GCTX.pl_engine_->get_jit_lock(), package.get_id()); + // latch_id = (bucket_id % bucket_cnt_) / 8, so it is needed to multiply 8 to avoid consecutive ids being mapped to the same latch + ObBucketHashWLockGuard compile_id_guard(GCTX.pl_engine_->get_jit_lock().first, package.get_id() * 8); + ObBucketHashWLockGuard compile_num_guard(GCTX.pl_engine_->get_jit_lock().second, (package.get_id() % GCONF._ob_pl_compile_max_concurrency) * 8); + OZ (ObPL::check_session_alive(session_info_)); if (OB_SUCC(ret)) { if (need_read_dll) { @@ -815,11 +824,6 @@ int ObPLCompiler::compile_package(const ObPackageInfo &package_info, package_ast, package_info.is_for_trigger())); { - // check session status after get lock - if (OB_SUCC(ret) && OB_FAIL(ObPL::check_session_alive(session_info_))) { - LOG_WARN("query or session is killed after get PL jit lock", K(ret)); - } - if (OB_SUCC(ret)) { #ifdef USE_MCJIT HEAP_VAR(ObPLCodeGenerator, cg ,allocator_, session_info_) { @@ -834,7 +838,11 @@ int ObPLCompiler::compile_package(const ObPackageInfo &package_info, lib::is_oracle_mode()) { #endif lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(MTL_ID(), GET_PL_MOD_STRING(pl::OB_PL_CODE_GEN))); - ObBucketHashWLockGuard compile_guard(GCTX.pl_engine_->get_jit_lock(), package.get_id()); + + // latch_id = (bucket_id % bucket_cnt_) / 8, so it is needed to multiply 8 to avoid consecutive ids being mapped to the same latch + ObBucketHashWLockGuard compile_id_guard(GCTX.pl_engine_->get_jit_lock().first, package.get_id() * 8); + ObBucketHashWLockGuard compile_num_guard(GCTX.pl_engine_->get_jit_lock().second, (package.get_id() % GCONF._ob_pl_compile_max_concurrency) * 8); + // check session status after get lock OZ (ObPL::check_session_alive(session_info_)); diff --git a/src/share/parameter/ob_parameter_seed.ipp b/src/share/parameter/ob_parameter_seed.ipp index 066e31ab6..7b434b70b 100644 --- a/src/share/parameter/ob_parameter_seed.ipp +++ b/src/share/parameter/ob_parameter_seed.ipp @@ -1302,11 +1302,6 @@ DEF_STR(plsql_code_type, OB_TENANT_PARAMETER, "native", DEF_BOOL(plsql_debug, OB_TENANT_PARAMETER, "False", "specifies whether or not PL/SQL library units will be compiled for debugging", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); -DEF_INT(plsql_optimize_level, OB_TENANT_PARAMETER, "1", - "specifies the optimization level that will be used to" - "compile PL/SQL library units. The higher the setting of this parameter, the more effort" - "the compiler makes to optimize PL/SQL library units", - ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_BOOL(plsql_v2_compatibility, OB_TENANT_PARAMETER, "False", "allows some abnormal behavior that Version 8 disallows, not available", ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); @@ -1965,4 +1960,8 @@ DEF_BOOL(_enable_dbms_job_package, OB_CLUSTER_PARAMETER, "True", // obkv feature switch DEF_BOOL(_enable_kv_feature, OB_CLUSTER_PARAMETER, "True", "Enable or disable OBKV feature.", - ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); \ No newline at end of file + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); + +DEF_INT(_ob_pl_compile_max_concurrency, OB_CLUSTER_PARAMETER, "4", "[0,)", + "The maximum number of threads that an observer node can compile PL concurrently.", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); diff --git a/src/share/system_variable/ob_sys_var_class_type.h b/src/share/system_variable/ob_sys_var_class_type.h index 60b69730e..96258fd72 100644 --- a/src/share/system_variable/ob_sys_var_class_type.h +++ b/src/share/system_variable/ob_sys_var_class_type.h @@ -438,6 +438,7 @@ enum ObSysVarClassType SYS_VAR_INNODB_AUTOINC_LOCK_MODE = 10389, SYS_VAR_SKIP_EXTERNAL_LOCKING = 10390, SYS_VAR_SUPER_READ_ONLY = 10391, + SYS_VAR_PLSQL_OPTIMIZE_LEVEL = 10393, }; } diff --git a/src/share/system_variable/ob_system_variable_alias.h b/src/share/system_variable/ob_system_variable_alias.h index 339610573..c0bc8e7d6 100644 --- a/src/share/system_variable/ob_system_variable_alias.h +++ b/src/share/system_variable/ob_system_variable_alias.h @@ -433,6 +433,7 @@ namespace share static const char* const OB_SV_INNODB_AUTOINC_LOCK_MODE = "innodb_autoinc_lock_mode"; static const char* const OB_SV_SKIP_EXTERNAL_LOCKING = "skip_external_locking"; static const char* const OB_SV_SUPER_READ_ONLY = "super_read_only"; + static const char* const OB_SV_PLSQL_OPTIMIZE_LEVEL = "plsql_optimize_level"; } } diff --git a/src/share/system_variable/ob_system_variable_factory.cpp b/src/share/system_variable/ob_system_variable_factory.cpp index bb5066f46..5718d8b19 100644 --- a/src/share/system_variable/ob_system_variable_factory.cpp +++ b/src/share/system_variable/ob_system_variable_factory.cpp @@ -705,6 +705,7 @@ const char *ObSysVarFactory::SYS_VAR_NAMES_SORTED_BY_NAME[] = { "parallel_servers_target", "performance_schema", "plsql_ccflags", + "plsql_optimize_level", "plsql_warnings", "plugin_dir", "privilege_features_enable", @@ -1125,6 +1126,7 @@ const ObSysVarClassType ObSysVarFactory::SYS_VAR_IDS_SORTED_BY_NAME[] = { SYS_VAR_PARALLEL_SERVERS_TARGET, SYS_VAR_PERFORMANCE_SCHEMA, SYS_VAR_PLSQL_CCFLAGS, + SYS_VAR_PLSQL_OPTIMIZE_LEVEL, SYS_VAR_PLSQL_WARNINGS, SYS_VAR_PLUGIN_DIR, SYS_VAR_PRIVILEGE_FEATURES_ENABLE, @@ -1659,7 +1661,8 @@ const char *ObSysVarFactory::SYS_VAR_NAMES_SORTED_BY_ID[] = { "innodb_api_disable_rowlock", "innodb_autoinc_lock_mode", "skip_external_locking", - "super_read_only" + "super_read_only", + "plsql_optimize_level" }; bool ObSysVarFactory::sys_var_name_case_cmp(const char *name1, const ObString &name2) @@ -2245,6 +2248,7 @@ int ObSysVarFactory::create_all_sys_vars() + sizeof(ObSysVarInnodbAutoincLockMode) + sizeof(ObSysVarSkipExternalLocking) + sizeof(ObSysVarSuperReadOnly) + + sizeof(ObSysVarPlsqlOptimizeLevel) ; void *ptr = NULL; if (OB_ISNULL(ptr = allocator_.alloc(total_mem_size))) { @@ -6006,6 +6010,15 @@ int ObSysVarFactory::create_all_sys_vars() ptr = (void *)((char *)ptr + sizeof(ObSysVarSuperReadOnly)); } } + if (OB_SUCC(ret)) { + if (OB_ISNULL(sys_var_ptr = new (ptr)ObSysVarPlsqlOptimizeLevel())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("fail to new ObSysVarPlsqlOptimizeLevel", K(ret)); + } else { + store_buf_[ObSysVarsToIdxMap::get_store_idx(static_cast(SYS_VAR_PLSQL_OPTIMIZE_LEVEL))] = sys_var_ptr; + ptr = (void *)((char *)ptr + sizeof(ObSysVarPlsqlOptimizeLevel)); + } + } } return ret; @@ -10603,6 +10616,17 @@ int ObSysVarFactory::create_sys_var(ObIAllocator &allocator_, ObSysVarClassType } break; } + case SYS_VAR_PLSQL_OPTIMIZE_LEVEL: { + void *ptr = NULL; + if (OB_ISNULL(ptr = allocator_.alloc(sizeof(ObSysVarPlsqlOptimizeLevel)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("fail to alloc memory", K(ret), K(sizeof(ObSysVarPlsqlOptimizeLevel))); + } else if (OB_ISNULL(sys_var_ptr = new (ptr)ObSysVarPlsqlOptimizeLevel())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("fail to new ObSysVarPlsqlOptimizeLevel", K(ret)); + } + break; + } default: { ret = OB_ERR_UNEXPECTED; diff --git a/src/share/system_variable/ob_system_variable_factory.h b/src/share/system_variable/ob_system_variable_factory.h index 0854011e9..15936cf7d 100644 --- a/src/share/system_variable/ob_system_variable_factory.h +++ b/src/share/system_variable/ob_system_variable_factory.h @@ -3072,6 +3072,13 @@ public: inline virtual ObSysVarClassType get_type() const { return SYS_VAR_SUPER_READ_ONLY; } inline virtual const common::ObObj &get_global_default_value() const { return ObSysVariables::get_default_value(416); } }; +class ObSysVarPlsqlOptimizeLevel : public ObIntSysVar +{ +public: + ObSysVarPlsqlOptimizeLevel() : ObIntSysVar(NULL, NULL, NULL, NULL, NULL) {} + inline virtual ObSysVarClassType get_type() const { return SYS_VAR_PLSQL_OPTIMIZE_LEVEL; } + inline virtual const common::ObObj &get_global_default_value() const { return ObSysVariables::get_default_value(417); } +}; class ObSysVarFactory @@ -3092,7 +3099,7 @@ public: static const common::ObString get_sys_var_name_by_id(ObSysVarClassType sys_var_id); const static int64_t MYSQL_SYS_VARS_COUNT = 99; - const static int64_t OB_SYS_VARS_COUNT = 318; + const static int64_t OB_SYS_VARS_COUNT = 319; const static int64_t ALL_SYS_VARS_COUNT = MYSQL_SYS_VARS_COUNT + OB_SYS_VARS_COUNT; const static int64_t INVALID_MAX_READ_STALE_TIME = -1; diff --git a/src/share/system_variable/ob_system_variable_init.cpp b/src/share/system_variable/ob_system_variable_init.cpp index cdaee28dc..e0f9e9b96 100644 --- a/src/share/system_variable/ob_system_variable_init.cpp +++ b/src/share/system_variable/ob_system_variable_init.cpp @@ -5886,13 +5886,26 @@ static struct VarsInit{ ObSysVars[416].alias_ = "OB_SV_SUPER_READ_ONLY" ; }(); + [&] (){ + ObSysVars[417].default_value_ = "2" ; + ObSysVars[417].info_ = "PLSQL_OPTIMIZE_LEVEL specifies the optimization level that will be used to compile PL/SQL library units. The higher the setting of this parameter, the more effort the compiler makes to optimize PL/SQL library units." ; + ObSysVars[417].name_ = "plsql_optimize_level" ; + ObSysVars[417].data_type_ = ObIntType ; + ObSysVars[417].flags_ = ObSysVarFlag::SESSION_SCOPE | ObSysVarFlag::GLOBAL_SCOPE | ObSysVarFlag::NEED_SERIALIZE ; + ObSysVars[417].id_ = SYS_VAR_PLSQL_OPTIMIZE_LEVEL ; + cur_max_var_id = MAX(cur_max_var_id, static_cast(SYS_VAR_PLSQL_OPTIMIZE_LEVEL)) ; + ObSysVarsIdToArrayIdx[SYS_VAR_PLSQL_OPTIMIZE_LEVEL] = 417 ; + ObSysVars[417].base_value_ = "2" ; + ObSysVars[417].alias_ = "OB_SV_PLSQL_OPTIMIZE_LEVEL" ; + }(); + if (cur_max_var_id >= ObSysVarFactory::OB_MAX_SYS_VAR_ID) { HasInvalidSysVar = true; } } }vars_init; -static int64_t var_amount = 417; +static int64_t var_amount = 418; int64_t ObSysVariables::get_all_sys_var_count(){ return ObSysVarFactory::ALL_SYS_VARS_COUNT;} ObSysVarClassType ObSysVariables::get_sys_var_id(int64_t i){ return ObSysVars[i].id_;} diff --git a/src/share/system_variable/ob_system_variable_init.json b/src/share/system_variable/ob_system_variable_init.json index 4c4e24ca8..d5f8410c2 100644 --- a/src/share/system_variable/ob_system_variable_init.json +++ b/src/share/system_variable/ob_system_variable_init.json @@ -6985,5 +6985,18 @@ "background_cn": "", "ref_url": "", "placeholder": true + }, + "plsql_optimize_level": { + "id": 10393, + "name": "plsql_optimize_level", + "default_value": "2", + "base_value": "2", + "data_type": "int", + "info": "PLSQL_OPTIMIZE_LEVEL specifies the optimization level that will be used to compile PL/SQL library units. The higher the setting of this parameter, the more effort the compiler makes to optimize PL/SQL library units.", + "flags": "SESSION | GLOBAL | NEED_SERIALIZE", + "publish_version": "423", + "info_cn": "", + "background_cn": "", + "ref_url": "" } } diff --git a/src/sql/session/ob_basic_session_info.cpp b/src/sql/session/ob_basic_session_info.cpp index 98b0a9688..7906f9e6a 100644 --- a/src/sql/session/ob_basic_session_info.cpp +++ b/src/sql/session/ob_basic_session_info.cpp @@ -6488,6 +6488,9 @@ void ObExecEnv::reset() collation_connection_ = CS_TYPE_INVALID; collation_database_ = CS_TYPE_INVALID; plsql_ccflags_.reset(); + + // default PLSQL_OPTIMIZE_LEVEL = 2 + plsql_optimize_level_ = 2; } bool ObExecEnv::operator==(const ObExecEnv &other) const @@ -6496,7 +6499,8 @@ bool ObExecEnv::operator==(const ObExecEnv &other) const && charset_client_ == other.charset_client_ && collation_connection_ == other.collation_connection_ && collation_database_ == other.collation_database_ - && plsql_ccflags_ == other.plsql_ccflags_; + && plsql_ccflags_ == other.plsql_ccflags_ + && plsql_optimize_level_ == other.plsql_optimize_level_; } bool ObExecEnv::operator!=(const ObExecEnv &other) const @@ -6535,7 +6539,8 @@ int ObExecEnv::gen_exec_env(const ObBasicSessionInfo &session, char* buf, int64_ case SQL_MODE: case CHARSET_CLIENT: case COLLATION_CONNECTION: - case COLLATION_DATABASE: { + case COLLATION_DATABASE: + case PLSQL_OPTIMIZE_LEVEL: { int64_t size = 0; val.reset(); OZ (session.get_sys_variable(ExecEnvMap[i], val)); @@ -6597,7 +6602,8 @@ int ObExecEnv::gen_exec_env(const share::schema::ObSysVariableSchema &sys_variab case SQL_MODE: case CHARSET_CLIENT: case COLLATION_CONNECTION: - case COLLATION_DATABASE: { + case COLLATION_DATABASE: + case PLSQL_OPTIMIZE_LEVEL: { int64_t size = 0; if (OB_FAIL(sys_variable.get_sysvar_schema(ExecEnvMap[i], sysvar_schema))) { LOG_WARN("failed to get sysvar schema", K(ret)); @@ -6653,7 +6659,14 @@ int ObExecEnv::init(const ObString &exec_env) int ret = OB_SUCCESS; ObString value_str; ObString start = exec_env; + bool is_oracle_mode = lib::is_oracle_mode(); + for (int64_t i = 0; OB_SUCC(ret) && i < MAX_ENV; ++i) { + // mysql mode do not have plsql_ccflags_length + if (PLSQL_CCFLAGS == i && !is_oracle_mode) { + continue; + } + GET_ENV_VALUE(start, value_str); if (OB_SUCC(ret)) { switch (i) { @@ -6679,11 +6692,20 @@ int ObExecEnv::init(const ObString &exec_env) } else { int32_t plsql_ccflags_length = 0; SET_ENV_VALUE(plsql_ccflags_length, int32_t); + CK (plsql_ccflags_length >= 0); if (OB_FAIL(ret)) { } else if (plsql_ccflags_length > 0) { plsql_ccflags_.assign(start.ptr(), plsql_ccflags_length); - start += plsql_ccflags_length + 1;// 1 for ',' } + OX (start += plsql_ccflags_length + 1);// 1 for ',' + } + } + break; + case PLSQL_OPTIMIZE_LEVEL: { + if (value_str.empty()) { + // do nothing, old routine object version do not have plsql_optimize_level + } else { + SET_ENV_VALUE(plsql_optimize_level_, int64_t); } } break; @@ -6737,6 +6759,10 @@ int ObExecEnv::load(ObBasicSessionInfo &session, ObIAllocator *alloc) } } break; + case PLSQL_OPTIMIZE_LEVEL: { + plsql_optimize_level_ = static_cast(val.get_int()); + } + break; default: { ret = common::OB_ERR_UNEXPECTED; LOG_WARN("Invalid env type", K(i), K(ret)); @@ -6776,6 +6802,10 @@ int ObExecEnv::store(ObBasicSessionInfo &session) val.set_collation_type(ObCharset::get_system_collation()); } break; + case PLSQL_OPTIMIZE_LEVEL: { + val.set_int(plsql_optimize_level_); + } + break; default: { ret = common::OB_ERR_UNEXPECTED; LOG_WARN("Invalid env type", K(i), K(ret)); diff --git a/src/sql/session/ob_basic_session_info.h b/src/sql/session/ob_basic_session_info.h index 4eabe4fca..d6e0f4a2a 100644 --- a/src/sql/session/ob_basic_session_info.h +++ b/src/sql/session/ob_basic_session_info.h @@ -2592,6 +2592,7 @@ public: COLLATION_CONNECTION, COLLATION_DATABASE, PLSQL_CCFLAGS, + PLSQL_OPTIMIZE_LEVEL, MAX_ENV, }; @@ -2601,6 +2602,7 @@ public: share::SYS_VAR_COLLATION_CONNECTION, share::SYS_VAR_COLLATION_DATABASE, share::SYS_VAR_PLSQL_CCFLAGS, + share::SYS_VAR_PLSQL_OPTIMIZE_LEVEL, share::SYS_VAR_INVALID }; @@ -2609,7 +2611,9 @@ public: charset_client_(CS_TYPE_INVALID), collation_connection_(CS_TYPE_INVALID), collation_database_(CS_TYPE_INVALID), - plsql_ccflags_() {} + plsql_ccflags_(), + plsql_optimize_level_(2) // default PLSQL_OPTIMIZE_LEVEL = 2 + { } virtual ~ObExecEnv() {} @@ -2617,7 +2621,8 @@ public: K_(charset_client), K_(collation_connection), K_(collation_database), - K_(plsql_ccflags)); + K_(plsql_ccflags), + K_(plsql_optimize_level)); void reset(); @@ -2642,12 +2647,16 @@ public: void set_plsql_ccflags(ObString &plsql_ccflags) { plsql_ccflags_ = plsql_ccflags; } + int64_t get_plsql_optimize_level() { return plsql_optimize_level_; } + void set_plsql_optimize_level(int64_t level) { plsql_optimize_level_ = plsql_optimize_level_; } + private: ObSQLMode sql_mode_; ObCollationType charset_client_; ObCollationType collation_connection_; ObCollationType collation_database_; ObString plsql_ccflags_; + int64_t plsql_optimize_level_; }; diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result index 438ec75f8..f804f5d8e 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result @@ -180,7 +180,6 @@ partition_balance_schedule_interval plan_cache_evict_interval plsql_code_type plsql_debug -plsql_optimize_level plsql_v2_compatibility px_task_size px_workers_per_cpu_quota @@ -385,6 +384,7 @@ _ob_max_thread_num _ob_obj_dep_maint_task_interval _ob_plan_cache_auto_flush_interval _ob_plan_cache_gc_strategy +_ob_pl_compile_max_concurrency _ob_query_rate_limit _ob_ssl_invited_nodes _ob_trans_rpc_timeout