[FEAT MERGE]client session

This commit is contained in:
obdev 2024-02-07 14:41:39 +00:00 committed by ob-robot
parent 01f977c065
commit faf440e6ea
52 changed files with 1008 additions and 66 deletions

View File

@ -1455,6 +1455,10 @@ const char *const OB_MYSQL_CLIENT_OBPROXY_MODE_NAME = "__ob_proxy";
const char *const OB_MYSQL_CONNECTION_ID = "__connection_id";
const char *const OB_MYSQL_GLOBAL_VARS_VERSION = "__global_vars_version";
const char *const OB_MYSQL_PROXY_CONNECTION_ID = "__proxy_connection_id";
// add client_session_id, addr_port & client session create time us
const char *const OB_MYSQL_CLIENT_SESSION_ID = "__client_session_id";
const char *const OB_MYSQL_CLIENT_ADDR_PORT = "__client_addr_port";
const char *const OB_MYSQL_CLIENT_CONNECT_TIME_US = "__client_connect_time";
const char *const OB_MYSQL_PROXY_SESSION_CREATE_TIME_US = "__proxy_session_create_time_us";
const char *const OB_MYSQL_CLUSTER_NAME = "__cluster_name";
const char *const OB_MYSQL_CLUSTER_ID = "__cluster_id";

View File

@ -763,7 +763,7 @@ class EventTable
EN_SESS_POOL_MGR_CTRL = 1186,
// session info diagnosis control
// EN_SESS_INFO_DIAGNOSIS_CONTROL = 1187,
// EN_SESS_CLEAN_KILL_MAP_TIME = 1188,
EN_SESS_CLEAN_KILL_MAP_TIME = 1188,
EN_ENABLE_NEWSORT_FORCE = 1200,
// Transaction // 2001 - 2100

View File

@ -161,6 +161,7 @@ union ObProxyCapabilityFlags
bool is_weak_stale_feedback() const { return 1 == cap_flags_.OB_CAP_PROXY_WEAK_STALE_FEEDBACK; }
bool is_flt_show_trace_support() const { return 1 == cap_flags_.OB_CAP_PROXY_FULL_LINK_TRACING_EXT
&& is_ob_protocol_v2_support(); }
bool is_client_sessid_support() const { return 1 == cap_flags_.OB_CAP_PROXY_CLIENT_SESSION_ID; }
uint64_t capability_;
struct CapabilityFlags
@ -194,8 +195,8 @@ union ObProxyCapabilityFlags
uint64_t OB_CAP_PROXY_FULL_LINK_TRACING_EXT: 1;
// duplicate session_info sync of transaction type
uint64_t OB_CAP_SERVER_DUP_SESS_INFO_SYNC: 1;
uint64_t OB_CAP_LOCAL_FILES: 1;
// client session id consultation
uint64_t OB_CAP_PROXY_CLIENT_SESSION_ID: 1;
uint64_t OB_CAP_OB_PROTOCOL_V2_COMPRESS: 1;
uint64_t OB_CAP_RESERVED_NOT_USE: 41;

View File

@ -77,6 +77,9 @@ public:
pkt_rec_wrapper_.init();
client_type_ = common::OB_CLIENT_INVALID_TYPE;
client_version_ = 0;
client_sessid_ = INVALID_SESSID;
client_addr_port_ = 0;
client_create_time_ = 0;
}
obmysql::ObCompressType get_compress_type() {
@ -202,6 +205,10 @@ public:
obmysql::ObPacketRecordWrapper pkt_rec_wrapper_;
ObClientType client_type_;
uint64_t client_version_;
// The client establishes a connection ID to ensure that the tenant is globally unique.
uint32_t client_sessid_;
int32_t client_addr_port_;
int64_t client_create_time_;
};
} // end of namespace observer
} // end of namespace oceanbase

View File

@ -1088,11 +1088,10 @@ PCODE_DEF(OB_CREATE_TRIGGER_WITH_RES, 0x160D)
// for direct load resource
// PCODE_DEF(OB_DIRECT_LOAD_RESOURCE, 0x1613)
// kill client session.
// PCODE_DEF(OB_KILL_CLIENT_SESSION, 0x1614)
PCODE_DEF(OB_KILL_CLIENT_SESSION, 0x1614)
// obtain client session create time.
// PCODE_DEF(OB_CLIENT_SESSION_CONNECT_TIME, 0x1615)
PCODE_DEF(OB_CLIENT_SESSION_CONNECT_TIME, 0x1615)
//tenant clone
//PCODE_DEF(OB_NOTIFY_CLONE_SCHEDULER, 0x1616)

View File

@ -218,8 +218,15 @@ public:
if (v.session_.is_terminate(ret)) {
v.no_more_test_ = true;
v.retry_type_ = RETRY_TYPE_NONE;
v.client_ret_ = ret; // session terminated
LOG_WARN("execution was terminated", K(ret));
// In the kill client session scenario, the server session will be marked
// with the SESSION_KILLED mark. In the retry scenario, there will be an error
// code covering 5066, so the judgment logic is added here.
if (ret == OB_ERR_SESSION_INTERRUPTED && v.err_ == OB_ERR_KILL_CLIENT_SESSION) {
v.client_ret_ = v.err_;
} else{
v.client_ret_ = ret; // session terminated
}
LOG_WARN("execution was terminated", K(ret), K(v.client_ret_), K(v.err_));
} else if (THIS_WORKER.is_timeout()) {
v.no_more_test_ = true;
v.retry_type_ = RETRY_TYPE_NONE;
@ -597,8 +604,15 @@ public:
} else if (v.session_.is_terminate(ret)) {
v.no_more_test_ = true;
v.retry_type_ = RETRY_TYPE_NONE;
v.client_ret_ = ret; // session terminated
LOG_WARN("execution was terminated", K(ret));
// In the kill client session scenario, the server session will be marked
// with the SESSION_KILLED mark. In the retry scenario, there will be an error
// code covering 5066, so the judgment logic is added here.
if (ret == OB_ERR_SESSION_INTERRUPTED && v.err_ == OB_ERR_KILL_CLIENT_SESSION) {
v.client_ret_ = v.err_;
} else{
v.client_ret_ = ret; // session terminated
}
LOG_WARN("execution was terminated", K(ret), K(v.client_ret_), K(v.err_));
} else if (THIS_WORKER.is_timeout()) {
v.no_more_test_ = true;
v.retry_type_ = RETRY_TYPE_NONE;

View File

@ -286,7 +286,7 @@ int ObMPBase::create_session(ObSMConnection *conn, ObSQLSessionInfo *&sess_info)
} else {
sess_info->set_ssl_cipher("");
}
sess_info->set_client_sessid(conn->client_sessid_);
sess_info->gen_gtt_session_scope_unique_id();
sess_info->gen_gtt_trans_scope_unique_id();
}
@ -624,6 +624,39 @@ int ObMPBase::process_extra_info(sql::ObSQLSessionInfo &session,
return ret;
}
// The obmp layer handles the kill client session logic.
int ObMPBase::process_kill_client_session(sql::ObSQLSessionInfo &session, bool is_connect)
{
int ret = OB_SUCCESS;
uint64_t create_time = 0;
if (OB_ISNULL(gctx_.session_mgr_)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session mgr", K(ret), K(gctx_));
} else if (OB_UNLIKELY(session.is_mark_killed())) {
ret = OB_ERR_KILL_CLIENT_SESSION;
LOG_WARN("client session need be killed", K(session.get_session_state()),
K(session.get_sessid()), "proxy_sessid", session.get_proxy_sessid(),
K(session.get_client_sessid()), K(ret));
} else if (is_connect) {
if (OB_UNLIKELY(OB_HASH_NOT_EXIST != (gctx_.session_mgr_->get_kill_client_sess_map().
get_refactored(session.get_client_sessid(), create_time)))) {
if (session.get_client_create_time() == create_time) {
ret = OB_ERR_KILL_CLIENT_SESSION;
LOG_WARN("client session need be killed", K(session.get_session_state()),
K(session.get_sessid()), "proxy_sessid", session.get_proxy_sessid(),
K(session.get_client_sessid()), K(ret),K(create_time));
} else {
LOG_DEBUG("client session is created later", K(create_time),
K(session.get_client_create_time()),
K(session.get_sessid()), "proxy_sessid", session.get_proxy_sessid(),
K(session.get_client_sessid()));
}
}
} else {
}
return ret;
}
int ObMPBase::update_charset_sys_vars(ObSMConnection &conn, ObSQLSessionInfo &sess_info)
{
int ret = OB_SUCCESS;

View File

@ -126,6 +126,7 @@ protected:
bool is_packed);
int process_extra_info(sql::ObSQLSessionInfo &session, const obmysql::ObMySQLRawPacket &pkt,
bool &need_response_error);
int process_kill_client_session(sql::ObSQLSessionInfo &session, bool is_connect = false);
protected:
static const int64_t MAX_TRY_STEPS = 5;
static int64_t TRY_EZ_BUF_SIZES[MAX_TRY_STEPS];

View File

