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

215 lines
7.6 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 "ob_all_virtual_tx_data.h"
#include "observer/ob_server_struct.h"
#include "observer/omt/ob_tenant.h"
#include "observer/omt/ob_multi_tenant.h"
#include "storage/tx_storage/ob_ls_handle.h"
#include "storage/tx_storage/ob_ls_service.h"
namespace oceanbase {
namespace observer {
using namespace share;
using namespace storage;
using namespace transaction;
using namespace omt;
int ObAllVirtualTxData::inner_get_next_row(common::ObNewRow *&row)
{
int ret = OB_SUCCESS;
if (false == start_to_read_) {
if (OB_FAIL(get_primary_key_())) {
SERVER_LOG(WARN, "get primary key failed", KR(ret));
} else if (OB_FAIL(generate_virtual_tx_data_row_(tx_data_row_))) {
if (OB_ITER_END == ret) {
} else if (OB_TRANS_CTX_NOT_EXIST == ret) {
ret = OB_ITER_END;
} else {
SERVER_LOG(WARN, "generate virtual tx data row failed", KR(ret));
}
} else if (OB_FAIL(fill_in_row_(tx_data_row_, row))) {
SERVER_LOG(WARN, "fill in row failed", KR(ret));
} else {
start_to_read_ = true;
}
} else {
ret = OB_ITER_END;
}
return ret;
}
int ObAllVirtualTxData::fill_in_row_(const VirtualTxDataRow &row_data, common::ObNewRow *&row)
{
int ret = OB_SUCCESS;
const int64_t col_count = output_column_ids_.count();
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 TENANT_ID_COL:
cur_row_.cells_[i].set_int(tenant_id_);
break;
case LS_ID_COL:
cur_row_.cells_[i].set_int(ls_id_.id());
break;
case TX_ID_COL:
cur_row_.cells_[i].set_int(tx_id_.get_id());
break;
case SVR_IP_COL:
if (addr_.ip_to_string(ip_buf_, sizeof(ip_buf_))) {
cur_row_.cells_[i].set_varchar(ip_buf_);
cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
} else {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(WARN, "fail to execute ip_to_string", KR(ret));
}
break;
case SVR_PORT_COL:
cur_row_.cells_[i].set_int(addr_.get_port());
break;
case STATE_COL:
cur_row_.cells_[i].set_varchar(ObTxCommitData::get_state_string(row_data.state_));
cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
break;
case START_SCN_COL: {
uint64_t v = row_data.start_scn_.get_val_for_inner_table_field();
cur_row_.cells_[i].set_uint64(v);
break;
}
case END_SCN_COL: {
uint64_t v = row_data.end_scn_.get_val_for_inner_table_field();
cur_row_.cells_[i].set_uint64(v);
break;
}
case COMMIT_VERSION_COL: {
uint64_t v = row_data.commit_version_.get_val_for_inner_table_field();
cur_row_.cells_[i].set_uint64(v);
break;
}
case UNDO_STATUS_COL:
cur_row_.cells_[i].set_varchar(row_data.undo_status_list_str_);
cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
break;
case TX_OP_COL:
cur_row_.cells_[i].set_varchar(row_data.tx_op_str_);
cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
break;
default:
ret = OB_ERR_UNEXPECTED;
break;
}
}
if (OB_SUCC(ret)) {
row = &cur_row_;
}
return ret;
}
int ObAllVirtualTxData::get_primary_key_()
{
int ret = OB_SUCCESS;
if (key_ranges_.count() != 1) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "only support select a single tx data once, multiple range select is ");
SERVER_LOG(WARN, "invalid key ranges", KR(ret));
} else {
ObNewRange &key_range = key_ranges_.at(0);
if (OB_UNLIKELY(key_range.get_start_key().get_obj_cnt() != 3 || key_range.get_end_key().get_obj_cnt() != 3)) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(ERROR,
"unexpected key_ranges_ of rowkey columns",
KR(ret),
"size of start key",
key_range.get_start_key().get_obj_cnt(),
"size of end key",
key_range.get_end_key().get_obj_cnt());
} else if (OB_FAIL(handle_key_range_(key_range))) {
SERVER_LOG(WARN, "handle key range faield", KR(ret));
}
}
return ret;
}
int ObAllVirtualTxData::handle_key_range_(ObNewRange &key_range)
{
int ret = OB_SUCCESS;
ObObj tenant_obj_low = (key_range.get_start_key().get_obj_ptr()[0]);
ObObj tenant_obj_high = (key_range.get_end_key().get_obj_ptr()[0]);
ObObj ls_obj_low = (key_range.get_start_key().get_obj_ptr()[1]);
ObObj ls_obj_high = (key_range.get_end_key().get_obj_ptr()[1]);
ObObj tx_id_obj_low = (key_range.get_start_key().get_obj_ptr()[2]);
ObObj tx_id_obj_high = (key_range.get_end_key().get_obj_ptr()[2]);
uint64_t tenant_low = tenant_obj_low.is_min_value() ? 0 : tenant_obj_low.get_uint64();
uint64_t tenant_high = tenant_obj_high.is_max_value() ? UINT64_MAX : tenant_obj_high.get_uint64();
ObLSID ls_low = ls_obj_low.is_min_value() ? ObLSID(0) : ObLSID(ls_obj_low.get_int());
ObLSID ls_high = ls_obj_high.is_max_value() ? ObLSID(INT64_MAX) : ObLSID(ls_obj_high.get_int());
ObTransID tx_id_low = tx_id_obj_low.is_min_value() ? ObTransID(0) : ObTransID(tx_id_obj_low.get_int());
ObTransID tx_id_high = tx_id_obj_high.is_min_value() ? ObTransID(INT64_MAX) : ObTransID(tx_id_obj_high.get_int());
if (tenant_low != tenant_high || ls_low != ls_high || tx_id_low != tx_id_high) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "tenant name, ls id and trans id must be specified. range select is ");
SERVER_LOG(WARN,
"only support point select.",
KR(ret),
K(tenant_low),
K(tenant_high),
K(ls_low),
K(ls_high),
K(tx_id_low),
K(tx_id_high));
} else {
tenant_id_ = tenant_low;
ls_id_ = ls_low;
tx_id_ = tx_id_low;
}
return ret;
}
int ObAllVirtualTxData::generate_virtual_tx_data_row_(VirtualTxDataRow &tx_data_row)
{
int ret = OB_SUCCESS;
MTL_SWITCH(tenant_id_)
{
ObLSHandle ls_handle;
ObLS *ls = nullptr;
ObLSService *ls_service = MTL(ObLSService *);
if (OB_FAIL(ls_service->get_ls(ls_id_, ls_handle, ObLSGetMod::OBSERVER_MOD))) {
if (OB_LS_NOT_EXIST == ret) {
ret = OB_ITER_END;
} else {
SERVER_LOG(WARN, "get ls from ls service failed", KR(ret), K(ls_id_));
}
} else if (OB_ISNULL(ls = ls_handle.get_ls())) {
ret = OB_ERR_UNEXPECTED;
SERVER_LOG(ERROR, "get ls failed from ls handle", KR(ret), K(ls_handle), K(tenant_id_), K(ls_id_));
} else if (OB_FAIL(ls->generate_virtual_tx_data_row(tx_id_, tx_data_row))) {
SERVER_LOG(WARN, "ls genenrate virtual tx data row failed", KR(ret), K(ls_handle), K(tenant_id_), K(ls_id_));
} else {
SERVER_LOG(DEBUG, "generate tx data row succeed", KPC(ls), K(tx_data_row));
}
}
if (OB_FAIL(ret) && OB_TENANT_NOT_IN_SERVER == ret) {
ret = OB_ITER_END;
}
return ret;
}
} // namespace observer
} // namespace oceanbase