215 lines
7.6 KiB
C++
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
|