[FEAT MERGE] Improve the inner implementation of tx table
Co-authored-by: kongfy <njukongfy@gmail.com>
This commit is contained in:
210
src/observer/virtual_table/ob_all_virtual_tx_data.cpp
Normal file
210
src/observer/virtual_table/ob_all_virtual_tx_data.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/**
|
||||
* 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;
|
||||
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
|
||||
Reference in New Issue
Block a user