@ -210,6 +210,8 @@ int ObMPChangeUser::process()
} else if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("fail to get session info", K(ret), K(session));
} else if (OB_FAIL(process_kill_client_session(*session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (FALSE_IT(session->set_txn_free_route(pkt.txn_free_route()))) {
} else if (OB_FAIL(process_extra_info(*session, pkt, need_response_error))) {
LOG_WARN("fail get process extra info", K(ret));
@ -343,8 +345,8 @@ int ObMPChangeUser::load_privilege_info(ObSQLSessionInfo *session)
OB_LOG(WARN, "fail to set tenant", "tenant name", login_info.tenant_name_, K(ret));
} else if (OB_FAIL(session->set_default_database(database_))) {
OB_LOG(WARN, "failed to set default database", K(ret), K(database_));
} else if (OB_FAIL(session->set_real_client_ip(login_info.client_ip_))) {
LOG_WARN("failed to set_real_client_ip", K(ret));
} else if (OB_FAIL(session->set_real_client_ip_and_port(login_info.client_ip_, session->get_client_addr_port()))) {
LOG_WARN("failed to set_real_client_ip_and_port", K(ret));
} else if (OB_FAIL(schema_guard.get_sys_variable_schema(session_priv.tenant_id_, sys_variable_schema))) {
LOG_WARN("get sys variable schema failed", K(ret));
} else if (OB_ISNULL(sys_variable_schema)) {

View File

@ -343,6 +343,8 @@ int ObMPConnect::process()
LOG_ERROR("null session", K(ret), K(session));
} else if (OB_FAIL(verify_identify(*conn, *session, tenant_id))) {
LOG_WARN("fail to verify_identify", K(ret));
} else if (OB_FAIL(process_kill_client_session(*session, true))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_FAIL(update_transmission_checksum_flag(*session))) {
LOG_WARN("update transmisson checksum flag failed", K(ret));
} else if (OB_FAIL(update_proxy_sys_vars(*session))) {
@ -358,6 +360,9 @@ int ObMPConnect::process()
session->set_sql_request_level(conn->sql_req_level_);
// set session var sync info.
session->set_session_var_sync(conn->proxy_cap_flags_.is_session_var_sync_support());
// proxy mode & direct mode
session->set_client_sessid_support(conn->proxy_cap_flags_.is_client_sessid_support()
|| (conn->proxy_sessid_ == 0));
session->get_control_info().support_show_trace_ = conn->proxy_cap_flags_.is_flt_show_trace_support();
LOG_TRACE("setup user resource group OK",
"user_id", session->get_user_id(),
@ -385,6 +390,7 @@ int ObMPConnect::process()
const ObCSProtocolType protoType = conn->get_cs_protocol_type();
const uint32_t sessid = conn->sessid_;
const uint64_t proxy_sessid = conn->proxy_sessid_;
const uint32_t client_sessid = conn->client_sessid_;
const int64_t sess_create_time = conn->sess_create_time_;
const uint32_t capability = conn->cap_flags_.capability_;
const bool from_proxy = conn->is_proxy_;
@ -473,7 +479,7 @@ int ObMPConnect::process()
LOG_INFO("MySQL LOGIN", "direct_client_ip", client_ip_buf, K_(client_ip),
K_(tenant_name), K(tenant_id), K_(user_name), K(host_name),
K(sessid), K(proxy_sessid), K(sess_create_time), K(from_proxy),
K(sessid), K(proxy_sessid), K(client_sessid), K(from_proxy),
K(from_java_client), K(from_oci_client), K(from_jdbc_client),
K(capability), K(proxy_capability), K(use_ssl),
"c/s protocol", get_cs_protocol_type_name(protoType),
@ -726,8 +732,8 @@ int ObMPConnect::load_privilege_info(ObSQLSessionInfo &session)
const ObTenantSchema *tenant_schema = NULL;
if (OB_FAIL(session.set_user(user_name_, session_priv.host_name_, session_priv.user_id_))) {
LOG_WARN("failed to set_user", K(ret));
} else if (OB_FAIL(session.set_real_client_ip(client_ip_))) {
LOG_WARN("failed to set_real_client_ip", K(ret));
} else if (OB_FAIL(session.set_real_client_ip_and_port(client_ip_, client_port_))) {
LOG_WARN("failed to set_real_client_ip_and_port", K(ret));
} else if (OB_FAIL(session.set_default_database(session_priv.db_))) {
LOG_WARN("failed to set default database", K(ret), K(session_priv.db_));
} else if (OB_FAIL(schema_guard.get_tenant_info(session_priv.tenant_id_, tenant_schema))) {
@ -1480,6 +1486,93 @@ int ObMPConnect::get_proxy_conn_id(uint64_t &proxy_conn_id) const
return ret;
}
int ObMPConnect::get_client_addr_port(int32_t &client_addr_port) const
{
int ret = OB_SUCCESS;
bool is_found = false;
ObString key_str;
key_str.assign_ptr(OB_MYSQL_CLIENT_ADDR_PORT , static_cast<int32_t>(STRLEN(OB_MYSQL_CLIENT_ADDR_PORT)));
for (int64_t i = 0; i < hsr_.get_connect_attrs().count() && OB_SUCC(ret) && !is_found; ++i) {
const ObStringKV &kv = hsr_.get_connect_attrs().at(i);
if (key_str == kv.key_) {
ObObj value;
value.set_varchar(kv.value_);
ObArenaAllocator allocator(ObModIds::OB_SQL_EXPR);
ObCastCtx cast_ctx(&allocator, NULL, CM_NONE, ObCharset::get_system_collation());
EXPR_GET_INT32_V2(value, client_addr_port);
if (OB_FAIL(ret)) {
LOG_WARN("fail to cast client connection id to int32", K(kv.value_), K(ret));
} else {
is_found = true;
}
}
}
if (OB_SUCC(ret) && !is_found) {
//if fail to find client addr port, ignore it, compatible with old obproxyro's connection
client_addr_port = 0;
}
return ret;
}
int ObMPConnect::get_client_conn_id(uint32_t &client_sessid) const
{
int ret = OB_SUCCESS;
bool is_found = false;
ObString key_str;
key_str.assign_ptr(OB_MYSQL_CLIENT_SESSION_ID , static_cast<int32_t>(STRLEN(OB_MYSQL_CLIENT_SESSION_ID)));
for (int64_t i = 0; i < hsr_.get_connect_attrs().count() && OB_SUCC(ret) && !is_found; ++i) {
const ObStringKV &kv = hsr_.get_connect_attrs().at(i);
if (key_str == kv.key_) {
ObObj value;
value.set_varchar(kv.value_);
ObArenaAllocator allocator(ObModIds::OB_SQL_EXPR);
ObCastCtx cast_ctx(&allocator, NULL, CM_NONE, ObCharset::get_system_collation());
EXPR_GET_UINT32_V2(value, client_sessid);
if (OB_FAIL(ret)) {
LOG_WARN("fail to cast client connection id to uint32", K(kv.value_), K(ret));
} else {
is_found = true;
}
}
}
if (OB_SUCC(ret) && !is_found) {
// if fail to find proxy_connection_id, ignore it, compatible with old obproxyro's connection
client_sessid = INVALID_SESSID;
}
return ret;
}
int ObMPConnect::get_client_create_time(int64_t &client_create_time) const
{
int ret = OB_SUCCESS;
bool is_found = false;
ObString key_str;
key_str.assign_ptr(OB_MYSQL_CLIENT_CONNECT_TIME_US , static_cast<int32_t>(STRLEN(OB_MYSQL_CLIENT_CONNECT_TIME_US)));
for (int64_t i = 0; i < hsr_.get_connect_attrs().count() && OB_SUCC(ret) && !is_found; ++i) {
const ObStringKV &kv = hsr_.get_connect_attrs().at(i);
if (key_str == kv.key_) {
ObObj value;
value.set_varchar(kv.value_);
ObArenaAllocator allocator(ObModIds::OB_SQL_EXPR);
ObCastCtx cast_ctx(&allocator, NULL, CM_NONE, ObCharset::get_system_collation());
EXPR_GET_INT64_V2(value, client_create_time);
if (OB_FAIL(ret)) {
LOG_WARN("fail to cast client create time", K(kv.value_), K(ret));
} else {
is_found = true;
}
}
}
if (OB_SUCC(ret) && !is_found) {
//if fail to find client_create_time, ignore it, compatible with old obproxyro's connection
client_create_time = 0;
}
return ret;
}
//proxy连接方式时获取client->proxy的连接创建时间
int ObMPConnect::get_proxy_sess_create_time(int64_t &sess_create_time) const
{
@ -1596,6 +1689,11 @@ int ObMPConnect::check_update_proxy_capability(ObSMConnection &conn) const
server_proxy_cap_flag.cap_flags_.OB_CAP_PROXY_SESSION_VAR_SYNC = 1;
server_proxy_cap_flag.cap_flags_.OB_CAP_PROXY_FULL_LINK_TRACING_EXT = 1;
server_proxy_cap_flag.cap_flags_.OB_CAP_SERVER_DUP_SESS_INFO_SYNC = 1;
if (GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_4_3_0_0) {
server_proxy_cap_flag.cap_flags_.OB_CAP_PROXY_CLIENT_SESSION_ID = 1;
} else {
server_proxy_cap_flag.cap_flags_.OB_CAP_PROXY_CLIENT_SESSION_ID = 0;
}
conn.proxy_cap_flags_.capability_ = (server_proxy_cap_flag.capability_ & client_proxy_cap);//if old java client, set it 0
LOG_DEBUG("Negotiated capability",
@ -1693,6 +1791,9 @@ int ObMPConnect::check_user_cluster(const ObString &server_cluster, const int64_
int ObMPConnect::check_common_property(ObSMConnection &conn, ObMySQLCapabilityFlags &client_cap) {
int ret = OB_SUCCESS;
uint64_t proxy_sessid = 0;
uint32_t client_sessid = INVALID_SESSID;
int32_t client_addr_port = 0;
int64_t client_create_time = 0;
int64_t sess_create_time = 0;
if (OB_FAIL(check_user_cluster(ObString::make_string(GCONF.cluster), GCONF.cluster_id))) {
LOG_WARN("fail to check user cluster", K(ret));
@ -1700,11 +1801,23 @@ int ObMPConnect::check_common_property(ObSMConnection &conn, ObMySQLCapabilityFl
LOG_WARN("fail to check_update_proxy_capability", K(ret));
} else if (OB_FAIL(get_proxy_conn_id(proxy_sessid))) {
LOG_WARN("get proxy connection id fail", K(ret));
} else if (OB_FAIL(get_client_conn_id(client_sessid))) {
LOG_WARN("get client connection id fail", K(ret), K(client_sessid));
} else if (OB_FAIL(get_client_addr_port(client_addr_port))) {
LOG_WARN("get client connection id fail", K(ret), K(client_addr_port));
} else if (OB_FAIL(get_client_create_time(client_create_time))) {
LOG_WARN("get client connection id fail", K(ret), K(client_addr_port));
} else if (OB_FAIL(get_proxy_sess_create_time(sess_create_time))) {
LOG_WARN("get proxy session create time fail", K(ret));
} else {
conn.proxy_sessid_ = proxy_sessid;
conn.client_sessid_ = client_sessid;
conn.client_addr_port_ = client_addr_port;
conn.client_create_time_ = client_create_time;
conn.sess_create_time_ = sess_create_time;
int64_t code = 0;
LOG_DEBUG("construct session id", K(conn.client_sessid_), K(conn.sessid_),
K(conn.client_addr_port_), K(conn.client_create_time_) ,K(conn.proxy_sessid_));
if (conn.proxy_cap_flags_.is_ob_protocol_v2_support()) {
// when used 2.0 protocol, do not use mysql compress
client_cap.cap_flags_.OB_CLIENT_COMPRESS = 0;
@ -1775,7 +1888,12 @@ int ObMPConnect::check_client_property(ObSMConnection &conn)
} else {
client_ip_ = client_ip;
}
// Distinguish client addr port between proxy mode and direct connection mode
if (conn.client_addr_port_ == 0) {
client_port_ = get_peer().get_port();
} else {
client_port_ = conn.client_addr_port_;
}
hsr_.set_capability_flags(client_cap);
conn.cap_flags_ = client_cap;
return ret;

View File

@ -49,6 +49,9 @@ private:
int64_t get_database_id();
int get_conn_id(uint32_t &conn_id) const;
int get_proxy_conn_id(uint64_t &conn_id) const;
int get_client_addr_port(int32_t &client_addr_port) const;
int get_client_conn_id(uint32_t &conn_id) const;
int get_client_create_time(int64_t &client_create_time) const;
int get_proxy_sess_create_time(int64_t &sess_create_time) const;
int get_proxy_capability(uint64_t &cap) const;
int get_proxy_scramble(ObString &proxy_scramble) const;
@ -134,6 +137,7 @@ private:
char user_name_var_[OB_MAX_USER_NAME_BUF_LENGTH];
char db_name_var_[OB_MAX_DATABASE_NAME_BUF_LENGTH];
int deser_ret_;
int32_t client_port_;
}; // end of class ObMPConnect
} // end of namespace observer

View File

@ -65,6 +65,8 @@ int ObMPInitDB::process()
} else if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("null pointer");
} else if (OB_FAIL(process_kill_client_session(*session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_FAIL(session->get_query_timeout(query_timeout))) {
LOG_WARN("fail to get query timeout", K(ret));
} else if (OB_ISNULL(gctx_.schema_service_)) {

View File

@ -49,6 +49,8 @@ int ObMPPing::process()
} else if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("sql session info is null", K(ret));
} else if (OB_FAIL(process_kill_client_session(*session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (FALSE_IT(session->set_txn_free_route(pkt.txn_free_route()))) {
} else if (OB_FAIL(process_extra_info(*session, pkt, need_response_error))) {
LOG_WARN("fail get process extra info", K(ret));

View File

@ -164,6 +164,8 @@ int ObMPQuery::process()
if (OB_UNLIKELY(!session.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(sql), K(ret));
} else if (OB_FAIL(process_kill_client_session(session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session.is_zombie())) {
//session has been killed some moment ago
ret = OB_ERR_SESSION_INTERRUPTED;

View File

@ -52,6 +52,8 @@ int ObMPStatistic::process()
} else if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("sql session info is null", K(ret));
} else if (OB_FAIL(process_kill_client_session(*session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (FALSE_IT(session->set_txn_free_route(mysql_pkt.txn_free_route()))) {
} else if (OB_FAIL(process_extra_info(*session, mysql_pkt, need_response_error))) {
LOG_WARN("fail get process extra info", K(ret));

View File

@ -1839,6 +1839,8 @@ int ObMPStmtExecute::process()
if (OB_UNLIKELY(!session.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(stmt_id), K(ret));
} else if (OB_FAIL(process_kill_client_session(session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session.is_zombie())) {
//session has been killed some moment ago
ret = OB_ERR_SESSION_INTERRUPTED;

View File

@ -695,6 +695,8 @@ int ObMPStmtFetch::process()
if (OB_UNLIKELY(!session.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(cursor_id), K(ret));
} else if (OB_FAIL(process_kill_client_session(session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session.is_zombie())) {
//session has been killed some moment ago
ret = OB_ERR_SESSION_INTERRUPTED;

View File

@ -126,6 +126,8 @@ int ObMPStmtGetPieceData::process()
if (OB_UNLIKELY(!session.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(stmt_id), K(ret));
} else if (OB_FAIL(process_kill_client_session(session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session.is_zombie())) {
ret = OB_ERR_SESSION_INTERRUPTED;
LOG_WARN("session has been killed", K(session.get_session_state()), K_(stmt_id),

View File

@ -192,6 +192,8 @@ int ObMPStmtPrepare::process()
if (OB_UNLIKELY(!session.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(sql), K(ret));
} else if (OB_FAIL(process_kill_client_session(session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session.is_zombie())) {
ret = OB_ERR_SESSION_INTERRUPTED;
LOG_WARN("session has been killed", K(session.get_session_state()), K_(sql),

View File

@ -166,6 +166,8 @@ int ObMPStmtPrexecute::before_process()
if (OB_UNLIKELY(!session->is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(sql), K(ret));
} else if (OB_FAIL(process_kill_client_session(*session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session->is_zombie())) {
ret = OB_ERR_SESSION_INTERRUPTED;
LOG_WARN("session has been killed", K(session->get_session_state()), K_(sql),

View File

@ -68,6 +68,8 @@ int ObMPStmtReset::process()
} else if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session is NULL or invalid", K(ret), K(session));
} else if (OB_FAIL(process_kill_client_session(*session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (FALSE_IT(session->set_txn_free_route(pkt.txn_free_route()))) {
} else if (OB_FAIL(process_extra_info(*session, pkt, need_response_error))) {
LOG_WARN("fail get process extra info", K(ret));

View File

@ -131,6 +131,8 @@ int ObMPStmtSendLongData::process()
if (OB_UNLIKELY(!session.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(stmt_id), K_(param_id), K(ret));
} else if (OB_FAIL(process_kill_client_session(session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session.is_zombie())) {
ret = OB_ERR_SESSION_INTERRUPTED;
LOG_WARN("session has been killed", K(session.get_session_state()), K_(stmt_id), K_(param_id),

View File

@ -136,6 +136,8 @@ int ObMPStmtSendPieceData::process()
if (OB_UNLIKELY(!session.is_valid())) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("invalid session", K_(stmt_id), K_(param_id), K(ret));
} else if (OB_FAIL(process_kill_client_session(session))) {
LOG_WARN("client session has been killed", K(ret));
} else if (OB_UNLIKELY(session.is_zombie())) {
ret = OB_ERR_SESSION_INTERRUPTED;
LOG_WARN("session has been killed", K(session.get_session_state()), K_(stmt_id), K_(param_id),

View File

@ -2861,6 +2861,83 @@ int ObAdminUnlockMemberListP::process()
return ret;
}
int ObKillClientSessionP::process()
{
int ret = OB_SUCCESS;
ObSQLSessionInfo *session = NULL;
uint32_t server_sess_id = INVALID_SESSID;
if (OB_ISNULL(gctx_.session_mgr_)) {
ret = OB_ERR_UNEXPECTED;
COMMON_LOG(WARN, "session_mgr_ is null", KR(ret));
} else if (OB_FAIL(gctx_.session_mgr_->get_client_sess_map().get_refactored(
arg_.get_client_sess_id(), server_sess_id))) {
if (ret == OB_HASH_NOT_EXIST) {
// no need to display info, if current server no this proxy session id.
ret = OB_SUCCESS;
LOG_DEBUG("current client session id not find", K(ret), K(arg_.get_client_sess_id()));
} else {
COMMON_LOG(WARN, "get session failed", KR(ret), K(arg_));
}
} else if (OB_FAIL(gctx_.session_mgr_->get_session(server_sess_id, session))) {
LOG_INFO("fail to get session", K(ret), K(server_sess_id));
ret = OB_SUCCESS;
} else if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session info is NULL", K(ret), K(arg_.get_client_sess_id()));
} else {
session->set_mark_killed(true);
// Ensure smooth exit of executed requests.
session->set_session_state(SESSION_KILLED);
}
if (NULL != session) {
gctx_.session_mgr_->revert_session(session);
}
if (OB_SUCC(ret)) {
// record kill_client_sess_map.
int flag = 1;
gctx_.session_mgr_->get_kill_client_sess_map().set_refactored(arg_.get_client_sess_id(),
arg_.get_create_time(), flag);
result_.set_can_kill_client_sess(true);
}
return ret;
}
int ObClientSessionConnectTimeP::process()
{
int ret = OB_SUCCESS;
ObSQLSessionInfo *session = NULL;
ObString str_result;
uint32_t server_sess_id = INVALID_SESSID;
if (OB_ISNULL(gctx_.session_mgr_)) {
ret = OB_ERR_UNEXPECTED;
COMMON_LOG(WARN, "session_mgr_ is null", KR(ret));
} else if (OB_FAIL(gctx_.session_mgr_->get_client_sess_map().get_refactored(
arg_.get_client_sess_id(), server_sess_id))) {
COMMON_LOG(WARN, "get session failed", KR(ret), K(arg_));
} else if (OB_FAIL(gctx_.session_mgr_->get_session(server_sess_id, session))) {
LOG_WARN("fail to get session", K(ret), K(server_sess_id));
} else if (OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session info is NULL", K(ret), K(arg_.get_client_sess_id()));
} else {
result_.set_client_create_time(session->get_client_create_time());
if (((OB_SYS_TENANT_ID == arg_.get_tenant_id())
|| ((arg_.get_tenant_id() == session->get_priv_tenant_id())
&& (arg_.is_has_user_super_privilege() ||
arg_.get_user_id() == session->get_user_id())))) {
result_.set_have_kill_auth(true);
} else {
result_.set_have_kill_auth(false);
}
LOG_DEBUG("get connect time rpc", K(session->get_client_create_time()),
K(session->get_sessid()), K(session->get_client_sessid()));
}
if (NULL != session) {
gctx_.session_mgr_->revert_session(session);
}
return ret;
}
int ObTabletLocationReceiveP::process()
{
int ret = OB_SUCCESS;

View File

@ -260,6 +260,8 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_TABLET_MAJOR_FREEZE, ObRpcTabletMajorFreezeP);
// OB_DEFINE_PROCESSOR_S(Srv, OB_CLIENT_SESSION_CONNECT_TIME, ObClientSessionConnectTimeP);
OB_DEFINE_PROCESSOR_S(Srv, OB_TABLET_LOCATION_BROADCAST, ObTabletLocationReceiveP);
OB_DEFINE_PROCESSOR_S(Srv, OB_KILL_CLIENT_SESSION, ObKillClientSessionP);
OB_DEFINE_PROCESSOR_S(Srv, OB_CLIENT_SESSION_CONNECT_TIME, ObClientSessionConnectTimeP);
} // end of namespace observer
} // end of namespace oceanbase

View File

@ -309,7 +309,7 @@ void oceanbase::observer::init_srv_xlator_for_others(ObSrvRpcXlator *xlator) {
RPC_PROCESSOR(ObWrSyncUserModifySettingsTaskP, gctx_);
// kill client session
// RPC_PROCESSOR(ObKillClientSessionP, gctx_);
RPC_PROCESSOR(ObKillClientSessionP, gctx_);
// client session create time
// RPC_PROCESSOR(ObClientSessionConnectTimeP, gctx_);
RPC_PROCESSOR(ObClientSessionConnectTimeP, gctx_);
}

View File

@ -119,7 +119,8 @@ int ObAllVirtualSessionInfo::FillScanner::operator()(
uint64_t col_id = output_column_ids_.at(i);
switch(col_id) {
case ID: {
cur_row_->cells_[cell_idx].set_uint64(static_cast<uint64_t>(sess_info->get_sessid()));
cur_row_->cells_[cell_idx].set_uint64(static_cast<uint64_t>(
sess_info->get_compatibility_sessid()));
break;
}
case USER: {
@ -297,7 +298,7 @@ int ObAllVirtualSessionInfo::FillScanner::operator()(
break;
}
case USER_CLIENT_PORT: {
cur_row_->cells_[cell_idx].set_int(0);
cur_row_->cells_[cell_idx].set_int(sess_info->get_client_addr_port());
break;
}
default: {

View File

@ -140,7 +140,8 @@ bool ObShowProcesslist::FillScanner::operator()(sql::ObSQLSessionMgr::Key key, O
//Otherwise, you can show only the threads at the same Tenant with you.
//If you have the PROCESS privilege, you can show all threads at your Tenant.
//Otherwise, you can show only your own threads.
if (sess_info->is_shadow()) {
// if session is marked killed, no display to user.
if (sess_info->is_shadow() || sess_info->is_mark_killed()) {
//this session info is logical free, shouldn't be added to scanner
} else if ((OB_SYS_TENANT_ID == my_session_->get_priv_tenant_id())
|| (sess_info->get_priv_tenant_id() == my_session_->get_priv_tenant_id()
@ -154,7 +155,8 @@ bool ObShowProcesslist::FillScanner::operator()(sql::ObSQLSessionMgr::Key key, O
uint64_t col_id = output_column_ids_.at(i);
switch(col_id) {
case ID: {
cur_row_->cells_[cell_idx].set_uint64(static_cast<uint64_t>(key.sessid_));
cur_row_->cells_[cell_idx].set_uint64(static_cast<uint64_t>(
sess_info->get_compatibility_sessid()));
break;
}
case USER: {
@ -442,7 +444,7 @@ bool ObShowProcesslist::FillScanner::operator()(sql::ObSQLSessionMgr::Key key, O
break;
}
case USER_CLIENT_PORT: {
cur_row_->cells_[cell_idx].set_int(0);
cur_row_->cells_[cell_idx].set_int(sess_info->get_client_addr_port());
break;
}
default: {

View File

@ -78,7 +78,7 @@ RPC_F(obrpc::OB_NOTIFY_SWITCH_LEADER, obrpc::ObNotifySwitchLeaderArg,
obrpc::ObSrvRpcProxy::ObRpc<obrpc::OB_NOTIFY_SWITCH_LEADER>::Response, ObNotifySwitchLeaderProxy);
RPC_F(obrpc::OB_UPDATE_TENANT_INFO_CACHE, obrpc::ObUpdateTenantInfoCacheArg, obrpc::ObUpdateTenantInfoCacheRes, ObUpdateTenantInfoCacheProxy);
RPC_F(obrpc::OB_BROADCAST_CONSENSUS_VERSION, obrpc::ObBroadcastConsensusVersionArg, obrpc::ObBroadcastConsensusVersionRes, ObBroadcstConsensusVersionProxy);
// RPC_F(obrpc::OB_KILL_CLIENT_SESSION, obrpc::ObKillClientSessionArg, obrpc::ObKillClientSessionRes, ObKillClientSessionProxy);
RPC_F(obrpc::OB_KILL_CLIENT_SESSION, obrpc::ObKillClientSessionArg, obrpc::ObKillClientSessionRes, ObKillClientSessionProxy);
#ifdef OB_BUILD_TDE_SECURITY
RPC_F(obrpc::OB_RESTORE_KEY, obrpc::ObRestoreKeyArg, obrpc::ObRestoreKeyResult, ObRestoreKeyProxy);
RPC_F(obrpc::OB_SET_ROOT_KEY, obrpc::ObRootKeyArg, obrpc::ObRootKeyResult, ObSetRootKeyProxy);

View File

@ -121,7 +121,7 @@ bool ObActiveSessHistTask::operator()(sql::ObSQLSessionMgr::Key key, ObSQLSessio
stat.sample_time_ = sample_time_;
stat.tenant_id_ = sess_info->get_effective_tenant_id();
stat.user_id_ = sess_info->get_user_id();
stat.session_id_ = sess_info->get_sessid();
stat.session_id_ = sess_info->get_compatibility_sessid();
stat.plan_id_ = sess_info->get_current_plan_id();
stat.trace_id_ = sess_info->get_current_trace_id();
sess_info->get_cur_sql_id(stat.sql_id_, sizeof(stat.sql_id_));

View File

@ -560,7 +560,7 @@ int ObInnerTableSchema::processlist_schema(ObTableSchema &table_schema)
table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
if (OB_SUCC(ret)) {
if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT id AS ID, user AS USER, host AS HOST, db AS DB, command AS COMMAND, time AS TIME, state AS STATE, info AS INFO FROM oceanbase.__all_virtual_processlist WHERE is_serving_tenant(svr_ip, svr_port, effective_tenant_id()) )__"))) {
if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT id AS ID, user AS USER, concat(user_client_ip, ':', user_client_port) AS HOST, db AS DB, command AS COMMAND, time AS TIME, state AS STATE, info AS INFO FROM oceanbase.__all_virtual_processlist WHERE is_serving_tenant(svr_ip, svr_port, effective_tenant_id()) )__"))) {
LOG_ERROR("fail to set view_definition", K(ret));
}
}

View File

@ -14135,7 +14135,7 @@ def_table_schema(
table_type = 'SYSTEM_VIEW',
gm_columns = [],
rowkey_columns = [],
view_definition = """SELECT id AS ID, user AS USER, host AS HOST, db AS DB, command AS COMMAND, time AS TIME, state AS STATE, info AS INFO FROM oceanbase.__all_virtual_processlist WHERE is_serving_tenant(svr_ip, svr_port, effective_tenant_id())
view_definition = """SELECT id AS ID, user AS USER, concat(user_client_ip, ':', user_client_port) AS HOST, db AS DB, command AS COMMAND, time AS TIME, state AS STATE, info AS INFO FROM oceanbase.__all_virtual_processlist WHERE is_serving_tenant(svr_ip, svr_port, effective_tenant_id())
""".replace("\n", " "),
in_tenant_space = True,

File diff suppressed because one or more lines are too long

View File

@ -460,8 +460,9 @@ DEFINE_ERROR(OB_ENCODING_EST_SIZE_OVERFLOW, -4397, -1, "HY000", "Encoding estima
DEFINE_ORACLE_ERROR(OB_INVALID_SUB_PARTITION_TYPE, -4398, 1500, "HY000", "It is only possible to mix RANGE/LIST partitioning with HASH/KEY partitioning for subpartitioning", 14020, "this physical attribute may not be specified for a table partition");
DEFINE_ERROR(OB_ERR_UNEXPECTED_UNIT_STATUS, -4399, -1, "HY000", "Unit status is not expected");
DEFINE_ERROR(OB_AUTOINC_CACHE_NOT_EQUAL, -4400, -1, "HY000", "Autoinc cache's autoinc version is not equal to request's autoinc version");
// DEFINE_ERROR(OB_ERR_KILL_CLIENT_SESSION, -4401, -1, "HY000", "Client Session need be killed");
// DEFINE_ERROR(OB_ERR_KILL_CLIENT_SESSION_FAILED, -4402, -1, "HY000", "Kill Client Session failed");
DEFINE_ORACLE_ERROR(OB_ERR_KILL_CLIENT_SESSION, -4401, 4401, "HY000", "Client Session need be killed", 4401, "Client Session need be killed");
DEFINE_ERROR(OB_ERR_KILL_CLIENT_SESSION_FAILED, -4402, -1, "HY000", "Kill Client Session failed");
DEFINE_ERROR(OB_IMPROPER_OS_PARAM, -4403, -1, "HY000", "OS params check failed, because the operating system has improper parameter configurations");
////////////////////////////////////////////////////////////////
//error code for root server & server management -4500 ---- -5000

View File

@ -266,6 +266,8 @@ constexpr int OB_ENCODING_EST_SIZE_OVERFLOW = -4397;
constexpr int OB_INVALID_SUB_PARTITION_TYPE = -4398;
constexpr int OB_ERR_UNEXPECTED_UNIT_STATUS = -4399;
constexpr int OB_AUTOINC_CACHE_NOT_EQUAL = -4400;
constexpr int OB_ERR_KILL_CLIENT_SESSION = -4401;
constexpr int OB_ERR_KILL_CLIENT_SESSION_FAILED = -4402;
constexpr int OB_IMPROPER_OS_PARAM = -4403;
constexpr int OB_IMPORT_NOT_IN_SERVER = -4505;
constexpr int OB_CONVERT_ERROR = -4507;
@ -2200,6 +2202,8 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_INVALID_SUB_PARTITION_TYPE__USER_ERROR_MSG "It is only possible to mix RANGE/LIST partitioning with HASH/KEY partitioning for subpartitioning"
#define OB_ERR_UNEXPECTED_UNIT_STATUS__USER_ERROR_MSG "Unit status is not expected"
#define OB_AUTOINC_CACHE_NOT_EQUAL__USER_ERROR_MSG "Autoinc cache's autoinc version is not equal to request's autoinc version"
#define OB_ERR_KILL_CLIENT_SESSION__USER_ERROR_MSG "Client Session need be killed"
#define OB_ERR_KILL_CLIENT_SESSION_FAILED__USER_ERROR_MSG "Kill Client Session failed"
#define OB_IMPROPER_OS_PARAM__USER_ERROR_MSG "OS params check failed, because the operating system has improper parameter configurations"
#define OB_IMPORT_NOT_IN_SERVER__USER_ERROR_MSG "Import not in service"
#define OB_CONVERT_ERROR__USER_ERROR_MSG "Convert error"
@ -4393,6 +4397,8 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_INVALID_SUB_PARTITION_TYPE__ORA_USER_ERROR_MSG "ORA-14020: this physical attribute may not be specified for a table partition"
#define OB_ERR_UNEXPECTED_UNIT_STATUS__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4399, Unit status is not expected"
#define OB_AUTOINC_CACHE_NOT_EQUAL__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4400, Autoinc cache's autoinc version is not equal to request's autoinc version"
#define OB_ERR_KILL_CLIENT_SESSION__ORA_USER_ERROR_MSG "ORA-04401: Client Session need be killed"
#define OB_ERR_KILL_CLIENT_SESSION_FAILED__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4402, Kill Client Session failed"
#define OB_IMPROPER_OS_PARAM__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4403, OS params check failed, because the operating system has improper parameter configurations"
#define OB_IMPORT_NOT_IN_SERVER__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4505, Import not in service"
#define OB_CONVERT_ERROR__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4507, Convert error"
@ -6224,7 +6230,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)"
#define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld"
extern int g_all_ob_errnos[2189];
extern int g_all_ob_errnos[2191];
const char *ob_error_name(const int oberr);
const char* ob_error_cause(const int oberr);

View File

@ -9582,6 +9582,22 @@ OB_DEF_SERIALIZE_SIZE(ObSessionInfoVeriRes)
return len;
}
bool ObKillClientSessionArg::is_valid() const
{
return true;
}
bool ObKillClientSessionRes::is_valid() const
{
return true;
}
OB_SERIALIZE_MEMBER(ObKillClientSessionArg, create_time_, client_sess_id_);
OB_SERIALIZE_MEMBER(ObKillClientSessionRes, can_kill_client_sess_);
OB_SERIALIZE_MEMBER(ObClientSessionCreateTimeAndAuthArg, client_sess_id_, tenant_id_, user_id_, has_user_super_privilege_);
OB_SERIALIZE_MEMBER(ObClientSessionCreateTimeAndAuthRes, client_sess_create_time_, have_kill_auth_);
OB_SERIALIZE_MEMBER(ObGetLeaderLocationsArg, addr_);
OB_SERIALIZE_MEMBER(ObGetLeaderLocationsResult, addr_, leader_replicas_);

View File

@ -10282,6 +10282,129 @@ public:
share::ObLSID ls_id_;
int64_t lock_id_;
};
// kill client session arg
struct ObKillClientSessionArg
{
OB_UNIS_VERSION(1);
public:
ObKillClientSessionArg() : create_time_(0), client_sess_id_(0) {}
~ObKillClientSessionArg() {}
bool is_valid() const;
void reset() { create_time_ = 0;
client_sess_id_ = 0; }
int assign(const ObKillClientSessionArg &other)
{
int ret = common::OB_SUCCESS;
create_time_ = other.create_time_;
client_sess_id_ = other.client_sess_id_;
return ret;
}
void set_create_time(int64_t create_time) { create_time_ = create_time; }
int64_t get_create_time() { return create_time_; }
void set_client_sess_id(uint32_t client_sess_id) { client_sess_id_ = client_sess_id; }
uint32_t get_client_sess_id() { return client_sess_id_; }
TO_STRING_KV(K_(create_time), K_(client_sess_id));
private:
int64_t create_time_;
uint32_t client_sess_id_;
};
// kill client session result
struct ObKillClientSessionRes
{
OB_UNIS_VERSION(1);
public:
ObKillClientSessionRes() : can_kill_client_sess_(false) {}
~ObKillClientSessionRes() {}
bool is_valid() const;
void reset() { can_kill_client_sess_ = false;}
int assign(const ObKillClientSessionRes &other)
{
int ret = common::OB_SUCCESS;
can_kill_client_sess_ = other.can_kill_client_sess_;
return ret;
}
void set_can_kill_client_sess(bool can_kill_client_sess) { can_kill_client_sess_ = can_kill_client_sess; }
bool get_can_kill_client_sess() {return can_kill_client_sess_;}
TO_STRING_KV(K_(can_kill_client_sess));
bool can_kill_client_sess_;
};
// kill client session arg & Authentication
struct ObClientSessionCreateTimeAndAuthArg
{
OB_UNIS_VERSION(1);
public:
ObClientSessionCreateTimeAndAuthArg() : client_sess_id_(0),
tenant_id_(0), user_id_(0), has_user_super_privilege_(false) {}
~ObClientSessionCreateTimeAndAuthArg() {}
bool is_valid() const;
void reset()
{
client_sess_id_ = 0;
tenant_id_ = 0;
user_id_ = 0;
has_user_super_privilege_ = false;
}
int assign(const ObClientSessionCreateTimeAndAuthArg &other)
{
int ret = common::OB_SUCCESS;
client_sess_id_ = other.client_sess_id_;
tenant_id_ = other.tenant_id_;
user_id_ = other.user_id_;
has_user_super_privilege_ = other.has_user_super_privilege_;
return ret;
}
void set_client_sess_id(uint32_t client_sess_id) { client_sess_id_ = client_sess_id; }
uint32_t get_client_sess_id() { return client_sess_id_; }
void set_tenant_id(uint64_t tenant_id) { tenant_id_ = tenant_id; }
uint64_t get_tenant_id() { return tenant_id_; }
void set_user_id(uint64_t user_id) { user_id_ = user_id; }
uint64_t get_user_id() { return user_id_; }
void set_has_user_super_privilege(bool has_user_super_privilege)
{
has_user_super_privilege_ = has_user_super_privilege;
}
bool is_has_user_super_privilege() { return has_user_super_privilege_; }
TO_STRING_KV(K_(client_sess_id), K_(tenant_id), K_(user_id), K_(has_user_super_privilege));
private:
uint32_t client_sess_id_;
uint64_t tenant_id_;
uint64_t user_id_;
bool has_user_super_privilege_;
};
// kill client session result
struct ObClientSessionCreateTimeAndAuthRes
{
OB_UNIS_VERSION(1);
public:
ObClientSessionCreateTimeAndAuthRes() : client_sess_create_time_(0), have_kill_auth_(false) {}
~ObClientSessionCreateTimeAndAuthRes() {}
bool is_valid() const;
void reset()
{
client_sess_create_time_ = 0;
have_kill_auth_ = false;
}
int assign(const ObClientSessionCreateTimeAndAuthRes &other)
{
int ret = common::OB_SUCCESS;
client_sess_create_time_ = other.client_sess_create_time_;
have_kill_auth_ = other.have_kill_auth_;
return ret;
}
void set_client_create_time(int64_t client_sess_create_time)
{
client_sess_create_time_ = client_sess_create_time;
}
int64_t get_client_create_time() { return client_sess_create_time_; }
void set_have_kill_auth(bool have_kill_auth) { have_kill_auth_ = have_kill_auth; }
bool is_have_kill_auth() {return have_kill_auth_;}
TO_STRING_KV(K_(client_sess_create_time), K_(have_kill_auth));
int64_t client_sess_create_time_;
bool have_kill_auth_;
};
struct ObTabletLocationSendArg final
{

View File

@ -238,8 +238,8 @@ public:
RPC_S(PR5 dispatch_ttl, OB_TABLE_TTL, (obrpc::ObTTLRequestArg), obrpc::ObTTLResponseArg);
RPC_S(PR5 admin_unlock_member_list_op, OB_HA_UNLOCK_MEMBER_LIST, (obrpc::ObAdminUnlockMemberListOpArg));
RPC_AP(PR5 tablet_major_freeze, OB_TABLET_MAJOR_FREEZE, (ObTabletMajorFreezeArg), obrpc::Int64);
// RPC_AP(PR5 kill_client_session, OB_KILL_CLIENT_SESSION, (ObKillClientSessionArg), ObKillClientSessionRes);
// RPC_S(PR5 client_session_create_time, OB_CLIENT_SESSION_CONNECT_TIME, (ObClientSessionCreateTimeArg), ObClientSessionCreateTimeRes);
RPC_AP(PR5 kill_client_session, OB_KILL_CLIENT_SESSION, (ObKillClientSessionArg), ObKillClientSessionRes);
RPC_S(PR5 client_session_create_time, OB_CLIENT_SESSION_CONNECT_TIME, (ObClientSessionCreateTimeAndAuthArg), ObClientSessionCreateTimeAndAuthRes);
RPC_AP(PR5 tablet_location_send, OB_TABLET_LOCATION_BROADCAST, (obrpc::ObTabletLocationSendArg), obrpc::ObTabletLocationSendResult);
}; // end of class ObSrvRpcProxy

View File

@ -40,17 +40,39 @@ int ObKillExecutor::execute(ObExecContext &ctx, ObKillStmt &stmt)
if (OB_FAIL(arg.init(ctx, stmt))) {
LOG_WARN("fail to init kill_session arg", K(ret), K(arg), K(ctx), K(stmt));
} else if (OB_FAIL(kill_session(arg, session_mgr))) {
if (OB_ENTRY_NOT_EXIST == ret) {//doesn't find sessid in current server
if (OB_FAIL(get_remote_session_location(arg, ctx, addr))) {
LOG_WARN("fail to get remote session location", K(ret), K(arg), K(ctx), K(addr));
} else if (OB_FAIL(kill_remote_session(ctx, addr, arg))) {
LOG_WARN("fail to kill remote session", K(ret), K(ctx), K(addr), K(arg));
} else { /*do nothing*/}
} else {
LOG_WARN("fail to kill session", K(ret), K(arg));
} else {
uint32_t SERVER_SESSID_TAG = 1ULL << 31;
bool is_client_id_support = false;
if (OB_NOT_NULL(ctx.get_my_session())) {
is_client_id_support = ctx.get_my_session()->is_client_sessid_support();
}
} else {/*do nothing*/}
bool direct_mode = !is_client_id_support ||
((arg.sess_id_ & SERVER_SESSID_TAG) >> 31) || arg.is_query_ == true;
// Direct connection scenario kill session or kill query
if (direct_mode) {
if (OB_FAIL(kill_session(arg, session_mgr))) {
if (OB_ENTRY_NOT_EXIST == ret) {//doesn't find sessid in current server
if (OB_FAIL(get_remote_session_location(arg, ctx, addr))) {
LOG_WARN("fail to get remote session location", K(ret), K(arg), K(ctx), K(addr));
} else if (OB_FAIL(kill_remote_session(ctx, addr, arg))) {
LOG_WARN("fail to kill remote session", K(ret), K(ctx), K(addr), K(arg));
} else { /*do nothing*/}
} else {
LOG_WARN("fail to kill session", K(ret), K(arg));
}
}
} else {
// Proxy connection scenario kill session.
if (OB_FAIL(kill_client_session(arg, session_mgr, ctx))) {
if (ret == OB_ERR_KILL_CLIENT_SESSION) {
LOG_DEBUG("Succ to Kill Client Session", K(ret), K(arg));
} else {
LOG_WARN("Fail to kill client session", K(ret), K(arg));
}
} else {
}
}
}
if (OB_UNKNOWN_CONNECTION == ret) {
LOG_USER_ERROR(OB_UNKNOWN_CONNECTION, static_cast<uint64_t>(arg.sess_id_));
@ -60,6 +82,200 @@ int ObKillExecutor::execute(ObExecContext &ctx, ObKillStmt &stmt)
return ret;
}
int ObKillExecutor::kill_client_session(const ObKillSessionArg &arg, ObSQLSessionMgr &sess_mgr,
ObExecContext &ctx)
{
int ret = OB_SUCCESS;
int tmp_ret = OB_SUCCESS;
ObSQLSessionInfo *sess_info = NULL;
ObSQLSessionInfo *curr_sess_info = NULL;
ObAddr addr;
uint32_t client_sess_id = arg.sess_id_;
uint32_t server_sess_id = INVALID_SESSID;
// Proxy connection scenario kill session
if (OB_ISNULL(curr_sess_info = ctx.get_my_session())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session is NULL", K(ret), K(ctx));
} else if (OB_FAIL(sess_mgr.get_client_sess_map().get_refactored(client_sess_id, server_sess_id))) {
//The current machine does not have this id and needs to be broadcast to other machines.
// 1. In order to obtain the create time of the killed client ID for storing the map,
// if it cannot be found on the current machine, you need to search globally.
// 2. If no one can be found, the kill will fail directly. It should be an illegal ID.
// 3. If found, the first address that can be obtained is recorded. If the address is
// specified, the time will be sent back when sending remotely.
// If all machines are unsuccessful, it should be that this ID does not exist or
// there is a network problem. If some are successful and some fail, it is a network problem.
LOG_WARN("fail to get client session in this server", K(ret), K(client_sess_id));
ret = OB_SUCCESS;
} else if (OB_FAIL(sess_mgr.get_session(server_sess_id, sess_info))) {
ret = OB_SUCCESS;
} else if (OB_ISNULL(sess_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session info is NULL", K(ret), K(client_sess_id));
} else if (client_sess_id == curr_sess_info->get_client_sessid()) {
// If it is kill the session currently executing the kill command
// it can directly return the error code to the proxy.
sess_info->set_mark_killed(true);
ret = OB_ERR_KILL_CLIENT_SESSION;
LOG_INFO("current server conclude kill client session", K(arg.sess_id_));
} else {
}
if (OB_SUCC(ret)) {
ObAddr cs_addr;
int64_t create_time = 0;
// current server not have cs_id, find it in remote.
// If there is no link between proxy and server,
// unknown client session id will be reported.
if (OB_FAIL(get_remote_session_location(arg, ctx, cs_addr, true))) {
LOG_WARN("fail to get client session location, unknown client sessid",
K(ret), K(arg), K(ctx), K(cs_addr));
// Obtain the client establishment time for map maintenance.
} else if (OB_FAIL(get_client_session_create_time_and_auth(arg, ctx, cs_addr, create_time))) {
LOG_WARN("fail to get client session create time or no auth",
K(ret), K(arg), K(ctx), K(cs_addr), K(ret));
// If the time cannot be obtained, return kill failure.
if (ret == OB_ENTRY_NOT_EXIST) {
ret = OB_ERR_KILL_CLIENT_SESSION_FAILED;
}
} else if (cs_addr.is_valid()) {
obrpc::ObKillClientSessionArg cs_arg;
obrpc::ObKillClientSessionRes cs_result;
common::ObZone zone;
ObArray<share::ObServerInfoInTable> servers_info;
bool is_kill_succ = true;
// Determine the broadcast range based on whether it is a system tenant
// bool is_sys_kill = curr_sess_info->get_effective_tenant_id() == OB_SYS_TENANT_ID;
// Currently, there is no interface for querying node addresses at tenant granularity,
// which can be optimized later.
LOG_DEBUG("Begin to send kill session rpc", K(arg.sess_id_),K(create_time));
if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(GCTX.root_service_)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("fail to get srv_rpc_proxy", K(ret), K(GCTX.srv_rpc_proxy_),
K(GCTX.root_service_));
} else if (OB_FAIL(share::ObAllServerTracer::get_instance().get_servers_info(
zone, servers_info))) {
LOG_WARN("fail to get servers info", K(ret));
} else if (FALSE_IT(cs_arg.set_create_time(create_time))) {
} else if (FALSE_IT(cs_arg.set_client_sess_id(client_sess_id))) {
} else {
ObAddr addr;
const int64_t rpc_timeout = GCONF.rpc_timeout;
rootserver::ObKillClientSessionProxy proxy(*GCTX.srv_rpc_proxy_,
&obrpc::ObSrvRpcProxy::kill_client_session);
for (int64_t i = 0; OB_SUCC(ret) && i < servers_info.count(); i++) {
addr = servers_info.at(i).get_server();
if (addr != GCTX.self_addr() && OB_FAIL(proxy.call(addr, rpc_timeout,
curr_sess_info->get_effective_tenant_id(), cs_arg))) {
LOG_WARN("send rpc failed", KR(ret),
K(rpc_timeout), K(arg), "server", addr);
ret = OB_SUCCESS;
}
}
int tmp_ret = OB_SUCCESS;
ObArray<int> return_code_array;
if (OB_TMP_FAIL(proxy.wait_all(return_code_array))) {
LOG_WARN("wait result failed", KR(tmp_ret));
is_kill_succ = false;
} else if (return_code_array.count() != proxy.get_results().count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("cnt not match",
K(ret),
"return_cnt",
return_code_array.count(),
"result_cnt",
proxy.get_results().count());
} else {
for (int64_t i = 0; i < proxy.get_results().count(); i++) {
if (OB_FAIL(return_code_array.at(i))) {
if (return_code_array.at(i) == OB_TENANT_NOT_IN_SERVER) {
ret = OB_SUCCESS; // ignore error
} else {
LOG_WARN("rpc execute failed", KR(ret));
}
} else {
const obrpc::ObKillClientSessionRes *result = proxy.get_results().at(i);
if (OB_ISNULL(result)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("fail to get result", K(ret), K(i));
} else if (const_cast<obrpc::ObKillClientSessionRes*>(
result)->get_can_kill_client_sess() == false) {
is_kill_succ = false;
}
}
}
}
}
if (OB_FAIL(ret)) {
// do nothing.
} else if (is_kill_succ == false) {
ret = OB_ERR_KILL_CLIENT_SESSION_FAILED;
LOG_WARN("Fail to Kill Client Session", K(ret), K(client_sess_id));
} else {
LOG_INFO("Succ to Kill Client Session", K(ret), K(client_sess_id));
}
// In the end, if everything succeeds here, the current map will be recorded.
// If it is not completely successful, there is no need to record it, in order
// to ensure that the recording time is valid.
if (OB_FAIL(ret)) {
LOG_WARN("kill client session not all successful", K(ret), K(cs_arg));
} else {
if (NULL != sess_info) {
// The mark maintained here is used to trigger a link
// break when the next request hits the current session.
sess_info->set_mark_killed(true);
}
// The reason for maintaining the kill session id map is that proxy A's kill
// request kills proxy B's client link. The next time a new connection is requested,
// the map will be used to determine whether kill is needed.
int flag = 1;
sess_mgr.get_kill_client_sess_map().set_refactored(client_sess_id, create_time, flag);
}
}
}
if (NULL != sess_info) {
sess_mgr.revert_session(sess_info);
}
return ret;
}
int ObKillExecutor::get_client_session_create_time_and_auth(const ObKillSessionArg &arg, ObExecContext &ctx,
common::ObAddr &cs_addr, int64_t &create_time)
{
int ret = OB_SUCCESS;
obrpc::ObClientSessionCreateTimeAndAuthArg cs_arg;
obrpc::ObClientSessionCreateTimeAndAuthRes cs_result;
common::ObZone zone;
ObArray<share::ObServerInfoInTable> servers_info;
if (OB_ISNULL(GCTX.srv_rpc_proxy_)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("fail to get srv_rpc_proxy", K(ret), K(GCTX.srv_rpc_proxy_));
} else if (OB_FAIL(share::ObAllServerTracer::get_instance().get_servers_info(
zone, servers_info))) {
LOG_WARN("fail to get servers info", K(ret));
} else if (FALSE_IT(cs_arg.set_client_sess_id(arg.sess_id_))) {
} else if (FALSE_IT(cs_arg.set_tenant_id(arg.tenant_id_))) {
} else if (FALSE_IT(cs_arg.set_has_user_super_privilege(arg.has_user_super_privilege_))) {
} else if (FALSE_IT(cs_arg.set_user_id(arg.user_id_))) {
} else if (OB_FAIL(GCTX.srv_rpc_proxy_->to(cs_addr).by(MTL_ID()).
client_session_create_time(cs_arg, cs_result))) {
// rpc fail not kill client session.
LOG_WARN("fail to rpc", K(ret));
} else if (cs_result.is_have_kill_auth() == false) {
ret = OB_ERR_KILL_DENIED;
LOG_WARN("no permissions for kill", K(ret), K(arg.sess_id_));
} else if (FALSE_IT(create_time = cs_result.get_client_create_time())) {
} else if (create_time == 0) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to set client create time", K(ret));
}
return ret;
}
//If you are in system tenant, you can kill all threads and statements in any tenant.
//If you have the SUPER privilege, you can kill all threads and statements at your Tenant.
//Otherwise, you can kill only your own threads and statements.
@ -94,7 +310,9 @@ int ObKillSession::kill_session(const ObKillSessionArg &arg, ObSQLSessionMgr &se
return ret;
}
int ObKillExecutor::get_remote_session_location(const ObKillSessionArg &arg, ObExecContext &ctx, ObAddr &addr)
// is_client_session = true, for finding kill client session
int ObKillExecutor::get_remote_session_location(const ObKillSessionArg &arg,
ObExecContext &ctx, ObAddr &addr, bool is_client_session)
{
int ret = OB_SUCCESS;
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
@ -149,7 +367,7 @@ int ObKillExecutor::get_remote_session_location(const ObKillSessionArg &arg, ObE
//set addr
if (OB_FAIL(ret)) {
} else if (OB_UNLIKELY(OB_ITER_END != result_set->next())) {
} else if (!is_client_session && OB_UNLIKELY(OB_ITER_END != result_set->next())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("more than one sessid record", K(ret), K(arg), K(read_sql));
} else if (OB_UNLIKELY(!addr.set_ip_addr(svr_ip, static_cast<int32_t>(svr_port)))) {

View File

@ -50,7 +50,11 @@ public:
virtual ~ObKillExecutor() {}
int execute(ObExecContext &ctx, ObKillStmt &stmt);
private:
int get_remote_session_location(const ObKillSessionArg &arg, ObExecContext &ctx, common::ObAddr &addr);
int kill_client_session(const ObKillSessionArg &arg, ObSQLSessionMgr &sess_mgr,
ObExecContext &ctx);
int get_client_session_create_time_and_auth(const ObKillSessionArg &arg, ObExecContext &ctx,
common::ObAddr &cs_addr, int64_t &create_time);
int get_remote_session_location(const ObKillSessionArg &arg, ObExecContext &ctx, common::ObAddr &addr, bool is_client_session = false);
int generate_read_sql(uint32_t sess_id, common::ObSqlString &sql);
int generate_read_sql_from_session_info(uint32_t sess_id, common::ObSqlString &sql);
int kill_remote_session(ObExecContext &ctx, const common::ObAddr &addr, const ObKillSessionArg &arg);

View File

@ -52,6 +52,8 @@ int ObExprConnectionId::eval_connection_id(const ObExpr &expr, ObEvalCtx &ctx,
LOG_WARN("session info is null", K(ret));
} else {
auto sid = session_info->is_master_session() ? session_info->get_sessid() : session_info->get_master_sessid();
sid = session_info->get_client_sessid() == INVALID_SESSID ?
sid : session_info->get_client_sessid();
expr_datum.set_uint32(sid);
}
return ret;

View File

@ -402,7 +402,7 @@ int ObExprSysContext::eval_sessionid(const ObExpr &expr, ObDatum &res, const ObD
const ObSQLSessionInfo *session = ctx.exec_ctx_.get_my_session();
CK(OB_NOT_NULL(session));
if (OB_SUCC(ret)) {
const uint64_t sid = session->get_sessid();
const uint64_t sid = session->get_compatibility_sessid();
char out_id[256];
sprintf(out_id, "%lu", sid);
ObString out_id_str(strlen(out_id), out_id);

View File

@ -242,7 +242,7 @@ int ObExprUserEnv::eval_sessionid_result1(const ObExpr &expr, ObEvalCtx &ctx, Ob
} else if (arg->is_null()) {
res.set_null();
} else {
const uint64_t sid = ctx.exec_ctx_.get_my_session()->get_sessid();
const uint64_t sid = ctx.exec_ctx_.get_my_session()->get_compatibility_sessid();
ObNumStackOnceAlloc tmp_alloc;
number::ObNumber res_nmb;
if (OB_FAIL(res_nmb.from(sid, tmp_alloc))) {

View File

@ -68,6 +68,8 @@ ObBasicSessionInfo::ObBasicSessionInfo(const uint64_t tenant_id)
driver_version_(),
sessid_(0),
master_sessid_(INVALID_SESSID),
client_sessid_(INVALID_SESSID),
client_create_time_(0),
proxy_sessid_(VALID_PROXY_SESSID),
global_vars_version_(0),
sys_var_base_version_(OB_INVALID_VERSION),
@ -338,6 +340,8 @@ void ObBasicSessionInfo::reset(bool skip_sys_var)
driver_version_.reset();
sessid_ = 0;
master_sessid_ = INVALID_SESSID;
client_sessid_ = INVALID_SESSID;
client_create_time_ = 0,
proxy_sessid_ = VALID_PROXY_SESSID;
global_vars_version_ = 0;
@ -652,7 +656,7 @@ int ObBasicSessionInfo::set_user(const ObString &user_name, const ObString &host
return ret;
}
int ObBasicSessionInfo::set_real_client_ip(const common::ObString &client_ip)
int ObBasicSessionInfo::set_real_client_ip_and_port(const common::ObString &client_ip, int32_t client_addr_port)
{
int ret = OB_SUCCESS;
char tmp_buf[common::OB_MAX_USER_NAME_LENGTH + common::OB_MAX_HOST_NAME_LENGTH + 2] = {};
@ -667,7 +671,8 @@ int ObBasicSessionInfo::set_real_client_ip(const common::ObString &client_ip)
} else if (OB_FAIL(name_pool_.write_string(tmp_string, &thread_data_.user_at_client_ip_))) {
LOG_WARN("fail to write user_at_host_name to string_buf_", K(tmp_string), K(ret));
} else {
thread_data_.user_client_addr_.set_ip_addr(client_ip, 0);
thread_data_.client_addr_port_ = client_addr_port;
thread_data_.user_client_addr_.set_ip_addr(client_ip, client_addr_port);
}
return ret;
}

View File

@ -663,6 +663,21 @@ public:
int gen_sys_var_in_pc_str();
int gen_configs_in_pc_str();
uint32_t get_sessid() const { return sessid_; }
// Used for view or function compatibility display.
uint32_t get_compatibility_sessid() const
{
return client_sessid_ == INVALID_SESSID ? sessid_ : client_sessid_;
}
uint32_t get_client_sessid() const { return client_sessid_; }
inline void set_client_sessid(uint32_t client_sessid)
{
client_sessid_ = client_sessid;
}
uint64_t get_client_create_time() const { return client_create_time_; }
inline void set_client_create_time(uint64_t client_create_time)
{
client_create_time_ = client_create_time;
}
uint64_t get_proxy_sessid() const { return proxy_sessid_; }
uint64_t get_sessid_for_table() const { return is_obproxy_mode()? get_proxy_sessid() : (is_master_session() ? get_sessid() : get_master_sessid()); } //用于临时表、查询建表时session id获取
uint32_t get_master_sessid() const { return master_sessid_; }
@ -691,12 +706,17 @@ public:
/// @{ thread_data_ related: }
int set_user(const common::ObString &user_name, const common::ObString &host_name, const uint64_t user_id);
int set_real_client_ip(const common::ObString &client_ip);
int set_real_client_ip_and_port(const common::ObString &client_ip, int32_t client_addr_port);
const common::ObString &get_user_name() const { return thread_data_.user_name_;}
const common::ObString &get_host_name() const { return thread_data_.host_name_;}
const common::ObString &get_client_ip() const { return thread_data_.client_ip_;}
const common::ObString &get_user_at_host() const { return thread_data_.user_at_host_name_;}
const common::ObString &get_user_at_client_ip() const { return thread_data_.user_at_client_ip_;}
void set_client_addr_port(const int32_t client_addr_port)
{
thread_data_.client_addr_port_ = client_addr_port;
};
int32_t get_client_addr_port() const { return thread_data_.client_addr_port_; };
rpc::ObSqlSockDesc& get_sock_desc() { return thread_data_.sock_desc_;}
observer::ObSMConnection *get_sm_connection();
void set_peer_addr(common::ObAddr peer_addr)
@ -1167,6 +1187,8 @@ public:
}
void set_shadow(bool is_shadow) { ATOMIC_STORE(&thread_data_.is_shadow_, is_shadow); }
bool is_shadow() { return ATOMIC_LOAD(&thread_data_.is_shadow_); }
void set_mark_killed(bool is_mark_killed) { ATOMIC_STORE(&thread_data_.is_mark_killed_, is_mark_killed); }
bool is_mark_killed() { return ATOMIC_LOAD(&thread_data_.is_mark_killed_); }
uint32_t get_magic_num() {return magic_num_;}
int64_t get_current_execution_id() const { return current_execution_id_; }
const common::ObCurTraceId::TraceId &get_last_trace_id() const { return last_trace_id_; }
@ -1300,6 +1322,9 @@ public:
void set_password_expired(bool value) { is_password_expired_ = value; }
int64_t get_process_query_time() const { return process_query_time_; }
void set_process_query_time(int64_t time) { process_query_time_ = time; }
inline void set_client_sessid_support(bool is_client_sessid_support)
{ is_client_sessid_support_ = is_client_sessid_support; }
inline bool is_client_sessid_support() { return is_client_sessid_support_; }
int replace_new_session_label(uint64_t policy_id, const share::ObLabelSeSessionLabel &new_session_label);
int load_default_sys_variable(common::ObIAllocator &allocator, int64_t var_idx);
@ -1418,7 +1443,9 @@ protected:
interactive_timeout_(0),
max_packet_size_(MultiThreadData::DEFAULT_MAX_PACKET_SIZE),
is_shadow_(false),
is_in_retry_(SESS_NOT_IN_RETRY)
is_in_retry_(SESS_NOT_IN_RETRY),
client_addr_port_(0),
is_mark_killed_(false)
{
CHAR_CARRAY_INIT(database_name_);
}
@ -1455,6 +1482,8 @@ protected:
max_packet_size_ = MultiThreadData::DEFAULT_MAX_PACKET_SIZE;
is_shadow_ = false;
is_in_retry_ = SESS_NOT_IN_RETRY;
client_addr_port_ = 0;
is_mark_killed_ = false;
}
~MultiThreadData ()
{
@ -1488,6 +1517,8 @@ protected:
int64_t max_packet_size_;
bool is_shadow_;
ObSessionRetryStatus is_in_retry_;//标识当前session是否处于query retry的状态
int32_t client_addr_port_; // Record client address port.
bool is_mark_killed_; // Mark the current session as delayed kill
};
public:
@ -2037,6 +2068,8 @@ private:
common::ObString driver_version_; // current driver version
uint32_t sessid_;
uint32_t master_sessid_;
uint32_t client_sessid_;
uint64_t client_create_time_;
uint64_t proxy_sessid_;
int64_t global_vars_version_; // used for obproxy synchronize variables
int64_t sys_var_base_version_;

View File

@ -214,7 +214,7 @@ ObSQLSessionInfo::~ObSQLSessionInfo()
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)
uint64_t tenant_id, int64_t client_create_time)
{
UNUSED(tenant_id);
int ret = OB_SUCCESS;
@ -245,6 +245,7 @@ int ObSQLSessionInfo::init(uint32_t sessid, uint64_t proxy_sessid,
} 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_))) {

View File

@ -732,7 +732,8 @@ public:
common::ObIAllocator *bucket_allocator,
const ObTZInfoMap *tz_info = NULL,
int64_t sess_create_time = 0,
uint64_t tenant_id = OB_INVALID_TENANT_ID);
uint64_t tenant_id = OB_INVALID_TENANT_ID,
int64_t client_create_time = 0);
//for test
int test_init(uint32_t version, uint32_t sessid, uint64_t proxy_sessid,
common::ObIAllocator *bucket_allocator);
@ -1410,7 +1411,6 @@ private:
bool is_ob20_protocol_; // mark as whether use oceanbase 2.0 protocol
bool is_session_var_sync_; //session var sync support flag.
common::hash::ObHashSet<common::ObString> *pl_sync_pkg_vars_ = NULL;
void *inner_conn_; // ObInnerSQLConnection * will cause .h included from each other.

View File

@ -255,9 +255,36 @@ void ObSQLSessionMgr::ValueAlloc::free_value(ObSQLSessionInfo *session)
int64_t free_total_count = 0;
// delete from hold map, ingore error
int tmp_ret = OB_SUCCESS;
uint32_t server_sessid = INVALID_SESSID;
if (OB_SUCCESS != (tmp_ret = GCTX.session_mgr_->get_sess_hold_map().erase_refactored(
reinterpret_cast<uint64_t>(session)))) {
LOG_WARN("fail to erase session", K(session->get_sessid()), K(tmp_ret), KP(session));
} else if (session->get_client_sessid() != INVALID_SESSID) {
if (OB_SUCCESS != (tmp_ret = GCTX.session_mgr_->get_client_sess_map().get_refactored(
session->get_client_sessid(), server_sessid))) {
if (tmp_ret == OB_HASH_NOT_EXIST) {
// no need to display info, if current server no this client session id.
tmp_ret = OB_SUCCESS;
LOG_DEBUG("current client session id not find", K(tmp_ret),
K(session->get_client_sessid()));
} else {
COMMON_LOG(WARN, "get session failed", K(tmp_ret), K(session->get_client_sessid()));
}
} else if (session->get_sessid() == server_sessid) {
ObClientSessMapErase client_sess_map_erase(session->get_sessid());
bool is_erased = false;
if (OB_SUCCESS != (tmp_ret = GCTX.session_mgr_->get_client_sess_map().erase_if(
session->get_client_sessid(),client_sess_map_erase, is_erased))) {
LOG_WARN("fail to erase client session", K(session->get_client_sessid()),
K(session->get_sessid()), K(tmp_ret));
} else {
LOG_DEBUG("success to erase cs id", K(session->get_client_sessid()),
K(session->get_sessid()), K(lbt()));
}
} else {
LOG_DEBUG("no need to erase client session", K(session->get_client_sessid()),
K(session->get_sessid()), K(server_sessid), K(tmp_ret),K(lbt()));
}
}
auto *t_session_mgr = session->get_tenant_session_mgr();
if (t_session_mgr != NULL) {
@ -282,6 +309,14 @@ int ObSQLSessionMgr::init()
SET_USE_500("SessHoldMapBuck"),
SET_USE_500("SessHoldMapNode")))) {
LOG_WARN("failed to init sess_hold_map", K(ret));
} else if (OB_FAIL(client_sess_map_.create(BUCKET_COUNT,
SET_USE_500("ClientSessBuck"),
SET_USE_500("ClientSessNode")))) {
LOG_WARN("failed to init client_sess_map", K(ret));
} else if (OB_FAIL(kill_client_sess_map_.create(BUCKET_COUNT,
SET_USE_500("KillSessMapBuck"),
SET_USE_500("KillSessMapNode")))) {
LOG_WARN("failed to init client_sess_map", K(ret));
}
for (uint32_t i = 1; OB_SUCC(ret) && i <= MAX_LOCAL_SEQ; ++i) {
if (OB_FAIL(sessid_sequence_.push(reinterpret_cast<void*>(i)))) {
@ -295,6 +330,8 @@ void ObSQLSessionMgr::destroy()
{
sessinfo_map_.destroy();
sessid_sequence_.destroy();
client_sess_map_.destroy();
kill_client_sess_map_.destroy();
sess_hold_map_.destroy();
}
@ -368,6 +405,12 @@ int ObSQLSessionMgr::create_session(ObSMConnection *conn, ObSQLSessionInfo *&ses
{
int ret = OB_SUCCESS;
sess_info = NULL;
// In order to be compatible with lower versions,
// the client session id of unsupported versions is INVALID_SESSID.
// proxy mode, client sess id will be passed by proxy.
// direct mode, cs_id same as session id.
conn->client_sessid_ = conn->proxy_cap_flags_.is_client_sessid_support() || (conn->proxy_sessid_ == 0)
? (conn->client_sessid_ == INVALID_SESSID ? conn->sessid_ : conn->client_sessid_) : INVALID_SESSID;
if (OB_ISNULL(conn)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("conn is NULL", K(ret));
@ -375,7 +418,9 @@ int ObSQLSessionMgr::create_session(ObSMConnection *conn, ObSQLSessionInfo *&ses
conn->sessid_,
conn->proxy_sessid_,
conn->sess_create_time_,
sess_info))) {
sess_info,
conn->client_sessid_,
conn->client_create_time_))) {
LOG_WARN("create session failed", K(ret));
} else if (OB_ISNULL(sess_info)) {
ret = OB_ERR_UNEXPECTED;
@ -393,7 +438,9 @@ int ObSQLSessionMgr::create_session(const uint64_t tenant_id,
const uint32_t sessid,
const uint64_t proxy_sessid,
const int64_t create_time,
ObSQLSessionInfo *&session_info)
ObSQLSessionInfo *&session_info,
const uint32_t client_sessid,
const int64_t client_create_time)
{
int ret = OB_SUCCESS;
int err = OB_SUCCESS;
@ -407,6 +454,38 @@ int ObSQLSessionMgr::create_session(const uint64_t tenant_id,
} else if (OB_ISNULL(tmp_sess)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to alloc session info", K(ret), K(sessid), K(proxy_sessid));
} else if (client_sessid != INVALID_SESSID && OB_FAIL(GCTX.session_mgr_->get_client_sess_map()
.set_refactored(client_sessid, sessid))) {
if (OB_HASH_EXIST == ret) {
ret = OB_SUCCESS;
int flag = 1;
ObSQLSessionInfo *last_server_session = NULL;
uint32_t last_sessid = INVALID_SESSID;
if (OB_FAIL(GCTX.session_mgr_->get_client_sess_map()
.get_refactored(client_sessid, last_sessid))) {
ret = OB_SUCCESS;
} else if (OB_FAIL(get_session(last_sessid, last_server_session))) {
ret = OB_SUCCESS;
} else if (OB_ISNULL(last_server_session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to alloc session info", K(last_sessid),
K(client_sessid), K(ret));
} else if (proxy_sessid != last_server_session->get_proxy_sessid()) {
LOG_ERROR("conclude same client session", K(client_sessid), K(proxy_sessid),
K(last_server_session->get_proxy_sessid()));
}
if (OB_FAIL(GCTX.session_mgr_->get_client_sess_map()
.set_refactored(client_sessid, sessid, flag))) {
ret = OB_SUCCESS;
LOG_WARN("fail to set client session, no gurantee client session info", K(client_sessid));
} else {
}
if (NULL != last_server_session) {
revert_session(last_server_session);
}
} else {
// revert session behind.
}
} else {
// create session contains a 'get_session' action implicitly
const bool v = GCONF._enable_trace_session_leak;
@ -416,9 +495,17 @@ int ObSQLSessionMgr::create_session(const uint64_t tenant_id,
}
if (OB_FAIL(ret)) {
// pass
if (NULL != tmp_sess) {
if (FALSE_IT(revert_session(tmp_sess))) {
} else if (OB_SUCCESS != (err = sessinfo_map_.del(Key(sessid)))) {
LOG_ERROR("fail to free session", K(err), K(sessid), K(client_sessid));
} else {
LOG_DEBUG("free session successfully in create session", K(err),
K(sessid), K(client_sessid));
}
}
} else if (OB_FAIL(tmp_sess->init(sessid, proxy_sessid, NULL, NULL, create_time,
tenant_id))) {
tenant_id, client_create_time))) {
LOG_WARN("fail to init session", K(ret), K(tmp_sess),
K(sessid), K(proxy_sessid), K(create_time));
if (FALSE_IT(revert_session(tmp_sess))) {
@ -427,7 +514,7 @@ int ObSQLSessionMgr::create_session(const uint64_t tenant_id,
LOG_ERROR("fail to free session", K(err), K(sessid), K(proxy_sessid));
} else {
LOG_DEBUG("free session successfully in create session", K(err),
K(sessid), K(proxy_sessid));
K(sessid), K(proxy_sessid), K(client_create_time));
}
} else {
// set tenant info to session, if has.
@ -550,6 +637,20 @@ int ObSQLSessionMgr::check_session_leak()
void ObSQLSessionMgr::runTimerTask()
{
try_check_session();
traverse_times_++;
// 30s clean kill client session map
if (traverse_times_ == TRAVERSE_MAX_TIMES) {
traverse_times_ = 0;
RecordCleanKillClientSession clean_kill_client_session(this);
for_each_kill_client_session(clean_kill_client_session);
for (int64_t i =0; i< clean_kill_client_session.clean_kill_array_.count(); i++) {
bool is_erased = false;
CleanKillClientSessionFin clean_kill_client_sessionf(this, clean_kill_client_session.clean_kill_array_.at(i).first,
clean_kill_client_session.clean_kill_array_.at(i).second);
GCTX.session_mgr_->get_kill_client_sess_map().erase_if(clean_kill_client_session.clean_kill_array_.at(i).first,
clean_kill_client_sessionf, is_erased);
}
}
}
// just a wrapper
@ -852,6 +953,46 @@ int ObSQLSessionMgr::DumpHoldSession::operator()(
return ret;
}
int ObSQLSessionMgr::RecordCleanKillClientSession::operator()(
common::hash::HashMapPair<uint32_t, uint64_t> &entry)
{
int ret = common::OB_SUCCESS;
uint64_t now = ObTimeUtility::current_time();
// Cleared from map after 8h, can be controled by switch.
int64_t code = 0;
code = OB_E(EventTable::EN_SESS_CLEAN_KILL_MAP_TIME) OB_SUCCESS;
if (code < 0) {
clean_kill_time_ = -code;
} else {
clean_kill_time_ = CLEAN_KILL_CLIENT_SESSION_TIME;
}
if ((now - entry.second) > clean_kill_time_) {
clean_kill_array_.push_back(std::make_pair(entry.first, entry.second));
}
return ret;
}
bool ObSQLSessionMgr::CleanKillClientSessionFin::operator()(
common::hash::HashMapPair<uint32_t, uint64_t> &entry)
{
int ret = common::OB_SUCCESS;
// Cleared from map after 8h, can be controled by switch.
bool judge = false;
if (entry.first == cs_id_ && entry.second == cs_connect_time_) {
judge = true;
} else {
LOG_DEBUG("Not match clean", K(entry.first),K(entry.second),K(cs_id_),K(cs_connect_time_),K(ret));
}
return judge;
}
bool ObSQLSessionMgr::ObClientSessMapErase::operator() (
common::hash::HashMapPair<uint32_t, uint32_t> &entry)
{
return entry.second == sess_id_;
}
ObSessionGetterGuard::ObSessionGetterGuard(ObSQLSessionMgr &sess_mgr, uint32_t sessid)
: mgr_(sess_mgr), session_(NULL)
{

View File

@ -17,6 +17,7 @@
#include "lib/container/ob_concurrent_bitset.h"
#include "sql/session/ob_sql_session_info.h"
#include "sql/ob_end_trans_callback.h"
namespace oceanbase
{
namespace observer
@ -53,14 +54,22 @@ public:
static const uint32_t SERVER_SESSID_TAG = 1ULL << 31;
static const uint32_t LOCAL_SESSID_TAG = 0; // used for sessions overflow
static const int64_t BUCKET_COUNT = 1024;
static const uint32_t TRAVERSE_MAX_TIMES = 6; // 6 * 5s
static const uint64_t CLEAN_KILL_CLIENT_SESSION_TIME = 28800000000; // 8h
typedef SessionInfoKey Key;
typedef common::hash::ObHashMap<uint64_t, ObSQLSessionInfo*> SessionMap;
// client session id -> server session id
typedef common::hash::ObHashMap<uint32_t, uint32_t> ClientSessionMap;
// client session id -> timestamp
typedef common::hash::ObHashMap<uint32_t, uint64_t> KillClientSessMap;
explicit ObSQLSessionMgr():
//null_callback_(),
sessinfo_map_(),
sessid_sequence_(),
first_seq_(NON_DURABLE_VALUE),
increment_sessid_(NON_DURABLE_VALUE)
increment_sessid_(NON_DURABLE_VALUE),
traverse_times_(NON_DURABLE_VALUE)
// CLEAN_KILL_CLIENT_SESSION_TIME(28800000000)
{
}
virtual ~ObSQLSessionMgr(){}
@ -77,7 +86,9 @@ public:
// create session by session id and proxy session id.
// need call revert_session if return success.
int create_session(const uint64_t tenant_id, const uint32_t sessid, const uint64_t proxy_sessid,
const int64_t create_time, ObSQLSessionInfo *&session_info);
const int64_t create_time, ObSQLSessionInfo *&session_info,
const uint32_t client_sessid = INVALID_SESSID,
const int64_t client_create_time = 0);
/**
* @brief get the ObSQLSessioninfo
@ -108,6 +119,9 @@ public:
template <typename Function>
int for_each_hold_session(Function &fn);
template <typename Function>
int for_each_kill_client_session(Function &fn);
int kill_query(ObSQLSessionInfo &session);
int set_query_deadlocked(ObSQLSessionInfo &session);
static int kill_query(ObSQLSessionInfo &session,
@ -140,6 +154,8 @@ public:
int mark_sessid_unused(uint32_t sess_id);
//inline ObNullEndTransCallback &get_null_callback() { return null_callback_; }
SessionMap &get_sess_hold_map() { return sess_hold_map_; }
ClientSessionMap &get_client_sess_map() { return client_sess_map_; }
KillClientSessMap &get_kill_client_sess_map() { return kill_client_sess_map_; }
private:
int check_session_leak();
int get_avaiable_local_seq(uint32_t &local_seq);
@ -198,6 +214,44 @@ private:
ObSQLSessionMgr *sess_mgr_;
};
class RecordCleanKillClientSession
{
public:
RecordCleanKillClientSession() : sess_mgr_(NULL), clean_kill_time_(CLEAN_KILL_CLIENT_SESSION_TIME)
{
clean_kill_array_.reset();
}
explicit RecordCleanKillClientSession(ObSQLSessionMgr *sess_mgr): sess_mgr_(sess_mgr) {}
virtual ~RecordCleanKillClientSession() {}
void reset()
{
clean_kill_array_.reset();
clean_kill_time_ = CLEAN_KILL_CLIENT_SESSION_TIME;
}
int operator()(common::hash::HashMapPair<uint32_t, uint64_t> &entry);
private:
ObSQLSessionMgr *sess_mgr_;
public:
uint64_t clean_kill_time_;
common::ObSEArray<std::pair<uint32_t, uint64_t>,16> clean_kill_array_;
};
class CleanKillClientSessionFin
{
public:
CleanKillClientSessionFin() : sess_mgr_(NULL), cs_id_(0), cs_connect_time_(0)
{
}
explicit CleanKillClientSessionFin(ObSQLSessionMgr *sess_mgr, uint32_t cs_id, uint64_t cs_connect_time):
sess_mgr_(sess_mgr), cs_id_(cs_id), cs_connect_time_(cs_connect_time) {}
virtual ~CleanKillClientSessionFin() {}
bool operator()(common::hash::HashMapPair<uint32_t, uint64_t> &entry);
private:
ObSQLSessionMgr *sess_mgr_;
uint32_t cs_id_;
uint64_t cs_connect_time_;
};
class KillTenant
{
public:
@ -210,6 +264,17 @@ private:
const uint64_t tenant_id_;
};
class ObClientSessMapErase
{
public:
ObClientSessMapErase(const uint32_t sess_id)
:sess_id_(sess_id)
{}
bool operator()(common::hash::HashMapPair<uint32_t, uint32_t> &entry);
private:
uint32_t sess_id_;
};
private:
//注:必须在session_map_之前定义,依赖于析构的顺序。
//ObNullEndTransCallback null_callback_;
@ -230,6 +295,12 @@ private:
uint32_t first_seq_;
uint32_t increment_sessid_;
SessionMap sess_hold_map_;
// client session id -> session
ClientSessionMap client_sess_map_;
// client session id -> create client session time, used for kill client session.
KillClientSessMap kill_client_sess_map_;
// The number of traversals is used to regularly clean up kill_client_sess_map
uint32_t traverse_times_;
DISALLOW_COPY_AND_ASSIGN(ObSQLSessionMgr);
}; // end of class ObSQLSessionMgr
@ -245,6 +316,12 @@ int ObSQLSessionMgr::for_each_hold_session(Function &fn)
return get_sess_hold_map().foreach_refactored(fn);
}
template <typename Function>
int ObSQLSessionMgr::for_each_kill_client_session(Function &fn)
{
return get_kill_client_sess_map().foreach_refactored(fn);
}
inline int ObSQLSessionMgr::get_session(uint32_t sessid, ObSQLSessionInfo *&sess_info)
{
int ret = sessinfo_map_.get(Key(sessid), sess_info);

View File

@ -94,7 +94,7 @@ desc processlist;
Field Type Null Key Default Extra
ID bigint(20) unsigned NO
USER varchar(32) NO
HOST varchar(128) NO
HOST varchar(67) YES NULL
DB varchar(128) YES NULL
COMMAND varchar(4096) NO
TIME bigint(20) NO
@ -251,7 +251,7 @@ View Create View character_set_client collation_connection
PARTITIONS CREATE VIEW `PARTITIONS` AS SELECT CAST('def' as CHAR(4096)) AS TABLE_CATALOG, DB.DATABASE_NAME AS TABLE_SCHEMA, T.TABLE_NAME AS TABLE_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, CAST(PART_POSITION AS UNSIGNED) AS PARTITION_ORDINAL_POSITION, CAST(SUB_PART_POSITION AS UNSIGNED) AS SUBPARTITION_ORDINAL_POSITION, CAST(CASE WHEN T.PART_LEVEL = 0 THEN NULL ELSE (CASE T.PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) PARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE T.SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) SUBPARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE T.PART_FUNC_EXPR END AS CHAR(2048)) PARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE T.SUB_PART_FUNC_EXPR END AS CHAR(2048)) SUBPARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL ELSE P.LIST_VAL END) END AS CHAR(4096)) AS PARTITION_DESCRIPTION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL ELSE SP.LIST_VAL END) END AS CHAR(4096)) AS SUBPARTITION_DESCRIPTION, CAST(TS.ROW_CNT AS UNSIGNED) AS TABLE_ROWS, CAST(TS.AVG_ROW_LEN AS UNSIGNED) AS AVG_ROW_LENGTH, CAST(NULL AS UNSIGNED) AS DATA_LENGTH, CAST(NULL AS UNSIGNED) AS MAX_DATA_LENGTH, CAST(NULL AS UNSIGNED) AS INDEX_LENGTH, CAST(NULL AS UNSIGNED) AS DATA_FREE, CASE T.PART_LEVEL WHEN 0 THEN T.GMT_CREATE WHEN 1 THEN P.GMT_CREATE WHEN 2 THEN SP.GMT_CREATE END AS CREATE_TIME, CAST(NULL AS DATETIME) AS UPDATE_TIME, CAST(NULL AS DATETIME) AS CHECK_TIME, CAST(NULL AS SIGNED) AS CHECKSUM, CAST(CASE T.PART_LEVEL WHEN 0 THEN NULL WHEN 1 THEN P.COMMENT WHEN 2 THEN SP.COMMENT END AS CHAR(1024)) AS PARTITION_COMMENT, CAST('default' AS CHAR(256)) NODEGROUP, CAST(TP.TABLESPACE_NAME AS CHAR(268)) AS TABLESPACE_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_DATABASE DB ON T.DATABASE_ID = DB.DATABASE_ID AND T.TENANT_ID = DB.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID ORDER BY PART_IDX) AS PART_POSITION FROM OCEANBASE.__ALL_PART ) P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID,PART_ID ORDER BY SUB_PART_IDX) AS SUB_PART_POSITION FROM OCEANBASE.__ALL_SUB_PART ) SP ON T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID AND T.TENANT_ID = SP.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = IFNULL(SP.TABLESPACE_ID, P.TABLESPACE_ID) AND TP.TENANT_ID = T.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TABLE_STAT TS ON T.TENANT_ID = TS.TENANT_ID AND TS.TABLE_ID = T.TABLE_ID AND TS.PARTITION_ID = CASE T.PART_LEVEL WHEN 0 THEN T.TABLE_ID WHEN 1 THEN P.PART_ID WHEN 2 THEN SP.SUB_PART_ID END WHERE T.TABLE_TYPE IN (3,6,8,9,14) utf8mb4 utf8mb4_general_ci
show create table processlist;
View Create View character_set_client collation_connection
PROCESSLIST CREATE VIEW `PROCESSLIST` AS SELECT id AS ID, user AS USER, host AS HOST, db AS DB, command AS COMMAND, time AS TIME, state AS STATE, info AS INFO FROM oceanbase.__all_virtual_processlist WHERE is_serving_tenant(svr_ip, svr_port, effective_tenant_id()) utf8mb4 utf8mb4_general_ci
PROCESSLIST CREATE VIEW `PROCESSLIST` AS SELECT id AS ID, user AS USER, concat(user_client_ip, ':', user_client_port) AS HOST, db AS DB, command AS COMMAND, time AS TIME, state AS STATE, info AS INFO FROM oceanbase.__all_virtual_processlist WHERE is_serving_tenant(svr_ip, svr_port, effective_tenant_id()) utf8mb4 utf8mb4_general_ci
show create table schema_privileges;
View Create View character_set_client collation_connection
SCHEMA_PRIVILEGES CREATE VIEW `SCHEMA_PRIVILEGES` AS SELECT CAST(CONCAT('''', V.USER_NAME, '''', '@', '''', V.HOST, '''') AS CHAR(81)) AS GRANTEE , CAST('def' AS CHAR(512)) AS TABLE_CATALOG , CAST(V.DATABASE_NAME AS CHAR(128)) AS TABLE_SCHEMA , CAST(V.PRIVILEGE_TYPE AS CHAR(64)) AS PRIVILEGE_TYPE , CAST(V.IS_GRANTABLE AS CHAR(3)) AS IS_GRANTABLE FROM (SELECT DP.DATABASE_NAME DATABASE_NAME, U.USER_NAME AS USER_NAME, U.HOST AS HOST, CASE WHEN V1.C1 = 1 AND DP.PRIV_ALTER = 1 THEN 'ALTER' WHEN V1.C1 = 2 AND DP.PRIV_CREATE = 1 THEN 'CREATE' WHEN V1.C1 = 4 AND DP.PRIV_DELETE = 1 THEN 'DELETE' WHEN V1.C1 = 5 AND DP.PRIV_DROP = 1 THEN 'DROP' WHEN V1.C1 = 7 AND DP.PRIV_INSERT = 1 THEN 'INSERT' WHEN V1.C1 = 8 AND DP.PRIV_UPDATE = 1 THEN 'UPDATE' WHEN V1.C1 = 9 AND DP.PRIV_SELECT = 1 THEN 'SELECT' WHEN V1.C1 = 10 AND DP.PRIV_INDEX = 1 THEN 'INDEX' WHEN V1.C1 = 11 AND DP.PRIV_CREATE_VIEW = 1 THEN 'CREATE VIEW' WHEN V1.C1 = 12 AND DP.PRIV_SHOW_VIEW = 1 THEN 'SHOW VIEW' ELSE NULL END PRIVILEGE_TYPE , CASE WHEN DP.PRIV_GRANT_OPTION = 1 THEN 'YES' WHEN DP.PRIV_GRANT_OPTION = 0 THEN 'NO' END IS_GRANTABLE FROM oceanbase.__all_database_privilege DP, oceanbase.__all_user U, (SELECT 1 AS C1 UNION ALL SELECT 2 AS C1 UNION ALL SELECT 4 AS C1 UNION ALL SELECT 5 AS C1 UNION ALL SELECT 7 AS C1 UNION ALL SELECT 8 AS C1 UNION ALL SELECT 9 AS C1 UNION ALL SELECT 10 AS C1 UNION ALL SELECT 11 AS C1 UNION ALL SELECT 12 AS C1) V1, (SELECT USER_ID FROM oceanbase.__all_user WHERE TENANT_ID= 0 AND CONCAT(USER_NAME, '@', HOST) = CURRENT_USER()) CURR LEFT JOIN (SELECT USER_ID FROM oceanbase.__all_database_privilege WHERE TENANT_ID = 0 AND DATABASE_NAME = 'mysql' AND PRIV_SELECT = 1) DB ON CURR.USER_ID = DB.USER_ID WHERE DP.TENANT_ID = 0 AND DP.TENANT_ID = U.TENANT_ID AND DP.USER_ID = U.USER_ID AND DP.DATABASE_NAME != '__recyclebin' AND DP.DATABASE_NAME != '__public' AND DP.DATABASE_NAME != 'SYS' AND DP.DATABASE_NAME != 'LBACSYS' AND DP.DATABASE_NAME != 'ORAAUDITOR' AND (DB.USER_ID IS NOT NULL OR 512 & CURRENT_USER_PRIV() = 512 OR DP.USER_ID = CURR.USER_ID)) V WHERE V.PRIVILEGE_TYPE IS NOT NULL utf8mb4 utf8mb4_general_ci

View File

@ -199,7 +199,7 @@ desc information_schema.PROCESSLIST;
Field Type Null Key Default Extra
ID bigint(20) unsigned NO
USER varchar(32) NO
HOST varchar(128) NO
HOST varchar(67) YES NULL
DB varchar(128) YES NULL
COMMAND varchar(4096) NO
TIME bigint(20) NO

View File

@ -200,7 +200,7 @@ desc information_schema.PROCESSLIST;
Field Type Null Key Default Extra
ID bigint(20) unsigned NO
USER varchar(32) NO
HOST varchar(128) NO
HOST varchar(67) YES NULL
DB varchar(128) YES NULL
COMMAND varchar(4096) NO
TIME bigint(20) NO