Files
oceanbase/src/observer/virtual_table/ob_all_virtual_session_info.cpp

358 lines
14 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.
*/
#include "lib/string/ob_string.h"
#include "share/config/ob_server_config.h"
#include "observer/virtual_table/ob_all_virtual_session_info.h"
#include "observer/ob_server.h"
#include "sql/session/ob_sql_session_info.h"
using namespace oceanbase::common;
namespace oceanbase
{
namespace observer
{
ObAllVirtualSessionInfo::ObAllVirtualSessionInfo()
: ObVirtualTableScannerIterator(),
session_mgr_(NULL),
fill_scanner_()
{
}
ObAllVirtualSessionInfo::~ObAllVirtualSessionInfo()
{
reset();
}
void ObAllVirtualSessionInfo::reset()
{
session_mgr_ = NULL;
fill_scanner_.reset();
ObVirtualTableScannerIterator::reset();
}
int ObAllVirtualSessionInfo::inner_get_next_row(ObNewRow *&row)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(session_mgr_)) {
ret = OB_NOT_INIT;
SERVER_LOG(WARN, "sessionMgr is NULL", K(ret));
} else {
if (!start_to_read_) {
if (OB_FAIL(fill_scanner_.init(allocator_,
&scanner_,
session_,
&cur_row_,
output_column_ids_,
schema_guard_))) {
SERVER_LOG(WARN, "init fill_scanner fail", K(ret));
} else if (OB_FAIL(session_mgr_->for_each_hold_session(fill_scanner_))) {
SERVER_LOG(WARN, "fill scanner fail", K(ret));
} else {
scanner_it_ = scanner_.begin();
start_to_read_ = true;
}
}
if (OB_SUCCESS == ret && start_to_read_) {
if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) {
if (OB_UNLIKELY(OB_ITER_END != ret)) {
SERVER_LOG(WARN, "fail to get next row", K(ret));
}
} else {
row = &cur_row_;
}
}
}
return ret;
}
int ObAllVirtualSessionInfo::FillScanner::operator()(
hash::HashMapPair<uint64_t, ObSQLSessionInfo *> &entry)
{
int ret = OB_SUCCESS;
ObSQLSessionInfo *sess_info = entry.second;
if (OB_UNLIKELY(NULL == scanner_
|| NULL == allocator_
|| NULL == cur_row_
|| NULL == cur_row_->cells_
|| NULL == sess_info
|| NULL == my_session_)) {
ret = OB_NOT_INIT;
SERVER_LOG(WARN,
"parameter or data member is NULL",
K(ret),
K(scanner_),
K(allocator_),
K(cur_row_),
K(sess_info),
K(my_session_));
} else if (OB_UNLIKELY(cur_row_->count_ < output_column_ids_.count())) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN,
"cells count is less than output column count",
K(ret),
K(cur_row_->count_),
K(output_column_ids_.count()));
} else {
ObServer &server = ObServer::get_instance();
uint64_t cell_idx = 0;
char ip_buf[common::OB_IP_STR_BUFF];
char peer_buf[common::OB_IP_PORT_STR_BUFF];
char sql_id[common::OB_MAX_SQL_ID_LENGTH + 1];
//If you are in system tenant, you can see all thread.
if (true) {
ObSQLSessionInfo::LockGuard lock_guard(sess_info->get_thread_data_lock());
const int64_t col_count = output_column_ids_.count();
ObCharsetType default_charset = ObCharset::get_default_charset();
ObCollationType default_collation = ObCharset::get_default_collation(default_charset);
for (int64_t i = 0; OB_SUCC(ret) && i < col_count; ++i) {
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()));
break;
}
case USER: {
if (sess_info->get_is_deserialized()) {
// this is a tmp solution to avoid core when we execute 'show processlist'
// before we finally find the reason and resolve the bug. otherwise we cannot
// use this command in on-line cluster.
// see
cur_row_->cells_[cell_idx].set_null();
} else {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_user_name());
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
}
break;
}
case TENANT: {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_effective_tenant_name());
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
break;
}
case HOST: {
if (OB_FAIL(sess_info->get_peer_addr().ip_port_to_string(peer_buf, common::OB_IP_PORT_STR_BUFF))) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN, "fail to get ip string", K(ret), K(sess_info->get_peer_addr()));
} else {
cur_row_->cells_[cell_idx].set_varchar(ObString::make_string(peer_buf));
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
}
break;
}
case DB_NAME: {
if (0 == sess_info->get_database_name().length()) {//session don't select database
cur_row_->cells_[cell_idx].set_varchar(ObString::make_string("NULL"));
} else {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_database_name());
}
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
break;
}
case COMMAND: {
cur_row_->cells_[cell_idx].set_varchar(ObString::make_string(sess_info->get_mysql_cmd_str()));
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
break;
}
case SQL_ID: {
sess_info->get_cur_sql_id(sql_id, OB_MAX_SQL_ID_LENGTH + 1);
cur_row_->cells_[cell_idx].set_varchar(ObString::make_string(sql_id));
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
break;
}
case TIME: {
int64_t time_sec = (::oceanbase::common::ObTimeUtility::current_time() - sess_info->get_cur_state_start_time()) / 1000000;
cur_row_->cells_[cell_idx].set_int(time_sec);
break;
}
case STATE: {
cur_row_->cells_[cell_idx].set_varchar(ObString::make_string(sess_info->get_session_state_str()));
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
break;
}
case INFO: {
if (obmysql::COM_QUERY == sess_info->get_mysql_cmd() ||
obmysql::COM_STMT_EXECUTE == sess_info->get_mysql_cmd() ||
obmysql::COM_STMT_PREPARE == sess_info->get_mysql_cmd() ||
obmysql::COM_STMT_PREXECUTE == sess_info->get_mysql_cmd()) {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_current_query_string());
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
} else {
cur_row_->cells_[cell_idx].set_null();
}
break;
}
case SVR_IP: {
if (!server.get_self().ip_to_string(ip_buf, common::OB_IP_STR_BUFF)) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN, "fail to get ip string", K(ret), K(server.get_self()));
} else {
cur_row_->cells_[cell_idx].set_varchar(ObString::make_string(ip_buf));
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
}
break;
}
case SVR_PORT: {
cur_row_->cells_[cell_idx].set_int(server.get_self().get_port());
break;
}
case SQL_PORT: {
cur_row_->cells_[cell_idx].set_int(GCONF.mysql_port);
break;
}
case PROXY_SESSID: {
if (ObBasicSessionInfo::VALID_PROXY_SESSID == sess_info->get_proxy_sessid()) {
cur_row_->cells_[cell_idx].set_null();
} else {
cur_row_->cells_[cell_idx].set_uint64(sess_info->get_proxy_sessid());
}
break;
}
case MASTER_SESSID: {
if (ObBasicSessionInfo::INVALID_SESSID == sess_info->get_master_sessid()) {
cur_row_->cells_[cell_idx].set_null();
} else {
cur_row_->cells_[cell_idx].set_uint64(sess_info->get_master_sessid());
}
break;
}
case USER_CLIENT_IP: {
if (sess_info->get_client_ip().empty()) {
cur_row_->cells_[cell_idx].set_null();
} else {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_client_ip());
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
}
break;
}
case USER_HOST: {
if (sess_info->get_host_name().empty()) {
cur_row_->cells_[cell_idx].set_null();
} else {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_host_name());
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
}
break;
}
case TRANS_ID: {
uint64_t tx_id = sess_info->get_tx_id();
cur_row_->cells_[cell_idx].set_uint64(tx_id);
break;
}
case THREAD_ID: {
cur_row_->cells_[cell_idx].set_uint64(
static_cast<uint64_t>(sess_info->get_thread_id()));
break;
}
case SSL_CIPHER: {
if (sess_info->get_ssl_cipher().empty()) {
cur_row_->cells_[cell_idx].set_null();
} else {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_ssl_cipher());
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
}
break;
}
case TRACE_ID: {
if (obmysql::COM_QUERY == sess_info->get_mysql_cmd() ||
obmysql::COM_STMT_EXECUTE == sess_info->get_mysql_cmd() ||
obmysql::COM_STMT_PREPARE == sess_info->get_mysql_cmd() ||
obmysql::COM_STMT_PREXECUTE == sess_info->get_mysql_cmd()) {
int len = sess_info->get_current_trace_id().to_string(trace_id_, sizeof(trace_id_));
cur_row_->cells_[cell_idx].set_varchar(trace_id_, len);
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
} else {
// when cmd=Sleep, we don't want to display its last query trace id
// as it is weird, not the meaning for 'processlist'
cur_row_->cells_[cell_idx].set_null();
}
break;
}
case REF_COUNT: {
cur_row_->cells_[cell_idx].set_int(sess_info->get_sess_ref_cnt());
break;
}
case BACKTRACE: {
cur_row_->cells_[cell_idx].set_varchar(sess_info->get_sess_bt());
cur_row_->cells_[cell_idx].set_collation_type(default_collation);
break;
}
case TRANS_STATE: {
if (sess_info->is_in_transaction()) {
cur_row_->cells_[cell_idx].set_varchar(
sess_info->get_tx_desc()->get_tx_state_str());
} else {
cur_row_->cells_[cell_idx].set_varchar("");
}
break;
}
default: {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN, "invalid column id", K(ret), K(cell_idx),
K(i), K(output_column_ids_), K(col_id));
break;
}
}
if (OB_SUCC(ret)) {
cell_idx++;
}
} // for
if (OB_UNLIKELY(OB_SUCCESS == ret && OB_SUCCESS != (ret = scanner_->add_row(*cur_row_)))) {
SERVER_LOG(WARN, "fail to add row", K(ret), K(*cur_row_));
}
}
}
return ret;
}
void ObAllVirtualSessionInfo::FillScanner::reset()
{
allocator_ = NULL;
scanner_ = NULL;
cur_row_ = NULL;
my_session_ = NULL;
trace_id_[0] = '\0';
output_column_ids_.reset();
}
int ObAllVirtualSessionInfo::FillScanner::init(ObIAllocator *allocator,
common::ObScanner *scanner,
sql::ObSQLSessionInfo *session_info,
common::ObNewRow *cur_row,
const ObIArray<uint64_t> &column_ids,
share::schema::ObSchemaGetterGuard* schema_guard)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(NULL == allocator
|| NULL == scanner
|| NULL == cur_row
|| NULL == session_info)) {
ret = OB_NOT_INIT;
SERVER_LOG(WARN,
"some parameter is NULL", K(ret), K(allocator), K(scanner), K(cur_row), K(session_info));
} else if (OB_FAIL(output_column_ids_.assign(column_ids))) {
SQL_ENG_LOG(WARN, "fail to assign output column ids", K(ret), K(column_ids));
} else {
allocator_ = allocator;
scanner_ = scanner;
cur_row_ = cur_row;
my_session_ = session_info;
schema_guard_ = schema_guard;
}
return ret;
}
}/* ns observer*/
}/* ns oceanbase */