4422 lines
165 KiB
C++
4422 lines
165 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.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX SQL_SESSION
|
|
|
|
#include "sql/session/ob_sql_session_info.h"
|
|
#include "lib/trace/ob_trace_event.h"
|
|
#include "lib/alloc/alloc_func.h"
|
|
#include "lib/string/ob_sql_string.h"
|
|
#include "lib/rc/ob_rc.h"
|
|
#include "sql/ob_sql_utils.h"
|
|
#include "sql/ob_sql_trans_control.h"
|
|
#include "sql/session/ob_sql_session_mgr.h"
|
|
#include "io/easy_io.h"
|
|
#include "rpc/ob_rpc_define.h"
|
|
#include "observer/omt/ob_tenant_config_mgr.h"
|
|
#include "observer/ob_server_struct.h"
|
|
#include "pl/ob_pl.h"
|
|
#include "pl/ob_pl_package.h"
|
|
#include "pl/sys_package/ob_dbms_sql.h"
|
|
#include "observer/mysql/ob_mysql_request_manager.h"
|
|
#include "observer/mysql/obmp_stmt_send_piece_data.h"
|
|
#include "observer/mysql/ob_query_driver.h"
|
|
#include "observer/ob_server.h"
|
|
#include "share/rc/ob_context.h"
|
|
#include "share/rc/ob_tenant_base.h"
|
|
#include "sql/resolver/cmd/ob_call_procedure_stmt.h"
|
|
#include "sql/resolver/ddl/ob_ddl_stmt.h"
|
|
#include "observer/omt/ob_tenant_config_mgr.h"
|
|
#include "share/schema/ob_schema_struct.h"
|
|
#include "sql/resolver/ddl/ob_create_synonym_stmt.h"
|
|
#include "sql/resolver/ddl/ob_drop_synonym_stmt.h"
|
|
#include "sql/engine/expr/ob_datum_cast.h"
|
|
#include "lib/checksum/ob_crc64.h"
|
|
#include "lib/alloc/alloc_assist.h"
|
|
#include "lib/string/ob_string.h"
|
|
#include "sql/engine/px/ob_px_target_mgr.h"
|
|
#include "lib/utility/utility.h"
|
|
#include "lib/utility/ob_proto_trans_util.h"
|
|
#ifdef OB_BUILD_ORACLE_PL
|
|
#include "pl/debug/ob_pl_debugger_manager.h"
|
|
#include "pl/sys_package/ob_pl_utl_file.h"
|
|
#endif
|
|
#include "lib/allocator/ob_mod_define.h"
|
|
#include "lib/string/ob_hex_utils_base.h"
|
|
#include "share/stat/ob_opt_stat_manager.h"
|
|
#include "sql/plan_cache/ob_ps_cache.h"
|
|
#include "observer/ob_sql_client_decorator.h"
|
|
#include "ob_sess_info_verify.h"
|
|
#include "share/schema/ob_schema_utils.h"
|
|
|
|
using namespace oceanbase::sql;
|
|
using namespace oceanbase::common;
|
|
using namespace oceanbase::share::schema;
|
|
using namespace oceanbase::share;
|
|
using namespace oceanbase::pl;
|
|
using namespace oceanbase::obmysql;
|
|
|
|
static const int64_t DEFAULT_XA_END_TIMEOUT_SECONDS = 60;/*60s*/
|
|
|
|
const char *state_str[] =
|
|
{
|
|
"INIT",
|
|
"SLEEP",
|
|
"ACTIVE",
|
|
"QUERY_KILLED",
|
|
"SESSION_KILLED",
|
|
};
|
|
|
|
void ObTenantCachedSchemaGuardInfo::reset()
|
|
{
|
|
schema_guard_.reset();
|
|
ref_ts_ = 0;
|
|
tenant_id_ = 0;
|
|
schema_version_ = 0;
|
|
}
|
|
|
|
int ObTenantCachedSchemaGuardInfo::refresh_tenant_schema_guard(const uint64_t tenant_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
|
|
if (OB_FAIL(OBSERVER.get_gctx().schema_service_->get_tenant_schema_guard(tenant_id, schema_guard_))) {
|
|
LOG_WARN("get schema guard failed", K(ret), K(tenant_id));
|
|
} else if (OB_FAIL(schema_guard_.get_schema_version(tenant_id, schema_version_))) {
|
|
LOG_WARN("fail get schema version", K(ret), K(tenant_id));
|
|
} else {
|
|
ref_ts_ = ObClockGenerator::getClock();
|
|
tenant_id_ = tenant_id;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void ObTenantCachedSchemaGuardInfo::try_revert_schema_guard()
|
|
{
|
|
if (schema_guard_.is_inited()) {
|
|
const int64_t MAX_SCHEMA_GUARD_CACHED_TIME = 10 * 1000 * 1000;
|
|
if (ObClockGenerator::getClock() - ref_ts_ > MAX_SCHEMA_GUARD_CACHED_TIME) {
|
|
LOG_DEBUG("revert schema guard success by sql",
|
|
"session_id", schema_guard_.get_session_id(),
|
|
K_(tenant_id),
|
|
K_(schema_version));
|
|
reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
ObSQLSessionInfo::ObSQLSessionInfo(const uint64_t tenant_id) :
|
|
ObVersionProvider(),
|
|
ObBasicSessionInfo(tenant_id),
|
|
is_inited_(false),
|
|
warnings_buf_(),
|
|
show_warnings_buf_(),
|
|
end_trans_cb_(),
|
|
user_priv_set_(),
|
|
db_priv_set_(),
|
|
curr_trans_start_time_(0),
|
|
curr_trans_last_stmt_time_(0),
|
|
sess_create_time_(0),
|
|
last_refresh_temp_table_time_(0),
|
|
has_temp_table_flag_(false),
|
|
has_accessed_session_level_temp_table_(false),
|
|
enable_early_lock_release_(false),
|
|
is_for_trigger_package_(false),
|
|
trans_type_(transaction::ObTxClass::USER),
|
|
version_provider_(NULL),
|
|
config_provider_(NULL),
|
|
request_manager_(NULL),
|
|
flt_span_mgr_(NULL),
|
|
plan_cache_(NULL),
|
|
ps_cache_(NULL),
|
|
found_rows_(1),
|
|
affected_rows_(-1),
|
|
global_sessid_(0),
|
|
read_uncommited_(false),
|
|
trace_recorder_(NULL),
|
|
inner_flag_(false),
|
|
is_max_availability_mode_(false),
|
|
next_client_ps_stmt_id_(0),
|
|
is_remote_session_(false),
|
|
session_type_(INVALID_TYPE),
|
|
curr_session_context_size_(0),
|
|
pl_context_(NULL),
|
|
pl_can_retry_(true),
|
|
#ifdef OB_BUILD_ORACLE_PL
|
|
pl_debugger_(NULL),
|
|
#endif
|
|
#ifdef OB_BUILD_SPM
|
|
select_plan_type_(ObSpmCacheCtx::INVALID_TYPE),
|
|
#endif
|
|
pl_attach_session_id_(0),
|
|
pl_query_sender_(NULL),
|
|
pl_ps_protocol_(false),
|
|
is_ob20_protocol_(false),
|
|
is_session_var_sync_(false),
|
|
pl_sync_pkg_vars_(NULL),
|
|
inner_conn_(NULL),
|
|
encrypt_info_(),
|
|
enable_role_array_(),
|
|
in_definer_named_proc_(false),
|
|
priv_user_id_(OB_INVALID_ID),
|
|
xa_end_timeout_seconds_(transaction::ObXADefault::OB_XA_TIMEOUT_SECONDS),
|
|
xa_last_result_(OB_SUCCESS),
|
|
cached_tenant_config_info_(this),
|
|
prelock_(false),
|
|
proxy_version_(0),
|
|
min_proxy_version_ps_(0),
|
|
is_ignore_stmt_(false),
|
|
ddl_info_(),
|
|
is_table_name_hidden_(false),
|
|
piece_cache_(NULL),
|
|
is_load_data_exec_session_(false),
|
|
pl_exact_err_msg_(),
|
|
is_varparams_sql_prepare_(false),
|
|
got_tenant_conn_res_(false),
|
|
got_user_conn_res_(false),
|
|
conn_res_user_id_(OB_INVALID_ID),
|
|
mem_context_(nullptr),
|
|
has_query_executed_(false),
|
|
is_latest_sess_info_(false),
|
|
cur_exec_ctx_(nullptr),
|
|
restore_auto_commit_(false),
|
|
dblink_context_(this),
|
|
sql_req_level_(0),
|
|
expect_group_id_(OB_INVALID_ID),
|
|
group_id_not_expected_(false),
|
|
gtt_session_scope_unique_id_(0),
|
|
gtt_trans_scope_unique_id_(0),
|
|
vid_(OB_INVALID_ID),
|
|
vport_(0),
|
|
in_bytes_(0),
|
|
out_bytes_(0),
|
|
current_dblink_sequence_id_(0),
|
|
client_non_standard_(false),
|
|
is_session_sync_support_(false)
|
|
{
|
|
MEMSET(tenant_buff_, 0, sizeof(share::ObTenantSpaceFetcher));
|
|
MEMSET(vip_buf_, 0, sizeof(vip_buf_));
|
|
}
|
|
|
|
ObSQLSessionInfo::~ObSQLSessionInfo()
|
|
{
|
|
plan_cache_ = NULL;
|
|
destroy(false);
|
|
}
|
|
|
|
int ObSQLSessionInfo::init(uint32_t sessid, uint64_t proxy_sessid,
|
|
common::ObIAllocator *bucket_allocator, const ObTZInfoMap *tz_info, int64_t sess_create_time,
|
|
uint64_t tenant_id, int64_t client_create_time)
|
|
{
|
|
UNUSED(tenant_id);
|
|
int ret = OB_SUCCESS;
|
|
static const int64_t PS_BUCKET_NUM = 64;
|
|
if (OB_FAIL(ObBasicSessionInfo::init(sessid, proxy_sessid, bucket_allocator, tz_info))) {
|
|
LOG_WARN("fail to init basic session info", K(ret));
|
|
} else if (FALSE_IT(txn_free_route_ctx_.set_sessid(sessid))) {
|
|
} else if (!is_acquire_from_pool() &&
|
|
OB_FAIL(package_state_map_.create(hash::cal_next_prime(4),
|
|
ObMemAttr(orig_tenant_id_, "PackStateMap")))) {
|
|
LOG_WARN("create package state map failed", K(ret));
|
|
} else if (!is_acquire_from_pool() &&
|
|
OB_FAIL(sequence_currval_map_.create(hash::cal_next_prime(32),
|
|
ObMemAttr(orig_tenant_id_, "SequenceMap")))) {
|
|
LOG_WARN("create sequence current value map failed", K(ret));
|
|
} else if (!is_acquire_from_pool() &&
|
|
OB_FAIL(dblink_sequence_id_map_.create(hash::cal_next_prime(32),
|
|
ObMemAttr(orig_tenant_id_, "SequenceIdMap")))) {
|
|
LOG_WARN("create dblink sequence id map failed", K(ret));
|
|
} else if (!is_acquire_from_pool() &&
|
|
OB_FAIL(contexts_map_.create(hash::cal_next_prime(32),
|
|
ObMemAttr(orig_tenant_id_, "ContextsMap")))) {
|
|
LOG_WARN("create contexts map failed", K(ret));
|
|
} else {
|
|
curr_session_context_size_ = 0;
|
|
if (is_obproxy_mode()) {
|
|
sess_create_time_ = sess_create_time;
|
|
} else {
|
|
sess_create_time_ = ObTimeUtility::current_time();
|
|
}
|
|
set_client_create_time(client_create_time);
|
|
const char *sup_proxy_min_version = "1.8.4";
|
|
min_proxy_version_ps_ = 0;
|
|
if (OB_FAIL(ObClusterVersion::get_version(sup_proxy_min_version, min_proxy_version_ps_))) {
|
|
LOG_WARN("failed to get version", K(ret));
|
|
} else {
|
|
is_inited_ = true;
|
|
refresh_temp_tables_sess_active_time();
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//for test
|
|
int ObSQLSessionInfo::test_init(uint32_t version, uint32_t sessid, uint64_t proxy_sessid,
|
|
common::ObIAllocator *bucket_allocator)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(version);
|
|
if (OB_FAIL(ObBasicSessionInfo::test_init(sessid, proxy_sessid, bucket_allocator))) {
|
|
LOG_WARN("fail to init basic session info", K(ret));
|
|
} else if (FALSE_IT(txn_free_route_ctx_.set_sessid(sessid))) {
|
|
} else {
|
|
is_inited_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObSQLSessionInfo::reset(bool skip_sys_var)
|
|
{
|
|
if (is_inited_) {
|
|
// ObVersionProvider::reset();
|
|
reset_all_package_changed_info();
|
|
warnings_buf_.reset();
|
|
show_warnings_buf_.reset();
|
|
end_trans_cb_.reset(),
|
|
audit_record_.reset();
|
|
user_priv_set_ = 0;
|
|
db_priv_set_ = 0;
|
|
curr_trans_start_time_ = 0;
|
|
curr_trans_last_stmt_time_ = 0;
|
|
sess_create_time_ = 0;
|
|
last_refresh_temp_table_time_ = 0;
|
|
has_temp_table_flag_ = false;
|
|
has_accessed_session_level_temp_table_ = false;
|
|
is_for_trigger_package_ = false;
|
|
trans_type_ = transaction::ObTxClass::USER;
|
|
version_provider_ = NULL;
|
|
config_provider_ = NULL;
|
|
request_manager_ = NULL;
|
|
flt_span_mgr_ = NULL;
|
|
MEMSET(tenant_buff_, 0, sizeof(share::ObTenantSpaceFetcher));
|
|
ps_cache_ = NULL;
|
|
found_rows_ = 1;
|
|
affected_rows_ = -1;
|
|
global_sessid_ = 0;
|
|
read_uncommited_ = false;
|
|
trace_recorder_ = NULL;
|
|
inner_flag_ = false;
|
|
is_max_availability_mode_ = false;
|
|
enable_early_lock_release_ = false;
|
|
ps_session_info_map_.reuse();
|
|
ps_name_id_map_.reuse();
|
|
next_client_ps_stmt_id_ = 0;
|
|
is_remote_session_ = false;
|
|
session_type_ = INVALID_TYPE;
|
|
package_state_map_.reuse();
|
|
sequence_currval_map_.reuse();
|
|
dblink_sequence_id_map_.reuse();
|
|
curr_session_context_size_ = 0;
|
|
pl_context_ = NULL;
|
|
pl_can_retry_ = true;
|
|
#ifdef OB_BUILD_ORACLE_PL
|
|
pl_debugger_ = NULL;
|
|
#endif
|
|
pl_attach_session_id_ = 0;
|
|
pl_query_sender_ = NULL;
|
|
pl_ps_protocol_ = false;
|
|
if (pl_cursor_cache_.is_inited()) {
|
|
// when select GV$OPEN_CURSOR, we will add get_thread_data_lock to fetch pl_cursor_map_
|
|
// so we need get_thread_data_lock there
|
|
ObSQLSessionInfo::LockGuard lock_guard(get_thread_data_lock());
|
|
pl_cursor_cache_.reset();
|
|
}
|
|
inner_conn_ = NULL;
|
|
session_stat_.reset();
|
|
pl_sync_pkg_vars_ = NULL;
|
|
//encrypt_info_.reset();
|
|
cached_schema_guard_info_.reset();
|
|
encrypt_info_.reset();
|
|
enable_role_array_.reset();
|
|
in_definer_named_proc_ = false;
|
|
priv_user_id_ = OB_INVALID_ID;
|
|
xa_end_timeout_seconds_ = transaction::ObXADefault::OB_XA_TIMEOUT_SECONDS;
|
|
xa_last_result_ = OB_SUCCESS;
|
|
prelock_ = false;
|
|
proxy_version_ = 0;
|
|
min_proxy_version_ps_ = 0;
|
|
if (OB_NOT_NULL(mem_context_)) {
|
|
destroy_contexts_map(contexts_map_, mem_context_->get_malloc_allocator());
|
|
DESTROY_CONTEXT(mem_context_);
|
|
mem_context_ = NULL;
|
|
}
|
|
contexts_map_.reuse();
|
|
cur_exec_ctx_ = nullptr;
|
|
plan_cache_ = NULL;
|
|
client_app_info_.reset();
|
|
has_query_executed_ = false;
|
|
flt_control_info_.reset();
|
|
is_send_control_info_ = false;
|
|
trace_enable_ = false;
|
|
auto_flush_trace_ = false;
|
|
coninfo_set_by_sess_ = false;
|
|
is_ob20_protocol_ = false;
|
|
is_session_var_sync_ = false;
|
|
is_latest_sess_info_ = false;
|
|
int temp_ret = OB_SUCCESS;
|
|
sql_req_level_ = 0;
|
|
optimizer_tracer_.reset();
|
|
expect_group_id_ = OB_INVALID_ID;
|
|
flt_control_info_.reset();
|
|
group_id_not_expected_ = false;
|
|
//call at last time
|
|
dblink_context_.reset(); // need reset before ObBasicSessionInfo::reset(skip_sys_var);
|
|
ObBasicSessionInfo::reset(skip_sys_var);
|
|
txn_free_route_ctx_.reset();
|
|
client_non_standard_ = false;
|
|
}
|
|
gtt_session_scope_unique_id_ = 0;
|
|
gtt_trans_scope_unique_id_ = 0;
|
|
gtt_session_scope_ids_.reset();
|
|
gtt_trans_scope_ids_.reset();
|
|
vid_ = OB_INVALID_ID;
|
|
vport_ = 0;
|
|
in_bytes_ = 0;
|
|
out_bytes_ = 0;
|
|
MEMSET(vip_buf_, 0, sizeof(vip_buf_));
|
|
current_dblink_sequence_id_ = 0;
|
|
dblink_sequence_schemas_.reset();
|
|
is_session_sync_support_ = false;
|
|
}
|
|
|
|
void ObSQLSessionInfo::clean_status()
|
|
{
|
|
reset_all_package_changed_info();
|
|
ObBasicSessionInfo::clean_status();
|
|
}
|
|
|
|
bool ObSQLSessionInfo::is_encrypt_tenant()
|
|
{
|
|
bool ret = false;
|
|
#ifdef OB_BUILD_TDE_SECURITY
|
|
uint64_t cur_time = ObClockGenerator::getClock();
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
if (cur_time - encrypt_info_.last_modify_time_ > 10 * 1000 * 1000L) {
|
|
if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) {
|
|
LOG_WARN("Invalid tenant id to init fast freeze checker", K(tenant_id));
|
|
} else {
|
|
encrypt_info_.last_modify_time_ = cur_time;
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
ObString method_str(tenant_config->tde_method.get_value());
|
|
if (ObTdeMethodUtil::is_kms(method_str)) {
|
|
encrypt_info_.is_encrypt_ = true;
|
|
ret = true;
|
|
} else {
|
|
encrypt_info_.is_encrypt_ = false;
|
|
ret = false;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
ret = encrypt_info_.is_encrypt_;
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::is_force_temp_table_inline(bool &force_inline) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t with_subquery_policy = 0;
|
|
force_inline = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
int64_t with_subquery_policy = tenant_config->_with_subquery;
|
|
if (2 == with_subquery_policy) {
|
|
force_inline = true;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::is_force_temp_table_materialize(bool &force_materialize) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t with_subquery_policy = 0;
|
|
force_materialize = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
int64_t with_subquery_policy = tenant_config->_with_subquery;
|
|
if (1 == with_subquery_policy) {
|
|
force_materialize = true;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::is_temp_table_transformation_enabled(bool &transformation_enabled) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
transformation_enabled = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
transformation_enabled = tenant_config->_xsolapi_generate_with_clause;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::is_groupby_placement_transformation_enabled(bool &transformation_enabled) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
transformation_enabled = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
transformation_enabled = tenant_config->_optimizer_group_by_placement;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::is_in_range_optimization_enabled() const
|
|
{
|
|
bool bret = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
bret = tenant_config->_enable_in_range_optimization;
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::is_better_inlist_enabled(bool &enabled) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
enabled = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
enabled = tenant_config->_optimizer_better_inlist_costing;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::is_index_skip_scan_enabled() const
|
|
{
|
|
bool bret = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
bret = tenant_config->_optimizer_skip_scan_enabled;
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::is_qualify_filter_enabled() const
|
|
{
|
|
bool bret = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
bret = tenant_config->_enable_optimizer_qualify_filter;
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::is_enable_range_extraction_for_not_in(bool &enabled) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
enabled = true;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
enabled = tenant_config->_enable_range_extraction_for_not_in;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::is_var_assign_use_das_enabled() const
|
|
{
|
|
bool bret = false;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
bret = tenant_config->_enable_var_assign_use_das;
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::is_adj_index_cost_enabled(bool &enabled, int64_t &stats_cost_percent) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
enabled = false;
|
|
stats_cost_percent = 0;
|
|
int64_t tenant_id = get_effective_tenant_id();
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
|
|
if (tenant_config.is_valid()) {
|
|
stats_cost_percent = tenant_config->optimizer_index_cost_adj;
|
|
enabled = (0 != stats_cost_percent);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObSQLSessionInfo::destroy(bool skip_sys_var)
|
|
{
|
|
if (is_inited_) {
|
|
int ret = OB_SUCCESS;
|
|
if (rpc::is_io_thread()) {
|
|
LOG_WARN("free session at IO thread", "sessid", get_sessid(), "proxy_sessid", get_proxy_sessid());
|
|
//事务层需要保持在end trans时,既没有阻塞操作,又没有rpc调用。否则会影响server IO性能或产生死锁
|
|
}
|
|
|
|
// 反序列化出来的 session 不应该做 end_trans 等清理工作
|
|
// bug:
|
|
if (false == get_is_deserialized()) {
|
|
if (false == ObSchemaService::g_liboblog_mode_) {
|
|
//session断开时调用ObTransService::end_trans回滚事务,
|
|
// 此处stmt_timeout = 当前时间 +语句query超时时间,而不是最后一条sql的start_time, 相关bug_id : 7961445
|
|
set_query_start_time(ObTimeUtility::current_time());
|
|
// 这里调用end_trans无需上锁,因为调用reclaim_value时意味着已经没有query并发使用session
|
|
// 调用这个函数之前会调session.set_session_state(SESSION_KILLED),
|
|
bool need_disconnect = false;
|
|
if (is_in_transaction() && !is_txn_free_route_temp()) {
|
|
transaction::ObTransID tx_id = get_tx_id();
|
|
MAKE_TENANT_SWITCH_SCOPE_GUARD(guard);
|
|
// inner session skip check switch tenant, because the inner connection was shared between tenant
|
|
if (OB_SUCC(guard.switch_to(get_effective_tenant_id(), !is_inner()))) {
|
|
if (OB_FAIL(ObSqlTransControl::rollback_trans(this, need_disconnect))) {
|
|
LOG_WARN("fail to rollback transaction", K(get_sessid()),
|
|
"proxy_sessid", get_proxy_sessid(), K(ret));
|
|
} else if (false == inner_flag_ && false == is_remote_session_) {
|
|
LOG_INFO("end trans successfully",
|
|
"sessid", get_sessid(),
|
|
"proxy_sessid", get_proxy_sessid(),
|
|
"trans id", tx_id);
|
|
}
|
|
} else {
|
|
LOG_WARN("fail to switch tenant", K(get_effective_tenant_id()), K(ret));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 临时表在 slave session 析构时不能清理
|
|
if (false == get_is_deserialized()) {
|
|
int temp_ret = drop_temp_tables();
|
|
if (OB_UNLIKELY(OB_SUCCESS != temp_ret)) {
|
|
LOG_WARN("fail to drop temp tables", K(temp_ret));
|
|
}
|
|
refresh_temp_tables_sess_active_time();
|
|
}
|
|
|
|
// slave session 上 ps_session_info_map_ 为空,调用 close 也不会有副作用
|
|
if (OB_SUCC(ret)) {
|
|
if (OB_FAIL(close_all_ps_stmt())) {
|
|
LOG_WARN("failed to close all stmt", K(ret));
|
|
}
|
|
}
|
|
|
|
//close all cursor
|
|
if (OB_SUCC(ret) && pl_cursor_cache_.is_inited()) {
|
|
if (OB_FAIL(pl_cursor_cache_.close_all(*this))) {
|
|
LOG_WARN("failed to close all cursor", K(ret));
|
|
}
|
|
}
|
|
|
|
if (OB_SUCC(ret) && NULL != piece_cache_) {
|
|
if (OB_FAIL((static_cast<observer::ObPieceCache*>(piece_cache_))
|
|
->close_all(*this))) {
|
|
LOG_WARN("failed to close all piece", K(ret));
|
|
}
|
|
static_cast<observer::ObPieceCache*>(piece_cache_)->~ObPieceCache();
|
|
get_session_allocator().free(piece_cache_);
|
|
piece_cache_ = NULL;
|
|
}
|
|
|
|
#ifdef OB_BUILD_ORACLE_PL
|
|
if (OB_SUCC(ret)) {
|
|
const int64_t session_id = get_sessid();
|
|
// utl file should close all fd when user session exits,
|
|
// so we should check session type here to avoid fd closing
|
|
// unexpectedly when inner session exists
|
|
if (is_user_session() && OB_FAIL(ObPLUtlFile::close_all(session_id))) {
|
|
LOG_WARN("failed to close all fd in utl file", K(ret), K(session_id));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef OB_BUILD_ORACLE_PL
|
|
// pl debug 功能, pl debug不支持分布式调试,但调用也不会有副作用
|
|
reset_pl_debugger_resource();
|
|
#endif
|
|
// 非分布式需要的话,分布式也需要,用于清理package的全局变量值
|
|
reset_all_package_state();
|
|
reset(skip_sys_var);
|
|
is_inited_ = false;
|
|
sql_req_level_ = 0;
|
|
}
|
|
}
|
|
|
|
int ObSQLSessionInfo::close_ps_stmt(ObPsStmtId client_stmt_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPsSessionInfo *ps_sess_info = NULL;
|
|
if (OB_FAIL(get_ps_session_info(client_stmt_id, ps_sess_info))) {
|
|
LOG_WARN("fail to get ps session info", K(client_stmt_id), "session_id", get_sessid(), K(ret));
|
|
} else if (OB_ISNULL(ps_sess_info)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("ps session info is null", K(client_stmt_id), "session_id", get_sessid(), K(ret));
|
|
} else {
|
|
ObPsStmtId inner_stmt_id = ps_sess_info->get_inner_stmt_id();
|
|
ps_sess_info->dec_ref_count();
|
|
if (ps_sess_info->need_erase()) {
|
|
if (OB_ISNULL(ps_cache_)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("ps cache is null", K(ret));
|
|
} else if (OB_FAIL(ps_cache_->deref_ps_stmt(inner_stmt_id))) {
|
|
LOG_WARN("close ps stmt failed", K(ret), "session_id", get_sessid(), K(ret));
|
|
}
|
|
//无论上面是否成功, 都需要将session info资源释放
|
|
int tmp_ret = OB_SUCCESS;
|
|
if (OB_SUCCESS != (tmp_ret = remove_ps_session_info(client_stmt_id))) {
|
|
ret = tmp_ret;
|
|
LOG_WARN("remove ps session info failed", K(client_stmt_id),
|
|
"session_id", get_sessid(), K(ret));
|
|
}
|
|
LOG_TRACE("close ps stmt", K(ret), K(client_stmt_id), K(inner_stmt_id), K(lbt()));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::close_all_ps_stmt()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_ISNULL(ps_cache_)) {
|
|
// do nothing, session no ps
|
|
} else if (!ps_session_info_map_.created()) {
|
|
// do nothing, no ps added to map
|
|
} else {
|
|
PsSessionInfoMap::iterator iter = ps_session_info_map_.begin();
|
|
ObPsStmtId inner_stmt_id = OB_INVALID_ID;
|
|
for (; iter != ps_session_info_map_.end(); ++iter) { //ignore ret
|
|
const ObPsStmtId client_stmt_id = iter->first;
|
|
if (OB_FAIL(get_inner_ps_stmt_id(client_stmt_id, inner_stmt_id))) {
|
|
LOG_WARN("get_inner_ps_stmt_id failed", K(ret), K(client_stmt_id), K(inner_stmt_id));
|
|
} else if (OB_FAIL(ps_cache_->deref_ps_stmt(inner_stmt_id))) {
|
|
LOG_WARN("close ps stmt failed", K(ret), K(client_stmt_id), K(inner_stmt_id));
|
|
} else if (OB_ISNULL(iter->second)) {
|
|
// do nothing
|
|
} else {
|
|
iter->second->~ObPsSessionInfo();
|
|
ps_session_info_allocator_.free(iter->second);
|
|
iter->second = NULL;
|
|
}
|
|
}
|
|
ps_session_info_allocator_.reset();
|
|
ps_session_info_map_.reuse();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//用于oracle临时表数据的清理, 在session断开(会话级&事务级)和commit时(事务级)调用
|
|
int ObSQLSessionInfo::delete_from_oracle_temp_tables(const obrpc::ObDropTableArg &const_drop_table_arg)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
common::ObSqlString sql;
|
|
common::ObMySQLProxy *sql_proxy = GCTX.sql_proxy_;
|
|
common::ObCommonSqlProxy *user_sql_proxy;
|
|
common::ObOracleSqlProxy oracle_sql_proxy;
|
|
ObSchemaGetterGuard schema_guard;
|
|
const ObDatabaseSchema *database_schema = NULL;
|
|
//ObSEArray<const ObSimpleTableSchemaV2 *, 512> table_schemas;
|
|
obrpc::ObDropTableArg &drop_table_arg = const_cast<obrpc::ObDropTableArg &>(const_drop_table_arg);
|
|
const share::schema::ObTableType table_type = drop_table_arg.table_type_;
|
|
const uint64_t tenant_id = drop_table_arg.tenant_id_;
|
|
const ObTableSchema *table_schema = NULL;
|
|
user_sql_proxy = &oracle_sql_proxy;
|
|
|
|
if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(
|
|
tenant_id,
|
|
schema_guard))) {
|
|
LOG_WARN("get schema guard failed.", K(ret), K(tenant_id));
|
|
} else if (OB_ISNULL(sql_proxy)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("sql proxy is null", K(ret));
|
|
} else if (OB_FAIL(oracle_sql_proxy.init(sql_proxy->get_pool()))) {
|
|
LOG_WARN("init oracle sql proxy failed", K(ret));
|
|
} else if (TMP_TABLE_ORA_SESS == table_type || TMP_TABLE_ORA_TRX == table_type) {
|
|
ObIArray<uint64_t> &table_ids = table_type == share::schema::TMP_TABLE_ORA_TRX ?
|
|
get_gtt_trans_scope_ids() : get_gtt_session_scope_ids();
|
|
uint64_t unique_id = table_type == share::schema::TMP_TABLE_ORA_TRX ?
|
|
get_gtt_trans_scope_unique_id() : get_gtt_session_scope_unique_id();
|
|
LOG_DEBUG("delete temp table", K(table_ids), K(unique_id));
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count(); i++) {
|
|
if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_ids.at(i), table_schema))) {
|
|
LOG_WARN("fail to get table schema", K(ret));
|
|
} else if (OB_ISNULL(table_schema)) {
|
|
//table may be dropped, ignore
|
|
} else if (tenant_id != table_schema->get_tenant_id()) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("tenant_id not match", K(ret), K(tenant_id), "table_id", table_schema->get_table_id());
|
|
} else if (((TMP_TABLE_ORA_SESS == table_type && table_schema->is_oracle_tmp_table())
|
|
|| (TMP_TABLE_ORA_TRX == table_type && table_schema->is_oracle_trx_tmp_table()))
|
|
&& table_schema->is_normal_schema()) {
|
|
database_schema = NULL;
|
|
if (OB_FAIL(schema_guard.get_database_schema(table_schema->get_tenant_id(),
|
|
table_schema->get_database_id(), database_schema))) {
|
|
LOG_WARN("failed to get database schema", K(ret));
|
|
} else if (OB_ISNULL(database_schema)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("database schema is null", K(ret));
|
|
} else if (database_schema->is_in_recyclebin() || table_schema->is_in_recyclebin()) {
|
|
LOG_DEBUG("skip table schema in recyclebin", K(*table_schema));
|
|
} else {
|
|
const int64_t limit = 1000;
|
|
ret = sql.assign_fmt("DELETE FROM \"%.*s\".\"%.*s\" WHERE %s = %ld AND ROWNUM <= %ld",
|
|
database_schema->get_database_name_str().length(),
|
|
database_schema->get_database_name_str().ptr(),
|
|
table_schema->get_table_name_str().length(),
|
|
table_schema->get_table_name_str().ptr(),
|
|
OB_HIDDEN_SESSION_ID_COLUMN_NAME, unique_id,
|
|
limit);
|
|
|
|
if (OB_SUCC(ret)) {
|
|
int64_t affect_rows = 0;
|
|
int64_t last_batch_affect_rows = limit;
|
|
int64_t cur_time = ObTimeUtility::current_time();
|
|
int64_t cur_timeout_backup = THIS_WORKER.get_timeout_ts();
|
|
THIS_WORKER.set_timeout_ts(ObTimeUtility::current_time() + OB_MAX_USER_SPECIFIED_TIMEOUT);
|
|
while (OB_SUCC(ret) && last_batch_affect_rows > 0) {
|
|
if (OB_FAIL(user_sql_proxy->write(tenant_id, sql.ptr(), last_batch_affect_rows))) {
|
|
LOG_WARN("execute sql failed", K(ret), K(sql));
|
|
} else {
|
|
affect_rows += last_batch_affect_rows;
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
LOG_DEBUG("succeed to delete rows in oracle temporary table", K(sql), K(affect_rows));
|
|
//delete relation temp table stats.
|
|
if (OB_FAIL(ObOptStatManager::get_instance().delete_table_stat(tenant_id,
|
|
table_schema->get_table_id(), affect_rows))) {
|
|
LOG_WARN("failed to delete table stats", K(ret));
|
|
}
|
|
} else {
|
|
LOG_WARN("failed to delete rows in oracle temporary table", K(ret), K(sql));
|
|
}
|
|
LOG_INFO("delete rows in oracle temporary table", K(sql), K(affect_rows),
|
|
"clean_time", ObTimeUtility::current_time() - cur_time);
|
|
THIS_WORKER.set_timeout_ts(cur_timeout_backup);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (TMP_TABLE_ORA_TRX == table_type && !get_is_deserialized()) {
|
|
gtt_trans_scope_ids_.reuse();
|
|
gen_gtt_trans_scope_unique_id();
|
|
if (gtt_session_scope_ids_.count() == 0) {
|
|
if (OB_FAIL(set_session_temp_table_used(false))) {
|
|
LOG_WARN("fail to set session temp table unused", K(ret));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
//mysql租户: 如果session创建过临时表, 直连模式: session断开时drop temp table;
|
|
//oracle租户, commit时为了清空数据也会调用此接口, 但仅清除事务级别的临时表;
|
|
// session断开时则清理掉事务级和会话级的临时表;
|
|
//由于oracle临时表仅仅是清理本session数据, 为避免rs拥塞,不发往rs由sql proxy执行
|
|
//对于分布式计划, 除非ac=1否则交给master session清理, 反序列化得到的session不做事情
|
|
int ObSQLSessionInfo::drop_temp_tables(const bool is_disconn, const bool is_xa_trans)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
bool ac = false;
|
|
bool is_sess_disconn = is_disconn;
|
|
obrpc::ObCommonRpcProxy *common_rpc_proxy = NULL;
|
|
if (OB_FAIL(get_autocommit(ac))) {
|
|
LOG_WARN("get autocommit error", K(ret), K(ac));
|
|
} else if (!(is_inner() && !is_user_session())
|
|
&& (get_has_temp_table_flag()
|
|
|| has_accessed_session_level_temp_table()
|
|
|| has_tx_level_temp_table()
|
|
|| is_xa_trans)
|
|
&& (!get_is_deserialized() || ac)) {
|
|
bool need_drop_temp_table = false;
|
|
//mysql: 仅直连 & sess 断开时
|
|
//oracle: commit; 或者 直连时的断session;
|
|
if (!is_oracle_mode()) {
|
|
if (false == is_obproxy_mode() && is_sess_disconn) {
|
|
need_drop_temp_table = true;
|
|
}
|
|
} else {
|
|
if (false == is_sess_disconn || false == is_obproxy_mode()) {
|
|
need_drop_temp_table = true;
|
|
//ac=1, 反序列化session断开时只是任务结束, 并不是真的sess断开, 视作trx commit
|
|
if (is_sess_disconn && get_is_deserialized() && ac) {
|
|
is_sess_disconn = false;
|
|
}
|
|
}
|
|
}
|
|
if (need_drop_temp_table) {
|
|
LOG_DEBUG("need_drop_temp_table",
|
|
K(is_oracle_mode()),
|
|
K(get_current_query_string()),
|
|
K(get_login_tenant_id()),
|
|
K(get_effective_tenant_id()),
|
|
K(lbt()));
|
|
obrpc::ObDDLRes res;
|
|
obrpc::ObDropTableArg drop_table_arg;
|
|
drop_table_arg.if_exist_ = true;
|
|
drop_table_arg.to_recyclebin_ = false;
|
|
if (false == is_sess_disconn) {
|
|
drop_table_arg.table_type_ = share::schema::TMP_TABLE_ORA_TRX;
|
|
} else if (is_oracle_mode()) {
|
|
drop_table_arg.table_type_ = share::schema::TMP_TABLE_ORA_SESS;
|
|
} else {
|
|
drop_table_arg.table_type_ = share::schema::TMP_TABLE;
|
|
}
|
|
drop_table_arg.session_id_ = get_sessid_for_table();
|
|
drop_table_arg.tenant_id_ = get_effective_tenant_id();
|
|
drop_table_arg.exec_tenant_id_ = get_effective_tenant_id();
|
|
common_rpc_proxy = GCTX.rs_rpc_proxy_;
|
|
if (OB_ISNULL(common_rpc_proxy)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("rpc proxy is null", K(ret));
|
|
} else if (OB_FAIL(delete_from_oracle_temp_tables(drop_table_arg))) {
|
|
LOG_WARN("failed to delete from oracle temporary table", K(drop_table_arg), K(ret));
|
|
}/* else if (!is_oracle_mode() && OB_FALSE_IT(drop_table_arg.compat_mode_ = lib::Worker::CompatMode::MYSQL)) {
|
|
} else if (!is_oracle_mode() && OB_FAIL(common_rpc_proxy->drop_table(drop_table_arg, res))) {
|
|
LOG_WARN("failed to drop temporary table", K(drop_table_arg), K(ret));
|
|
}*/ else {
|
|
LOG_INFO("temporary tables dropped due to connection disconnected", K(is_sess_disconn), K(drop_table_arg));
|
|
}
|
|
}
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
LOG_WARN("fail to drop temp tables", K(ret),
|
|
K(get_effective_tenant_id()), K(get_sessid()),
|
|
K(has_accessed_session_level_temp_table()),
|
|
K(is_xa_trans),
|
|
K(lbt()));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//清理oracle临时表中数据来源和当前session id相同, 但属于被重用的旧的session数据
|
|
int ObSQLSessionInfo::drop_reused_oracle_temp_tables()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
//obrpc::ObCommonRpcProxy *common_rpc_proxy = NULL;
|
|
if (false == get_is_deserialized()
|
|
&& !is_inner()
|
|
&& !GCTX.is_standby_cluster()) {
|
|
obrpc::ObDropTableArg drop_table_arg;
|
|
drop_table_arg.if_exist_ = true;
|
|
drop_table_arg.to_recyclebin_ = false;
|
|
drop_table_arg.table_type_ = share::schema::TMP_TABLE_ORA_SESS;
|
|
drop_table_arg.session_id_ = get_sessid_for_table();
|
|
drop_table_arg.tenant_id_ = get_effective_tenant_id();
|
|
drop_table_arg.sess_create_time_ = get_sess_create_time();
|
|
//common_rpc_proxy = GCTX.rs_rpc_proxy_;
|
|
if (OB_FAIL(delete_from_oracle_temp_tables(drop_table_arg))) {
|
|
//if (OB_FAIL(common_rpc_proxy->drop_table(drop_table_arg))) {
|
|
LOG_WARN("failed to drop reused temporary table", K(drop_table_arg), K(ret));
|
|
} else {
|
|
LOG_DEBUG("succeed to delete old rows for oracle temporary table", K(drop_table_arg));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//proxy方式下session创建、断开和后台定时task检查:
|
|
//如果距离上次更新此session->last_refresh_temp_table_time_ 超过1hr
|
|
//则更新session创建的临时表最后活动时间SESSION_ACTIVE_TIME
|
|
//oracle临时表依赖附加的__sess_create_time判断重用并清理, 不需要更新
|
|
void ObSQLSessionInfo::refresh_temp_tables_sess_active_time()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const int64_t REFRESH_INTERVAL = 60L * 60L * 1000L * 1000L; // 1hr
|
|
obrpc::ObCommonRpcProxy *common_rpc_proxy = NULL;
|
|
if (get_has_temp_table_flag() && is_obproxy_mode()
|
|
&& !is_oracle_mode()) {
|
|
int64_t now = ObTimeUtility::current_time();
|
|
obrpc::ObAlterTableRes res;
|
|
if (now - get_last_refresh_temp_table_time() >= REFRESH_INTERVAL) {
|
|
SMART_VAR(obrpc::ObAlterTableArg, alter_table_arg) {
|
|
AlterTableSchema *alter_table_schema = &alter_table_arg.alter_table_schema_;
|
|
alter_table_arg.session_id_ = get_sessid_for_table();
|
|
alter_table_schema->alter_type_ = OB_DDL_ALTER_TABLE;
|
|
common_rpc_proxy = GCTX.rs_rpc_proxy_;
|
|
alter_table_arg.nls_formats_[ObNLSFormatEnum::NLS_DATE] = ObTimeConverter::COMPAT_OLD_NLS_DATE_FORMAT;
|
|
alter_table_arg.nls_formats_[ObNLSFormatEnum::NLS_TIMESTAMP] = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_FORMAT;
|
|
alter_table_arg.nls_formats_[ObNLSFormatEnum::NLS_TIMESTAMP_TZ] = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_TZ_FORMAT;
|
|
alter_table_arg.compat_mode_ = lib::Worker::CompatMode::MYSQL;
|
|
if (OB_FAIL(alter_table_schema->alter_option_bitset_.add_member(obrpc::ObAlterTableArg::SESSION_ACTIVE_TIME))) {
|
|
LOG_WARN("failed to add member SESSION_ACTIVE_TIME for alter table schema", K(ret));
|
|
} else if (OB_FAIL(alter_table_arg.tz_info_wrap_.deep_copy(get_tz_info_wrap()))) {
|
|
LOG_WARN("failed to deep copy tz_info_wrap", K(ret));
|
|
} else if (OB_FAIL(common_rpc_proxy->alter_table(alter_table_arg, res))) {
|
|
LOG_WARN("failed to alter temporary table session active time", K(alter_table_arg), K(ret), K(is_obproxy_mode()));
|
|
} else {
|
|
LOG_DEBUG("session active time of temporary tables refreshed", K(ret), "last refresh time", get_last_refresh_temp_table_time());
|
|
set_last_refresh_temp_table_time(now);
|
|
}
|
|
}
|
|
} else {
|
|
LOG_DEBUG("no need to refresh session active time of temporary tables", "last refresh time", get_last_refresh_temp_table_time());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ObMySQLRequestManager* ObSQLSessionInfo::get_request_manager()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (NULL == request_manager_) {
|
|
MTL_SWITCH(get_effective_tenant_id()) {
|
|
request_manager_ = MTL(obmysql::ObMySQLRequestManager*);
|
|
}
|
|
}
|
|
|
|
return request_manager_;
|
|
}
|
|
|
|
ObFLTSpanMgr* ObSQLSessionInfo::get_flt_span_manager()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (NULL == flt_span_mgr_) {
|
|
MTL_SWITCH(get_priv_tenant_id()) {
|
|
flt_span_mgr_ = MTL(sql::ObFLTSpanMgr*);
|
|
}
|
|
}
|
|
return flt_span_mgr_;
|
|
}
|
|
|
|
void ObSQLSessionInfo::set_show_warnings_buf(int error_code)
|
|
{
|
|
// if error message didn't insert into THREAD warning buffer,
|
|
// insert it into SESSION warning buffer
|
|
// if no error at all,
|
|
// clear err.
|
|
if (OB_SUCCESS != error_code && strlen(warnings_buf_.get_err_msg()) <= 0) {
|
|
warnings_buf_.set_error(ob_errpkt_strerror(error_code, lib::is_oracle_mode()), error_code);
|
|
warnings_buf_.reset_warning();
|
|
} else if (OB_SUCCESS == error_code) {
|
|
warnings_buf_.reset_err();
|
|
}
|
|
show_warnings_buf_ = warnings_buf_; // show_warnings_buf_用于show warnings
|
|
}
|
|
|
|
void ObSQLSessionInfo::update_show_warnings_buf()
|
|
{
|
|
for (int64_t i = 0; i < warnings_buf_.get_readable_warning_count(); i++) {
|
|
const ObWarningBuffer::WarningItem *item = warnings_buf_.get_warning_item(i);
|
|
if (OB_ISNULL(item)) {
|
|
} else if (item->log_level_ == common::ObLogger::UserMsgLevel::USER_WARN) {
|
|
show_warnings_buf_.append_warning(item->msg_, item->code_);
|
|
} else if (item->log_level_ == common::ObLogger::UserMsgLevel::USER_NOTE) {
|
|
show_warnings_buf_.append_note(item->msg_, item->code_);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObSQLSessionInfo::get_session_priv_info(share::schema::ObSessionPrivInfo &session_priv) const
|
|
{
|
|
session_priv.tenant_id_ = get_priv_tenant_id();
|
|
session_priv.user_id_ = get_user_id();
|
|
session_priv.user_name_ = get_user_name();
|
|
session_priv.host_name_ = get_host_name();
|
|
session_priv.db_ = get_database_name();
|
|
session_priv.user_priv_set_ = user_priv_set_;
|
|
session_priv.db_priv_set_ = db_priv_set_;
|
|
session_priv.enable_role_id_array_.assign(enable_role_array_);
|
|
}
|
|
|
|
ObPlanCache *ObSQLSessionInfo::get_plan_cache()
|
|
{
|
|
if (OB_NOT_NULL(plan_cache_)) {
|
|
// do nothing
|
|
} else {
|
|
//release old plancache and get new
|
|
ObPCMemPctConf pc_mem_conf;
|
|
if (OB_SUCCESS != get_pc_mem_conf(pc_mem_conf)) {
|
|
LOG_ERROR_RET(OB_ERR_UNEXPECTED, "fail to get pc mem conf");
|
|
plan_cache_ = NULL;
|
|
} else {
|
|
plan_cache_ = MTL(ObPlanCache*);
|
|
if (OB_ISNULL(plan_cache_)) {
|
|
LOG_WARN_RET(OB_ERR_UNEXPECTED, "failed to get plan cache");
|
|
} else if (MTL_ID() != get_effective_tenant_id()) {
|
|
LOG_ERROR_RET(OB_ERR_UNEXPECTED, "unmatched tenant_id", K(MTL_ID()), K(get_effective_tenant_id()));
|
|
} else if (plan_cache_->is_inited()) {
|
|
// skip update mem conf
|
|
} else if (OB_SUCCESS != plan_cache_->set_mem_conf(pc_mem_conf)) {
|
|
LOG_ERROR_RET(OB_ERR_UNEXPECTED, "fail to set plan cache memory conf");
|
|
}
|
|
}
|
|
}
|
|
return plan_cache_;
|
|
}
|
|
|
|
ObPsCache *ObSQLSessionInfo::get_ps_cache()
|
|
{
|
|
if (OB_NOT_NULL(ps_cache_)) {
|
|
//do nothing
|
|
} else {
|
|
int ret = OB_SUCCESS;
|
|
const uint64_t tenant_id = get_effective_tenant_id();
|
|
ObPCMemPctConf pc_mem_conf;
|
|
ObMemAttr mem_attr;
|
|
mem_attr.label_ = "PsSessionInfo";
|
|
mem_attr.tenant_id_ = tenant_id;
|
|
mem_attr.ctx_id_ = ObCtxIds::DEFAULT_CTX_ID;
|
|
if (OB_FAIL(get_pc_mem_conf(pc_mem_conf))) {
|
|
LOG_ERROR("failed to get pc mem conf");
|
|
ps_cache_ = NULL;
|
|
} else {
|
|
ps_cache_ = MTL(ObPsCache*);
|
|
if (OB_ISNULL(ps_cache_)) {
|
|
LOG_WARN("failed to get ps cache");
|
|
} else if (MTL_ID() != get_effective_tenant_id()) {
|
|
LOG_ERROR("unmatched tenant_id", K(MTL_ID()), K(get_effective_tenant_id()));
|
|
} else if (!ps_cache_->is_inited() &&
|
|
OB_FAIL(ps_cache_->init(common::OB_PLAN_CACHE_BUCKET_NUMBER, tenant_id))) {
|
|
LOG_WARN("failed to init ps cache");
|
|
} else {
|
|
ps_session_info_allocator_.set_attr(mem_attr);
|
|
}
|
|
}
|
|
}
|
|
return ps_cache_;
|
|
}
|
|
|
|
|
|
//whether the user has the super privilege
|
|
bool ObSQLSessionInfo::has_user_super_privilege() const
|
|
{
|
|
int ret = false;
|
|
if (OB_PRIV_HAS_ANY(user_priv_set_, OB_PRIV_SUPER)) {
|
|
ret = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//whether the user has the process privilege
|
|
bool ObSQLSessionInfo::has_user_process_privilege() const
|
|
{
|
|
int ret = false;
|
|
if (OB_PRIV_HAS_ANY(user_priv_set_, OB_PRIV_PROCESS)) {
|
|
ret = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//check tenant read_only
|
|
int ObSQLSessionInfo::check_global_read_only_privilege(const bool read_only,
|
|
const ObSqlTraits &sql_traits)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (!has_user_super_privilege()
|
|
&& !is_tenant_changed()
|
|
&& read_only) {
|
|
/** session1 session2
|
|
* insert into xxx;
|
|
* set @@global.read_only = 1;
|
|
* update xxx (should fail)
|
|
* create (should fail)
|
|
* ... (all write stmt should fail)
|
|
*/
|
|
if (!sql_traits.is_readonly_stmt_) {
|
|
if (sql_traits.is_modify_tenant_stmt_) {
|
|
ret = OB_ERR_NO_PRIVILEGE;
|
|
LOG_USER_ERROR(OB_ERR_NO_PRIVILEGE, "SUPER");
|
|
LOG_WARN("Access denied; you need (at least one of)"
|
|
"the SUPER privilege(s) for this operation");
|
|
} else {
|
|
ret = OB_ERR_OPTION_PREVENTS_STATEMENT;
|
|
|
|
LOG_WARN("the server is running with read_only, cannot execute stmt");
|
|
}
|
|
} else {
|
|
/** session1 session2 session3
|
|
* begin begin;
|
|
* insert into xxx; (without write stmt)
|
|
* set @@global.read_only = 1;
|
|
* commit; (should fail) commit; (should success)
|
|
*/
|
|
if (sql_traits.is_commit_stmt_ && is_in_transaction() && !tx_desc_->is_clean()) {
|
|
ret = OB_ERR_OPTION_PREVENTS_STATEMENT;
|
|
LOG_WARN("the server is running with read_only, cannot execute stmt");
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::remove_prepare(const ObString &ps_name)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPsStmtId ps_id = OB_INVALID_ID;
|
|
if (OB_UNLIKELY(!ps_name_id_map_.created())) {
|
|
ret = OB_HASH_NOT_EXIST;
|
|
LOG_WARN("map not created before insert any element", K(ret));
|
|
} else if (OB_FAIL(ps_name_id_map_.erase_refactored(ps_name, &ps_id))) {
|
|
LOG_WARN("ps session info not exist", K(ps_name));
|
|
} else if (OB_INVALID_ID == ps_id) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("session_info is null", K(ret));
|
|
} else { /*do nothing*/ }
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_prepare_id(const ObString &ps_name, ObPsStmtId &ps_id) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ps_id = OB_INVALID_ID;
|
|
if (OB_UNLIKELY(!ps_name_id_map_.created())) {
|
|
ret = OB_HASH_NOT_EXIST;
|
|
} else if (OB_FAIL(ps_name_id_map_.get_refactored(ps_name, ps_id))) {
|
|
LOG_WARN("get ps session info failed", K(ps_name));
|
|
} else if (OB_INVALID_ID == ps_id) {
|
|
ret = OB_HASH_NOT_EXIST;
|
|
LOG_WARN("ps info is null", K(ret), K(ps_name));
|
|
} else { /*do nothing*/ }
|
|
|
|
if (ret == OB_HASH_NOT_EXIST) {
|
|
ret = OB_EER_UNKNOWN_STMT_HANDLER;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::add_prepare(const ObString &ps_name, ObPsStmtId ps_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObString stored_name;
|
|
ObPsStmtId exist_ps_id = OB_INVALID_ID;
|
|
if (OB_FAIL(name_pool_.write_string(ps_name, &stored_name))) {
|
|
LOG_WARN("failed to copy name", K(ps_name), K(ps_id), K(ret));
|
|
} else if (OB_FAIL(try_create_ps_name_id_map())) {
|
|
LOG_WARN("fail create ps name id map", K(ret));
|
|
} else if (OB_FAIL(ps_name_id_map_.get_refactored(stored_name, exist_ps_id))) {
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
if (OB_FAIL(ps_name_id_map_.set_refactored(stored_name, ps_id))) {
|
|
LOG_WARN("fail insert ps id to hash map", K(stored_name), K(ps_id), K(ret));
|
|
}
|
|
} else {
|
|
LOG_WARN("fail to search ps name hash id map", K(stored_name), K(ret));
|
|
}
|
|
} else if (ps_id != exist_ps_id) {
|
|
LOG_DEBUG("exist ps id is diff", K(ps_id), K(exist_ps_id), K(ps_name), K(stored_name));
|
|
if (OB_FAIL(remove_prepare(stored_name))) {
|
|
LOG_WARN("failed to remove prepare", K(stored_name), K(ret));
|
|
} else if (OB_FAIL(remove_ps_session_info(exist_ps_id))) {
|
|
LOG_WARN("failed to remove prepare sesion info", K(exist_ps_id), K(stored_name), K(ret));
|
|
} else if (OB_FAIL(ps_name_id_map_.set_refactored(stored_name, ps_id))) {
|
|
LOG_WARN("fail insert ps id to hash map", K(stored_name), K(ps_id), K(ret));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_ps_session_info(const ObPsStmtId stmt_id,
|
|
ObPsSessionInfo *&ps_session_info) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ps_session_info = NULL;
|
|
if (OB_UNLIKELY(!ps_session_info_map_.created())) {
|
|
ret = OB_HASH_NOT_EXIST;
|
|
LOG_WARN("map not created before insert any element", K(ret));
|
|
} else if (OB_FAIL(ps_session_info_map_.get_refactored(stmt_id, ps_session_info))) {
|
|
LOG_WARN("get ps session info failed", K(stmt_id), K(get_sessid()));
|
|
if (ret == OB_HASH_NOT_EXIST) {
|
|
ret = OB_EER_UNKNOWN_STMT_HANDLER;
|
|
}
|
|
} else if (OB_ISNULL(ps_session_info)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("ps session info is null", K(ret), K(stmt_id));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::remove_ps_session_info(const ObPsStmtId stmt_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPsSessionInfo *session_info = NULL;
|
|
LOG_TRACE("remove ps session info", K(ret), K(stmt_id), K(get_sessid()), K(lbt()));
|
|
if (OB_UNLIKELY(!ps_session_info_map_.created())) {
|
|
ret = OB_HASH_NOT_EXIST;
|
|
LOG_WARN("map not created before insert any element", K(ret));
|
|
} else if (OB_FAIL(ps_session_info_map_.erase_refactored(stmt_id, &session_info))) {
|
|
LOG_WARN("ps session info not exist", K(stmt_id));
|
|
} else if (OB_ISNULL(session_info)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("session_info is null", K(ret));
|
|
} else {
|
|
LOG_TRACE("remove ps session info", K(ret), K(stmt_id), K(get_sessid()));
|
|
session_info->~ObPsSessionInfo();
|
|
ps_session_info_allocator_.free(session_info);
|
|
session_info = NULL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::prepare_ps_stmt(const ObPsStmtId inner_stmt_id,
|
|
const ObPsStmtInfo *stmt_info,
|
|
ObPsStmtId &client_stmt_id,
|
|
bool &already_exists,
|
|
bool is_inner_sql)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPsSessionInfo *session_info = NULL;
|
|
// 相同sql返回不同stmt id:
|
|
// 1. 有proxy且版本大于等于1.8.4以上 or 直连情况
|
|
// 3. 非内部sql
|
|
const bool is_new_proxy = ((is_obproxy_mode() && proxy_version_ >= min_proxy_version_ps_)
|
|
|| !is_obproxy_mode());
|
|
if (is_new_proxy && !is_inner_sql) {
|
|
client_stmt_id = ++next_client_ps_stmt_id_;
|
|
} else {
|
|
client_stmt_id = inner_stmt_id;
|
|
}
|
|
already_exists = false;
|
|
if (is_inner_sql) {
|
|
LOG_TRACE("is inner sql no need to add session info",
|
|
K(proxy_version_), K(min_proxy_version_ps_), K(inner_stmt_id),
|
|
K(client_stmt_id), K(next_client_ps_stmt_id_), K(is_new_proxy), K(is_inner_sql));
|
|
} else {
|
|
LOG_TRACE("will add session info", K(proxy_version_), K(min_proxy_version_ps_),
|
|
K(inner_stmt_id), K(client_stmt_id), K(next_client_ps_stmt_id_),
|
|
K(is_new_proxy), K(ret), K(is_inner_sql));
|
|
|
|
if (OB_FAIL(try_create_ps_session_info_map())) {
|
|
LOG_WARN("fail create map", K(ret));
|
|
} else {
|
|
ret = ps_session_info_map_.get_refactored(client_stmt_id, session_info);
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
if (OB_ISNULL(session_info)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("session_info is NULL", K(ret), K(inner_stmt_id), K(client_stmt_id));
|
|
} else {
|
|
already_exists = true;
|
|
session_info->inc_ref_count();
|
|
}
|
|
} else if (OB_HASH_NOT_EXIST == ret) {
|
|
ret = OB_SUCCESS;
|
|
char *buf = static_cast<char*>(ps_session_info_allocator_.alloc(sizeof(ObPsSessionInfo)));
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("allocate memory failed", K(ret));
|
|
} else if (OB_ISNULL(stmt_info)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("stmt info is null", K(ret), K(stmt_info));
|
|
} else {
|
|
session_info = new (buf) ObPsSessionInfo(orig_tenant_id_, stmt_info->get_num_of_param());
|
|
session_info->set_stmt_id(client_stmt_id);
|
|
session_info->set_stmt_type(stmt_info->get_stmt_type());
|
|
session_info->set_ps_stmt_checksum(stmt_info->get_ps_stmt_checksum());
|
|
session_info->set_inner_stmt_id(inner_stmt_id);
|
|
session_info->set_num_of_returning_into(stmt_info->get_num_of_returning_into());
|
|
LOG_TRACE("add ps session info", K(stmt_info->get_ps_sql()),
|
|
K(stmt_info->get_ps_stmt_checksum()),
|
|
K(client_stmt_id),
|
|
K(inner_stmt_id),
|
|
K(get_sessid()),
|
|
K(stmt_info->get_num_of_param()),
|
|
K(stmt_info->get_num_of_returning_into()));
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
session_info->inc_ref_count();
|
|
if (OB_FAIL(ps_session_info_map_.set_refactored(client_stmt_id, session_info))) {
|
|
// OB_HASH_EXIST cannot be here, no need to handle
|
|
LOG_WARN("push back ps_session info failed", K(ret), K(client_stmt_id));
|
|
} else {
|
|
LOG_TRACE("add ps session info success", K(client_stmt_id), K(get_sessid()));
|
|
}
|
|
}
|
|
if (OB_FAIL(ret) && OB_NOT_NULL(session_info)) {
|
|
session_info->~ObPsSessionInfo();
|
|
ps_session_info_allocator_.free(session_info);
|
|
session_info = NULL;
|
|
buf = NULL;
|
|
}
|
|
} else {
|
|
LOG_WARN("get ps session failed", K(ret), K(client_stmt_id), K(inner_stmt_id));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_inner_ps_stmt_id(ObPsStmtId cli_stmt_id, ObPsStmtId &inner_stmt_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPsSessionInfo *ps_session_info = NULL;
|
|
if (OB_UNLIKELY(!ps_session_info_map_.created())) {
|
|
ret = OB_HASH_NOT_EXIST;
|
|
LOG_WARN("map not created before insert any element", K(ret));
|
|
} else if (OB_FAIL(ps_session_info_map_.get_refactored(cli_stmt_id, ps_session_info))) {
|
|
LOG_WARN("get inner ps stmt id failed", K(ret), K(cli_stmt_id), K(lbt()));
|
|
} else if (OB_ISNULL(ps_session_info)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("ps session info is null", K(cli_stmt_id), "session_id", get_sessid(), K(ret));
|
|
} else {
|
|
inner_stmt_id = ps_session_info->get_inner_stmt_id();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
ObPLCursorInfo *ObSQLSessionInfo::get_cursor(int64_t cursor_id)
|
|
{
|
|
ObPLCursorInfo *cursor = NULL;
|
|
if (OB_SUCCESS != pl_cursor_cache_.pl_cursor_map_.get_refactored(cursor_id, cursor)) {
|
|
LOG_WARN_RET(OB_ERR_UNEXPECTED, "get cursor info failed", K(cursor_id), K(get_sessid()));
|
|
}
|
|
return cursor;
|
|
}
|
|
|
|
ObDbmsCursorInfo *ObSQLSessionInfo::get_dbms_cursor(int64_t cursor_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPLCursorInfo *cursor = NULL;
|
|
ObDbmsCursorInfo *dbms_cursor = NULL;
|
|
OV (OB_NOT_NULL(cursor = get_cursor(cursor_id)),
|
|
OB_INVALID_ARGUMENT, cursor_id);
|
|
OV (OB_NOT_NULL(dbms_cursor = dynamic_cast<ObDbmsCursorInfo *>(cursor)),
|
|
OB_INVALID_ARGUMENT, cursor_id);
|
|
return dbms_cursor;
|
|
}
|
|
|
|
int ObSQLSessionInfo::add_cursor(pl::ObPLCursorInfo *cursor)
|
|
{
|
|
// open_cursors is 0 to indicate a special state, no limit is set
|
|
#define NEED_CHECK_SESS_OPEN_CURSORS_LIMIT(v) (0 == v ? false : true)
|
|
int ret = OB_SUCCESS;
|
|
bool add_cursor_success = false;
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(get_effective_tenant_id()));
|
|
CK (tenant_config.is_valid());
|
|
CK (OB_NOT_NULL(cursor));
|
|
if (OB_SUCC(ret)) {
|
|
int64_t open_cursors_limit = tenant_config->open_cursors;
|
|
if (NEED_CHECK_SESS_OPEN_CURSORS_LIMIT(open_cursors_limit)
|
|
&& open_cursors_limit <= pl_cursor_cache_.pl_cursor_map_.size()) {
|
|
ret = OB_ERR_OPEN_CURSORS_EXCEEDED;
|
|
LOG_WARN("maximum open cursors exceeded",
|
|
K(ret), K(open_cursors_limit), K(pl_cursor_cache_.pl_cursor_map_.size()));
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
int64_t id = cursor->get_id();
|
|
if (OB_INVALID_ID == id) {
|
|
// mysql ps模式时,会提前将cursor id设置为 stmt_id
|
|
id = pl_cursor_cache_.gen_cursor_id();
|
|
// ps cursor: proxy will record server ip, other ops of ps cursor will route by record ip.
|
|
|
|
// server cursor(not ps cursor) has same logic with temporary table,
|
|
// because we can not sync server cursor status to other server,
|
|
// so after open server cursor, other modify of this cursor need to do on same server.
|
|
bool is_already_set = false;
|
|
OZ (get_session_temp_table_used(is_already_set));
|
|
if (OB_SUCC(ret) && !is_already_set) {
|
|
OZ (set_session_temp_table_used(true));
|
|
}
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
} else {
|
|
// when select GV$OPEN_CURSOR, we will add get_thread_data_lock to fetch pl_cursor_map_
|
|
// so we need get_thread_data_lock there
|
|
ObSQLSessionInfo::LockGuard lock_guard(get_thread_data_lock());
|
|
if (OB_FAIL(pl_cursor_cache_.pl_cursor_map_.set_refactored(id, cursor))) {
|
|
LOG_WARN("fail insert ps id to hash map", K(id), K(*cursor), K(ret));
|
|
} else {
|
|
cursor->set_id(id);
|
|
add_cursor_success = true;
|
|
if (lib::is_diagnose_info_enabled()) {
|
|
EVENT_INC(SQL_OPEN_CURSORS_CURRENT);
|
|
EVENT_INC(SQL_OPEN_CURSORS_CUMULATIVE);
|
|
}
|
|
LOG_DEBUG("ps cursor: add cursor", K(ret), K(id), K(get_sessid()));
|
|
}
|
|
}
|
|
}
|
|
if (!add_cursor_success && OB_NOT_NULL(cursor)) {
|
|
int64_t id = cursor->get_id();
|
|
int tmp_ret = close_cursor(cursor);
|
|
ret = OB_SUCCESS == ret ? tmp_ret : ret;
|
|
if (OB_SUCCESS != tmp_ret) {
|
|
LOG_WARN("close cursor fail when add cursor to sesssion.", K(ret), K(id), K(get_sessid()));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::close_cursor(ObPLCursorInfo *&cursor)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_NOT_NULL(cursor)) {
|
|
int64_t id = cursor->get_id();
|
|
OZ (cursor->close(*this));
|
|
cursor->~ObPLCursorInfo();
|
|
get_cursor_allocator().free(cursor);
|
|
cursor = NULL;
|
|
LOG_DEBUG("close cursor", K(ret), K(id), K(get_sessid()));
|
|
} else {
|
|
LOG_DEBUG("close cursor is null", K(get_sessid()));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::close_cursor(int64_t cursor_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPLCursorInfo *cursor = NULL;
|
|
LOG_INFO("ps cursor : remove cursor", K(ret), K(cursor_id), K(get_sessid()));
|
|
// when select GV$OPEN_CURSOR, we will add get_thread_data_lock to fetch pl_cursor_map_
|
|
// so we need get_thread_data_lock there
|
|
ObSQLSessionInfo::LockGuard lock_guard(get_thread_data_lock());
|
|
if (OB_FAIL(pl_cursor_cache_.pl_cursor_map_.erase_refactored(cursor_id, &cursor))) {
|
|
LOG_WARN("cursor info not exist", K(cursor_id));
|
|
} else if (OB_ISNULL(cursor)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("session_info is null", K(ret));
|
|
} else {
|
|
LOG_DEBUG("close cursor", K(ret), K(cursor_id), K(get_sessid()));
|
|
OZ (cursor->close(*this));
|
|
cursor->~ObPLCursorInfo();
|
|
get_cursor_allocator().free(cursor);
|
|
cursor = NULL;
|
|
if (lib::is_diagnose_info_enabled()) {
|
|
EVENT_DEC(SQL_OPEN_CURSORS_CURRENT);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::print_all_cursor()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t open_cnt = 0;
|
|
int64_t unexpected_cnt = 0;
|
|
LOG_DEBUG("CURSOR DEBUG: total cursors in cursor map: ",
|
|
K(pl_cursor_cache_.pl_cursor_map_.size()));
|
|
for (CursorCache::CursorMap::iterator iter = pl_cursor_cache_.pl_cursor_map_.begin(); //ignore ret
|
|
iter != pl_cursor_cache_.pl_cursor_map_.end(); ++iter) {
|
|
pl::ObPLCursorInfo *cursor_info = iter->second;
|
|
if (OB_ISNULL(cursor_info)) {
|
|
// do nothing;
|
|
} else {
|
|
if (cursor_info->isopen()) {
|
|
open_cnt++;
|
|
LOG_DEBUG("CURSOR DEBUG: found open cursor", K(*cursor_info),
|
|
K(cursor_info->get_ref_count()));
|
|
} else {
|
|
if (0 != cursor_info->get_ref_count()) {
|
|
unexpected_cnt++;
|
|
LOG_DEBUG("CURSOR DEBUG: found closed cursor", K(*cursor_info),
|
|
K(cursor_info->get_ref_count()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LOG_DEBUG("CURSOR DEBUG: may illegal cursors in cursor map: ", K(open_cnt), K(unexpected_cnt));
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::init_cursor_cache()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (!pl_cursor_cache_.is_inited()) {
|
|
// when select GV$OPEN_CURSOR, we will add get_thread_data_lock to fetch pl_cursor_map_
|
|
// so we need get_thread_data_lock there
|
|
ObSQLSessionInfo::LockGuard lock_guard(get_thread_data_lock());
|
|
OZ (pl_cursor_cache_.init(get_effective_tenant_id()),
|
|
get_effective_tenant_id(),
|
|
get_proxy_sessid(),
|
|
get_sessid());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::close_dbms_cursor(int64_t cursor_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPLCursorInfo *cursor = NULL;
|
|
LOG_INFO("remove dbms cursor", K(ret), K(cursor_id), K(get_sessid()));
|
|
// when select GV$OPEN_CURSOR, we will add get_thread_data_lock to fetch pl_cursor_map_
|
|
// so we need get_thread_data_lock there
|
|
ObSQLSessionInfo::LockGuard lock_guard(get_thread_data_lock());
|
|
OZ (pl_cursor_cache_.pl_cursor_map_.erase_refactored(cursor_id, &cursor), cursor_id);
|
|
OV (OB_NOT_NULL(cursor), OB_ERR_UNEXPECTED, cursor_id);
|
|
if (OB_SUCC(ret) && lib::is_diagnose_info_enabled()) {
|
|
EVENT_DEC(SQL_OPEN_CURSORS_CURRENT);
|
|
}
|
|
// dbms cursor应该先执行spi接口关闭,再执行session接口删除。
|
|
OV (!cursor->isopen(), OB_ERR_UNEXPECTED, cursor_id);
|
|
OX (cursor->reset());
|
|
OX (get_cursor_allocator().free(cursor));
|
|
OX (cursor = NULL);
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::make_cursor(pl::ObPLCursorInfo *&cursor)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
#ifndef OB_BUILD_ORACLE_PL
|
|
UNUSED(cursor);
|
|
#else
|
|
const pl::ObRefCursorType pl_type;
|
|
ObObj param;
|
|
param.set_ext(reinterpret_cast<int64_t>(cursor));
|
|
int64_t param_size = 0;
|
|
ObSchemaGetterGuard dummy_schema_guard;
|
|
OZ (init_cursor_cache());
|
|
OZ (pl_type.init_obj(dummy_schema_guard, get_cursor_allocator(), param, param_size));
|
|
OX (cursor = reinterpret_cast<ObPLCursorInfo*>(param.get_ext()));
|
|
OZ (add_cursor(cursor));
|
|
LOG_DEBUG("cursor alloc, session cursor", K(cursor));
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::make_dbms_cursor(pl::ObDbmsCursorInfo *&cursor,
|
|
uint64_t id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
void *buf = NULL;
|
|
if (!pl_cursor_cache_.is_inited()) {
|
|
OZ (pl_cursor_cache_.init(get_effective_tenant_id()),
|
|
get_effective_tenant_id(), get_proxy_sessid(), get_sessid());
|
|
}
|
|
OV (OB_NOT_NULL(buf = get_cursor_allocator().alloc(sizeof(ObDbmsCursorInfo))),
|
|
OB_ALLOCATE_MEMORY_FAILED, sizeof(ObDbmsCursorInfo));
|
|
OX (MEMSET(buf, 0, sizeof(ObDbmsCursorInfo)));
|
|
OV (OB_NOT_NULL(cursor = new (buf) ObDbmsCursorInfo(get_cursor_allocator())));
|
|
OZ (cursor->init());
|
|
OX (cursor->set_id(id));
|
|
OZ (add_cursor(cursor));
|
|
/*
|
|
* 一个dbms cursor可以在open之后反复parse,每次都可以切换为不同语句,所以内部不同对象需要使用不同allocator:
|
|
* 1. cursor_id在open_cursor之后就不变化,直到close_cursor,所以生命周期比较长,从session的allocator分配。
|
|
* 2. sql_stmt_等其它属性都是每次parse之后就变化的,所以生命周期较短,从entiry分配内存,并且在每次parse时重新
|
|
* 创建entity。
|
|
* 3. spi_result、spi_cursor也要在每次parse时重置。
|
|
*/
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::check_read_only_privilege(const bool read_only,
|
|
const ObSqlTraits &sql_traits)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(check_global_read_only_privilege(read_only, sql_traits))) {
|
|
LOG_WARN("failed to check global read_only privilege!", K(ret));
|
|
} else if (OB_FAIL(check_tx_read_only_privilege(sql_traits))){
|
|
LOG_WARN("failed to check tx_read_only privilege!", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//在session中当trace被打开过一次,则分配一个buffer, 该buffer在整个session析构时才会被释放。
|
|
ObTraceEventRecorder* ObSQLSessionInfo::get_trace_buf()
|
|
{
|
|
if (NULL == trace_recorder_) {
|
|
void *ptr = name_pool_.alloc(sizeof(ObTraceEventRecorder));
|
|
if (NULL == ptr) {
|
|
LOG_WARN_RET(OB_ALLOCATE_MEMORY_FAILED, "fail to alloc trace recorder");
|
|
} else {
|
|
trace_recorder_ = new (ptr) ObTraceEventRecorder(false, ObLatchIds::SESSION_TRACE_RECORDER_LOCK);
|
|
}
|
|
}
|
|
return trace_recorder_;
|
|
}
|
|
|
|
void ObSQLSessionInfo::clear_trace_buf()
|
|
{
|
|
if (NULL != trace_recorder_) {
|
|
trace_recorder_->reset();
|
|
}
|
|
}
|
|
|
|
OB_DEF_SERIALIZE(ObSQLSessionInfo::ApplicationInfo)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LST_DO_CODE(OB_UNIS_ENCODE, module_name_, action_name_, client_info_);
|
|
return ret;
|
|
}
|
|
|
|
OB_DEF_DESERIALIZE(ObSQLSessionInfo::ApplicationInfo)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LST_DO_CODE(OB_UNIS_DECODE, module_name_, action_name_, client_info_);
|
|
return ret;
|
|
}
|
|
|
|
OB_DEF_SERIALIZE_SIZE(ObSQLSessionInfo::ApplicationInfo)
|
|
{
|
|
int64_t len = 0;
|
|
LST_DO_CODE(OB_UNIS_ADD_LEN, module_name_, action_name_, client_info_);
|
|
return len;
|
|
}
|
|
|
|
OB_DEF_SERIALIZE(ObSQLSessionInfo)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
BASE_SER((ObSQLSessionInfo, ObBasicSessionInfo));
|
|
LST_DO_CODE(OB_UNIS_ENCODE,
|
|
thread_data_.cur_query_start_time_,
|
|
user_priv_set_,
|
|
db_priv_set_,
|
|
trans_type_,
|
|
global_sessid_,
|
|
inner_flag_,
|
|
is_max_availability_mode_,
|
|
session_type_,
|
|
has_temp_table_flag_,
|
|
enable_early_lock_release_,
|
|
enable_role_array_,
|
|
in_definer_named_proc_,
|
|
priv_user_id_,
|
|
xa_end_timeout_seconds_,
|
|
prelock_,
|
|
proxy_version_,
|
|
min_proxy_version_ps_,
|
|
thread_data_.is_in_retry_,
|
|
ddl_info_,
|
|
gtt_session_scope_unique_id_,
|
|
gtt_trans_scope_unique_id_,
|
|
gtt_session_scope_ids_,
|
|
gtt_trans_scope_ids_,
|
|
affected_rows_);
|
|
return ret;
|
|
}
|
|
|
|
OB_DEF_DESERIALIZE(ObSQLSessionInfo)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
BASE_DESER((ObSQLSessionInfo, ObBasicSessionInfo));
|
|
LST_DO_CODE(OB_UNIS_DECODE,
|
|
thread_data_.cur_query_start_time_,
|
|
user_priv_set_,
|
|
db_priv_set_,
|
|
trans_type_,
|
|
global_sessid_,
|
|
inner_flag_,
|
|
is_max_availability_mode_,
|
|
session_type_,
|
|
has_temp_table_flag_,
|
|
enable_early_lock_release_,
|
|
enable_role_array_,
|
|
in_definer_named_proc_,
|
|
priv_user_id_,
|
|
xa_end_timeout_seconds_,
|
|
prelock_,
|
|
proxy_version_,
|
|
min_proxy_version_ps_,
|
|
thread_data_.is_in_retry_,
|
|
ddl_info_,
|
|
gtt_session_scope_unique_id_,
|
|
gtt_trans_scope_unique_id_,
|
|
gtt_session_scope_ids_,
|
|
gtt_trans_scope_ids_,
|
|
affected_rows_);
|
|
(void)ObSQLUtils::adjust_time_by_ntp_offset(thread_data_.cur_query_start_time_);
|
|
return ret;
|
|
}
|
|
|
|
OB_DEF_SERIALIZE_SIZE(ObSQLSessionInfo)
|
|
{
|
|
int64_t len = 0;
|
|
BASE_ADD_LEN((ObSQLSessionInfo, ObBasicSessionInfo));
|
|
LST_DO_CODE(OB_UNIS_ADD_LEN,
|
|
thread_data_.cur_query_start_time_,
|
|
user_priv_set_,
|
|
db_priv_set_,
|
|
trans_type_,
|
|
global_sessid_,
|
|
inner_flag_,
|
|
is_max_availability_mode_,
|
|
session_type_,
|
|
has_temp_table_flag_,
|
|
enable_early_lock_release_,
|
|
enable_role_array_,
|
|
in_definer_named_proc_,
|
|
priv_user_id_,
|
|
xa_end_timeout_seconds_,
|
|
prelock_,
|
|
proxy_version_,
|
|
min_proxy_version_ps_,
|
|
thread_data_.is_in_retry_,
|
|
ddl_info_,
|
|
gtt_session_scope_unique_id_,
|
|
gtt_trans_scope_unique_id_,
|
|
gtt_session_scope_ids_,
|
|
gtt_trans_scope_ids_,
|
|
affected_rows_);
|
|
return len;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_collation_type_of_names(
|
|
const ObNameTypeClass type_class,
|
|
ObCollationType &cs_type) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObNameCaseMode case_mode = OB_NAME_CASE_INVALID;
|
|
cs_type = CS_TYPE_INVALID;
|
|
if (OB_TABLE_NAME_CLASS == type_class) {
|
|
if (OB_FAIL(get_name_case_mode(case_mode))) {
|
|
LOG_WARN("fail to get name case mode", K(ret));
|
|
} else if (OB_ORIGIN_AND_SENSITIVE == case_mode) {
|
|
cs_type = CS_TYPE_UTF8MB4_BIN;
|
|
} else if (OB_ORIGIN_AND_INSENSITIVE == case_mode || OB_LOWERCASE_AND_INSENSITIVE == case_mode) {
|
|
cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
|
|
}
|
|
} else if (OB_COLUMN_NAME_CLASS == type_class) {
|
|
cs_type = CS_TYPE_UTF8MB4_GENERAL_CI;
|
|
} else if (OB_USER_NAME_CLASS == type_class) {
|
|
cs_type = CS_TYPE_UTF8MB4_BIN;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::name_case_cmp(
|
|
const ObString &name,
|
|
const ObString &name_other,
|
|
const ObNameTypeClass type_class,
|
|
bool &is_equal) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObCollationType cs_type = CS_TYPE_INVALID;
|
|
if (OB_FAIL(get_collation_type_of_names(type_class, cs_type))) {
|
|
LOG_WARN("fail to get collation type of name", K(name), K(name_other), K(type_class), K(ret));
|
|
} else {
|
|
if (0 == ObCharset::strcmp(cs_type, name, name_other)) {
|
|
is_equal = true;
|
|
} else {
|
|
is_equal = false;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::kill_query()
|
|
{
|
|
LOG_INFO("kill query", K(get_sessid()), K(get_proxy_sessid()), K(get_current_query_string()));
|
|
ObSQLSessionInfo::LockGuard lock_guard(get_thread_data_lock());
|
|
update_last_active_time();
|
|
set_session_state(QUERY_KILLED);
|
|
return OB_SUCCESS;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_query_deadlocked()
|
|
{
|
|
LOG_INFO("set query deadlocked", K(get_sessid()), K(get_proxy_sessid()), K(get_current_query_string()));
|
|
ObSQLSessionInfo::LockGuard lock_guard(get_thread_data_lock());
|
|
update_last_active_time();
|
|
set_session_state(QUERY_DEADLOCKED);
|
|
return OB_SUCCESS;
|
|
}
|
|
|
|
const ObAuditRecordData &ObSQLSessionInfo::get_final_audit_record(
|
|
ObExecuteMode mode)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
audit_record_.trace_id_ = *ObCurTraceId::get_trace_id();
|
|
audit_record_.request_type_ = mode;
|
|
audit_record_.session_id_ = get_sessid();
|
|
audit_record_.proxy_session_id_ = get_proxy_sessid();
|
|
audit_record_.tenant_id_ = get_priv_tenant_id();
|
|
audit_record_.user_id_ = get_user_id();
|
|
audit_record_.effective_tenant_id_ = get_effective_tenant_id();
|
|
if (EXECUTE_INNER == mode
|
|
|| EXECUTE_LOCAL == mode
|
|
|| EXECUTE_PS_PREPARE == mode
|
|
|| EXECUTE_PS_EXECUTE == mode
|
|
|| EXECUTE_PS_SEND_PIECE == mode
|
|
|| EXECUTE_PS_GET_PIECE == mode
|
|
|| EXECUTE_PS_SEND_LONG_DATA == mode
|
|
|| EXECUTE_PS_FETCH == mode
|
|
|| EXECUTE_PL_EXECUTE == mode) {
|
|
audit_record_.tenant_name_ = const_cast<char *>(get_tenant_name().ptr());
|
|
audit_record_.tenant_name_len_ = min(get_tenant_name().length(),
|
|
OB_MAX_TENANT_NAME_LENGTH);
|
|
audit_record_.user_name_ = const_cast<char *>(get_user_name().ptr());
|
|
audit_record_.user_name_len_ = min(get_user_name().length(),
|
|
OB_MAX_USER_NAME_LENGTH);
|
|
audit_record_.db_name_ = const_cast<char *>(get_database_name().ptr());
|
|
audit_record_.db_name_len_ = min(get_database_name().length(),
|
|
OB_MAX_DATABASE_NAME_LENGTH);
|
|
|
|
if (EXECUTE_PS_EXECUTE == mode
|
|
|| EXECUTE_PS_SEND_PIECE == mode
|
|
|| EXECUTE_PS_GET_PIECE == mode
|
|
|| EXECUTE_PS_SEND_LONG_DATA == mode
|
|
|| EXECUTE_PS_FETCH == mode) {
|
|
//ps模式对应的sql在协议层中设置, session的current_query_中没值
|
|
// do nothing
|
|
} else {
|
|
ObString sql = get_current_query_string();
|
|
audit_record_.sql_ = const_cast<char *>(sql.ptr());
|
|
audit_record_.sql_len_ = min(sql.length(), OB_MAX_SQL_LENGTH);
|
|
audit_record_.sql_cs_type_ = get_local_collation_connection();
|
|
}
|
|
|
|
if (OB_FAIL(get_database_id(audit_record_.db_id_))) {
|
|
LOG_WARN("fail to get database id", K(ret));
|
|
}
|
|
} else if (EXECUTE_REMOTE == mode || EXECUTE_DIST == mode) {
|
|
audit_record_.tenant_name_ = NULL;
|
|
audit_record_.tenant_name_len_ = 0;
|
|
audit_record_.user_name_ = NULL;
|
|
audit_record_.user_name_len_ = 0;
|
|
audit_record_.db_name_ = NULL;
|
|
audit_record_.db_name_len_ = 0;
|
|
audit_record_.sql_ = NULL;
|
|
audit_record_.sql_len_ = 0;
|
|
audit_record_.sql_cs_type_ = CS_TYPE_INVALID;
|
|
}
|
|
|
|
audit_record_.txn_free_route_flag_ = txn_free_route_ctx_.get_audit_record();
|
|
audit_record_.txn_free_route_version_ = txn_free_route_ctx_.get_global_version();
|
|
trace::UUID trc_uuid = OBTRACE->get_trace_id();
|
|
int64_t pos = 0;
|
|
if (trc_uuid.is_inited()) {
|
|
trc_uuid.tostring(audit_record_.flt_trace_id_, OB_MAX_UUID_STR_LENGTH + 1, pos);
|
|
} else {
|
|
// do nothing
|
|
}
|
|
audit_record_.flt_trace_id_[pos] = '\0';
|
|
return audit_record_;
|
|
}
|
|
|
|
void ObSQLSessionInfo::update_stat_from_exec_record()
|
|
{
|
|
session_stat_.total_logical_read_ += (audit_record_.exec_record_.memstore_read_row_count_
|
|
+ audit_record_.exec_record_.ssstore_read_row_count_);
|
|
// session_stat_.total_logical_write_ += 0;
|
|
// session_stat_.total_physical_read_ += 0;
|
|
// session_stat_.total_lock_count_ += 0;
|
|
}
|
|
|
|
void ObSQLSessionInfo::update_stat_from_exec_timestamp()
|
|
{
|
|
session_stat_.total_cpu_time_us_ += audit_record_.exec_timestamp_.executor_t_;
|
|
session_stat_.total_exec_time_us_ += audit_record_.exec_timestamp_.elapsed_t_;
|
|
}
|
|
|
|
void ObSQLSessionInfo::update_alive_time_stat()
|
|
{
|
|
session_stat_.total_alive_time_us_ = ObTimeUtility::current_time() - sess_create_time_;;
|
|
}
|
|
|
|
void ObSQLSessionInfo::set_session_type_with_flag()
|
|
{
|
|
if (OB_UNLIKELY(INVALID_TYPE == session_type_)) {
|
|
LOG_WARN_RET(OB_ERR_UNEXPECTED, "session type is not init, only happen when old server send rpc to new server");
|
|
session_type_ = inner_flag_ ? INNER_SESSION : USER_SESSION;
|
|
}
|
|
}
|
|
|
|
void ObSQLSessionInfo::set_early_lock_release(bool enable)
|
|
{
|
|
enable_early_lock_release_ = enable;
|
|
if (enable) {
|
|
SQL_SESSION_LOG(DEBUG, "set early lock release success",
|
|
"sessid", get_sessid(), "proxy_sessid", get_proxy_sessid());
|
|
}
|
|
}
|
|
|
|
ObPLCursorInfo *ObSQLSessionInfo::get_pl_implicit_cursor()
|
|
{
|
|
return NULL != pl_context_ ? &(pl_context_->get_cursor_info()) : NULL;
|
|
}
|
|
const ObPLCursorInfo *ObSQLSessionInfo::get_pl_implicit_cursor() const
|
|
{
|
|
return NULL != pl_context_ ? &(pl_context_->get_cursor_info()) : NULL;
|
|
}
|
|
|
|
ObPLSqlCodeInfo *ObSQLSessionInfo::get_pl_sqlcode_info()
|
|
{
|
|
return NULL != pl_context_ ? &(pl_context_->get_sqlcode_info()) : NULL;
|
|
}
|
|
const ObPLSqlCodeInfo *ObSQLSessionInfo::get_pl_sqlcode_info() const
|
|
{
|
|
return NULL != pl_context_ ? &(pl_context_->get_sqlcode_info()) : NULL;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::has_pl_implicit_savepoint()
|
|
{
|
|
return NULL != pl_context_ ? pl_context_->has_implicit_savepoint() : false;
|
|
}
|
|
|
|
void ObSQLSessionInfo::clear_pl_implicit_savepoint()
|
|
{
|
|
if (OB_NOT_NULL(pl_context_)) {
|
|
pl_context_->clear_implicit_savepoint();
|
|
}
|
|
}
|
|
|
|
void ObSQLSessionInfo::set_has_pl_implicit_savepoint(bool v)
|
|
{
|
|
if (OB_NOT_NULL(pl_context_)) {
|
|
pl_context_->set_has_implicit_savepoint(v);
|
|
}
|
|
}
|
|
|
|
bool ObSQLSessionInfo::is_pl_debug_on()
|
|
{
|
|
bool is_on = false;
|
|
#ifdef OB_BUILD_ORACLE_PL
|
|
is_on = pl_debugger_ != NULL && pl_debugger_->is_debug_on();
|
|
#endif
|
|
return is_on;
|
|
}
|
|
|
|
|
|
#ifdef OB_BUILD_ORACLE_PL
|
|
int ObSQLSessionInfo::initialize_pl_debugger()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPDBManager *instance = ObPDBManager::get_instance();
|
|
if (OB_NOT_NULL(instance)) {
|
|
OZ (instance->alloc(pl_debugger_, this));
|
|
CK (OB_NOT_NULL(pl_debugger_));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("current observer has not debugger instance!", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_pl_debugger(
|
|
uint32_t id, pl::debugger::ObPLDebugger *& pl_debugger)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPDBManager *instance = ObPDBManager::get_instance();
|
|
if (OB_NOT_NULL(instance)) {
|
|
OZ (instance->get(id, pl_debugger));
|
|
CK (OB_NOT_NULL(pl_debugger));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("current observer has not debugger instance!", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::release_pl_debugger(pl::debugger::ObPLDebugger *pl_debugger)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPDBManager *instance = ObPDBManager::get_instance();
|
|
if (OB_ISNULL(pl_debugger)) {
|
|
} else if (OB_NOT_NULL(instance)) {
|
|
instance->release(pl_debugger);
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_ERROR("current observer has not debugger instance!", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::free_pl_debugger()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObPDBManager *instance = ObPDBManager::get_instance();
|
|
if (OB_ISNULL(pl_debugger_)) {
|
|
} else if (OB_NOT_NULL(instance)) {
|
|
instance->free(pl_debugger_);
|
|
pl_debugger_ = NULL;
|
|
LOG_INFO("free current session debugger", K(ret));
|
|
} else {
|
|
LOG_ERROR("current observer has not debugger instance!");
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObSQLSessionInfo::reset_pl_debugger_resource()
|
|
{
|
|
free_pl_debugger();
|
|
}
|
|
#endif
|
|
|
|
void ObSQLSessionInfo::reset_all_package_changed_info()
|
|
{
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
it->second->reset_package_changed_info();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObSQLSessionInfo::reset_all_package_state()
|
|
{
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
it->second->reset(this);
|
|
it->second->~ObPLPackageState();
|
|
get_package_allocator().free(it->second);
|
|
it->second = NULL;
|
|
}
|
|
package_state_map_.clear();
|
|
}
|
|
}
|
|
|
|
int ObSQLSessionInfo::reset_all_package_state_by_dbms_session(bool need_set_sync_var)
|
|
{
|
|
/* its called by dbms_session.reset_package()
|
|
* in this mode
|
|
* 1. we also should reset all user variable mocked by package var
|
|
* 2. if the package is a trigger, we should do nothing
|
|
*
|
|
*/
|
|
int ret = OB_SUCCESS;
|
|
if (0 == package_state_map_.size()
|
|
|| NULL != get_pl_context()
|
|
|| false == need_reset_package()) {
|
|
// do nothing
|
|
} else {
|
|
ObSEArray<int64_t, 4> remove_packages;
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
if (!share::schema::ObTriggerInfo::is_trigger_package_id(it->second->get_package_id())) {
|
|
ret = ret != OB_SUCCESS ? ret : remove_packages.push_back(it->first);
|
|
}
|
|
}
|
|
}
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < remove_packages.count(); ++i) {
|
|
ObPLPackageState *package_state = NULL;
|
|
bool need_reset = false;
|
|
OZ (package_state_map_.get_refactored(remove_packages.at(i), package_state));
|
|
CK (OB_NOT_NULL(package_state));
|
|
OZ (package_state_map_.erase_refactored(remove_packages.at(i)));
|
|
OX (need_reset = true);
|
|
OZ (package_state->remove_user_variables_for_package_state(*this));
|
|
if (need_reset && NULL != package_state) {
|
|
package_state->reset(this);
|
|
package_state->~ObPLPackageState();
|
|
get_package_allocator().free(package_state);
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && need_set_sync_var) {
|
|
ObSessionVariable sess_var;
|
|
ObString key("##__OB_RESET_ALL_PACKAGE_BY_DBMS_SESSION_RESET_PACKAGE__");
|
|
sess_var.meta_.set_timestamp();
|
|
sess_var.value_.set_timestamp(ObTimeUtility::current_time());
|
|
if (OB_FAIL(ObBasicSessionInfo::replace_user_variable(key, sess_var))) {
|
|
LOG_WARN("add user var failed", K(ret));
|
|
}
|
|
}
|
|
// wether reset succ or not, set need_reset_package to false
|
|
set_need_reset_package(false);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::reset_all_serially_package_state()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSEArray<int64_t, 4> serially_packages;
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
if (it->second->get_serially_reusable()) {
|
|
it->second->reset(this);
|
|
OZ (serially_packages.push_back(it->first));
|
|
}
|
|
}
|
|
}
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < serially_packages.count(); ++i) {
|
|
OZ (package_state_map_.erase_refactored(serially_packages.at(i)));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::is_package_state_changed() const
|
|
{
|
|
bool b_ret = false;
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
if (it->second->is_package_info_changed()) {
|
|
b_ret = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return b_ret;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::get_changed_package_state_num() const
|
|
{
|
|
int64_t changed_num = 0;
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
if (it->second->is_package_info_changed()) {
|
|
changed_num++;
|
|
}
|
|
}
|
|
}
|
|
return changed_num;
|
|
}
|
|
|
|
int ObSQLSessionInfo::add_changed_package_info(ObExecContext &exec_ctx)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObArenaAllocator allocator;
|
|
ObPLExecCtx pl_ctx(&allocator, &exec_ctx, NULL, NULL, NULL, NULL);
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
ObPLPackageState *package_state = it->second;
|
|
if (package_state->is_package_info_changed()) {
|
|
ObSEArray<ObString, 4> key;
|
|
ObSEArray<ObObj, 4> value;
|
|
bool is_valid = false;
|
|
if (OB_FAIL(package_state->check_package_state_valid(exec_ctx, is_valid))) {
|
|
LOG_WARN("check package state failed", K(ret), KPC(package_state));
|
|
} else if (!is_valid) {
|
|
LOG_INFO("package state is invalid, ignore this package.", KPC(package_state));
|
|
} else if (OB_FAIL(package_state->convert_changed_info_to_string_kvs(pl_ctx, key, value))) {
|
|
LOG_WARN("convert package state to string kv failed", K(ret));
|
|
} else {
|
|
ObSessionVariable sess_var;
|
|
int tmp_ret = OB_SUCCESS;
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < key.count(); i++) {
|
|
sess_var.value_ = value[i];
|
|
sess_var.meta_ = value[i].get_meta();
|
|
if (OB_FAIL(ObBasicSessionInfo::replace_user_variable(key[i], sess_var))) {
|
|
LOG_WARN("add user var failed", K(ret));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::shrink_package_info()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (0 != package_state_map_.size()) {
|
|
FOREACH(it, package_state_map_) {
|
|
ObPLPackageState *package_state = it->second;
|
|
if (OB_FAIL(package_state->shrink())) {
|
|
LOG_WARN("package shrink failed", K(ret));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::replace_user_variable(
|
|
const common::ObString &name, const ObSessionVariable &value)
|
|
{
|
|
return ObBasicSessionInfo::replace_user_variable(name, value);
|
|
}
|
|
|
|
int ObSQLSessionInfo::replace_user_variable(
|
|
ObExecContext &ctx, const common::ObString &name, const ObSessionVariable &value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
bool is_package_variable = false;
|
|
if (name.prefix_match("pkg.") && name.length() >= 52) {
|
|
is_package_variable = true;
|
|
for (int64_t i = 4; i < name.length(); ++i) {
|
|
if (!((name[i] >= '0' && name[i] <= '9')
|
|
|| (name[i] >= 'a' && name[i] <= 'z'))) {
|
|
is_package_variable = false;
|
|
}
|
|
}
|
|
}
|
|
if (0 == name.case_compare("##__OB_RESET_ALL_PACKAGE_BY_DBMS_SESSION_RESET_PACKAGE__")) {
|
|
// "##__OB_RESET_ALL_PACKAGE_BY_DBMS_SESSION_RESET_PACKAGE__"
|
|
// this variable is used to reset_package.
|
|
// if we get a set stmt of OB_RESET_ALL_PACKAGE_BY_DBMS_SESSION_RESET_PACKAGE
|
|
// we should only reset_all_package, do not need set_user_variable
|
|
OZ (reset_all_package_state_by_dbms_session(false));
|
|
} else if (is_package_variable && OB_NOT_NULL(get_pl_engine())) {
|
|
OZ (set_package_variable(ctx, name, value.value_, true));
|
|
} else {
|
|
OZ (ObBasicSessionInfo::replace_user_variable(name, value));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::replace_user_variables(const ObSessionValMap &user_var_map)
|
|
{
|
|
return ObBasicSessionInfo::replace_user_variables(user_var_map);
|
|
}
|
|
|
|
int ObSQLSessionInfo::replace_user_variables(
|
|
ObExecContext &ctx, const ObSessionValMap &user_var_map)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OZ (ObBasicSessionInfo::replace_user_variables(user_var_map));
|
|
if (OB_SUCC(ret)
|
|
&& OB_NOT_NULL(get_pl_engine())
|
|
&& user_var_map.size() > 0) {
|
|
OZ (set_package_variables(ctx, user_var_map));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_package_variables(
|
|
ObExecContext &ctx, const ObSessionValMap &user_var_map)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LOG_DEBUG("set package variables now!");
|
|
const sql::ObSessionValMap::VarNameValMap &new_map = user_var_map.get_val_map();
|
|
common::hash::ObHashSet<common::ObString> sync_pkg_vars;
|
|
OZ (sync_pkg_vars.create(32));
|
|
OX (pl_sync_pkg_vars_ = &sync_pkg_vars);
|
|
for (sql::ObSessionValMap::VarNameValMap::const_iterator iter = new_map.begin();
|
|
OB_SUCC(ret) && iter != new_map.end(); iter++) {
|
|
const common::ObString &key = iter->first;
|
|
const ObObj &value = iter->second.value_;
|
|
if (!key.prefix_match("pkg.")) {
|
|
// do nothing ...
|
|
} else if (OB_HASH_EXIST == sync_pkg_vars.exist_refactored(key)) {
|
|
// do nothing ...
|
|
} else {
|
|
OZ (set_package_variable(ctx, key, value));
|
|
}
|
|
}
|
|
LOG_DEBUG("set package variables end!!!", K(ret));
|
|
pl_sync_pkg_vars_ = NULL;
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_package_variable(
|
|
ObExecContext &ctx, const common::ObString &key, const common::ObObj &value, bool from_proxy)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
pl::ObPLPackageManager &pl_manager = get_pl_engine()->get_package_manager();
|
|
share::schema::ObSchemaGetterGuard schema_guard;
|
|
pl::ObPLPackageGuard package_guard(ctx.get_my_session()->get_effective_tenant_id());
|
|
ObPackageVarSetName name;
|
|
ObArenaAllocator allocator;
|
|
bool match = false;
|
|
CK (OB_NOT_NULL(GCTX.schema_service_));
|
|
CK (OB_NOT_NULL(ctx.get_sql_proxy()));
|
|
if (OB_SUCC(ret)) {
|
|
ObPLResolveCtx resolve_ctx(
|
|
ctx.get_allocator(),
|
|
*this,
|
|
schema_guard,
|
|
package_guard,
|
|
*(ctx.get_sql_proxy()),
|
|
false, /*ps*/
|
|
false, /*check mode*/
|
|
false, /*sql scope*/
|
|
NULL, /*param_list*/
|
|
NULL, /*extern_param_info*/
|
|
TgTimingEvent::TG_TIMING_EVENT_INVALID,
|
|
true /*is_sync_pacakge_var*/);
|
|
OZ (package_guard.init());
|
|
OZ (name.decode(allocator, key));
|
|
CK (name.valid());
|
|
OZ (GCTX.schema_service_->get_tenant_schema_guard(get_effective_tenant_id(), schema_guard));
|
|
OZ (pl_manager.check_version(resolve_ctx, name.package_id_, name.state_version_, match));
|
|
if (OB_SUCC(ret) && match) {
|
|
OZ (pl_manager.set_package_var_val(
|
|
resolve_ctx, ctx, name.package_id_, name.var_idx_, value, true, from_proxy));
|
|
LOG_DEBUG("set pacakge variable",
|
|
K(ret), K(key), K(name.package_id_),
|
|
K(name.state_version_.package_version_),
|
|
K(name.state_version_.package_body_version_));
|
|
} else {
|
|
LOG_INFO("set package variable failed", K(ret), K(match), K(name), K(value));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_sequence_value(uint64_t tenant_id,
|
|
uint64_t seq_id,
|
|
share::ObSequenceValue &value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id ||
|
|
OB_INVALID_ID == seq_id)) {
|
|
LOG_WARN("invalid args", K(tenant_id), K(seq_id), K(ret));
|
|
} else if (OB_FAIL(sequence_currval_map_.get_refactored(seq_id, value))) {
|
|
LOG_WARN("fail get seq", K(tenant_id), K(seq_id), K(ret));
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
ret = OB_ERR_SEQUENCE_NOT_DEFINE;
|
|
LOG_USER_ERROR(OB_ERR_SEQUENCE_NOT_DEFINE);
|
|
}
|
|
} else {
|
|
// ok
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_sequence_value(uint64_t tenant_id,
|
|
uint64_t seq_id,
|
|
const ObSequenceValue &value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const bool overwrite_exits = true;
|
|
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id ||
|
|
OB_INVALID_ID == seq_id)) {
|
|
LOG_WARN("invalid args", K(tenant_id), K(seq_id), K(ret));
|
|
} else if (OB_FAIL(sequence_currval_map_.set_refactored(seq_id, value, overwrite_exits))) {
|
|
LOG_WARN("fail get seq", K(tenant_id), K(seq_id), K(ret));
|
|
} else {
|
|
sequence_currval_encoder_.is_changed_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::drop_sequence_value_if_exists(uint64_t seq_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_UNLIKELY(OB_INVALID_ID == seq_id)) {
|
|
LOG_WARN("invalid args", K(seq_id), K(ret));
|
|
} else if (OB_FAIL(sequence_currval_map_.erase_refactored(seq_id))) {
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
LOG_INFO("drop sequence value not exists", K(ret), K(seq_id));
|
|
ret = OB_SUCCESS;
|
|
} else {
|
|
LOG_WARN("drop sequence value failed", K(ret), K(seq_id));
|
|
}
|
|
} else {
|
|
sequence_currval_encoder_.is_changed_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_dblink_sequence_id(const ObString &sequence_name,
|
|
uint64_t dblink_id,
|
|
uint64_t &seq_id)const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObDBlinkSequenceIdKey key(sequence_name, dblink_id);
|
|
if (OB_UNLIKELY(OB_INVALID_ID == dblink_id ||
|
|
sequence_name.empty())) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("invalid args", K(dblink_id), K(seq_id), K(ret));
|
|
} else if (OB_FAIL(dblink_sequence_id_map_.get_refactored(key, seq_id))) {
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
seq_id = OB_INVALID_ID;
|
|
ret = OB_SUCCESS;
|
|
}
|
|
} else {
|
|
// ok
|
|
}
|
|
LOG_TRACE("get dblink sequence id", K(sequence_name), K(dblink_id), K(seq_id));
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_next_sequence_id(uint64_t &seq_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
seq_id = ++current_dblink_sequence_id_;
|
|
sequence_currval_encoder_.is_changed_ = true;
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_dblink_sequence_id(const ObString &sequence_name,
|
|
uint64_t dblink_id,
|
|
uint64_t seq_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObString name;
|
|
const bool overwrite_exits = true;
|
|
if (OB_UNLIKELY(OB_INVALID_ID == dblink_id ||
|
|
OB_INVALID_ID == seq_id ||
|
|
sequence_name.empty())) {
|
|
LOG_WARN("invalid args", K(dblink_id), K(seq_id), K(ret));
|
|
} else if (OB_FAIL(ob_write_string(get_session_allocator(), sequence_name, name))) {
|
|
LOG_WARN("failed to write obstring", K(ret));
|
|
} else {
|
|
ObDBlinkSequenceIdKey key(name, dblink_id);
|
|
if (OB_FAIL(dblink_sequence_id_map_.set_refactored(key, seq_id, overwrite_exits))) {
|
|
LOG_WARN("fail get seq", K(dblink_id), K(seq_id), K(ret));
|
|
} else {
|
|
sequence_currval_encoder_.is_changed_ = true;
|
|
LOG_TRACE("set new dblink sequence id", K(name), K(dblink_id), K(seq_id));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::drop_dblink_sequence_id_if_exists(const ObString &sequence_name,
|
|
uint64_t dblink_id,
|
|
uint64_t seq_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObDBlinkSequenceIdKey key(sequence_name, dblink_id);
|
|
if (OB_UNLIKELY(OB_INVALID_ID == dblink_id ||
|
|
OB_INVALID_ID == seq_id ||
|
|
sequence_name.empty())) {
|
|
LOG_WARN("invalid args", K(sequence_name), K(dblink_id), K(seq_id), K(ret));
|
|
} else if (OB_FAIL(drop_sequence_value_if_exists(seq_id))) {
|
|
LOG_WARN("failed to drop sequence value", K(ret));
|
|
} else if (OB_FAIL(dblink_sequence_id_map_.erase_refactored(key))) {
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
LOG_INFO("drop sequence value not exists", K(ret), K(dblink_id), K(seq_id));
|
|
ret = OB_SUCCESS;
|
|
} else {
|
|
LOG_WARN("drop sequence value failed", K(ret), K(dblink_id), K(seq_id));
|
|
}
|
|
} else {
|
|
sequence_currval_encoder_.is_changed_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_context_values(const ObString &context_name,
|
|
const ObString &attribute,
|
|
ObString &value,
|
|
bool &exist)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObInnerContextMap *inner_map = nullptr;
|
|
ObContextUnit *unit = nullptr;
|
|
exist = false;
|
|
if (OB_FAIL(contexts_map_.get_refactored(context_name, inner_map))) {
|
|
if (OB_HASH_NOT_EXIST != ret) {
|
|
LOG_WARN("failed to probe hash map", K(ret));
|
|
} else {
|
|
ret = OB_SUCCESS;
|
|
}
|
|
} else if (OB_ISNULL(inner_map) || OB_ISNULL(inner_map->context_map_)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get correct hash map", K(ret), KP(inner_map));
|
|
} else if (OB_FAIL(inner_map->context_map_->get_refactored(attribute, unit))) {
|
|
if (OB_HASH_NOT_EXIST != ret) {
|
|
LOG_WARN("failed to probe hash map", K(ret));
|
|
} else {
|
|
ret = OB_SUCCESS;
|
|
}
|
|
} else if (OB_ISNULL(unit)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get correct unit", K(ret));
|
|
} else {
|
|
exist = true;
|
|
value = unit->value_;
|
|
}
|
|
return ret;
|
|
}
|
|
int ObSQLSessionInfo::set_context_values(const ObString &context_name,
|
|
const ObString &attribute,
|
|
const ObString &value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObInnerContextMap *inner_map = nullptr;
|
|
ObContextUnit *exist_unit = nullptr;
|
|
const bool overwrite_exits = true;
|
|
int32_t session_context_size = static_cast<int32_t> (GCONF._session_context_size);
|
|
if (OB_FAIL(init_mem_context(get_effective_tenant_id()))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get mem context", K(ret));
|
|
} else {
|
|
ObIAllocator &malloc_alloc = mem_context_->get_malloc_allocator();
|
|
if (OB_FAIL(contexts_map_.get_refactored(context_name, inner_map))) {
|
|
if (OB_HASH_NOT_EXIST != ret) {
|
|
LOG_WARN("failed to probe hash map", K(ret));
|
|
} else if (curr_session_context_size_ >= session_context_size) {
|
|
ret = OB_ERR_SESSION_CONTEXT_EXCEEDED;
|
|
LOG_USER_ERROR(OB_ERR_SESSION_CONTEXT_EXCEEDED);
|
|
LOG_WARN("use too much local context in a session", K(session_context_size),
|
|
K(curr_session_context_size_));
|
|
} else {
|
|
ObInnerContextMap *new_map = nullptr;
|
|
ObContextUnit *new_unit = nullptr;
|
|
if (OB_ISNULL(new_map = static_cast<ObInnerContextMap *>
|
|
(malloc_alloc.alloc(sizeof(ObInnerContextMap))))) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("failed to alloc context map", K(ret));
|
|
} else if (FALSE_IT(new (new_map) ObInnerContextMap(malloc_alloc))) {
|
|
} else if (OB_FAIL(new_map->init())) {
|
|
LOG_WARN("failed to init context map", K(ret));
|
|
} else if (OB_FAIL(ob_write_string(malloc_alloc,
|
|
context_name,
|
|
new_map->context_name_))) {
|
|
LOG_WARN("failed to write name", K(ret));
|
|
} else if (OB_ISNULL(new_unit = static_cast<ObContextUnit *>
|
|
(malloc_alloc.alloc(sizeof(ObContextUnit))))) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("failed to alloc context unit", K(ret));
|
|
} else if (FALSE_IT(new (new_unit) ObContextUnit())) {
|
|
} else if (OB_FAIL(new_unit->deep_copy(attribute, value, malloc_alloc))) {
|
|
LOG_WARN("failed to copy context unit", K(ret));
|
|
} else if (OB_FAIL(new_map->context_map_->set_refactored(new_unit->attribute_, new_unit))) {
|
|
LOG_WARN("failed to insert new unit", K(ret));
|
|
} else if (OB_FAIL(contexts_map_.set_refactored(new_map->context_name_, new_map))) {
|
|
LOG_WARN("failed to insert new map", K(ret));
|
|
} else {
|
|
app_ctx_info_encoder_.is_changed_ = true;
|
|
++curr_session_context_size_;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
if (OB_NOT_NULL(new_unit)) {
|
|
new_unit->free(malloc_alloc);
|
|
malloc_alloc.free(new_unit);
|
|
}
|
|
if (OB_NOT_NULL(new_map)) {
|
|
new_map->destroy_map();
|
|
malloc_alloc.free(new_map);
|
|
}
|
|
}
|
|
}
|
|
} else if (OB_ISNULL(inner_map) || OB_ISNULL(inner_map->context_map_)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get correct hash map", K(ret), KP(inner_map));
|
|
} else if (OB_FAIL(inner_map->context_map_->get_refactored(attribute, exist_unit))) {
|
|
if (OB_HASH_NOT_EXIST != ret) {
|
|
LOG_WARN("failed to probe hash map", K(ret));
|
|
} else if (curr_session_context_size_ >= session_context_size) {
|
|
ret = OB_ERR_SESSION_CONTEXT_EXCEEDED;
|
|
LOG_USER_ERROR(OB_ERR_SESSION_CONTEXT_EXCEEDED);
|
|
LOG_WARN("use too much local context in a session", K(session_context_size),
|
|
K(curr_session_context_size_));
|
|
} else {
|
|
ObContextUnit *new_unit = nullptr;
|
|
if (OB_ISNULL(new_unit = static_cast<ObContextUnit *>
|
|
(malloc_alloc.alloc(sizeof(ObContextUnit))))) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("failed to alloc context unit", K(ret));
|
|
} else if (FALSE_IT(new (new_unit) ObContextUnit())) {
|
|
} else if (OB_FAIL(new_unit->deep_copy(attribute, value, malloc_alloc))) {
|
|
LOG_WARN("failed to construst context unit", K(ret));
|
|
} else if (OB_FAIL(inner_map->context_map_->set_refactored(new_unit->attribute_,
|
|
new_unit))) {
|
|
LOG_WARN("failed to insert new unit", K(ret));
|
|
} else {
|
|
app_ctx_info_encoder_.is_changed_ = true;
|
|
++curr_session_context_size_;
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
if (OB_NOT_NULL(new_unit)) {
|
|
new_unit->free(malloc_alloc);
|
|
malloc_alloc.free(new_unit);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
app_ctx_info_encoder_.is_changed_ = true;
|
|
malloc_alloc.free(exist_unit->value_.ptr());
|
|
exist_unit->value_.reset();
|
|
if (OB_FAIL(ob_write_string(malloc_alloc, value, exist_unit->value_))) {
|
|
LOG_WARN("failed to write value", K(ret));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::clear_all_context(const ObString &context_name)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObInnerContextMap *inner_map = nullptr;
|
|
if (OB_FAIL(init_mem_context(get_effective_tenant_id()))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get mem context", K(ret));
|
|
} else if (OB_FAIL(contexts_map_.erase_refactored(context_name, &inner_map))) {
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
ret = OB_SUCCESS;
|
|
} else {
|
|
LOG_WARN("failed to erase namespace", K(ret));
|
|
}
|
|
} else if (OB_ISNULL(inner_map) || OB_ISNULL(inner_map->context_map_)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get correct hash map", K(ret), KP(inner_map));
|
|
} else {
|
|
app_ctx_info_encoder_.is_changed_ = true;
|
|
curr_session_context_size_ -= inner_map->context_map_->size();
|
|
inner_map->destroy();
|
|
mem_context_->get_malloc_allocator().free(inner_map);
|
|
}
|
|
return ret;
|
|
}
|
|
int ObSQLSessionInfo::clear_context(const ObString &context_name,
|
|
const ObString &attribute)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObInnerContextMap *inner_map = nullptr;
|
|
ObContextUnit *ctx_unit = nullptr;
|
|
if (OB_FAIL(init_mem_context(get_effective_tenant_id()))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get mem context", K(ret));
|
|
} else if (OB_FAIL(contexts_map_.get_refactored(context_name, inner_map))) {
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
ret = OB_SUCCESS;
|
|
} else {
|
|
LOG_WARN("failed to erase namespace", K(ret));
|
|
}
|
|
} else if (OB_ISNULL(inner_map) || OB_ISNULL(inner_map->context_map_)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get correct hash map", K(ret), KP(inner_map));
|
|
} else if (OB_FAIL(inner_map->context_map_->erase_refactored(attribute, &ctx_unit))) {
|
|
if (OB_HASH_NOT_EXIST == ret) {
|
|
ret = OB_SUCCESS;
|
|
} else {
|
|
LOG_WARN("failed to erase namespace", K(ret));
|
|
}
|
|
} else {
|
|
app_ctx_info_encoder_.is_changed_ = true;
|
|
--curr_session_context_size_;
|
|
ctx_unit->free(mem_context_->get_malloc_allocator());
|
|
mem_context_->get_malloc_allocator().free(ctx_unit);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObSQLSessionInfo::set_flt_control_info(const FLTControlInfo &con_info)
|
|
{
|
|
bool support_show_trace = flt_control_info_.support_show_trace_;
|
|
flt_control_info_ = con_info;
|
|
flt_control_info_.support_show_trace_ = support_show_trace;
|
|
control_info_encoder_.is_changed_ = true;
|
|
}
|
|
|
|
void ObSQLSessionInfo::set_flt_control_info_no_sync(const FLTControlInfo &con_info)
|
|
{
|
|
bool support_show_trace = flt_control_info_.support_show_trace_;
|
|
flt_control_info_ = con_info;
|
|
flt_control_info_.support_show_trace_ = support_show_trace;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_client_id(const common::ObString &client_identifier)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(ObBasicSessionInfo::set_client_identifier(client_identifier))) {
|
|
LOG_WARN("failed to set client id", K(ret));
|
|
} else {
|
|
client_id_info_encoder_.is_changed_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::save_session(StmtSavedValue &saved_value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OZ (save_basic_session(saved_value));
|
|
OZ (save_sql_session(saved_value));
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::save_sql_session(StmtSavedValue &saved_value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OX (saved_value.audit_record_.assign(audit_record_));
|
|
OX (audit_record_.reset());
|
|
OX (saved_value.inner_flag_ = inner_flag_);
|
|
OX (saved_value.session_type_ = session_type_);
|
|
OX (saved_value.read_uncommited_ = read_uncommited_);
|
|
OX (saved_value.is_ignore_stmt_ = is_ignore_stmt_);
|
|
OX (inner_flag_ = true);
|
|
#ifdef OB_BUILD_SPM
|
|
OX (saved_value.select_plan_type_ = select_plan_type_);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::restore_sql_session(StmtSavedValue &saved_value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OX (session_type_ = saved_value.session_type_);
|
|
OX (inner_flag_ = saved_value.inner_flag_);
|
|
OX (read_uncommited_ = saved_value.read_uncommited_);
|
|
OX (is_ignore_stmt_ = saved_value.is_ignore_stmt_);
|
|
OX (audit_record_.assign(saved_value.audit_record_));
|
|
#ifdef OB_BUILD_SPM
|
|
OX (select_plan_type_ = saved_value.select_plan_type_);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::restore_session(StmtSavedValue &saved_value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OZ (restore_sql_session(saved_value));
|
|
OZ (restore_basic_session(saved_value));
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::begin_nested_session(StmtSavedValue &saved_value, bool skip_cur_stmt_tables)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OV (nested_count_ >= 0, OB_ERR_UNEXPECTED, nested_count_);
|
|
OZ (ObBasicSessionInfo::begin_nested_session(saved_value, skip_cur_stmt_tables));
|
|
OZ (save_sql_session(saved_value));
|
|
OX (nested_count_++);
|
|
LOG_DEBUG("begin_nested_session", K(ret), K_(nested_count));
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::end_nested_session(StmtSavedValue &saved_value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OV (nested_count_ > 0, OB_ERR_UNEXPECTED, nested_count_);
|
|
OX (nested_count_--);
|
|
OZ (restore_sql_session(saved_value));
|
|
OZ (ObBasicSessionInfo::end_nested_session(saved_value));
|
|
OX (saved_value.reset());
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_enable_role_array(const ObIArray<uint64_t> &role_id_array)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ret = enable_role_array_.assign(role_id_array);
|
|
return ret;
|
|
}
|
|
|
|
void ObSQLSessionInfo::ObCachedTenantConfigInfo::refresh()
|
|
{
|
|
int tmp_ret = OB_SUCCESS;
|
|
const uint64_t effective_tenant_id = session_->get_effective_tenant_id();
|
|
int64_t cur_ts = ObClockGenerator::getClock();
|
|
const bool change_tenant = (saved_tenant_info_ != effective_tenant_id);
|
|
if (change_tenant || cur_ts - last_check_ec_ts_ > 5000000) {
|
|
if (change_tenant) {
|
|
LOG_DEBUG("refresh tenant config where tenant changed",
|
|
K_(saved_tenant_info), K(effective_tenant_id));
|
|
ATOMIC_STORE(&saved_tenant_info_, effective_tenant_id);
|
|
}
|
|
// 1.是否支持外部一致性
|
|
is_external_consistent_ = transaction::ObTsMgr::get_instance().is_external_consistent(effective_tenant_id);
|
|
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(effective_tenant_id));
|
|
if (OB_LIKELY(tenant_config.is_valid())) {
|
|
// 2.是否允许 batch_multi_statement
|
|
enable_batched_multi_statement_ = tenant_config->ob_enable_batched_multi_statement;
|
|
// 3.是否允许bloom_filter
|
|
if (tenant_config->_bloom_filter_enabled) {
|
|
enable_bloom_filter_ = true;
|
|
} else {
|
|
enable_bloom_filter_ = false;
|
|
}
|
|
// 4.sort area size
|
|
ATOMIC_STORE(&sort_area_size_, tenant_config->_sort_area_size);
|
|
ATOMIC_STORE(&hash_area_size_, tenant_config->_hash_area_size);
|
|
ATOMIC_STORE(&enable_query_response_time_stats_, tenant_config->query_response_time_stats);
|
|
ATOMIC_STORE(&enable_user_defined_rewrite_rules_, tenant_config->enable_user_defined_rewrite_rules);
|
|
ATOMIC_STORE(&range_optimizer_max_mem_size_, tenant_config->range_optimizer_max_mem_size);
|
|
// 5.allow security audit
|
|
if (OB_SUCCESS != (tmp_ret = ObSecurityAuditUtils::check_allow_audit(*session_, at_type_))) {
|
|
LOG_WARN_RET(tmp_ret, "fail get tenant_config", "ret", tmp_ret,
|
|
K(session_->get_priv_tenant_id()),
|
|
K(effective_tenant_id),
|
|
K(lbt()));
|
|
}
|
|
// 6. enable extended SQL syntax in the MySQL mode
|
|
enable_sql_extension_ = tenant_config->enable_sql_extension;
|
|
px_join_skew_handling_ = tenant_config->_px_join_skew_handling;
|
|
px_join_skew_minfreq_ = tenant_config->_px_join_skew_minfreq;
|
|
enable_column_store_ = tenant_config->_enable_column_store;
|
|
enable_decimal_int_type_ = tenant_config->_enable_decimal_int_type;
|
|
// 7. print_sample_ppm_ for flt
|
|
ATOMIC_STORE(&print_sample_ppm_, tenant_config->_print_sample_ppm);
|
|
}
|
|
ATOMIC_STORE(&last_check_ec_ts_, cur_ts);
|
|
session_->update_tenant_config_version(
|
|
(::oceanbase::omt::ObTenantConfigMgr::get_instance()).get_tenant_config_version(effective_tenant_id));
|
|
}
|
|
UNUSED(tmp_ret);
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_tmp_table_size(uint64_t &size) {
|
|
int ret = OB_SUCCESS;
|
|
const ObBasicSysVar *tmp_table_size = get_sys_var(SYS_VAR_TMP_TABLE_SIZE);
|
|
CK (OB_NOT_NULL(tmp_table_size));
|
|
if (OB_SUCC(ret) &&
|
|
tmp_table_size->get_value().get_uint64() != tmp_table_size->get_max_val().get_uint64()) {
|
|
size = tmp_table_size->get_value().get_uint64();
|
|
} else {
|
|
size = OB_INVALID_SIZE;
|
|
}
|
|
return ret;
|
|
}
|
|
int ObSQLSessionInfo::ps_use_stream_result_set(bool &use_stream) {
|
|
int ret = OB_SUCCESS;
|
|
uint64_t size = 0;
|
|
use_stream = false;
|
|
OZ (get_tmp_table_size(size));
|
|
if (OB_SUCC(ret) && OB_INVALID_SIZE == size) {
|
|
use_stream = true;
|
|
#if !defined(NDEBUG)
|
|
LOG_INFO("cursor use stream result.");
|
|
#endif
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void* ObSQLSessionInfo::get_piece_cache(bool need_init) {
|
|
if (NULL == piece_cache_ && need_init) {
|
|
void *buf = get_session_allocator().alloc(sizeof(observer::ObPieceCache));
|
|
if (NULL != buf) {
|
|
MEMSET(buf, 0, sizeof(observer::ObPieceCache));
|
|
piece_cache_ = new (buf) observer::ObPieceCache();
|
|
if (OB_SUCCESS != (static_cast<observer::ObPieceCache*>(piece_cache_))->init(
|
|
get_effective_tenant_id())) {
|
|
static_cast<observer::ObPieceCache*>(piece_cache_)->~ObPieceCache();
|
|
get_session_allocator().free(piece_cache_);
|
|
piece_cache_ = NULL;
|
|
LOG_WARN_RET(OB_ERR_UNEXPECTED, "init piece cache fail");
|
|
}
|
|
}
|
|
}
|
|
return piece_cache_;
|
|
}
|
|
|
|
|
|
|
|
|
|
int ObSQLSessionInfo::on_user_connect(share::schema::ObSessionPrivInfo &priv_info,
|
|
const ObUserInfo *user_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObConnectResourceMgr *conn_res_mgr = GCTX.conn_res_mgr_;
|
|
if (get_is_deserialized()) {
|
|
// do nothing
|
|
} else if (OB_ISNULL(conn_res_mgr) || OB_ISNULL(user_info)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("connect resource mgr or user info is null", K(ret), K(conn_res_mgr));
|
|
} else {
|
|
const ObPrivSet &priv = priv_info.user_priv_set_;
|
|
const ObString &user_name = priv_info.user_name_;
|
|
const uint64_t tenant_id = priv_info.tenant_id_;
|
|
const uint64_t user_id = priv_info.user_id_;
|
|
uint64_t max_connections_per_hour = user_info->get_max_connections();
|
|
uint64_t max_user_connections = user_info->get_max_user_connections();
|
|
uint64_t max_tenant_connections = 0;
|
|
if (OB_FAIL(get_sys_variable(SYS_VAR_MAX_CONNECTIONS, max_tenant_connections))) {
|
|
LOG_WARN("get system variable SYS_VAR_MAX_CONNECTIONS failed", K(ret));
|
|
} else if (0 == max_user_connections) {
|
|
if (OB_FAIL(get_sys_variable(SYS_VAR_MAX_USER_CONNECTIONS, max_user_connections))) {
|
|
LOG_WARN("get system variable SYS_VAR_MAX_USER_CONNECTIONS failed", K(ret));
|
|
}
|
|
} else {
|
|
ObObj val;
|
|
val.set_uint64(max_user_connections);
|
|
if (OB_FAIL(update_sys_variable(SYS_VAR_MAX_USER_CONNECTIONS, val))) {
|
|
LOG_WARN("set system variable SYS_VAR_MAX_USER_CONNECTIONS failed", K(ret), K(val));
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && OB_FAIL(conn_res_mgr->on_user_connect(
|
|
tenant_id, user_id, priv, user_name,
|
|
max_connections_per_hour,
|
|
max_user_connections,
|
|
max_tenant_connections, *this))) {
|
|
LOG_WARN("create user connection failed", K(ret));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::on_user_disconnect()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObConnectResourceMgr *conn_res_mgr = GCTX.conn_res_mgr_;
|
|
if (OB_ISNULL(conn_res_mgr)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("connect resource mgr is null", K(ret));
|
|
} else if (OB_FAIL(conn_res_mgr->on_user_disconnect(*this))) {
|
|
LOG_WARN("user disconnect failed", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// prepare baseline for the following `calc_txn_free_route` to get the diff
|
|
void ObSQLSessionInfo::prep_txn_free_route_baseline(bool reset_audit)
|
|
{
|
|
#define RESET_TXN_STATE_ENCODER_CHANGED_(x) txn_##x##_info_encoder_.is_changed_ = false
|
|
#define RESET_TXN_STATE_ENCODER_CHANGED(x) RESET_TXN_STATE_ENCODER_CHANGED_(x)
|
|
LST_DO(RESET_TXN_STATE_ENCODER_CHANGED, (;), static, dynamic, participants, extra);
|
|
#undef RESET_TXN_STATE_ENCODER_CHANGED
|
|
#undef RESET_TXN_STATE_ENCODER_CHANGED_
|
|
if (reset_audit) {
|
|
txn_free_route_ctx_.reset_audit_record();
|
|
}
|
|
txn_free_route_ctx_.init_before_handle_request(tx_desc_);
|
|
}
|
|
|
|
void ObSQLSessionInfo::post_sync_session_info()
|
|
{
|
|
if (!get_is_in_retry()) {
|
|
// preapre baseline for the following executing stmt/cmd
|
|
prep_txn_free_route_baseline(false);
|
|
}
|
|
}
|
|
|
|
void ObSQLSessionInfo::set_txn_free_route(bool txn_free_route)
|
|
{
|
|
txn_free_route_ctx_.reset_audit_record();
|
|
txn_free_route_ctx_.init_before_update_state(txn_free_route);
|
|
}
|
|
|
|
bool ObSQLSessionInfo::can_txn_free_route() const
|
|
{
|
|
return txn_free_route_ctx_.can_free_route();
|
|
}
|
|
|
|
int ObSQLSessionInfo::calc_txn_free_route()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (!txn_free_route_ctx_.has_calculated()) {
|
|
OZ (ObSqlTransControl::calc_txn_free_route(*this, txn_free_route_ctx_));
|
|
if (OB_SUCC(ret)) {
|
|
txn_static_info_encoder_.is_changed_ = txn_free_route_ctx_.is_static_changed();
|
|
txn_dynamic_info_encoder_.is_changed_ = txn_free_route_ctx_.is_dynamic_changed();
|
|
txn_participants_info_encoder_.is_changed_ = txn_free_route_ctx_.is_parts_changed();
|
|
txn_extra_info_encoder_.is_changed_ = txn_free_route_ctx_.is_extra_changed();
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObSQLSessionInfo::check_txn_free_route_alive()
|
|
{
|
|
ObSqlTransControl::check_free_route_tx_alive(*this, txn_free_route_ctx_);
|
|
}
|
|
|
|
void ObSQLSessionInfo::reset_tx_variable(bool reset_next_scope)
|
|
{
|
|
ObBasicSessionInfo::reset_tx_variable(reset_next_scope);
|
|
set_early_lock_release(false);
|
|
}
|
|
void ObSQLSessionInfo::destroy_contexts_map(ObContextsMap &map, common::ObIAllocator &alloc)
|
|
{
|
|
for (auto it = map.begin(); it != map.end(); ++it) {
|
|
it->second->destroy();
|
|
alloc.free(it->second);
|
|
}
|
|
}
|
|
|
|
inline int ObSQLSessionInfo::init_mem_context(uint64_t tenant_id)
|
|
{
|
|
int ret = common::OB_SUCCESS;
|
|
if (OB_LIKELY(NULL == mem_context_)) {
|
|
lib::ContextParam param;
|
|
param.set_mem_attr(tenant_id, ObModIds::OB_SQL_SESSION);
|
|
if (OB_FAIL(ROOT_CONTEXT->CREATE_CONTEXT(mem_context_, param))) {
|
|
SQL_ENG_LOG(WARN, "create entity failed", K(ret));
|
|
} else if (OB_ISNULL(mem_context_)) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
SQL_ENG_LOG(WARN, "mem entity is null", K(ret));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ObSQLSessionInfo::has_sess_info_modified() const {
|
|
bool is_changed = false;
|
|
for (int64_t i = 0; !is_changed && i < SESSION_SYNC_MAX_TYPE; i++) {
|
|
is_changed |= sess_encoders_[i]->is_changed_;
|
|
}
|
|
return is_changed;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_module_name(const common::ObString &mod) {
|
|
int ret = OB_SUCCESS;
|
|
MEMSET(module_buf_, 0x00, common::OB_MAX_MOD_NAME_LENGTH);
|
|
MEMCPY(module_buf_, mod.ptr(), min(common::OB_MAX_MOD_NAME_LENGTH, mod.length()));
|
|
client_app_info_.module_name_.assign(&module_buf_[0], min(common::OB_MAX_MOD_NAME_LENGTH, mod.length()));
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_action_name(const common::ObString &act) {
|
|
int ret = OB_SUCCESS;
|
|
MEMSET(action_buf_, 0x00, common::OB_MAX_ACT_NAME_LENGTH);
|
|
MEMCPY(action_buf_, act.ptr(), min(common::OB_MAX_ACT_NAME_LENGTH, act.length()));
|
|
client_app_info_.action_name_.assign(&action_buf_[0], min(common::OB_MAX_ACT_NAME_LENGTH, act.length()));
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_client_info(const common::ObString &client_info) {
|
|
int ret = OB_SUCCESS;
|
|
MEMSET(client_info_buf_, 0x00, common::OB_MAX_CLIENT_INFO_LENGTH);
|
|
MEMCPY(client_info_buf_, client_info.ptr(), min(common::OB_MAX_CLIENT_INFO_LENGTH, client_info.length()));
|
|
client_app_info_.client_info_.assign(&client_info_buf_[0], min(common::OB_MAX_CLIENT_INFO_LENGTH, client_info.length()));
|
|
return ret;
|
|
}
|
|
|
|
|
|
int ObSQLSessionInfo::get_sess_encoder(const SessionSyncInfoType sess_sync_info_type, ObSessInfoEncoder* &encoder)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_UNLIKELY(sess_sync_info_type >= SESSION_SYNC_MAX_TYPE)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid session sync info type", K(ret), K(sess_sync_info_type));
|
|
} else if (OB_ISNULL(sess_encoders_[sess_sync_info_type])) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid session sync info encoder", K(ret), K(sess_sync_info_type));
|
|
} else {
|
|
encoder = sess_encoders_[sess_sync_info_type];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::update_sess_sync_info(const SessionSyncInfoType sess_sync_info_type,
|
|
const char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LOG_TRACE("deserialize encode buf", KPHEX(buf+pos, length-pos), K(length-pos), K(pos));
|
|
if (OB_ISNULL(buf)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid buf", K(ret), K(buf));
|
|
} else if (sess_sync_info_type < 0 || sess_sync_info_type >= SESSION_SYNC_MAX_TYPE) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid session sync info type", K(ret), K(sess_sync_info_type));
|
|
} else if (OB_ISNULL(sess_encoders_[sess_sync_info_type])) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid session sync info encoder", K(ret), K(sess_sync_info_type));
|
|
} else if (OB_FAIL(sess_encoders_[sess_sync_info_type]->deserialize(*this, buf, length, pos))) {
|
|
LOG_WARN("failed to deserialize sess sync info", K(ret), K(sess_sync_info_type), KPHEX(buf, length), K(length), K(pos));
|
|
} else {
|
|
// do nothing
|
|
LOG_DEBUG("get app info", K(client_app_info_.module_name_), K(client_app_info_.action_name_), K(client_app_info_.client_info_));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int ObErrorSyncSysVarEncoder::serialize(ObSQLSessionInfo &sess, char *buf,
|
|
const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSEArray<ObSysVarClassType, ObSysVarFactory::ALL_SYS_VARS_COUNT> sys_var_delta_ids;
|
|
if (OB_FAIL(sess.get_error_sync_sys_vars(sys_var_delta_ids))) {
|
|
LOG_WARN("failed to calc need serialize vars", K(ret));
|
|
} else if (OB_FAIL(sess.serialize_sync_sys_vars(sys_var_delta_ids, buf, length, pos))) {
|
|
LOG_WARN("failed to serialize sys var delta", K(ret), K(sys_var_delta_ids.count()),
|
|
KPHEX(buf+pos, length-pos), K(length-pos), K(pos));
|
|
} else {
|
|
LOG_TRACE("success serialize sys var delta", K(ret), K(sys_var_delta_ids),
|
|
"inc sys var ids", sess.sys_var_inc_info_.get_all_sys_var_ids(),
|
|
K(sess.get_sessid()), K(sess.get_proxy_sessid()));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObErrorSyncSysVarEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf,
|
|
const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t deserialize_sys_var_count = 0;
|
|
if (OB_FAIL(sess.deserialize_sync_error_sys_vars(deserialize_sys_var_count, buf, length, pos))) {
|
|
LOG_WARN("failed to deserialize sys var delta", K(ret), K(deserialize_sys_var_count),
|
|
KPHEX(buf+pos, length-pos), K(length-pos), K(pos));
|
|
} else {
|
|
LOG_DEBUG("success deserialize sys var delta", K(ret), K(deserialize_sys_var_count));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObErrorSyncSysVarEncoder::get_serialize_size(ObSQLSessionInfo& sess, int64_t &len) const {
|
|
int ret = OB_SUCCESS;
|
|
ObSEArray<ObSysVarClassType, ObSysVarFactory::ALL_SYS_VARS_COUNT> sys_var_delta_ids;
|
|
if (OB_FAIL(sess.get_error_sync_sys_vars(sys_var_delta_ids))) {
|
|
LOG_WARN("failed to calc need serialize vars", K(ret));
|
|
} else if (OB_FAIL(sess.get_sync_sys_vars_size(sys_var_delta_ids, len))) {
|
|
LOG_WARN("failed to serialize size sys var delta", K(ret));
|
|
} else {
|
|
LOG_DEBUG("success serialize size sys var delta", K(ret), K(sys_var_delta_ids.count()), K(len));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObErrorSyncSysVarEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
for (int64_t j = 0; OB_SUCC(ret) && j< share::ObSysVarFactory::ALL_SYS_VARS_COUNT; ++j) {
|
|
if (ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_LAST_SCHEMA_VERSION) {
|
|
//need sync sys var
|
|
if (OB_FAIL(sess.get_sys_var(j)->serialize(buf, length, pos))) {
|
|
LOG_WARN("failed to serialize", K(length), K(ret));
|
|
}
|
|
} else {
|
|
// do nothing.
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObErrorSyncSysVarEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t size = 0;
|
|
for (int64_t j = 0; j< share::ObSysVarFactory::ALL_SYS_VARS_COUNT; ++j) {
|
|
if (ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_LAST_SCHEMA_VERSION) {
|
|
// need sync sys var
|
|
size += sess.get_sys_var(j)->get_serialize_size();
|
|
} else {
|
|
// do nothing.
|
|
}
|
|
}
|
|
return size;
|
|
}
|
|
|
|
int ObErrorSyncSysVarEncoder::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length,
|
|
const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (current_sess_length != last_sess_length) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare session info", K(ret), K(current_sess_length), K(last_sess_length),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
} else if (memcmp(current_sess_buf, last_sess_buf, current_sess_length) == 0) {
|
|
LOG_TRACE("success to compare session info", K(ret));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare buf session info", K(ret),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObErrorSyncSysVarEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf,
|
|
int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
int64_t pos = 0;
|
|
const char *buf = last_sess_buf;
|
|
int64_t data_len = last_sess_length;
|
|
common::ObArenaAllocator allocator(common::ObModIds::OB_SQL_SESSION,
|
|
OB_MALLOC_NORMAL_BLOCK_SIZE,
|
|
sess.get_effective_tenant_id());
|
|
|
|
ObBasicSysVar *last_sess_sys_vars = NULL;
|
|
for (int64_t j = 0; OB_SUCC(ret) && j< share::ObSysVarFactory::ALL_SYS_VARS_COUNT; ++j) {
|
|
if (ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_LAST_SCHEMA_VERSION) {
|
|
if (OB_FAIL(ObSessInfoVerify::create_tmp_sys_var(sess, ObSysVariables::get_sys_var_id(j),
|
|
last_sess_sys_vars, allocator))) {
|
|
LOG_WARN("fail to create sys var", K(ret));
|
|
} else if (OB_FAIL(last_sess_sys_vars->deserialize(buf, data_len, pos))) {
|
|
LOG_WARN("failed to deserialize", K(ret), K(data_len), K(pos));
|
|
} else if (!sess.get_sys_var(j)->get_value().can_compare(
|
|
last_sess_sys_vars->get_value())) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify sys vars", K(j), K(ret),
|
|
"current_sess_sys_vars", sess.get_sys_var(j)->get_value(),
|
|
"last_sess_sys_vars", last_sess_sys_vars->get_value());
|
|
} else if (sess.get_sys_var(j)->get_value() != last_sess_sys_vars->get_value()) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify sys vars", K(j), K(ret),
|
|
"current_sess_sys_vars", sess.get_sys_var(j)->get_value(),
|
|
"last_sess_sys_vars", last_sess_sys_vars->get_value());
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_mem_ctx_alloc(common::ObIAllocator *&alloc)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(init_mem_context(get_effective_tenant_id()))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("failed to get mem context", K(ret));
|
|
} else {
|
|
alloc = &mem_context_->get_malloc_allocator();
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSysVarEncoder::serialize(ObSQLSessionInfo &sess, char *buf,
|
|
const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSEArray<ObSysVarClassType, ObSysVarFactory::ALL_SYS_VARS_COUNT> sys_var_delta_ids;
|
|
if (OB_FAIL(sess.get_sync_sys_vars(sys_var_delta_ids))) {
|
|
LOG_WARN("failed to calc need serialize vars", K(ret));
|
|
} else if (OB_FAIL(sess.serialize_sync_sys_vars(sys_var_delta_ids, buf, length, pos))) {
|
|
LOG_WARN("failed to serialize sys var delta", K(ret), K(sys_var_delta_ids.count()),
|
|
KPHEX(buf+pos, length-pos), K(length-pos), K(pos));
|
|
} else {
|
|
LOG_TRACE("success serialize sys var delta", K(ret), K(sys_var_delta_ids),
|
|
"inc sys var ids", sess.sys_var_inc_info_.get_all_sys_var_ids(),
|
|
K(sess.get_sessid()), K(sess.get_proxy_sessid()));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSysVarEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf,
|
|
const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t deserialize_sys_var_count = 0;
|
|
if (OB_FAIL(sess.deserialize_sync_sys_vars(deserialize_sys_var_count, buf, length, pos))) {
|
|
LOG_WARN("failed to deserialize sys var delta", K(ret), K(deserialize_sys_var_count),
|
|
KPHEX(buf+pos, length-pos), K(length-pos), K(pos));
|
|
} else {
|
|
LOG_DEBUG("success deserialize sys var delta", K(ret), K(deserialize_sys_var_count));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSysVarEncoder::get_serialize_size(ObSQLSessionInfo& sess, int64_t &len) const {
|
|
int ret = OB_SUCCESS;
|
|
ObSEArray<ObSysVarClassType, ObSysVarFactory::ALL_SYS_VARS_COUNT> sys_var_delta_ids;
|
|
if (OB_FAIL(sess.get_sync_sys_vars(sys_var_delta_ids))) {
|
|
LOG_WARN("failed to calc need serialize vars", K(ret));
|
|
} else if (OB_FAIL(sess.get_sync_sys_vars_size(sys_var_delta_ids, len))) {
|
|
LOG_WARN("failed to serialize size sys var delta", K(ret));
|
|
} else {
|
|
LOG_DEBUG("success serialize size sys var delta", K(ret), K(sys_var_delta_ids.count()), K(len));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSysVarEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(sess.get_sys_var_cache_inc_data().serialize(buf, length, pos))) {
|
|
LOG_WARN("failed to serialize", K(length), K(ret));
|
|
} else if (OB_FAIL(sess.get_sys_var_in_pc_str().serialize(buf, length, pos))) {
|
|
LOG_WARN("failed to serialize", K(ret), K(length), K(pos));
|
|
} else {
|
|
for (int64_t j = 0; OB_SUCC(ret) && j< share::ObSysVarFactory::ALL_SYS_VARS_COUNT; ++j) {
|
|
if (ObSysVariables::get_sys_var_id(j) == SYS_VAR_SERVER_UUID ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_PROXY_PARTITION_HIT ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_STATEMENT_TRACE_ID ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_VERSION_COMMENT ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR__OB_PROXY_WEAKREAD_FEEDBACK ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_SYSTEM_TIME_ZONE) {
|
|
// no need sync sys var
|
|
continue;
|
|
}
|
|
if (OB_FAIL(sess.get_sys_var(j)->serialize(buf, length, pos))) {
|
|
LOG_WARN("failed to serialize", K(length), K(ret));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObSysVarEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t size = 0;
|
|
size = sess.get_sys_var_cache_inc_data().get_serialize_size();
|
|
size += sess.get_sys_var_in_pc_str().get_serialize_size();
|
|
for (int64_t j = 0; j< share::ObSysVarFactory::ALL_SYS_VARS_COUNT; ++j) {
|
|
if (ObSysVariables::get_sys_var_id(j) == SYS_VAR_SERVER_UUID ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_PROXY_PARTITION_HIT ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_STATEMENT_TRACE_ID ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_VERSION_COMMENT ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR__OB_PROXY_WEAKREAD_FEEDBACK ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_SYSTEM_TIME_ZONE) {
|
|
// no need sync sys var
|
|
continue;
|
|
}
|
|
size += sess.get_sys_var(j)->get_serialize_size();
|
|
}
|
|
return size;
|
|
}
|
|
|
|
int ObSysVarEncoder::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length,
|
|
const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (current_sess_length != last_sess_length) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare session info", K(ret), K(current_sess_length), K(last_sess_length),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
} else if (memcmp(current_sess_buf, last_sess_buf, current_sess_length) == 0) {
|
|
LOG_TRACE("success to compare session info", K(ret));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare buf session info", K(ret),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSysVarEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf,
|
|
int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
int64_t pos = 0;
|
|
const char *buf = last_sess_buf;
|
|
int64_t data_len = last_sess_length;
|
|
common::ObArenaAllocator allocator(common::ObModIds::OB_SQL_SESSION,
|
|
OB_MALLOC_NORMAL_BLOCK_SIZE,
|
|
sess.get_effective_tenant_id());
|
|
ObBasicSessionInfo::SysVarsCacheData last_sess_sys_var_cache_data;
|
|
ObString last_sess_sys_var_in_pc_str;
|
|
bool is_error = false; // judging the error location
|
|
if (OB_FAIL(last_sess_sys_var_cache_data.deserialize(buf, data_len, pos))) {
|
|
LOG_WARN("failed to deserialize", K(ret), K(data_len), K(pos));
|
|
} else if (OB_FAIL(last_sess_sys_var_in_pc_str.deserialize(buf, data_len, pos))) {
|
|
LOG_WARN("failed to deserialize", K(ret), K(data_len), K(pos));
|
|
} else {
|
|
ObBasicSysVar *last_sess_sys_vars = NULL;
|
|
for (int64_t j = 0; OB_SUCC(ret) && j< share::ObSysVarFactory::ALL_SYS_VARS_COUNT; ++j) {
|
|
if (ObSysVariables::get_sys_var_id(j) == SYS_VAR_SERVER_UUID ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_PROXY_PARTITION_HIT ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_OB_STATEMENT_TRACE_ID ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_VERSION_COMMENT ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR__OB_PROXY_WEAKREAD_FEEDBACK ||
|
|
ObSysVariables::get_sys_var_id(j) == SYS_VAR_SYSTEM_TIME_ZONE) {
|
|
// no need sync sys var
|
|
continue;
|
|
}
|
|
if (OB_FAIL(ObSessInfoVerify::create_tmp_sys_var(sess, ObSysVariables::get_sys_var_id(j),
|
|
last_sess_sys_vars, allocator))) {
|
|
LOG_WARN("fail to create sys var", K(ret));
|
|
} else if (OB_FAIL(last_sess_sys_vars->deserialize(buf, data_len, pos))) {
|
|
LOG_WARN("failed to deserialize", K(ret), K(data_len), K(pos));
|
|
} else if (!sess.get_sys_var(j)->get_value().can_compare(
|
|
last_sess_sys_vars->get_value())) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify sys vars", K(j), K(ret),
|
|
"current_sess_sys_vars", sess.get_sys_var(j)->get_value(),
|
|
"last_sess_sys_vars", last_sess_sys_vars->get_value());
|
|
is_error = true;
|
|
} else if (sess.get_sys_var(j)->get_value() != last_sess_sys_vars->get_value()) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify sys vars", K(j), K(ret),
|
|
"current_sess_sys_vars", sess.get_sys_var(j)->get_value(),
|
|
"last_sess_sys_vars", last_sess_sys_vars->get_value());
|
|
is_error = true;
|
|
} else {
|
|
// do nothing
|
|
}
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
|
|
} else if (sess.get_sys_var_in_pc_str() != last_sess_sys_var_in_pc_str) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify sys var in pc str", K(ret), "current_sess_sys_var_in_pc_str",
|
|
sess.get_sys_var_in_pc_str(),
|
|
"last_sess_sys_var_in_pc_str", last_sess_sys_var_in_pc_str);
|
|
} else if (!is_error) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify sys vars cache inc data", K(ret),
|
|
"current_sess_sys_var_cache_data", sess.get_sys_var_cache_inc_data(),
|
|
"last_sess_sys_var_cache_data", last_sess_sys_var_cache_data);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ObSQLSessionInfo::gen_gtt_session_scope_unique_id()
|
|
{
|
|
static int64_t cur_ts = 0;
|
|
int64_t next_ts = ObSQLUtils::combine_server_id(ObSQLUtils::get_next_ts(cur_ts), GCTX.server_id_);
|
|
gtt_session_scope_unique_id_ = next_ts;
|
|
LOG_DEBUG("check temporary table ssid session scope", K(next_ts), K(get_sessid_for_table()), K(GCTX.server_id_), K(lbt()));
|
|
}
|
|
|
|
void ObSQLSessionInfo::gen_gtt_trans_scope_unique_id()
|
|
{
|
|
static int64_t cur_ts = 0;
|
|
int64_t next_ts = ObSQLUtils::combine_server_id(ObSQLUtils::get_next_ts(cur_ts), GCTX.server_id_);
|
|
gtt_trans_scope_unique_id_ = next_ts;
|
|
LOG_DEBUG("check temporary table ssid trans scope", K(next_ts), K(get_sessid_for_table()), K(GCTX.server_id_), K(lbt()));
|
|
}
|
|
|
|
int ObAppInfoEncoder::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t org_pos = pos;
|
|
if (OB_FAIL(sess.get_client_app_info().serialize(buf, length, pos))) {
|
|
LOG_WARN("failed to serialize application info.", K(ret), K(pos), K(length));
|
|
} else {
|
|
LOG_DEBUG("serialize encode buf", KPHEX(buf+org_pos, pos-org_pos), K(pos-org_pos));
|
|
LOG_DEBUG("serialize buf", KPHEX(buf, pos));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppInfoEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LOG_TRACE("app info buf", KPHEX(buf, length), K(pos), K(length), KPHEX(buf+pos, length-pos));
|
|
sess.get_client_app_info().reset();
|
|
ObSQLSessionInfo::ApplicationInfo app_info;
|
|
if (OB_FAIL(app_info.deserialize(buf, length, pos))) {
|
|
LOG_WARN("failed to deserialize application info.", K(ret), K(pos), K(length));
|
|
} else if (OB_FAIL(sess.set_client_info(app_info.client_info_))) {
|
|
LOG_WARN("failed to set client info", K(ret));
|
|
} else if (OB_FAIL(sess.set_action_name(app_info.action_name_))) {
|
|
LOG_WARN("failed to set action name", K(ret));
|
|
} else if (OB_FAIL(sess.set_module_name(app_info.module_name_))) {
|
|
LOG_WARN("failed to set module name", K(ret));
|
|
} else {
|
|
LOG_TRACE("get encoder app info", K(sess.get_client_app_info().module_name_),
|
|
K(sess.get_client_app_info().action_name_),
|
|
K(sess.get_client_app_info().client_info_));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppInfoEncoder::get_serialize_size(ObSQLSessionInfo& sess, int64_t &len) const {
|
|
int ret = OB_SUCCESS;
|
|
len = sess.get_client_app_info().get_serialize_size();
|
|
return ret;
|
|
}
|
|
|
|
int ObAppInfoEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(serialize(sess, buf, length, pos))) {
|
|
LOG_WARN("failed to fetch session info.", K(ret), K(pos), K(length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObAppInfoEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t len = 0;
|
|
get_serialize_size(sess, len);
|
|
return len;
|
|
}
|
|
|
|
int ObAppInfoEncoder::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length,
|
|
const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (current_sess_length != last_sess_length) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare session info", K(ret), K(current_sess_length), K(last_sess_length),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
} else if (memcmp(current_sess_buf, last_sess_buf, current_sess_length) == 0) {
|
|
LOG_TRACE("success to compare session info", K(ret));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare buf session info", K(ret),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppInfoEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf,
|
|
int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t pos = 0;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
ObSQLSessionInfo::ApplicationInfo last_sess_app_info;
|
|
if (OB_FAIL(last_sess_app_info.deserialize(last_sess_buf, last_sess_length, pos))) {
|
|
LOG_WARN("failed to deserialize application info.", K(ret), K(pos), K(last_sess_length));
|
|
} else if (sess.get_client_info() != last_sess_app_info.client_info_) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify client info", K(ret),
|
|
"current_sess_app_info.client_info_", sess.get_client_info(),
|
|
"last_sess_app_info.client_info_", last_sess_app_info.client_info_);
|
|
} else if (sess.get_action_name() != last_sess_app_info.action_name_) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify action name", K(ret),
|
|
"current_sess_app_info.action_name_", sess.get_action_name(),
|
|
"last_sess_app_info.action_name_", last_sess_app_info.action_name_);
|
|
} else if (sess.get_module_name() != last_sess_app_info.module_name_) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify module name", K(ret),
|
|
"current_sess_app_info.module_name_", sess.get_module_name(),
|
|
"last_sess_app_info.module_name_", last_sess_app_info.module_name_);
|
|
} else {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_INFO("success to verify app info",
|
|
"current_sess_app_info client info", sess.get_client_info(),
|
|
"last_sess_app_info client info", last_sess_app_info.client_info_,
|
|
"current_sess_app_info action name", sess.get_action_name(),
|
|
"last_sess_app_info action name", last_sess_app_info.action_name_,
|
|
"current_sess_app_info module name", sess.get_module_name(),
|
|
"last_sess_app_info module name", last_sess_app_info.module_name_);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppInfoEncoder::set_client_info(ObSQLSessionInfo* sess, const ObString &client_info)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_ISNULL(sess)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("sess is NULL", K(ret));
|
|
} else if (OB_FAIL(sess->set_client_info(client_info))) {
|
|
LOG_WARN("failed to set client info", K(ret));
|
|
} else {
|
|
this->is_changed_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppInfoEncoder::set_module_name(ObSQLSessionInfo* sess, const ObString &mod)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_ISNULL(sess)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("sess is NULL", K(ret));
|
|
} else if (OB_FAIL(sess->set_module_name(mod))) {
|
|
LOG_WARN("failed to set module name", K(ret));
|
|
} else {
|
|
this->is_changed_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppInfoEncoder::set_action_name(ObSQLSessionInfo* sess, const ObString &act)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_ISNULL(sess)) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("sess is NULL", K(ret));
|
|
} else if (OB_FAIL(sess->set_action_name(act))) {
|
|
LOG_WARN("failed to set action name", K(ret));
|
|
} else {
|
|
this->is_changed_ = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObClientIdInfoEncoder::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t buf_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LST_DO_CODE(OB_UNIS_ENCODE, sess.get_client_identifier());
|
|
return ret;
|
|
}
|
|
int ObClientIdInfoEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf, const int64_t data_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(sess.init_client_identifier())) {
|
|
LOG_WARN("failed to init client identifier", K(ret));
|
|
} else {
|
|
LST_DO_CODE(OB_UNIS_DECODE, sess.get_client_identifier_for_update());
|
|
}
|
|
return ret;
|
|
}
|
|
int ObClientIdInfoEncoder::get_serialize_size(ObSQLSessionInfo& sess, int64_t &len) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OB_UNIS_ADD_LEN(sess.get_client_identifier());
|
|
return ret;
|
|
}
|
|
|
|
int ObClientIdInfoEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(serialize(sess, buf, length, pos))) {
|
|
LOG_WARN("failed to fetch session info.", K(ret), K(pos), K(length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObClientIdInfoEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t len = 0;
|
|
get_serialize_size(sess, len);
|
|
return len;
|
|
}
|
|
|
|
int ObClientIdInfoEncoder::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length,
|
|
const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (current_sess_length != last_sess_length) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare session info", K(ret), K(current_sess_length), K(last_sess_length),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
} else if (memcmp(current_sess_buf, last_sess_buf, current_sess_length) == 0) {
|
|
LOG_TRACE("success to compare session info", K(ret));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare buf session info", K(ret),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObClientIdInfoEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf,
|
|
int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
common::ObString last_sess_client_identifier;
|
|
const char *buf = last_sess_buf;
|
|
int64_t pos = 0;
|
|
int64_t data_len = last_sess_length;
|
|
LST_DO_CODE(OB_UNIS_DECODE, last_sess_client_identifier);
|
|
if (sess.get_client_identifier() != last_sess_client_identifier) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify client_identifier", K(ret),
|
|
"current_sess_client_identifier", sess.get_client_identifier(),
|
|
"last_sess_client_identifier", last_sess_client_identifier);
|
|
} else {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_INFO("success to verify clientid info",
|
|
"current_sess_client_identifier", sess.get_client_identifier(),
|
|
"last_sess_client_identifier", last_sess_client_identifier);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ObAppCtxInfoEncoder::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t buf_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObContextsMap &map = sess.get_contexts_map();
|
|
OB_UNIS_ENCODE(map.size());
|
|
int64_t count = 0;
|
|
for (auto it = map.begin(); OB_SUCC(ret) && it != map.end(); ++it, ++count) {
|
|
OB_UNIS_ENCODE(*it->second);
|
|
}
|
|
CK (count == map.size());
|
|
return ret;
|
|
}
|
|
int ObAppCtxInfoEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf, const int64_t data_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t map_size = 0;
|
|
OB_UNIS_DECODE(map_size);
|
|
ObIAllocator *alloc = nullptr;
|
|
OZ (sess.get_mem_ctx_alloc(alloc));
|
|
CK (OB_NOT_NULL(alloc));
|
|
OX (sess.reuse_context_map());
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < map_size; ++i) {
|
|
ObInnerContextMap *inner_map = nullptr;
|
|
if (OB_ISNULL(inner_map = static_cast<ObInnerContextMap *> (alloc->alloc(sizeof(ObInnerContextMap))))) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("failed to alloc inner context map", K(ret));
|
|
} else {
|
|
new (inner_map) ObInnerContextMap(*alloc);
|
|
OB_UNIS_DECODE(*inner_map);
|
|
OZ (sess.get_contexts_map().set_refactored(inner_map->context_name_, inner_map));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int ObAppCtxInfoEncoder::get_serialize_size(ObSQLSessionInfo& sess, int64_t &len) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObContextsMap &map = sess.get_contexts_map();
|
|
OB_UNIS_ADD_LEN(map.size());
|
|
for (auto it = map.begin(); it != map.end(); ++it) {
|
|
OB_UNIS_ADD_LEN(*it->second);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppCtxInfoEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(serialize(sess, buf, length, pos))) {
|
|
LOG_WARN("failed to fetch session info.", K(ret), K(pos), K(length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObAppCtxInfoEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t len = 0;
|
|
get_serialize_size(sess, len);
|
|
return len;
|
|
}
|
|
|
|
int ObAppCtxInfoEncoder::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length,
|
|
const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (current_sess_length != last_sess_length) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare session info", K(ret), K(current_sess_length), K(last_sess_length),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
} else if (memcmp(current_sess_buf, last_sess_buf, current_sess_length) == 0) {
|
|
LOG_TRACE("success to compare session info", K(ret));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare buf session info", K(ret),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObAppCtxInfoEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf,
|
|
int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
const char *buf = last_sess_buf;
|
|
int64_t pos = 0;
|
|
int64_t data_len = last_sess_length;
|
|
int64_t map_size = 0;
|
|
common::ObArenaAllocator allocator(common::ObModIds::OB_SQL_SESSION,
|
|
OB_MALLOC_NORMAL_BLOCK_SIZE,
|
|
sess.get_effective_tenant_id());
|
|
ObContextsMap &map = sess.get_contexts_map();
|
|
OB_UNIS_DECODE(map_size);
|
|
if (map_size != sess.get_contexts_map().size()) {
|
|
LOG_WARN("failed to verify app ctx info", K(ret), "current_map_size", map_size,
|
|
"last_map_size", sess.get_contexts_map().size());
|
|
} else {
|
|
auto it = map.begin();
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < map_size && it != map.end(); ++i, ++it) {
|
|
ObInnerContextMap *last_inner_map = nullptr;
|
|
if (OB_ISNULL(last_inner_map = static_cast<ObInnerContextMap *>
|
|
(allocator.alloc(sizeof(ObInnerContextMap))))) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("failed to alloc inner context map", K(ret));
|
|
} else {
|
|
new (last_inner_map) ObInnerContextMap(allocator);
|
|
OB_UNIS_DECODE(*last_inner_map);
|
|
if (*last_inner_map == *it->second) {
|
|
// do nothing
|
|
} else {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify app ctx info", K(ret),
|
|
"current_inner_map", it->second,
|
|
"last_inner_map", last_inner_map);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (OB_FAIL(ret)) {
|
|
} else {
|
|
LOG_TRACE("success to verify app ctx info", K(ret));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ObSequenceCurrvalEncoder::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t buf_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
//serialize currval map
|
|
ObSequenceCurrvalMap &map = sess.get_sequence_currval_map();
|
|
OB_UNIS_ENCODE(map.size());
|
|
int64_t count = 0;
|
|
for (auto it = map.begin(); OB_SUCC(ret) && it != map.end(); ++it, ++count) {
|
|
OB_UNIS_ENCODE(it->first);
|
|
OB_UNIS_ENCODE(it->second);
|
|
}
|
|
CK (count == map.size());
|
|
OB_UNIS_ENCODE(sess.get_current_dblink_sequence_id());
|
|
//serialize dblink sequence id map
|
|
ObDBlinkSequenceIdMap &id_map = sess.get_dblink_sequence_id_map();
|
|
OB_UNIS_ENCODE(id_map.size());
|
|
count = 0;
|
|
for (auto it = id_map.begin(); OB_SUCC(ret) && it != id_map.end(); ++it, ++count) {
|
|
OB_UNIS_ENCODE(it->first.sequence_name_);
|
|
OB_UNIS_ENCODE(it->first.dblink_id_);
|
|
OB_UNIS_ENCODE(it->second);
|
|
}
|
|
CK (count == id_map.size());
|
|
return ret;
|
|
}
|
|
|
|
int ObSequenceCurrvalEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf, const int64_t data_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t map_size = 0;
|
|
int64_t current_id = 0;
|
|
//deserialize currval map
|
|
OB_UNIS_DECODE(map_size);
|
|
ObSequenceCurrvalMap &map = sess.get_sequence_currval_map();
|
|
OX (sess.reuse_all_sequence_value());
|
|
uint64_t seq_id = 0;
|
|
ObSequenceValue seq_val;
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < map_size; ++i) {
|
|
OB_UNIS_DECODE(seq_id);
|
|
OB_UNIS_DECODE(seq_val);
|
|
OZ (map.set_refactored(seq_id, seq_val, true /*overwrite_exits*/));
|
|
}
|
|
OB_UNIS_DECODE(current_id);
|
|
sess.set_current_dblink_sequence_id(current_id);
|
|
//deserialize dblink seuqnce id map
|
|
OB_UNIS_DECODE(map_size);
|
|
ObDBlinkSequenceIdMap &id_map = sess.get_dblink_sequence_id_map();
|
|
ObDBlinkSequenceIdKey key;
|
|
seq_id = 0;
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < map_size; ++i) {
|
|
OB_UNIS_DECODE(key.sequence_name_);
|
|
OB_UNIS_DECODE(key.dblink_id_);
|
|
OB_UNIS_DECODE(seq_id);
|
|
OZ (id_map.set_refactored(key, seq_id, true /*overwrite_exits*/));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSequenceCurrvalEncoder::get_serialize_size(ObSQLSessionInfo& sess, int64_t &len) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSequenceCurrvalMap &map = sess.get_sequence_currval_map();
|
|
OB_UNIS_ADD_LEN(map.size());
|
|
for (auto it = map.begin(); it != map.end(); ++it) {
|
|
OB_UNIS_ADD_LEN(it->first);
|
|
OB_UNIS_ADD_LEN(it->second);
|
|
}
|
|
OB_UNIS_ADD_LEN(sess.get_current_dblink_sequence_id());
|
|
ObDBlinkSequenceIdMap &id_map = sess.get_dblink_sequence_id_map();
|
|
OB_UNIS_ADD_LEN(id_map.size());
|
|
for (auto it = id_map.begin(); it != id_map.end(); ++it) {
|
|
OB_UNIS_ADD_LEN(it->first.sequence_name_);
|
|
OB_UNIS_ADD_LEN(it->first.dblink_id_);
|
|
OB_UNIS_ADD_LEN(it->second);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSequenceCurrvalEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf,
|
|
const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(serialize(sess, buf, length, pos))) {
|
|
LOG_WARN("failed to fetch session info.", K(ret), K(pos), K(length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObSequenceCurrvalEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t len = 0;
|
|
get_serialize_size(sess, len);
|
|
return len;
|
|
}
|
|
|
|
int ObSequenceCurrvalEncoder::compare_sess_info(const char* current_sess_buf,
|
|
int64_t current_sess_length,
|
|
const char* last_sess_buf,
|
|
int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (current_sess_length != last_sess_length) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare session info", K(ret), K(current_sess_length), K(last_sess_length),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
} else if (memcmp(current_sess_buf, last_sess_buf, current_sess_length) == 0) {
|
|
LOG_TRACE("success to compare session info", K(ret));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare buf session info", K(ret),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSequenceCurrvalEncoder::display_sess_info(ObSQLSessionInfo &sess,
|
|
const char* current_sess_buf,
|
|
int64_t current_sess_length,
|
|
const char* last_sess_buf,
|
|
int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
const char *buf = last_sess_buf;
|
|
int64_t pos = 0;
|
|
int64_t data_len = last_sess_length;
|
|
int64_t map_size = 0;
|
|
int64_t current_id = 0;
|
|
bool found_mismatch = false;
|
|
OB_UNIS_DECODE(map_size);
|
|
ObSequenceCurrvalMap &map = sess.get_sequence_currval_map();
|
|
if (map_size != map.size()) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("Sequence currval map size mismatch", K(ret), "current_map_size", map.size(),
|
|
"last_map_size", map_size);
|
|
} else {
|
|
uint64_t seq_id = 0;
|
|
ObSequenceValue seq_val_decode;
|
|
ObSequenceValue seq_val_origin;
|
|
for (int64_t i = 0; OB_SUCC(ret) && !found_mismatch && i < map_size; ++i) {
|
|
OB_UNIS_DECODE(seq_id);
|
|
OB_UNIS_DECODE(seq_val_decode);
|
|
if (OB_SUCC(ret)) {
|
|
if (OB_FAIL(map.get_refactored(seq_id, seq_val_origin))) {
|
|
if (ret == OB_HASH_NOT_EXIST) {
|
|
found_mismatch = true;
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("Decoded sequence id not found", K(ret), K(i), K(map_size), K(seq_id));
|
|
ret = OB_SUCCESS;
|
|
} else {
|
|
LOG_WARN("Fail to get refactored from map", K(ret), K(seq_id));
|
|
}
|
|
} else if (seq_val_decode.val() != seq_val_origin.val()) {
|
|
found_mismatch = true;
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("Sequence currval mismatch", K(ret), K(i), K(map_size), K(seq_id),
|
|
"current_seq_val", seq_val_origin, "last_seq_val", seq_val_decode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
OB_UNIS_DECODE(current_id);
|
|
if (current_id != sess.get_current_dblink_sequence_id()) {
|
|
found_mismatch = true;
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("current dblink sequence id mismatch",
|
|
"current_seq_id", current_id, "last_seq_id", sess.get_current_dblink_sequence_id());
|
|
}
|
|
OB_UNIS_DECODE(map_size);
|
|
ObDBlinkSequenceIdMap &id_map = sess.get_dblink_sequence_id_map();
|
|
if (map_size != id_map.size()) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("Sequence id map size mismatch", K(ret), "current_map_size", id_map.size(),
|
|
"last_map_size", map_size);
|
|
} else {
|
|
ObDBlinkSequenceIdKey key;
|
|
uint64_t seq_id_decode = 0;
|
|
uint64_t seq_id_origin = 0;
|
|
for (int64_t i = 0; OB_SUCC(ret) && !found_mismatch && i < map_size; ++i) {
|
|
OB_UNIS_DECODE(key.sequence_name_);
|
|
OB_UNIS_DECODE(key.dblink_id_);
|
|
OB_UNIS_DECODE(seq_id_decode);
|
|
if (OB_SUCC(ret)) {
|
|
if (OB_FAIL(id_map.get_refactored(key, seq_id_origin))) {
|
|
if (ret == OB_HASH_NOT_EXIST) {
|
|
found_mismatch = true;
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("Decoded sequence id not found", K(ret), K(i), K(map_size), K(seq_id_decode));
|
|
ret = OB_SUCCESS;
|
|
} else {
|
|
LOG_WARN("Fail to get refactored from map", K(ret), K(seq_id_decode));
|
|
}
|
|
} else if (seq_id_decode != seq_id_origin) {
|
|
found_mismatch = true;
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("Sequence id mismatch", K(ret), K(i), K(map_size),
|
|
"current_seq_id", seq_id_decode, "last_seq_id", seq_id_origin);
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && !found_mismatch) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("All sequence currval is matched", K(ret), K(map_size));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObQueryInfoEncoder::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t buf_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OB_UNIS_ENCODE(sess.get_affected_rows());
|
|
return ret;
|
|
}
|
|
|
|
int ObQueryInfoEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf, const int64_t data_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t affected_rows = 0;
|
|
int64_t found_rows = 0;
|
|
OB_UNIS_DECODE(affected_rows);
|
|
sess.set_affected_rows(affected_rows);
|
|
return ret;
|
|
}
|
|
|
|
int ObQueryInfoEncoder::get_serialize_size(ObSQLSessionInfo &sess, int64_t &len) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
OB_UNIS_ADD_LEN(sess.get_affected_rows());
|
|
return ret;
|
|
}
|
|
|
|
int ObQueryInfoEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(serialize(sess, buf, length, pos))) {
|
|
LOG_WARN("failed to fetch session info.", K(ret), K(pos), K(length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObQueryInfoEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t len = 0;
|
|
get_serialize_size(sess, len);
|
|
return len;
|
|
}
|
|
|
|
int ObQueryInfoEncoder::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length,
|
|
const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (current_sess_length != last_sess_length) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare session info", K(ret), K(current_sess_length), K(last_sess_length),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
} else if (memcmp(current_sess_buf, last_sess_buf, current_sess_length) == 0) {
|
|
LOG_TRACE("success to compare session info", K(ret));
|
|
} else {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("fail to compare buf session info", K(ret),
|
|
KPHEX(current_sess_buf, current_sess_length), KPHEX(last_sess_buf, last_sess_length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObQueryInfoEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf,
|
|
int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
int64_t pos = 0;
|
|
const char *buf = last_sess_buf;
|
|
int64_t data_len = last_sess_length;
|
|
int64_t affected_rows = 0;
|
|
|
|
LST_DO_CODE(OB_UNIS_DECODE, affected_rows);
|
|
if (sess.get_affected_rows() != affected_rows) {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_WARN("failed to verify affected_rows", K(ret),
|
|
"current_affected_rows", sess.get_affected_rows(),
|
|
"last_affected_rows", affected_rows);
|
|
} else {
|
|
share::ObTaskController::get().allow_next_syslog();
|
|
LOG_INFO("success to verify VariousInfo", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
OB_DEF_SERIALIZE(ObInnerContextMap)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
CK (OB_NOT_NULL(context_map_));
|
|
OB_UNIS_ENCODE(context_name_);
|
|
OB_UNIS_ENCODE(context_map_->size());
|
|
for (auto it = context_map_->begin(); OB_SUCC(ret) && it != context_map_->end(); ++it) {
|
|
OB_UNIS_ENCODE(*it->second);
|
|
}
|
|
return ret;
|
|
}
|
|
OB_DEF_DESERIALIZE(ObInnerContextMap)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObString tmp_context_name;
|
|
int64_t map_size = 0;
|
|
OB_UNIS_DECODE(tmp_context_name);
|
|
OB_UNIS_DECODE(map_size);
|
|
OZ (ob_write_string(alloc_, tmp_context_name, context_name_));
|
|
OZ (init());
|
|
ObContextUnit tmp_unit;
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < map_size; ++i) {
|
|
ObContextUnit *unit = nullptr;
|
|
OB_UNIS_DECODE(tmp_unit);
|
|
CK (OB_NOT_NULL(unit = static_cast<ObContextUnit *> (alloc_.alloc(sizeof(ObContextUnit)))));
|
|
OZ (unit->deep_copy(tmp_unit.attribute_, tmp_unit.value_, alloc_));
|
|
OZ (context_map_->set_refactored(unit->attribute_, unit));
|
|
}
|
|
return ret;
|
|
}
|
|
OB_DEF_SERIALIZE_SIZE(ObInnerContextMap)
|
|
{
|
|
int64_t len = 0;
|
|
OB_UNIS_ADD_LEN(context_name_);
|
|
if (OB_NOT_NULL(context_map_)) {
|
|
OB_UNIS_ADD_LEN(context_map_->size());
|
|
for (auto it = context_map_->begin(); it != context_map_->end(); ++it) {
|
|
OB_UNIS_ADD_LEN(*it->second);
|
|
}
|
|
}
|
|
return len;
|
|
}
|
|
OB_DEF_SERIALIZE(ObContextUnit)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LST_DO_CODE(OB_UNIS_ENCODE,
|
|
attribute_,
|
|
value_);
|
|
return ret;
|
|
}
|
|
OB_DEF_DESERIALIZE(ObContextUnit)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
LST_DO_CODE(OB_UNIS_DECODE,
|
|
attribute_,
|
|
value_);
|
|
return ret;
|
|
}
|
|
OB_DEF_SERIALIZE_SIZE(ObContextUnit)
|
|
{
|
|
int64_t len = 0;
|
|
LST_DO_CODE(OB_UNIS_ADD_LEN,
|
|
attribute_,
|
|
value_);
|
|
return len;
|
|
}
|
|
|
|
int ObControlInfoEncoder::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t buf_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(sess.get_control_info().serialize(buf, buf_len, pos))) {
|
|
LOG_WARN("failed to serialize control info", K(buf_len), K(pos));
|
|
} else if (OB_FAIL(ObProtoTransUtil::store_int1(buf, buf_len, pos, sess.is_coninfo_set_by_sess(), CONINFO_BY_SESS))) {
|
|
LOG_WARN("failed to store control info set by sess", K(sess.is_coninfo_set_by_sess()), K(pos));
|
|
} else {
|
|
LOG_TRACE("serialize control info", K(sess.get_sessid()), K(sess.get_control_info()));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObControlInfoEncoder::deserialize(ObSQLSessionInfo &sess, const char *buf, const int64_t data_len, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
FLTControlInfo con;
|
|
FullLinkTraceExtraInfoType extra_type;
|
|
int32_t v_len = 0;
|
|
int16_t id = 0;
|
|
int8_t setby_sess = 0;
|
|
if (OB_FAIL(FLTExtraInfo::resolve_type_and_len(buf, data_len, pos, extra_type, v_len))) {
|
|
LOG_WARN("failed to resolve type and len", K(data_len), K(pos));
|
|
} else if (extra_type != FLT_TYPE_CONTROL_INFO) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid extra type", K(extra_type), K(ret));
|
|
} else if (OB_FAIL(con.deserialize(buf, pos+v_len, pos))) {
|
|
LOG_WARN("failed to resolve control info", K(v_len), K(pos));
|
|
} else if (OB_FAIL(ObProtoTransUtil::resolve_type_and_len(buf, data_len, pos, id, v_len))) {
|
|
LOG_WARN("failed to get extra_info", K(ret), KP(buf));
|
|
} else if (CONINFO_BY_SESS != id) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid id", K(id));
|
|
} else if (OB_FAIL(ObProtoTransUtil::get_int1(buf, *(const_cast<int64_t *>(&data_len)), pos, static_cast<int64_t>(v_len), setby_sess))) {
|
|
LOG_WARN("failed to resolve set by sess", K(ret));
|
|
} else {
|
|
sess.set_flt_control_info(con);
|
|
sess.set_coninfo_set_by_sess(static_cast<bool>(setby_sess));
|
|
// if control info not changed or control info not set, not need to feedback
|
|
if (con == sess.get_control_info() || !sess.get_control_info().is_valid()) {
|
|
// not need to feedback
|
|
sess.set_send_control_info(true);
|
|
sess.get_control_info_encoder().is_changed_ = false;
|
|
}
|
|
|
|
LOG_TRACE("deserialize control info", K(sess.get_sessid()), K(sess.get_control_info()));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObControlInfoEncoder::get_serialize_size(ObSQLSessionInfo& sess, int64_t &len) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
len = sess.get_control_info().get_serialize_size() + 6 + sizeof(bool);
|
|
return ret;
|
|
}
|
|
|
|
int ObControlInfoEncoder::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(serialize(sess, buf, length, pos))) {
|
|
LOG_WARN("failed to fetch session info.", K(ret), K(pos), K(length));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int64_t ObControlInfoEncoder::get_fetch_sess_info_size(ObSQLSessionInfo& sess)
|
|
{
|
|
int64_t len = 0;
|
|
get_serialize_size(sess, len);
|
|
return len;
|
|
}
|
|
|
|
int ObControlInfoEncoder::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length,
|
|
const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
// todo The current control info does not meet the synchronization mechanism and cannot be verified
|
|
return ret;
|
|
}
|
|
|
|
int ObControlInfoEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf,
|
|
int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
UNUSED(current_sess_buf);
|
|
UNUSED(current_sess_length);
|
|
const char *buf = last_sess_buf;
|
|
int64_t pos = 0;
|
|
int64_t data_len = last_sess_length;
|
|
FLTControlInfo last_sess_con;
|
|
FullLinkTraceExtraInfoType extra_type;
|
|
int32_t v_len = 0;
|
|
int16_t id = 0;
|
|
int8_t last_sess_setby_sess = 0;
|
|
if (OB_FAIL(FLTExtraInfo::resolve_type_and_len(buf, data_len, pos, extra_type, v_len))) {
|
|
LOG_WARN("failed to resolve type and len", K(data_len), K(pos));
|
|
} else if (extra_type != FLT_TYPE_CONTROL_INFO) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid extra type", K(extra_type), K(ret));
|
|
} else if (OB_FAIL(last_sess_con.deserialize(buf, pos+v_len, pos))) {
|
|
LOG_WARN("failed to resolve control info", K(v_len), K(pos));
|
|
} else if (OB_FAIL(ObProtoTransUtil::resolve_type_and_len(buf, data_len, pos, id, v_len))) {
|
|
LOG_WARN("failed to get extra_info", K(ret), KP(buf));
|
|
} else if (CONINFO_BY_SESS != id) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid id", K(id));
|
|
} else if (OB_FAIL(ObProtoTransUtil::get_int1(buf, *(const_cast<int64_t *>(&data_len)),
|
|
pos, static_cast<int64_t>(v_len), last_sess_setby_sess))) {
|
|
LOG_WARN("failed to resolve set by sess", K(ret));
|
|
} else {
|
|
if (sess.is_coninfo_set_by_sess() != last_sess_setby_sess) {
|
|
LOG_WARN("failed to verify control info", K(ret),
|
|
"current_coninfo_set_by_sess", sess.is_coninfo_set_by_sess(),
|
|
"last_coninfo_set_by_sess", last_sess_setby_sess);
|
|
} else if (sess.get_control_info().is_equal(last_sess_con)) {
|
|
LOG_INFO("success to verify control info, no need to attention support_show_trace", K(ret),
|
|
"current_coninfo", sess.get_control_info(),
|
|
"last_coninfo", last_sess_con);
|
|
} else {
|
|
LOG_WARN("failed to verify control info, no need to attention support_show_trace", K(ret),
|
|
"current_coninfo", sess.get_control_info(),
|
|
"last_coninfo", last_sess_con);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#define SESS_ENCODER_DELEGATE_TO_TXN(CLS, func) \
|
|
int CLS::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos)\
|
|
{ \
|
|
return ObSqlTransControl::serialize_txn_##func##_state(sess, buf, length, pos); \
|
|
} \
|
|
int CLS::deserialize(ObSQLSessionInfo &sess, const char *buf, const int64_t length, int64_t &pos) \
|
|
{ \
|
|
return ObSqlTransControl::update_txn_##func##_state(sess, buf, length, pos); \
|
|
} \
|
|
int CLS::get_serialize_size(ObSQLSessionInfo &sess, int64_t &len) const \
|
|
{ \
|
|
int ret = OB_SUCCESS; \
|
|
len = ObSqlTransControl::get_txn_##func##_state_serialize_size(sess); \
|
|
return ret; \
|
|
} \
|
|
int CLS::fetch_sess_info(ObSQLSessionInfo &sess, char *buf, const int64_t data_len, int64_t &pos) \
|
|
{ \
|
|
return ObSqlTransControl::fetch_txn_##func##_state(sess, buf, data_len, pos); \
|
|
} \
|
|
int64_t CLS::get_fetch_sess_info_size(ObSQLSessionInfo &sess) \
|
|
{ \
|
|
return ObSqlTransControl::get_fetch_txn_##func##_state_size(sess); \
|
|
} \
|
|
int CLS::compare_sess_info(const char* current_sess_buf, int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length) \
|
|
{ \
|
|
return ObSqlTransControl::cmp_txn_##func##_state(current_sess_buf, current_sess_length, last_sess_buf, last_sess_length); \
|
|
} \
|
|
int CLS::display_sess_info(ObSQLSessionInfo &sess, const char* current_sess_buf, int64_t current_sess_length, const char* last_sess_buf, int64_t last_sess_length) \
|
|
{ \
|
|
ObSqlTransControl::display_txn_##func##_state(sess, current_sess_buf, current_sess_length, last_sess_buf, last_sess_length); \
|
|
return OB_SUCCESS; \
|
|
}
|
|
|
|
SESS_ENCODER_DELEGATE_TO_TXN(ObTxnStaticInfoEncoder, static)
|
|
SESS_ENCODER_DELEGATE_TO_TXN(ObTxnDynamicInfoEncoder, dynamic)
|
|
SESS_ENCODER_DELEGATE_TO_TXN(ObTxnParticipantsInfoEncoder, parts)
|
|
SESS_ENCODER_DELEGATE_TO_TXN(ObTxnExtraInfoEncoder, extra)
|
|
|
|
#undef SESS_ENCODER_DELEGATE_TO_TXN
|
|
// in oracle mode, if the user variable is valid, we use it first
|
|
int64_t ObSQLSessionInfo::get_xa_end_timeout_seconds() const
|
|
{
|
|
int tmp_ret = OB_SUCCESS;
|
|
int64_t ret_val = 0;
|
|
if (is_oracle_mode()) {
|
|
const ObString xa_timeout_var(transaction::ObXADefault::OB_XA_TIMEOUT_NAME);
|
|
const ObObj *xa_timeout_value = get_user_variable_value(xa_timeout_var);
|
|
if (NULL != xa_timeout_value) {
|
|
int64_t tmp_val = 0;
|
|
if (OB_SUCCESS != (tmp_ret = xa_timeout_value->get_number().cast_to_int64(tmp_val))) {
|
|
LOG_WARN_RET(tmp_ret, "failed to get xa timeout", K(tmp_ret), K(tmp_val));
|
|
} else if (0 >= tmp_val) {
|
|
LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid xa timeout", K(tmp_val));
|
|
} else {
|
|
ret_val = tmp_val;
|
|
LOG_INFO("get xa timeout from user variable", K(ret_val), "session_id", get_sessid());
|
|
}
|
|
} else {
|
|
ret_val = xa_end_timeout_seconds_;
|
|
LOG_INFO("get xa timeout from local", K(ret_val), "session_id", get_sessid());
|
|
}
|
|
} else {
|
|
ret_val = xa_end_timeout_seconds_;
|
|
}
|
|
return ret_val;
|
|
}
|
|
|
|
int ObSQLSessionInfo::set_xa_end_timeout_seconds(int64_t seconds)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (0 >= seconds) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(ret), K(seconds));
|
|
} else {
|
|
if (is_oracle_mode()) {
|
|
const ObString xa_timeout_var(transaction::ObXADefault::OB_XA_TIMEOUT_NAME);
|
|
ObSessionVariable sess_var;
|
|
ObArenaAllocator allocator;
|
|
number::ObNumber value;
|
|
if (OB_FAIL(value.from(seconds, allocator))) {
|
|
LOG_WARN("failed to get number", K(ret));
|
|
} else {
|
|
xa_end_timeout_seconds_ = seconds;
|
|
sess_var.value_.set_number(value);
|
|
sess_var.meta_.set_type(sess_var.value_.get_type());
|
|
sess_var.meta_.set_scale(sess_var.value_.get_scale());
|
|
sess_var.meta_.set_collation_level(CS_LEVEL_IMPLICIT);
|
|
sess_var.meta_.set_collation_type(sess_var.value_.get_collation_type());
|
|
if (OB_FAIL(replace_user_variable(xa_timeout_var, sess_var))) {
|
|
LOG_WARN("failed to set variable xa timeout", K(ret), K(seconds));
|
|
} else {
|
|
LOG_INFO("set xa timeout in session", K(seconds), "session_id", get_sessid());
|
|
}
|
|
}
|
|
} else {
|
|
xa_end_timeout_seconds_ = seconds;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::add_dblink_sequence_schema(ObSequenceSchema *schema)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSequenceSchema *new_sequence_schema = NULL;
|
|
const ObSequenceSchema* exists_schema = NULL;
|
|
if (OB_ISNULL(schema)) {
|
|
ret = OB_NOT_INIT;
|
|
LOG_WARN("sequence schema is null", K(ret));
|
|
} else if (OB_UNLIKELY(!schema->is_valid())) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(ret), KPC(schema));
|
|
} else if (OB_FAIL(get_dblink_sequence_schema(schema->get_sequence_id(),
|
|
exists_schema))) {
|
|
LOG_WARN("failed to get dblink sequence schema", K(ret));
|
|
} else if (NULL != exists_schema) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("sequence exists", KPC(schema));
|
|
} else if (OB_FAIL(ObSchemaUtils::alloc_schema(get_session_allocator(),
|
|
*schema,
|
|
new_sequence_schema))) {
|
|
LOG_WARN("alloca sequence schema failed", K(ret));
|
|
} else if (OB_ISNULL(new_sequence_schema)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("NULL ptr", K(new_sequence_schema), K(ret));
|
|
} else if (OB_FAIL(dblink_sequence_schemas_.push_back(new_sequence_schema))) {
|
|
LOG_WARN("failed to push back sequence schema", K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSQLSessionInfo::get_dblink_sequence_schema(int64_t sequence_id, const ObSequenceSchema* &schema)const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
bool find = false;
|
|
schema = NULL;
|
|
for (int64_t i = 0; OB_SUCC(ret) && !find && i < dblink_sequence_schemas_.count(); ++i) {
|
|
ObSequenceSchema *seq_schema = dblink_sequence_schemas_.at(i);
|
|
if (OB_ISNULL(seq_schema)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unexpect null schema", K(ret));
|
|
} else if (sequence_id == seq_schema->get_sequence_id()) {
|
|
find = true;
|
|
schema = dblink_sequence_schemas_.at(i);
|
|
}
|
|
}
|
|
LOG_TRACE("get dblink sequence schema", K(sequence_id), K(dblink_sequence_schemas_));
|
|
return ret;
|
|
}
|