init push

This commit is contained in:
oceanbase-admin
2021-05-31 22:56:52 +08:00
commit cea7de1475
7020 changed files with 5689869 additions and 0 deletions

View File

@ -0,0 +1,169 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_cluster.h"
#include "lib/mysqlclient/ob_mysql_result.h"
#include "lib/string/ob_sql_string.h"
#include "lib/utility/ob_print_utils.h" // databuff_printf
#include "share/schema/ob_multi_version_schema_service.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/ob_remote_sql_proxy.h"
#include "share/ob_srv_rpc_proxy.h"
#include "share/ob_rpc_struct.h"
#include "share/ob_multi_cluster_util.h"
#include "share/inner_table/ob_inner_table_schema_constants.h"
#include "observer/ob_server_struct.h"
#include "rootserver/ob_zone_manager.h"
#include "rootserver/ob_root_service.h"
#include "rootserver/ob_server_manager.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
ObAllVirtualCluster::~ObAllVirtualCluster()
{
inited_ = false;
}
int ObAllVirtualCluster::init(share::schema::ObMultiVersionSchemaService& schema_service, ObZoneManager& zone_manager,
obrpc::ObCommonRpcProxy& common_rpc_proxy, ObMySQLProxy& sql_proxy, share::ObPartitionTableOperator& pt_operator,
obrpc::ObSrvRpcProxy& rpc_proxy, ObServerManager& server_manager, ObRootService& root_service)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else {
schema_service_ = &schema_service;
zone_manager_ = &zone_manager;
common_rpc_proxy_ = &common_rpc_proxy;
sql_proxy_ = &sql_proxy;
pt_operator_ = &pt_operator;
rpc_proxy_ = &rpc_proxy;
server_manager_ = &server_manager;
root_service_ = &root_service;
inited_ = true;
}
return ret;
}
int ObAllVirtualCluster::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
share::schema::ObSchemaGetterGuard schema_guard;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
LOG_WARN("failed to get schema guard", K(ret));
} else if (!start_to_read_) {
const share::schema::ObTableSchema* table_schema = NULL;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_CLUSTER_TID);
if (OB_FAIL(schema_guard.get_table_schema(table_id, table_schema))) {
LOG_WARN("failed to get table schema", K(ret), K(table_id));
} else if (OB_ISNULL(table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table schema is null", K(ret));
} else {
common::ObArray<Column> columns;
bool full_columns = true;
if (OB_FAIL(get_full_row(table_schema, columns, full_columns))) {
LOG_WARN("failed to add row", K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_, full_columns))) {
LOG_WARN("failed to project row", K(ret), K(columns), K(cur_row_));
} else {
start_to_read_ = true;
row = &cur_row_;
}
}
} else {
ret = OB_ITER_END;
}
return ret;
}
int ObAllVirtualCluster::get_full_row(
const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns, bool& full_columns)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", KR(ret));
} else {
common::ObFixedLengthString<common::MAX_ZONE_INFO_LENGTH> cluster_name;
char* cluster_name_str = NULL;
const char* cluster_role = "";
const char* cluster_status = "";
const char* switch_status_str = "";
const char* switchover_info_str = "";
const char* protection_mode = "";
const char* protection_level = "";
ObString redo_transopt_str;
int64_t current_scn = ObTimeUtility::current_time();
int64_t primary_cluster_id = OB_INVALID_ID;
int64_t standby_became_primary_scn = 0;
const int64_t cluster_create_ts = zone_manager_->get_cluster_create_timestamp();
obrpc::ObGetSwitchoverStatusRes get_switch_status_res;
full_columns = true;
arena_allocator_.reuse();
if (OB_FAIL(ret)) {
} else if (OB_FAIL(zone_manager_->get_cluster(cluster_name))) {
LOG_WARN("failed to get cluster name", K(ret));
} else if (OB_ISNULL(cluster_name_str = static_cast<char*>(arena_allocator_.alloc(MAX_ZONE_INFO_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed to allocate memory", KR(ret), KP(cluster_name_str));
} else if (OB_FAIL(databuff_printf(cluster_name_str, MAX_ZONE_INFO_LENGTH, "%s", cluster_name.ptr()))) {
LOG_WARN("failed to set cluster name", KR(ret), K(cluster_name));
} else {
// set cluster role amd cluster status
cluster_role = cluster_type_to_str(common::PRIMARY_CLUSTER);
cluster_status = cluster_status_to_str(common::CLUSTER_VALID);
protection_mode = cluster_protection_mode_to_str(common::MAXIMUM_PERFORMANCE_MODE);
protection_level = cluster_protection_level_to_str(common::MAXIMUM_PERFORMANCE_LEVEL);
switch_status_str = share::ObClusterInfo::in_memory_switchover_status_to_str(share::ObClusterInfo::I_NOT_ALLOW);
const int64_t switchover_epoch = 0;
const int64_t cluster_id = GCONF.cluster_id;
//////////////////////// make columns ////////////////////////
ADD_COLUMN(set_int, table, "cluster_id", cluster_id, columns);
ADD_COLUMN(set_varchar, table, "cluster_name", cluster_name_str, columns);
ADD_COLUMN(set_timestamp, table, "created", cluster_create_ts, columns);
ADD_COLUMN(set_varchar, table, "cluster_role", cluster_role, columns);
ADD_COLUMN(set_varchar, table, "cluster_status", cluster_status, columns);
ADD_COLUMN(set_int, table, "switchover#", switchover_epoch, columns);
ADD_COLUMN(set_varchar, table, "switchover_info", switchover_info_str, columns);
if (full_columns) {
ADD_COLUMN(set_varchar, table, "switchover_status", switch_status_str, columns);
}
ADD_COLUMN(set_int, table, "current_scn", current_scn, columns);
ADD_COLUMN(set_int, table, "standby_became_primary_scn", standby_became_primary_scn, columns);
if (OB_INVALID_ID != primary_cluster_id) {
ADD_COLUMN(set_int, table, "primary_cluster_id", primary_cluster_id, columns);
} else {
// set primary_cluster_id to NULL if primary not exist
ADD_NULL_COLUMN(table, "primary_cluster_id", columns);
}
ADD_COLUMN(set_varchar, table, "protection_mode", protection_mode, columns);
ADD_COLUMN(set_varchar, table, "protection_level", protection_level, columns);
ADD_COLUMN(set_varchar, table, "redo_transport_options", redo_transopt_str, columns);
}
}
return ret;
}
} // namespace rootserver
} // namespace oceanbase

View File

@ -0,0 +1,79 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_ALL_CLUSTER_H
#define OCEANBASE_ROOTSERVER_OB_ALL_CLUSTER_H
#include "share/ob_virtual_table_projector.h"
#include "share/ob_cluster_info_proxy.h"
namespace oceanbase {
namespace share {
class ObRemoteSqlProxy;
class ObClusterInfo;
namespace schema {
class ObTableSchema;
class ObMultiVersionSchemaService;
} // namespace schema
} // namespace share
namespace obrpc {
class ObSrvRpcProxy;
}
namespace rootserver {
class ObZoneManager;
class ObServerManager;
class ObAllVirtualCluster : public common::ObVirtualTableProjector {
public:
ObAllVirtualCluster()
: inited_(false),
zone_manager_(NULL),
schema_service_(NULL),
common_rpc_proxy_(NULL),
sql_proxy_(NULL),
pt_operator_(NULL),
rpc_proxy_(NULL),
server_manager_(NULL),
root_service_(NULL)
{}
virtual ~ObAllVirtualCluster();
int init(share::schema::ObMultiVersionSchemaService& schema_service_, ObZoneManager& zone_manager,
obrpc::ObCommonRpcProxy& common_rpc_proxy, ObMySQLProxy& sql_proxy, share::ObPartitionTableOperator& pt_operator,
obrpc::ObSrvRpcProxy& rpc_proxy, ObServerManager& server_manager, ObRootService& root_service);
virtual int inner_get_next_row(common::ObNewRow*& row);
private:
int get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns, bool& full_columns);
private:
static const int64_t RPC_TIMEOOUT = 1 * 1000 * 1000; // 1s
private:
bool inited_;
ObZoneManager* zone_manager_;
share::schema::ObMultiVersionSchemaService* schema_service_;
obrpc::ObCommonRpcProxy* common_rpc_proxy_;
ObMySQLProxy* sql_proxy_;
share::ObPartitionTableOperator* pt_operator_;
obrpc::ObSrvRpcProxy* rpc_proxy_;
ObServerManager* server_manager_;
ObRootService* root_service_;
ObArenaAllocator arena_allocator_;
private:
DISALLOW_COPY_AND_ASSIGN(ObAllVirtualCluster);
};
} // namespace rootserver
} // namespace oceanbase
#endif /* !OB_ALL_CLUSTER_H */

View File

@ -0,0 +1,299 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_partition_table.h"
#include "share/partition_table/ob_partition_table_operator.h"
#include "share/schema/ob_multi_version_schema_service.h"
#include "share/schema/ob_column_schema.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/schema/ob_table_schema.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
ObAllPartitionTable::ObAllPartitionTable()
: inited_(false),
pt_operator_(NULL),
schema_service_(NULL),
server_mgr_(NULL),
schema_guard_(NULL),
table_schema_(NULL),
partition_info_(),
all_pt_iter_(),
tenant_pt_iter_(),
table_pt_iter_(),
pt_iter_(NULL),
arena_allocator_(ObModIds::OB_RS_PARTITION_TABLE_TEMP)
{}
ObAllPartitionTable::~ObAllPartitionTable()
{}
int ObAllPartitionTable::init(ObPartitionTableOperator& pt_operator, ObMultiVersionSchemaService& schema_service,
ObServerManager& server_mgr, ObSchemaGetterGuard* schema_guard)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (NULL == schema_guard) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("schema_guard is null", K(ret));
} else {
pt_operator_ = &pt_operator;
schema_service_ = &schema_service;
server_mgr_ = &server_mgr;
schema_guard_ = schema_guard;
inited_ = true;
}
return ret;
}
int ObAllPartitionTable::inner_open()
{
int ret = OB_SUCCESS;
uint64_t specific_tenant_id = OB_INVALID_TENANT_ID;
uint64_t specific_table_id = OB_INVALID_ID;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_PARTITION_TABLE_TID);
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(schema_guard_->get_table_schema(table_id, table_schema_))) {
LOG_WARN("get_table_schema failed", K(table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
} else if (OB_FAIL(get_condition(specific_tenant_id, specific_table_id))) {
LOG_WARN("fail to get condition", K(ret));
} else {
const bool ignore_row_checksum = true;
if (OB_INVALID_TENANT_ID == specific_tenant_id) {
if (OB_FAIL(all_pt_iter_.init(*pt_operator_, *schema_service_, ignore_row_checksum))) {
LOG_WARN("all partition iterator init failed", K(ret));
} else {
pt_iter_ = &all_pt_iter_;
}
} else if (OB_INVALID_ID == specific_table_id) {
if (OB_FAIL(tenant_pt_iter_.init(*pt_operator_, *schema_service_, specific_tenant_id, ignore_row_checksum))) {
LOG_WARN("tenant partition iterator init failed", K(ret), K(specific_tenant_id));
} else {
pt_iter_ = &tenant_pt_iter_;
}
} else {
if (OB_FAIL(table_pt_iter_.init(specific_table_id, *schema_guard_, *pt_operator_))) {
LOG_WARN("table partition iterator init failed", K(ret), K(specific_tenant_id), K(specific_table_id));
} else {
pt_iter_ = &table_pt_iter_;
}
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(pt_iter_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("pt_iter is null", K(ret));
} else if (OB_FAIL(pt_iter_->get_filters().filter_delete_server(*server_mgr_))) {
LOG_WARN("set server_trace_filter failed", K(ret));
} else if (OB_FAIL(pt_iter_->get_filters().set_filter_permanent_offline(*server_mgr_))) {
LOG_WARN("set permanent_offline_filter failed", K(ret));
} else if (OB_FAIL(pt_iter_->get_filters().set_replica_status(REPLICA_STATUS_NORMAL))) {
LOG_WARN("set replica_status_filter failed", K(ret));
}
}
return ret;
}
int ObAllPartitionTable::inner_get_next_row(ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_ISNULL(pt_iter_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("pt_iter is null", K(ret));
} else {
while (OB_SUCC(ret) && 0 == partition_info_.replica_count()) {
if (OB_FAIL(pt_iter_->next(partition_info_))) {
if (OB_ITER_END != ret) {
LOG_WARN("fail to get next partition_info", K(ret));
}
}
}
if (OB_SUCC(ret)) {
const int64_t index = 0;
const ObPartitionReplica& replica = partition_info_.get_replicas_v2().at(index);
ObArray<Column> columns;
columns.reuse();
if (OB_FAIL(get_full_row(table_schema_, replica, columns))) {
LOG_WARN("get_full_row failed", "table_schema", table_schema_, "replica", replica, K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("project_row failed", K(columns), K(ret));
} else {
row = &cur_row_;
if (OB_FAIL(partition_info_.get_replicas_v2().remove(index))) {
LOG_WARN("partition_info remove fail", K(ret), K(replica), K(partition_info_));
}
}
}
}
return ret;
}
int ObAllPartitionTable::get_full_row(
const ObTableSchema* table, const ObPartitionReplica& replica, ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
char* ip = NULL;
char* zone = NULL;
char* member_list = NULL;
char* column_checksum = NULL;
const char* column_checksum_tmp = "";
char* fail_list = NULL;
arena_allocator_.reset();
const char* replica_status = ob_replica_status_str(replica.replica_status_);
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (!replica.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid replica", K(replica), K(ret));
} else {
if (NULL == (ip = static_cast<char*>(arena_allocator_.alloc(OB_MAX_SERVER_ADDR_SIZE)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc ip buf failed", "size", OB_MAX_SERVER_ADDR_SIZE, K(ret));
} else if (NULL == (zone = static_cast<char*>(arena_allocator_.alloc(MAX_ZONE_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc zone buf failed", "size", MAX_ZONE_LENGTH, K(ret));
} else if (NULL == (member_list = static_cast<char*>(arena_allocator_.alloc(MAX_MEMBER_LIST_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc member_list failed", "size", OB_MAX_SERVER_ADDR_SIZE, K(ret));
} else if (NULL == (fail_list = static_cast<char*>(arena_allocator_.alloc(OB_MAX_FAILLIST_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc fail_list failed", "size", OB_MAX_FAILLIST_LENGTH, K(ret));
} else if (NULL == (column_checksum = static_cast<char*>(arena_allocator_.alloc(COLUMN_CHECKSUM_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc column_checksum failed", "size", COLUMN_CHECKSUM_LENGTH, K(ret));
} else if (false == replica.server_.ip_to_string(ip, OB_MAX_SERVER_ADDR_SIZE)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("convert server ip to string failed", K(ret), "server", replica.server_);
} else if (OB_FAIL(databuff_printf(zone, MAX_ZONE_LENGTH, "%s", replica.zone_.ptr()))) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", "buf_len", MAX_ZONE_LENGTH, "src len", strlen(replica.zone_.ptr()), K(ret));
} else if (OB_FAIL(
ObPartitionReplica::member_list2text(replica.member_list_, member_list, MAX_MEMBER_LIST_LENGTH))) {
LOG_WARN("member_list2text failed", K(replica), K(ret));
} else if (OB_FAIL(databuff_printf(fail_list, OB_MAX_FAILLIST_LENGTH, "%s", replica.fail_list_.ptr()))) {
LOG_WARN("fail list to text failed", K(replica), K(ret));
} else if (OB_FAIL(databuff_printf(column_checksum, COLUMN_CHECKSUM_LENGTH, "%s", column_checksum_tmp))) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", "buf_len", COLUMN_CHECKSUM_LENGTH, "src len", strlen(column_checksum_tmp), K(ret));
} else {
const int64_t data_size = REPLICA_TYPE_LOGONLY == replica.replica_type_ ? 0 : replica.data_size_;
const int64_t required_size = REPLICA_TYPE_LOGONLY == replica.replica_type_ ? 0 : replica.required_size_;
ADD_COLUMN(set_int, table, "tenant_id", static_cast<int64_t>(extract_tenant_id(replica.table_id_)), columns);
ADD_COLUMN(set_int, table, "table_id", static_cast<int64_t>(replica.table_id_), columns);
ADD_COLUMN(set_int, table, "partition_id", replica.partition_id_, columns);
ADD_COLUMN(set_varchar, table, "svr_ip", ip, columns);
ADD_COLUMN(set_int, table, "svr_port", replica.server_.get_port(), columns);
ADD_COLUMN(set_int, table, "sql_port", replica.sql_port_, columns);
ADD_COLUMN(set_int, table, "unit_id", static_cast<int64_t>(replica.unit_id_), columns);
ADD_COLUMN(set_int, table, "partition_cnt", replica.partition_cnt_, columns);
ADD_COLUMN(set_varchar, table, "zone", zone, columns);
ADD_COLUMN(set_int, table, "role", replica.role_, columns);
ADD_COLUMN(set_varchar, table, "member_list", member_list, columns);
ADD_COLUMN(set_int, table, "row_count", replica.row_count_, columns);
ADD_COLUMN(set_int, table, "data_size", data_size, columns);
ADD_COLUMN(set_int, table, "data_version", replica.data_version_, columns);
ADD_COLUMN(set_int, table, "data_checksum", replica.data_checksum_, columns);
ADD_COLUMN(set_int, table, "row_checksum", static_cast<int64_t>(replica.row_checksum_.checksum_), columns);
ADD_COLUMN(set_varchar, table, "column_checksum", column_checksum, columns);
ADD_COLUMN(set_int, table, "is_original_leader", replica.is_original_leader_, columns);
ADD_COLUMN(set_int, table, "to_leader_time", replica.to_leader_time_, columns);
ADD_COLUMN(set_int, table, "create_time", 0, columns); // DEPRECATED
ADD_COLUMN(set_int, table, "rebuild", replica.rebuild_, columns);
ADD_COLUMN(set_int, table, "replica_type", replica.replica_type_, columns);
ADD_COLUMN(set_varchar, table, "status", replica_status, columns);
ADD_COLUMN(set_int, table, "partition_checksum", replica.partition_checksum_, columns);
ADD_COLUMN(set_int, table, "required_size", required_size, columns);
ADD_COLUMN(set_int, table, "is_restore", replica.is_restore_, columns);
ADD_COLUMN(set_int, table, "quorum", replica.quorum_, columns);
ADD_COLUMN(set_varchar, table, "fail_list", fail_list, columns);
ADD_COLUMN(set_int, table, "recovery_timestamp", replica.recovery_timestamp_, columns);
ADD_COLUMN(set_int, table, "memstore_percent", replica.get_memstore_percent(), columns);
ADD_COLUMN(set_int, table, "data_file_id", replica.data_file_id_, columns);
}
}
return ret;
}
int ObAllPartitionTable::get_condition(uint64_t& specific_tenant_id, uint64_t& specific_table_id)
{
int ret = OB_SUCCESS;
specific_tenant_id = OB_INVALID_TENANT_ID;
specific_table_id = OB_INVALID_ID;
if (1 == get_key_ranges().count()) {
// optimize specific cases:
// 1) specified tenant_id
// 2) specified (tenant_id, table_id)
const int64_t ROW_KEY_COUNT = 5; // index
ObRowkey start_key = get_key_ranges().at(0).start_key_;
ObRowkey end_key = get_key_ranges().at(0).end_key_;
if ((ROW_KEY_COUNT != start_key.get_obj_cnt()) || (ROW_KEY_COUNT != end_key.get_obj_cnt())) {
ret = OB_ERR_UNEXPECTED;
LOG_USER_ERROR(OB_ERR_UNEXPECTED, "row key count not match");
} else {
const ObObj* start_key_obj_ptr = start_key.get_obj_ptr();
const ObObj* end_key_obj_ptr = end_key.get_obj_ptr();
for (int64_t j = 0; OB_SUCC(ret) && j < ROW_KEY_COUNT; ++j) {
if (start_key_obj_ptr[j].is_min_value() || end_key_obj_ptr[j].is_max_value() ||
!start_key_obj_ptr[j].is_integer_type() || !end_key_obj_ptr[j].is_integer_type() ||
(start_key_obj_ptr[j] != end_key_obj_ptr[j])) {
// skip
} else {
switch (j) {
case 0: { // tenant_id
specific_tenant_id = end_key_obj_ptr[j].get_int();
break;
}
case 1: { // table_id
specific_table_id = end_key_obj_ptr[j].get_int();
break;
}
case 2:
case 3:
case 4: {
// do nothing
break;
}
default: {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid index", K(ret), K(j));
}
} // end of switch
} // end of else
} // end of for
}
}
LOG_DEBUG("get condition", K(ret), K(specific_tenant_id), K(specific_table_id));
return ret;
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -0,0 +1,74 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_ALL_PARTITION_TABLE_H_
#define OCEANBASE_ROOTSERVER_OB_ALL_PARTITION_TABLE_H_
#include "share/ob_virtual_table_projector.h"
#include "share/partition_table/ob_partition_info.h"
#include "share/partition_table/ob_partition_table_iterator.h"
#include "lib/container/ob_array.h"
#include "rootserver/ob_server_manager.h"
namespace oceanbase {
namespace share {
class ObPartitionInfo;
class ObPartitionTableIterator;
class ObPartitionTableOperator;
namespace schema {
class ObMultiVersionSchemaService;
class ObTableSchema;
class ObSchemaGetterGuard;
} // namespace schema
} // namespace share
namespace rootserver {
class ObServerManager;
class ObAllPartitionTable : public common::ObVirtualTableProjector {
public:
ObAllPartitionTable();
virtual ~ObAllPartitionTable();
int init(share::ObPartitionTableOperator& pt_operator, share::schema::ObMultiVersionSchemaService& schema_service,
ObServerManager& server_mgr, share::schema::ObSchemaGetterGuard* schema_guard);
virtual int inner_open();
virtual int inner_get_next_row(common::ObNewRow*& row);
protected:
virtual int get_condition(uint64_t& specific_tenant_id, uint64_t& specific_table_id);
private:
int get_full_row(const share::schema::ObTableSchema* table, const share::ObPartitionReplica& replica,
common::ObIArray<Column>& columns);
bool inited_;
share::ObPartitionTableOperator* pt_operator_;
share::schema::ObMultiVersionSchemaService* schema_service_;
ObServerManager* server_mgr_;
share::schema::ObSchemaGetterGuard* schema_guard_;
const share::schema::ObTableSchema* table_schema_;
share::ObPartitionInfo partition_info_;
share::ObPartitionTableIterator all_pt_iter_;
share::ObTenantPartitionIterator tenant_pt_iter_;
share::ObTablePartitionIterator table_pt_iter_;
share::ObIPartitionTableIterator* pt_iter_;
ObArenaAllocator arena_allocator_;
private:
DISALLOW_COPY_AND_ASSIGN(ObAllPartitionTable);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif // OCEANBASE_ROOTSERVER_OB_ALL_PARTITION_TABLE_H_

View File

@ -0,0 +1,374 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_map_item_stat.h"
#include "rootserver/ob_root_utils.h"
#include "rootserver/ob_partition_disk_balancer.h"
#include "rootserver/ob_partition_balancer.h"
#include "rootserver/ob_balance_group_data.h"
#include "share/schema/ob_multi_version_schema_service.h"
using namespace oceanbase::rootserver;
using namespace oceanbase::rootserver::balancer;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
ObAllRebalanceMapItemStat::ObAllRebalanceMapItemStat()
: inited_(false),
schema_service_(NULL),
tenant_balance_stat_(),
index_map_(),
all_tenants_(),
tenant_maps_(),
cur_tenant_idx_(-1),
cur_map_idx_(-1),
cur_map_size_(-1),
cur_zone_idx_(-1),
cur_item_idx_(-1),
schema_guard_(),
table_schema_(NULL),
columns_()
{}
ObAllRebalanceMapItemStat::~ObAllRebalanceMapItemStat()
{}
int ObAllRebalanceMapItemStat::init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider)
{
int ret = OB_SUCCESS;
const int64_t HASH_MAP_SIZE = 100 * 1024;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("ObAllRebalanceMapItemStat already inited", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.init(unit_mgr,
server_mgr,
pt_operator,
remote_pt_operator,
zone_mgr,
task_mgr,
check_stop_provider,
unit_mgr.get_sql_proxy()))) {
LOG_WARN("failed to init tenant_balance_stat", K(ret));
} else if (OB_FAIL(schema_service.get_schema_guard(schema_guard_))) {
LOG_WARN("fail to get schema guard", K(ret));
} else if (OB_FAIL(index_map_.init(HASH_MAP_SIZE))) {
LOG_WARN("fail to create", K(ret));
} else {
schema_service_ = &schema_service;
inited_ = true;
}
return ret;
}
int ObAllRebalanceMapItemStat::inner_open()
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.reuse_replica_count_mgr())) {
LOG_WARN("reuse_replica_count_mgr failed", K(ret));
} else if (OB_FAIL(get_all_tenant())) {
LOG_WARN("fail to get all maps", K(ret));
} else if (OB_FAIL(get_table_schema(OB_ALL_VIRTUAL_REBALANCE_MAP_ITEM_STAT_TID))) {
LOG_WARN("fail to get table schema", K(ret));
} else {
cur_tenant_idx_ = -1;
cur_map_idx_ = -1;
cur_map_size_ = -1;
cur_zone_idx_ = -1;
cur_item_idx_ = -1;
}
return ret;
}
int ObAllRebalanceMapItemStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
if (OB_FAIL(next())) {
} else if (OB_FAIL(get_row())) {
} else {
row = &cur_row_;
}
}
return ret;
}
// sequence: items->zones->maps->tenants
int ObAllRebalanceMapItemStat::next()
{
int ret = OB_SUCCESS;
bool try_again = false;
do {
try_again = false;
++cur_item_idx_;
if (cur_item_idx_ >= cur_map_size_) {
// end of current zone, move to next zone
if (OB_FAIL(next_zone())) {
if (OB_ITER_END != ret) {
LOG_WARN("fail move to next zone", K(ret));
}
} else if (OB_FAIL(rebuild_map())) {
LOG_WARN("fail build map", K(ret));
}
cur_item_idx_ = -1;
try_again = true;
}
} while (try_again && OB_SUCC(ret));
return ret;
}
int ObAllRebalanceMapItemStat::next_zone()
{
int ret = OB_SUCCESS;
bool try_again = false;
do {
try_again = false;
cur_zone_idx_++;
if (cur_zone_idx_ >= tenant_balance_stat_.all_zone_unit_.count()) {
// end of current map, move to next map
if (OB_FAIL(next_map())) {
if (OB_ITER_END != ret) {
LOG_WARN("fail move to next map", K(ret));
}
}
cur_zone_idx_ = -1;
try_again = true;
}
} while (try_again && OB_SUCC(ret));
return ret;
}
int ObAllRebalanceMapItemStat::next_map()
{
int ret = OB_SUCCESS;
bool try_again = false;
do {
try_again = false;
cur_map_idx_++;
if (cur_map_idx_ >= tenant_maps_.count()) {
// end of current tenant, move to next tenant
if (OB_FAIL(next_tenant())) {
if (OB_ITER_END != ret) {
LOG_WARN("fail move to next tenant", K(ret));
}
}
cur_map_idx_ = -1;
try_again = true;
}
} while (try_again && OB_SUCC(ret));
return ret;
}
int ObAllRebalanceMapItemStat::next_tenant()
{
int ret = OB_SUCCESS;
++cur_tenant_idx_;
if (cur_tenant_idx_ >= all_tenants_.count()) {
ret = OB_ITER_END;
} else if (OB_FAIL(init_tenant_balance_stat(all_tenants_.at(cur_tenant_idx_)))) {
LOG_WARN("fail init tenant balance stat", K_(cur_tenant_idx), K_(cur_map_idx), K(ret));
}
return ret;
}
int ObAllRebalanceMapItemStat::init_tenant_balance_stat(uint64_t tenant_id)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_INVALID_ID == tenant_id) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid tenant id", K(ret));
} else {
tenant_balance_stat_.reuse();
tenant_maps_.reuse();
index_map_.reuse();
TenantSchemaGetter stat_finder(tenant_id);
ObLeaderBalanceGroupContainer balance_group_container(schema_guard_, stat_finder, allocator_);
if (OB_FAIL(balance_group_container.init(tenant_id))) {
LOG_WARN("fail to init balance group container", K(ret), K(tenant_id));
} else if (OB_FAIL(balance_group_container.build())) {
LOG_WARN("fail to build balance index builder", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.gather_stat(
tenant_id, &schema_guard_, balance_group_container.get_hash_index()))) {
LOG_WARN("gather tenant balance statistics failed", K(ret), K(tenant_id));
} else {
// do it
balancer::ITenantStatFinder& stat_finder = tenant_balance_stat_;
balancer::ObPartitionBalanceGroupContainer container(schema_guard_, stat_finder, allocator_);
if (OB_FAIL(container.init(tenant_id))) {
LOG_WARN("fail to init", K(ret));
} else if (OB_FAIL(container.build())) {
LOG_WARN("fail to build", K(ret));
} else if (OB_FAIL(tenant_maps_.assign(container.get_square_id_map_array()))) {
LOG_WARN("fail to assign tenant maps", K(ret));
} else if (OB_FAIL(index_map_.assign(container.get_hash_index()))) {
LOG_WARN("fail to assign index map", K(ret));
}
}
}
return ret;
}
int ObAllRebalanceMapItemStat::rebuild_map()
{
int ret = OB_SUCCESS;
if (cur_map_idx_ < 0 || cur_map_idx_ >= tenant_maps_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected map idx", K_(cur_map_idx), "count", tenant_maps_.count(), K(ret));
} else if (cur_zone_idx_ < 0 || cur_zone_idx_ >= tenant_balance_stat_.all_zone_unit_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected zone idx", K_(cur_zone_idx), "count", tenant_balance_stat_.all_zone_unit_.count(), K(ret));
} else {
SquareIdMap& map = *tenant_maps_.at(cur_map_idx_);
ObPartitionUnitProvider unit_provider(tenant_balance_stat_.all_zone_unit_.at(cur_zone_idx_), tenant_balance_stat_);
ObZone& zone = tenant_balance_stat_.all_zone_unit_.at(cur_zone_idx_).zone_;
DynamicAverageDiskBalancer balancer(map, tenant_balance_stat_, unit_provider, zone, schema_guard_, index_map_);
if (OB_FAIL(calc_leader_balance_statistic(zone, index_map_, map))) {
LOG_WARN("fail to calc leader balance statistic", K(ret));
} else if (!map.is_valid()) {
LOG_WARN("map is invalid and can not do balance. check detail info by query inner table",
"inner_table",
OB_ALL_VIRTUAL_REBALANCE_MAP_STAT_TNAME,
K(map),
K(ret));
} else if (OB_FAIL(balancer.balance())) { // fill unit_id and dest_unit_id
if (OB_ENTRY_NOT_EXIST == ret) {
LOG_INFO("unit not determined for some replica. ignore balance map for now", K(map), K(ret));
ret = OB_SUCCESS;
} else {
LOG_WARN("fail balance map", K(map), K(ret));
}
}
cur_map_size_ = map.size();
cur_item_idx_ = -1;
}
return ret;
}
int ObAllRebalanceMapItemStat::get_row()
{
int ret = OB_SUCCESS;
columns_.reuse();
if (OB_FAIL(get_full_row(table_schema_, columns_))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(columns_, cur_row_))) {
LOG_WARN("fail to project row", K_(columns), K(ret));
}
return ret;
}
int ObAllRebalanceMapItemStat::calc_leader_balance_statistic(
const common::ObZone& zone, const HashIndexCollection& hash_index_collection, SquareIdMap& id_map)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (zone.is_empty()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret));
} else if (id_map.ignore_leader_balance()) {
// bypass
} else if (OB_FAIL(id_map.update_leader_balance_info(zone, hash_index_collection))) {
LOG_WARN("fail to update leader balance info", K(ret));
}
return ret;
}
int ObAllRebalanceMapItemStat::get_full_row(
const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (cur_map_idx_ >= tenant_maps_.count() || cur_map_idx_ < 0) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch", K_(cur_map_idx), K(ret));
} else if (cur_zone_idx_ >= tenant_balance_stat_.all_zone_unit_.count() || cur_zone_idx_ < 0) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch", K_(cur_zone_idx), K(ret));
} else {
const balancer::SquareIdMap& map = *tenant_maps_.at(cur_map_idx_);
balancer::SquareIdMap::Item item;
cur_map_size_ = map.size();
if (cur_item_idx_ >= cur_map_size_ || cur_item_idx_ < 0) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch", K_(cur_item_idx), K(ret));
} else if (OB_FAIL(map.get(cur_item_idx_, item))) {
LOG_WARN("fail get item from map", K(map), K_(cur_item_idx), K(ret));
} else {
uint64_t tenant_id = map.get_tenant_id();
const ObZone& zone = tenant_balance_stat_.all_zone_unit_.at(cur_zone_idx_).zone_;
if (tenant_id != tenant_balance_stat_.get_tenant_id()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant id not match", K(tenant_id), "other", tenant_balance_stat_.get_tenant_id(), K(ret));
} else {
ADD_COLUMN(set_int, table, "tenant_id", map.get_tenant_id(), columns);
ADD_COLUMN(set_varchar, table, "zone", zone.str(), columns);
ADD_COLUMN(set_int, table, "tablegroup_id", item.get_tablegroup_id(), columns);
ADD_COLUMN(set_int, table, "table_id", item.get_table_id(), columns);
ADD_COLUMN(set_int, table, "map_type", map.get_map_type(), columns);
ADD_COLUMN(set_int, table, "row_size", map.get_row_size(), columns);
ADD_COLUMN(set_int, table, "col_size", map.get_col_size(), columns);
ADD_COLUMN(set_int, table, "part_idx", item.get_partition_idx(), columns);
ADD_COLUMN(set_int, table, "designated_role", (item.is_designated_leader() ? 1 : 2), columns);
ADD_COLUMN(set_int, table, "unit_id", item.get_unit_id(), columns);
ADD_COLUMN(set_int, table, "dest_unit_id", item.get_dest_unit_id(), columns);
}
}
}
return ret;
}
int ObAllRebalanceMapItemStat::get_all_tenant()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceMapItemStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_tenant_ids(all_tenants_))) {
LOG_WARN("fail to get_tenant_ids", K(ret));
}
return ret;
}
int ObAllRebalanceMapItemStat::get_table_schema(uint64_t tid)
{
int ret = OB_SUCCESS;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, tid);
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceTenantStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_table_schema(table_id, table_schema_))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
}
return ret;
}

View File

@ -0,0 +1,84 @@
/**
* 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.
*/
#ifndef _OB_ALL_REBALANCE_MAP_ITEM_STAT_H
#define _OB_ALL_REBALANCE_MAP_ITEM_STAT_H 1
#include "share/ob_virtual_table_projector.h"
#include "rootserver/ob_balance_info.h"
#include "lib/container/ob_se_array.h"
#include "common/ob_zone.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "rootserver/ob_balance_group_data.h"
namespace oceanbase {
namespace share {
namespace schema {
class ObTableSchema;
class ObMultiVersionSchemaService;
} // namespace schema
} // namespace share
namespace rootserver {
namespace balancer {
class SquareIdMap;
}
class ObAllRebalanceMapItemStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceMapItemStat();
virtual ~ObAllRebalanceMapItemStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
int get_table_schema(uint64_t tid);
int get_all_tenant();
int init_tenant_balance_stat(uint64_t tenant_id);
int get_row();
int next();
int get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns);
int next_zone();
int next_map();
int next_tenant();
int rebuild_map();
int calc_leader_balance_statistic(const common::ObZone& zone,
const balancer::HashIndexCollection& hash_index_collection, balancer::SquareIdMap& id_map);
private:
// data members
bool inited_;
share::schema::ObMultiVersionSchemaService* schema_service_;
common::ObArenaAllocator allocator_;
TenantBalanceStat tenant_balance_stat_;
balancer::HashIndexCollection index_map_;
common::ObSEArray<uint64_t, 16> all_tenants_;
common::ObArray<balancer::SquareIdMap*> tenant_maps_;
int64_t cur_tenant_idx_;
int64_t cur_map_idx_;
int64_t cur_map_size_;
int64_t cur_zone_idx_;
int64_t cur_item_idx_;
share::schema::ObSchemaGetterGuard schema_guard_;
const share::schema::ObTableSchema* table_schema_;
common::ObSEArray<Column, 16> columns_;
DISALLOW_COPY_AND_ASSIGN(ObAllRebalanceMapItemStat);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_REBALANCE_MAP_ITEM_STAT_H */

View File

@ -0,0 +1,296 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_map_stat.h"
#include "rootserver/ob_root_utils.h"
#include "rootserver/ob_unit_manager.h"
#include "rootserver/ob_balance_group_container.h"
#include "share/schema/ob_multi_version_schema_service.h"
using namespace oceanbase::rootserver;
using namespace oceanbase::rootserver::balancer;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
ObAllRebalanceMapStat::ObAllRebalanceMapStat()
: inited_(false),
schema_service_(NULL),
tenant_balance_stat_(),
all_tenants_(),
tenant_maps_(),
cur_tenant_idx_(-1),
cur_map_idx_(-1),
schema_guard_(),
table_schema_(NULL),
columns_()
{}
ObAllRebalanceMapStat::~ObAllRebalanceMapStat()
{}
int ObAllRebalanceMapStat::init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("ObAllRebalanceMapStat already inited", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.init(unit_mgr,
server_mgr,
pt_operator,
remote_pt_operator,
zone_mgr,
task_mgr,
check_stop_provider,
unit_mgr.get_sql_proxy()))) {
LOG_WARN("failed to init tenant_balance_stat", K(ret));
} else if (OB_FAIL(schema_service.get_schema_guard(schema_guard_))) {
LOG_WARN("fail to get schema guard", K(ret));
} else {
schema_service_ = &schema_service;
inited_ = true;
}
return ret;
}
int ObAllRebalanceMapStat::inner_open()
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.reuse_replica_count_mgr())) {
LOG_WARN("reuse_replica_count_mgr failed", K(ret));
} else if (OB_FAIL(get_all_tenant())) {
LOG_WARN("fail to get all maps", K(ret));
} else if (OB_FAIL(get_table_schema(OB_ALL_VIRTUAL_REBALANCE_MAP_STAT_TID))) {
LOG_WARN("fail to get table schema", K(ret));
} else {
cur_tenant_idx_ = -1;
cur_map_idx_ = -1;
}
return ret;
}
int ObAllRebalanceMapStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
if (OB_FAIL(next())) {
} else if (OB_FAIL(get_row())) {
} else {
row = &cur_row_;
}
}
return ret;
}
int ObAllRebalanceMapStat::next()
{
int ret = OB_SUCCESS;
bool loop = false;
do {
loop = false;
++cur_map_idx_;
if (cur_map_idx_ >= tenant_maps_.count()) {
++cur_tenant_idx_;
if (cur_tenant_idx_ >= all_tenants_.count()) {
ret = OB_ITER_END;
} else if (OB_FAIL(init_tenant_balance_stat(all_tenants_.at(cur_tenant_idx_)))) {
LOG_WARN("fail init tenant balance stat", K_(cur_tenant_idx), K_(cur_map_idx), K(ret));
} else {
cur_map_idx_ = -1;
loop = true;
}
}
} while (loop);
return ret;
}
int ObAllRebalanceMapStat::get_row()
{
int ret = OB_SUCCESS;
columns_.reuse();
if (OB_FAIL(get_full_row(table_schema_, columns_))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(columns_, cur_row_))) {
LOG_WARN("fail to project row", K_(columns), K(ret));
}
return ret;
}
int ObAllRebalanceMapStat::get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (cur_map_idx_ >= tenant_maps_.count() || cur_map_idx_ < 0) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch", K_(cur_map_idx), K(ret));
} else {
const balancer::SquareIdMap& map = *tenant_maps_.at(cur_map_idx_);
ObArray<const ObPartitionSchema*> entity_schemas;
int64_t item_cnt = 0;
if (balancer::SHARD_GROUP_BALANCE_GROUP == map.get_map_type() ||
balancer::SHARD_PARTITION_BALANCE_GROUP == map.get_map_type()) {
FOREACH_X(item, map, OB_SUCC(ret))
{
int64_t tg_idx = item->all_tg_idx_;
uint64_t tenant_id = map.get_tenant_id();
if (tenant_id != tenant_balance_stat_.get_tenant_id()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant id not match", K(tenant_id), "other", tenant_balance_stat_.get_tenant_id(), K(ret));
} else if (tg_idx < 0 || tg_idx >= tenant_balance_stat_.all_tg_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected tg_idx value", K(tg_idx), "max", tenant_balance_stat_.all_tg_.count(), K(ret));
} else if (OB_FAIL(StatFinderUtil::get_partition_entity_schemas_by_tg_idx(
tenant_balance_stat_, schema_guard_, tenant_id, tg_idx, entity_schemas))) {
LOG_WARN("fail get tables schemas for tg", K(tenant_id), K(tg_idx));
} else {
if (++item_cnt >= map.get_col_size()) {
break; // only need first row
}
}
}
} else {
FOREACH_X(item, map, OB_SUCC(ret))
{
int64_t tg_idx = item->all_tg_idx_;
uint64_t tenant_id = map.get_tenant_id();
if (tenant_id != tenant_balance_stat_.get_tenant_id()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant id not match", K(tenant_id), "other", tenant_balance_stat_.get_tenant_id(), K(ret));
} else if (tg_idx < 0 || tg_idx >= tenant_balance_stat_.all_tg_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected tg_idx value", K(tg_idx), "max", tenant_balance_stat_.all_tg_.count(), K(ret));
} else if (OB_FAIL(StatFinderUtil::get_partition_entity_schemas_by_tg_idx(
tenant_balance_stat_, schema_guard_, tenant_id, tg_idx, entity_schemas))) {
LOG_WARN("fail get tables schemas for tg", K(tenant_id), K(tg_idx));
} else {
break; // only need first item
}
}
}
// max 64K per column
char* buf = NULL;
const int64_t buf_size = 64 * 1024;
int64_t pos = 0;
if (OB_SUCC(ret)) {
buf = static_cast<char*>(allocator_.alloc(buf_size));
if (NULL == buf) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("alloc memory fail", K(ret));
} else {
FOREACH_X(it, entity_schemas, OB_SUCC(ret))
{
const ObPartitionSchema* t = *it;
if (OB_ISNULL(t)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("NULL ptr", KP(t), K(ret));
} else {
int64_t write = snprintf(buf + pos, buf_size - pos, "%s ", t->get_entity_name());
if (write >= buf_size - pos) {
break; // overflow, truncate
} else {
pos += write;
}
}
}
}
}
ADD_COLUMN(set_int, table, "tenant_id", map.get_tenant_id(), columns);
ADD_COLUMN(set_int, table, "map_type", map.get_map_type(), columns);
ADD_COLUMN(set_bool, table, "is_valid", map.is_valid(), columns);
ADD_COLUMN(set_int, table, "row_size", map.get_row_size(), columns);
ADD_COLUMN(set_int, table, "col_size", map.get_col_size(), columns);
ADD_COLUMN(set_varchar, table, "tables", ObString(buf), columns);
}
return ret;
}
int ObAllRebalanceMapStat::get_all_tenant()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceMapStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_tenant_ids(all_tenants_))) {
LOG_WARN("fail to get_tenant_ids", K(ret));
}
return ret;
}
int ObAllRebalanceMapStat::init_tenant_balance_stat(uint64_t tenant_id)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_INVALID_ID == tenant_id) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid tenant id", K(ret));
} else {
tenant_balance_stat_.reuse();
tenant_maps_.reuse();
TenantSchemaGetter stat_finder(tenant_id);
ObLeaderBalanceGroupContainer balance_group_container(schema_guard_, stat_finder, allocator_);
if (OB_FAIL(balance_group_container.init(tenant_id))) {
LOG_WARN("fail to init balance group container", K(ret), K(tenant_id));
} else if (OB_FAIL(balance_group_container.build())) {
LOG_WARN("fail to build balance index builder", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.gather_stat(
tenant_id, &schema_guard_, balance_group_container.get_hash_index()))) {
LOG_WARN("gather tenant balance statistics failed", K(ret), K(tenant_id));
} else {
// do it
balancer::ITenantStatFinder& stat_finder = tenant_balance_stat_;
balancer::ObPartitionBalanceGroupContainer container(schema_guard_, stat_finder, allocator_);
if (OB_FAIL(container.init(tenant_id))) {
LOG_WARN("fail to init", K(ret));
} else if (OB_FAIL(container.build())) {
LOG_WARN("fail to build", K(ret));
} else if (OB_FAIL(tenant_maps_.assign(container.get_square_id_map_array()))) {
LOG_WARN("fail to assign tenant maps", K(ret));
}
}
}
return ret;
}
int ObAllRebalanceMapStat::get_table_schema(uint64_t tid)
{
int ret = OB_SUCCESS;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, tid);
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceTenantStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_table_schema(table_id, table_schema_))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
}
return ret;
}

View File

@ -0,0 +1,72 @@
/**
* 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.
*/
#ifndef _OB_ALL_REBALANCE_MAP_STAT_H
#define _OB_ALL_REBALANCE_MAP_STAT_H 1
#include "share/ob_virtual_table_projector.h"
#include "rootserver/ob_balance_info.h"
#include "lib/container/ob_se_array.h"
#include "share/schema/ob_schema_getter_guard.h"
namespace oceanbase {
namespace share {
namespace schema {
class ObTableSchema;
class ObMultiVersionSchemaService;
} // namespace schema
} // namespace share
namespace rootserver {
namespace balancer {
class SquareIdMap;
}
class ObAllRebalanceMapStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceMapStat();
virtual ~ObAllRebalanceMapStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
int get_table_schema(uint64_t tid);
int get_all_tenant();
int init_tenant_balance_stat(uint64_t tenant_id);
int get_row();
int next();
int get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns);
private:
// data members
bool inited_;
share::schema::ObMultiVersionSchemaService* schema_service_;
common::ObArenaAllocator allocator_;
TenantBalanceStat tenant_balance_stat_;
common::ObSEArray<uint64_t, 16> all_tenants_;
common::ObArray<balancer::SquareIdMap*> tenant_maps_;
int64_t cur_tenant_idx_;
int64_t cur_map_idx_;
share::schema::ObSchemaGetterGuard schema_guard_;
const share::schema::ObTableSchema* table_schema_;
common::ObSEArray<Column, 16> columns_;
DISALLOW_COPY_AND_ASSIGN(ObAllRebalanceMapStat);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_REBALANCE_MAP_STAT_H */

View File

@ -0,0 +1,152 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_replica_stat.h"
#include "share/schema/ob_multi_version_schema_service.h"
using namespace oceanbase::rootserver;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
ObAllRebalanceReplicaStat::ObAllRebalanceReplicaStat() : cur_partition_idx_(-1), cur_replica_idx_(-1)
{
ip_buf_[0] = '\0';
}
ObAllRebalanceReplicaStat::~ObAllRebalanceReplicaStat()
{}
int ObAllRebalanceReplicaStat::init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider)
{
return impl_.init(
schema_service, unit_mgr, server_mgr, pt_operator, remote_pt_operator, zone_mgr, task_mgr, check_stop_provider);
}
int ObAllRebalanceReplicaStat::inner_open()
{
int ret = OB_SUCCESS;
if (OB_FAIL(impl_.tenant_balance_stat_.reuse_replica_count_mgr())) {
LOG_WARN("reuse_replica_count_mgr failed", K(ret));
} else if (OB_FAIL(impl_.get_all_tenant())) {
} else if (OB_FAIL(impl_.get_table_schema(OB_ALL_VIRTUAL_REBALANCE_REPLICA_STAT_TID))) {
} else {
impl_.cur_tenant_idx_ = -1;
cur_partition_idx_ = -1;
cur_replica_idx_ = -1;
}
return ret;
}
int ObAllRebalanceReplicaStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (!impl_.inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
if (OB_FAIL(next())) {
} else if (OB_FAIL(get_row())) {
} else {
row = &cur_row_;
}
}
return ret;
}
int ObAllRebalanceReplicaStat::next()
{
int ret = OB_SUCCESS;
bool loop = false;
do {
loop = false;
++cur_replica_idx_; // next unit
if (cur_partition_idx_ < 0) {
cur_partition_idx_ = 0; // first zone
}
if (cur_partition_idx_ >= impl_.tenant_balance_stat_.all_partition_.count()) { // end of partition
++impl_.cur_tenant_idx_; // next tenant
if (impl_.cur_tenant_idx_ >= impl_.all_tenants_.count()) {
ret = OB_ITER_END;
} else {
if (OB_FAIL(impl_.init_tenant_balance_stat(impl_.all_tenants_.at(impl_.cur_tenant_idx_)))) {
} else {
cur_partition_idx_ = -1;
cur_replica_idx_ = -1;
loop = true;
}
}
} else { // valid partition
const Partition& partition = impl_.tenant_balance_stat_.all_partition_.at(cur_partition_idx_);
if (cur_replica_idx_ >= partition.get_replica_count()) { // end of replica
cur_partition_idx_++; // next partition
cur_replica_idx_ = -1;
loop = true;
}
}
} while (loop);
return ret;
}
int ObAllRebalanceReplicaStat::get_row()
{
int ret = OB_SUCCESS;
impl_.columns_.reuse();
if (OB_FAIL(get_full_row(impl_.table_schema_, impl_.columns_))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(impl_.columns_, cur_row_))) {
LOG_WARN("fail to project row", K_(impl_.columns), K(ret));
}
return ret;
}
int ObAllRebalanceReplicaStat::get_full_row(
const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (cur_partition_idx_ >= impl_.tenant_balance_stat_.all_partition_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch");
} else if (cur_replica_idx_ >= impl_.tenant_balance_stat_.all_partition_.at(cur_partition_idx_).get_replica_count()) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch");
} else {
const Partition& partition = impl_.tenant_balance_stat_.all_partition_.at(cur_partition_idx_);
const Replica& replica = impl_.tenant_balance_stat_.all_replica_.at(cur_partition_idx_);
// primary key
(void)replica.server_->server_.ip_to_string(ip_buf_, MAX_IP_ADDR_LENGTH);
ADD_COLUMN(set_int, table, "tenant_id", impl_.tenant_balance_stat_.tenant_id_, columns);
ADD_COLUMN(set_int, table, "table_id", partition.table_id_, columns);
ADD_COLUMN(set_int, table, "partition_id", partition.partition_id_, columns);
ADD_COLUMN(set_varchar, table, "svr_ip", ip_buf_, columns);
ADD_COLUMN(set_int, table, "svr_port", replica.server_->server_.get_port(), columns);
// other columns
ADD_COLUMN(set_double, table, "cpu_usage", replica.load_factor_.get_cpu_usage(), columns);
ADD_COLUMN(set_double, table, "disk_usage", replica.load_factor_.get_disk_usage(), columns);
ADD_COLUMN(set_double, table, "iops_usage", replica.load_factor_.get_iops_usage(), columns);
ADD_COLUMN(set_double, table, "memory_usage", replica.load_factor_.get_memory_usage(), columns);
ADD_COLUMN(set_double, table, "net_packet_usage", replica.load_factor_.get_net_packet_usage(), columns);
ADD_COLUMN(set_double, table, "net_throughput_usage", replica.load_factor_.get_net_throughput_usage(), columns);
ADD_COLUMN(set_int, table, "unit_id", replica.unit_->info_.unit_.unit_id_, columns);
ADD_COLUMN(set_varchar, table, "zone", replica.zone_.str(), columns);
}
return ret;
}

View File

@ -0,0 +1,49 @@
/**
* 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.
*/
#ifndef _OB_ALL_REBALANCE_REPLICA_STAT_H
#define _OB_ALL_REBALANCE_REPLICA_STAT_H 1
#include "ob_all_rebalance_tenant_stat.h"
namespace oceanbase {
namespace rootserver {
class ObAllRebalanceReplicaStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceReplicaStat();
virtual ~ObAllRebalanceReplicaStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObAllRebalanceReplicaStat);
// function members
int get_row();
int next();
int get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns);
private:
// data members
ObAllRebalanceTenantStat impl_;
int64_t cur_partition_idx_;
int64_t cur_replica_idx_;
char ip_buf_[common::MAX_IP_ADDR_LENGTH];
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_REBALANCE_REPLICA_STAT_H */

View File

@ -0,0 +1,305 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_task_stat.h"
#include "share/schema/ob_multi_version_schema_service.h"
#include "share/schema/ob_schema_getter_guard.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
void ObAllRebalanceTaskStat::Display::reset()
{
tenant_id_ = OB_INVALID_ID;
table_id_ = OB_INVALID_ID;
partition_id_ = OB_INVALID_INDEX;
partition_cnt_ = 0;
src_ = NULL;
data_src_ = NULL;
dest_ = NULL;
offline_ = NULL;
task_type_ = NULL;
is_replicate_ = NULL;
is_scheduled_ = NULL;
is_manual_ = NULL;
waiting_time_ = 0;
executing_time_ = 0;
}
ObAllRebalanceTaskStat::ObAllRebalanceTaskStat() : inited_(false), schema_service_(NULL), rebalance_task_mgr_(NULL)
{}
ObAllRebalanceTaskStat::~ObAllRebalanceTaskStat()
{}
int ObAllRebalanceTaskStat::init(ObMultiVersionSchemaService& schema_service, ObRebalanceTaskMgr& rebalance_task_mgr)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else {
schema_service_ = &schema_service;
rebalance_task_mgr_ = &rebalance_task_mgr;
inited_ = true;
}
return ret;
}
int ObAllRebalanceTaskStat::inner_get_next_row(ObNewRow*& row)
{
int ret = OB_SUCCESS;
ObSchemaGetterGuard schema_guard;
if (NULL == allocator_) {
ret = OB_NOT_INIT;
LOG_WARN("not init, allocator is null", K(ret));
} else if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
LOG_WARN("get schema guard error", K(ret));
} else if (!start_to_read_) {
common::ObArenaAllocator allocator;
ObArray<ObRebalanceTask*> task_stats;
const ObTableSchema* table_schema = NULL;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_REBALANCE_TASK_STAT_TID);
if (OB_FAIL(schema_guard.get_table_schema(table_id, table_schema))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (NULL == table_schema) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", KP(table_schema), K(ret));
} else if (OB_FAIL(rebalance_task_mgr_->get_all_tasks(allocator, task_stats))) {
LOG_WARN("fail to get tasks", K(ret));
} else {
ObArray<Column> columns;
for (int64_t j = 0; OB_SUCC(ret) && j < task_stats.count(); ++j) {
const ObRebalanceTask* task_stat = task_stats.at(j);
if (OB_UNLIKELY(nullptr == task_stat)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("task stat", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < task_stat->get_sub_task_count(); ++i) {
columns.reuse();
const ObRebalanceTaskInfo* task_info = task_stat->get_sub_task(i);
if (OB_UNLIKELY(nullptr == task_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("task info ptr is null", K(ret));
} else if (OB_FAIL(get_full_row(table_schema, *task_stat, *task_info, columns))) {
LOG_WARN("fail to get full row", "table_schema", *table_schema, "task_stat", *task_stat, K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("fail to project row", K(columns), K(ret));
} else if (OB_FAIL(scanner_.add_row(cur_row_))) {
LOG_WARN("fail to add row", K_(cur_row), K(ret));
}
}
}
}
}
for (int64_t j = 0; j < task_stats.count(); ++j) {
ObRebalanceTask* task_stat = task_stats.at(j);
if (nullptr != task_stat) {
task_stat->~ObRebalanceTask();
task_stat = nullptr;
}
}
if (OB_SUCC(ret)) {
scanner_it_ = scanner_.begin();
start_to_read_ = true;
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) {
if (OB_ITER_END != ret) {
LOG_WARN("fail to get next row", K(ret));
}
} else {
row = &cur_row_;
}
}
return ret;
}
int ObAllRebalanceTaskStat::generate_task_stat(
const ObRebalanceTask& task_stat, const ObRebalanceTaskInfo& task_info, Display& display)
{
int ret = OB_SUCCESS;
common::ObAddr src;
common::ObAddr data_src;
common::ObAddr dest;
common::ObAddr offline;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(task_info.get_virtual_rebalance_task_stat_info(src, data_src, dest, offline))) {
LOG_WARN("fail to get virtual rebalance task stat info", K(ret));
} else {
display.src_ = NULL;
display.dest_ = NULL;
display.data_src_ = NULL;
display.offline_ = NULL;
display.task_type_ = NULL;
display.is_replicate_ = NULL;
display.is_scheduled_ = NULL;
display.is_manual_ = NULL;
if (NULL == (display.src_ = static_cast<char*>(allocator_->alloc(OB_IP_PORT_STR_BUFF)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate source buf", "size", OB_IP_PORT_STR_BUFF, K(ret));
} else if (OB_FAIL(src.ip_port_to_string(display.src_, OB_IP_PORT_STR_BUFF))) {
LOG_WARN("fail to get source server ip:port", K(src), LITERAL_K(OB_IP_PORT_STR_BUFF), K(ret));
} else if (NULL == (display.data_src_ = static_cast<char*>(allocator_->alloc(OB_IP_PORT_STR_BUFF)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate data source buf", "size", OB_IP_PORT_STR_BUFF, K(ret));
} else if (OB_FAIL(data_src.ip_port_to_string(display.data_src_, OB_IP_PORT_STR_BUFF))) {
LOG_WARN("fail to get source server ip:port", K(data_src), LITERAL_K(OB_IP_PORT_STR_BUFF), K(ret));
} else if (NULL == (display.dest_ = static_cast<char*>(allocator_->alloc(OB_IP_PORT_STR_BUFF)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate destination server buf", "size", OB_IP_PORT_STR_BUFF, K(ret));
} else if (OB_FAIL(dest.ip_port_to_string(display.dest_, OB_IP_PORT_STR_BUFF))) {
LOG_WARN("fail to get destination server ip:port", K(dest), LITERAL_K(OB_IP_PORT_STR_BUFF), K(ret));
} else if (NULL == (display.offline_ = static_cast<char*>(allocator_->alloc(OB_IP_PORT_STR_BUFF)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate offline server buf", "size", OB_IP_PORT_STR_BUFF, K(ret));
} else if (OB_FAIL(offline.ip_port_to_string(display.offline_, OB_IP_PORT_STR_BUFF))) {
LOG_WARN("fail to get offline server ip:port", K(offline), LITERAL_K(OB_IP_PORT_STR_BUFF), K(ret));
} else if (NULL == (display.task_type_ = static_cast<char*>(allocator_->alloc(128)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate replicate status buf", "size", MAX_BOOL_STR_LENGTH, K(ret));
} else if (NULL == (display.is_replicate_ = static_cast<char*>(allocator_->alloc(MAX_BOOL_STR_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate scheduled status buf", "size", MAX_BOOL_STR_LENGTH, K(ret));
} else if (NULL == (display.is_scheduled_ = static_cast<char*>(allocator_->alloc(MAX_BOOL_STR_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate scheduled status buf", "size", MAX_BOOL_STR_LENGTH, K(ret));
} else if (NULL == (display.is_manual_ = static_cast<char*>(allocator_->alloc(MAX_BOOL_STR_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to allocate is_manual buf", "size", MAX_BOOL_STR_LENGTH, K(ret));
} else {
const char* task_type_str = task_stat.get_task_type_str(task_stat.get_rebalance_task_type());
const char* replicate_bool_str =
ObRebalanceTaskType::ADD_REPLICA == task_stat.get_rebalance_task_type() ? "Yes" : "No";
const char* scheduled_bool_str = task_stat.in_schedule() ? "Yes" : "No";
const char* is_manual_str = task_info.is_manual() ? "Yes" : "No";
const int64_t now = ObTimeUtility::current_time();
if (OB_FAIL(databuff_printf(display.task_type_, 128, "%s", task_type_str))) {
LOG_WARN("printf failed", "buf_len", 128, "src len", strlen(task_type_str), K(ret));
} else if (OB_FAIL(databuff_printf(display.is_replicate_, MAX_BOOL_STR_LENGTH, "%s", replicate_bool_str))) {
LOG_WARN("printf failed", "buf_len", MAX_BOOL_STR_LENGTH, "src len", strlen(replicate_bool_str), K(ret));
} else if (OB_FAIL(databuff_printf(display.is_scheduled_, MAX_BOOL_STR_LENGTH, "%s", scheduled_bool_str))) {
LOG_WARN("printf failed", "buf_len", MAX_BOOL_STR_LENGTH, "src len", strlen(scheduled_bool_str), K(ret));
} else if (OB_FAIL(databuff_printf(display.is_manual_, MAX_BOOL_STR_LENGTH, "%s", is_manual_str))) {
LOG_WARN("printf failed", "buf_len", MAX_BOOL_STR_LENGTH, "is_manual len", strlen(is_manual_str), K(ret));
} else {
display.table_id_ = task_info.get_partition_key().get_table_id();
display.tenant_id_ = task_info.get_tenant_id();
display.partition_id_ = task_info.get_partition_key().get_partition_id();
display.partition_cnt_ = task_info.get_partition_key().get_partition_cnt();
if (task_stat.in_schedule()) {
display.waiting_time_ = task_stat.get_schedule_time() - task_stat.get_generate_time();
display.executing_time_ = now - task_stat.get_schedule_time();
} else {
display.waiting_time_ = now - task_stat.get_generate_time();
display.executing_time_ = 0;
}
}
}
if (OB_FAIL(ret)) {
if (NULL != display.src_) {
allocator_->free(display.src_);
display.src_ = NULL;
}
if (NULL != display.data_src_) {
allocator_->free(display.data_src_);
display.data_src_ = NULL;
}
if (NULL != display.dest_) {
allocator_->free(display.dest_);
display.dest_ = NULL;
}
if (NULL != display.offline_) {
allocator_->free(display.offline_);
display.offline_ = NULL;
}
if (NULL != display.task_type_) {
allocator_->free(display.task_type_);
display.task_type_ = NULL;
}
if (NULL != display.is_replicate_) {
allocator_->free(display.is_replicate_);
display.is_replicate_ = NULL;
}
if (NULL != display.is_scheduled_) {
allocator_->free(display.is_scheduled_);
display.is_scheduled_ = NULL;
}
if (NULL != display.is_manual_) {
allocator_->free(display.is_manual_);
display.is_manual_ = NULL;
}
if (NULL != display.is_manual_) {
allocator_->free(display.is_manual_);
display.is_manual_ = NULL;
}
}
}
return ret;
}
int ObAllRebalanceTaskStat::get_full_row(const share::schema::ObTableSchema* table, const ObRebalanceTask& task_stat,
const ObRebalanceTaskInfo& task_info, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
// Display play a role of memory medium, no memory leak occurs, since the allocator
// is a page arena from outside.
Display display;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (OB_FAIL(generate_task_stat(task_stat, task_info, display))) {
LOG_WARN("fail to generate task stat", K(task_stat), K(ret));
} else {
ADD_COLUMN(set_uint64, table, "tenant_id", display.tenant_id_, columns);
ADD_COLUMN(set_uint64, table, "table_id", display.table_id_, columns);
ADD_COLUMN(set_int, table, "partition_id", display.partition_id_, columns);
ADD_COLUMN(set_int, table, "partition_count", display.partition_cnt_, columns);
ADD_COLUMN(set_varchar, table, "source", display.src_, columns);
ADD_COLUMN(set_varchar, table, "data_source", display.data_src_, columns);
ADD_COLUMN(set_varchar, table, "destination", display.dest_, columns);
ADD_COLUMN(set_varchar, table, "offline", display.offline_, columns);
// TODO: rename is_replicate to priority
ADD_COLUMN(set_varchar, table, "is_replicate", display.is_replicate_, columns);
ADD_COLUMN(set_varchar, table, "task_type", display.task_type_, columns);
ADD_COLUMN(set_varchar, table, "is_scheduled", display.is_scheduled_, columns);
ADD_COLUMN(set_varchar, table, "is_manual", display.is_manual_, columns);
ADD_COLUMN(set_int, table, "waiting_time", display.waiting_time_, columns);
ADD_COLUMN(set_int, table, "executing_time", display.executing_time_, columns);
}
return ret;
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -0,0 +1,74 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_ALL_REBALANCE_TASK_STAT_H_
#define OCEANBASE_ROOTSERVER_OB_ALL_REBALANCE_TASK_STAT_H_
#include "share/ob_virtual_table_projector.h"
#include "rootserver/ob_rebalance_task_mgr.h"
namespace oceanbase {
namespace share {
namespace schema {
class ObMultiVersionSchemaService;
class ObTableSchema;
} // namespace schema
} // namespace share
namespace rootserver {
class ObRebalanceTask;
class ObRebalanceTaskMgr;
class ObAllRebalanceTaskStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceTaskStat();
virtual ~ObAllRebalanceTaskStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, ObRebalanceTaskMgr& rebalance_task_mgr);
virtual int inner_get_next_row(common::ObNewRow*& row);
private:
struct Display {
void reset();
uint64_t tenant_id_;
uint64_t table_id_;
int64_t partition_id_;
int64_t partition_cnt_;
char* src_;
char* data_src_;
char* dest_;
char* offline_;
char* task_type_;
char* is_replicate_;
char* is_scheduled_;
int64_t waiting_time_;
int64_t executing_time_;
char* is_manual_;
TO_STRING_KV(K_(table_id), K_(partition_id), K_(partition_cnt), K_(src), K_(data_src), K_(dest), K_(offline),
K_(task_type), K_(is_replicate), K_(is_scheduled), K_(waiting_time), K_(executing_time), K_(is_manual));
};
int generate_task_stat(const ObRebalanceTask& task_stat, const ObRebalanceTaskInfo& task_info, Display& display);
int get_full_row(const share::schema::ObTableSchema* table, const ObRebalanceTask& task_stat,
const ObRebalanceTaskInfo& task_info, common::ObIArray<Column>& columns);
private:
bool inited_;
share::schema::ObMultiVersionSchemaService* schema_service_;
ObRebalanceTaskMgr* rebalance_task_mgr_;
private:
DISALLOW_COPY_AND_ASSIGN(ObAllRebalanceTaskStat);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif

View File

@ -0,0 +1,231 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_tenant_stat.h"
#include "rootserver/ob_root_utils.h"
#include "rootserver/ob_unit_manager.h"
#include "rootserver/ob_balance_group_container.h"
#include "share/schema/ob_multi_version_schema_service.h"
using namespace oceanbase::rootserver;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
using namespace oceanbase::rootserver::balancer;
ObAllRebalanceTenantStat::ObAllRebalanceTenantStat()
: inited_(false),
schema_service_(NULL),
tenant_balance_stat_(),
all_tenants_(),
cur_tenant_idx_(-1),
cur_zone_idx_(-1),
schema_guard_(),
table_schema_(NULL),
columns_()
{}
ObAllRebalanceTenantStat::~ObAllRebalanceTenantStat()
{}
int ObAllRebalanceTenantStat::init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("ObAllRebalanceTenantStat already inited", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.init(unit_mgr,
server_mgr,
pt_operator,
remote_pt_operator,
zone_mgr,
task_mgr,
check_stop_provider,
unit_mgr.get_sql_proxy()))) {
LOG_WARN("failed to init tenant_balance_stat", K(ret));
} else if (OB_FAIL(schema_service.get_schema_guard(schema_guard_))) {
LOG_WARN("fail to get schema guard", K(ret));
} else {
schema_service_ = &schema_service;
inited_ = true;
}
return ret;
}
int ObAllRebalanceTenantStat::inner_open()
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.reuse_replica_count_mgr())) {
LOG_WARN("reuse_replica_count_mgr failed", K(ret));
} else if (OB_FAIL(get_all_tenant())) {
LOG_WARN("fail to get all tenant", K(ret));
} else if (OB_FAIL(get_table_schema(OB_ALL_VIRTUAL_REBALANCE_TENANT_STAT_TID))) {
LOG_WARN("fail to get table schema", K(ret));
} else {
cur_tenant_idx_ = -1;
cur_zone_idx_ = -1;
}
return ret;
}
int ObAllRebalanceTenantStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
if (OB_FAIL(next())) {
} else if (OB_FAIL(get_row())) {
} else {
row = &cur_row_;
}
}
return ret;
}
int ObAllRebalanceTenantStat::next()
{
int ret = OB_SUCCESS;
bool loop = false;
do {
loop = false;
++cur_zone_idx_;
if (cur_zone_idx_ >= tenant_balance_stat_.all_zone_unit_.count()) {
++cur_tenant_idx_;
if (cur_tenant_idx_ >= all_tenants_.count()) {
ret = OB_ITER_END;
} else {
if (OB_FAIL(init_tenant_balance_stat(all_tenants_.at(cur_tenant_idx_)))) {
} else {
cur_zone_idx_ = -1;
loop = true;
}
}
}
} while (loop);
return ret;
}
int ObAllRebalanceTenantStat::get_row()
{
int ret = OB_SUCCESS;
columns_.reuse();
if (OB_FAIL(get_full_row(table_schema_, columns_))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(columns_, cur_row_))) {
LOG_WARN("fail to project row", K_(columns), K(ret));
}
return ret;
}
int ObAllRebalanceTenantStat::get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (cur_zone_idx_ >= tenant_balance_stat_.all_zone_unit_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch");
} else {
const ZoneUnit& zu = tenant_balance_stat_.all_zone_unit_.at(cur_zone_idx_);
// primary key
ADD_COLUMN(set_int, table, "tenant_id", tenant_balance_stat_.tenant_id_, columns);
ADD_COLUMN(set_varchar, table, "zone", zu.zone_.str(), columns);
// other columns
ADD_COLUMN(set_double, table, "cpu_weight", tenant_balance_stat_.resource_weight_.cpu_weight_, columns);
ADD_COLUMN(set_double, table, "disk_weight", tenant_balance_stat_.resource_weight_.disk_weight_, columns);
ADD_COLUMN(set_double, table, "iops_weight", tenant_balance_stat_.resource_weight_.iops_weight_, columns);
ADD_COLUMN(set_double, table, "memory_weight", tenant_balance_stat_.resource_weight_.memory_weight_, columns);
ADD_COLUMN(set_double, table, "load_imbalance", zu.load_imbalance_, columns);
ADD_COLUMN(set_double, table, "load_avg", zu.load_avg_, columns);
ADD_COLUMN(set_double, table, "cpu_imbalance", zu.cpu_imbalance_, columns);
ADD_COLUMN(set_double, table, "cpu_avg", zu.cpu_avg_, columns);
ADD_COLUMN(set_double, table, "disk_imbalance", zu.disk_imbalance_, columns);
ADD_COLUMN(set_double, table, "disk_avg", zu.disk_avg_, columns);
ADD_COLUMN(set_double, table, "iops_imbalance", zu.iops_imbalance_, columns);
ADD_COLUMN(set_double, table, "iops_avg", zu.iops_avg_, columns);
ADD_COLUMN(set_double, table, "memory_imbalance", zu.memory_imbalance_, columns);
ADD_COLUMN(set_double, table, "memory_avg", zu.memory_avg_, columns);
}
return ret;
}
int ObAllRebalanceTenantStat::get_all_tenant()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceTenantStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_tenant_ids(all_tenants_))) {
LOG_WARN("fail to get_tenant_ids", K(ret));
} else {
} // no more to do
return ret;
}
int ObAllRebalanceTenantStat::get_table_schema(uint64_t tid)
{
int ret = OB_SUCCESS;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, tid);
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceTenantStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_table_schema(table_id, table_schema_))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
} else {
}
return ret;
}
int ObAllRebalanceTenantStat::init_tenant_balance_stat(uint64_t tenant_id)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_INVALID_ID == tenant_id) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid tenant id", K(ret));
} else {
tenant_balance_stat_.reuse();
common::ObArenaAllocator allocator(ObModIds::OB_RS_PARTITION_BALANCER);
TenantSchemaGetter stat_finder(tenant_id);
ObLeaderBalanceGroupContainer balance_group_container(schema_guard_, stat_finder, allocator);
if (OB_FAIL(balance_group_container.init(tenant_id))) {
LOG_WARN("fail to init balance group container", K(ret), K(tenant_id));
} else if (OB_FAIL(balance_group_container.build())) {
LOG_WARN("fail to build balance index builder", K(ret));
} else if (OB_FAIL(tenant_balance_stat_.gather_stat(
tenant_id, &schema_guard_, balance_group_container.get_hash_index()))) {
LOG_WARN("gather tenant balance statistics failed", K(ret), K(tenant_id));
} else {
}
}
return ret;
}

View File

@ -0,0 +1,72 @@
/**
* 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.
*/
#ifndef _OB_ALL_REBALANCE_TENANT_STAT_H
#define _OB_ALL_REBALANCE_TENANT_STAT_H 1
#include "share/ob_virtual_table_projector.h"
#include "rootserver/ob_balance_info.h"
#include "lib/container/ob_se_array.h"
#include "share/schema/ob_schema_getter_guard.h"
namespace oceanbase {
namespace share {
namespace schema {
class ObTableSchema;
class ObMultiVersionSchemaService;
} // namespace schema
} // namespace share
namespace rootserver {
class ObAllRebalanceUnitStat;
class ObAllRebalanceReplicaStat;
class ObAllRebalanceTenantStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceTenantStat();
virtual ~ObAllRebalanceTenantStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
int get_table_schema(uint64_t tid);
int get_all_tenant();
int init_tenant_balance_stat(uint64_t tenant_id);
int get_row();
int next();
int get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns);
private:
// data members
bool inited_;
share::schema::ObMultiVersionSchemaService* schema_service_;
TenantBalanceStat tenant_balance_stat_;
common::ObSEArray<uint64_t, 16> all_tenants_;
int64_t cur_tenant_idx_;
int64_t cur_zone_idx_;
share::schema::ObSchemaGetterGuard schema_guard_;
const share::schema::ObTableSchema* table_schema_;
common::ObSEArray<Column, 16> columns_;
DISALLOW_COPY_AND_ASSIGN(ObAllRebalanceTenantStat);
friend class ObAllRebalanceUnitStat;
friend class ObAllRebalanceReplicaStat;
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_REBALANCE_TENANT_STAT_H */

View File

@ -0,0 +1,138 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_unit_distribution_stat.h"
using namespace oceanbase::rootserver;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
ObAllRebalanceUnitDistributionStat::ObAllRebalanceUnitDistributionStat(ObUnitManager& unit_mgr,
ObILeaderCoordinator& leader_coordinator, ObServerManager& server_mgr, ObZoneManager& zone_mgr)
: server_balance_plan_(unit_mgr, leader_coordinator, server_mgr, zone_mgr),
schema_guard_(),
svr_ip_buf_(),
unit_info_(),
inited_(false)
{}
ObAllRebalanceUnitDistributionStat::~ObAllRebalanceUnitDistributionStat()
{}
int ObAllRebalanceUnitDistributionStat::init(common::ObMySQLProxy& proxy, common::ObServerConfig& server_config,
share::schema::ObMultiVersionSchemaService& schema_service, ObRootBalancer& root_balancer)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(inited_)) {
ret = OB_INIT_TWICE;
LOG_WARN("cannot init twice", K(ret));
} else if (OB_FAIL(server_balance_plan_.init(proxy, server_config, schema_service, root_balancer))) {
LOG_WARN("fail to init server balance plan", K(ret));
} else if (OB_FAIL(schema_service.get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard_))) {
LOG_WARN("fail to get schema guard", K(ret));
} else {
inited_ = true;
}
return ret;
}
int ObAllRebalanceUnitDistributionStat::get_table_schema(uint64_t tid)
{
int ret = OB_SUCCESS;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, tid);
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceTenantStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_table_schema(table_id, table_schema_))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
}
return ret;
}
int ObAllRebalanceUnitDistributionStat::inner_open()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(get_table_schema(OB_ALL_VIRTUAL_REBALANCE_UNIT_DISTRIBUTION_STAT_TID))) {
LOG_WARN("fail to get table schema", K(ret));
} else if (OB_FAIL(server_balance_plan_.generate_server_balance_plan())) {
LOG_WARN("fail to generate server balance plan", K(ret));
} else {
} // no more to do
return ret;
}
int ObAllRebalanceUnitDistributionStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
ret = server_balance_plan_.get_next_unit_distribution(unit_info_);
if (OB_ITER_END == ret) {
// to the end
} else if (OB_SUCC(ret)) {
ObArray<Column> columns;
if (OB_FAIL(get_full_row(unit_info_, columns))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("fail to project row", K(ret));
} else {
row = &cur_row_;
}
} else {
LOG_WARN("fail to get next task", K(ret));
}
}
return ret;
}
int ObAllRebalanceUnitDistributionStat::get_full_row(
const share::ObUnitInfo& unit_info, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("virtual table schema ptr is null", K(ret), KP(table_schema_));
} else {
if (!unit_info.unit_.server_.ip_to_string(svr_ip_buf_, sizeof(svr_ip_buf_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to execute ip to string", K(ret));
} else {
ADD_COLUMN(set_int, table_schema_, "unit_id", unit_info.unit_.unit_id_, columns);
ADD_COLUMN(set_int, table_schema_, "tenant_id", unit_info.pool_.tenant_id_, columns);
ADD_COLUMN(set_varchar, table_schema_, "svr_ip", svr_ip_buf_, columns);
ADD_COLUMN(set_int, table_schema_, "svr_port", unit_info.unit_.server_.get_port(), columns);
ADD_COLUMN(set_varchar, table_schema_, "zone", unit_info.unit_.zone_.str(), columns);
ADD_COLUMN(set_double, table_schema_, "max_cpu", unit_info.config_.max_cpu_, columns);
ADD_COLUMN(set_double, table_schema_, "min_cpu", unit_info.config_.min_cpu_, columns);
ADD_COLUMN(set_int, table_schema_, "max_memory", unit_info.config_.max_memory_, columns);
ADD_COLUMN(set_int, table_schema_, "min_memory", unit_info.config_.min_memory_, columns);
ADD_COLUMN(set_int, table_schema_, "max_iops", unit_info.config_.max_iops_, columns);
ADD_COLUMN(set_int, table_schema_, "min_iops", unit_info.config_.min_iops_, columns);
ADD_COLUMN(set_int, table_schema_, "max_disk_size", unit_info.config_.max_disk_size_, columns);
ADD_COLUMN(set_int, table_schema_, "max_session_num", unit_info.config_.max_session_num_, columns);
}
}
return ret;
}

View File

@ -0,0 +1,49 @@
/**
* 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.
*/
#ifndef _OB_ALL_REBALANCE_UNIT_DISTRIBUTION_STAT_H
#define _OB_ALL_REBALANCE_UNIT_DISTRIBUTION_STAT_H 1
#include "share/ob_virtual_table_projector.h"
#include "rootserver/ob_server_balance_plan.h"
#include "common/ob_unit_info.h"
namespace oceanbase {
namespace rootserver {
class ObRootBalancer;
class ObAllRebalanceUnitDistributionStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceUnitDistributionStat(ObUnitManager& unit_mgr, ObILeaderCoordinator& leader_coordinator,
ObServerManager& server_mgr, ObZoneManager& zone_mgr);
virtual ~ObAllRebalanceUnitDistributionStat();
int init(common::ObMySQLProxy& proxy, common::ObServerConfig& server_config,
share::schema::ObMultiVersionSchemaService& schema_service, ObRootBalancer& root_balancer);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
int get_full_row(const share::ObUnitInfo& unit_info, common::ObIArray<Column>& columns);
int get_table_schema(uint64_t tid);
private:
// data members
ObServerBalancePlan server_balance_plan_;
share::schema::ObSchemaGetterGuard schema_guard_;
char svr_ip_buf_[common::OB_IP_STR_BUFF];
share::ObUnitInfo unit_info_;
bool inited_;
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_REBALANCE_MAP_ITEM_STAT_H */

View File

@ -0,0 +1,134 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_unit_migrate_stat.h"
using namespace oceanbase::rootserver;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
ObAllRebalanceUnitMigrateStat::ObAllRebalanceUnitMigrateStat(ObUnitManager& unit_mgr,
ObILeaderCoordinator& leader_coordinator, ObServerManager& server_mgr, ObZoneManager& zone_mgr)
: server_balance_plan_(unit_mgr, leader_coordinator, server_mgr, zone_mgr),
schema_guard_(),
src_ip_buf_(),
dst_ip_buf_(),
task_(),
inited_(false)
{}
ObAllRebalanceUnitMigrateStat::~ObAllRebalanceUnitMigrateStat()
{}
int ObAllRebalanceUnitMigrateStat::init(common::ObMySQLProxy& proxy, common::ObServerConfig& server_config,
share::schema::ObMultiVersionSchemaService& schema_service, ObRootBalancer& root_balancer)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(inited_)) {
ret = OB_INIT_TWICE;
LOG_WARN("cannot init twice", K(ret));
} else if (OB_FAIL(server_balance_plan_.init(proxy, server_config, schema_service, root_balancer))) {
LOG_WARN("fail to init server balance plan", K(ret));
} else if (OB_FAIL(schema_service.get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard_))) {
LOG_WARN("fail to get schema guard", K(ret));
} else {
inited_ = true;
}
return ret;
}
int ObAllRebalanceUnitMigrateStat::get_table_schema(uint64_t tid)
{
int ret = OB_SUCCESS;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, tid);
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllRebalanceTenantStat not init", K(ret), K(inited_));
} else if (OB_FAIL(schema_guard_.get_table_schema(table_id, table_schema_))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
}
return ret;
}
int ObAllRebalanceUnitMigrateStat::inner_open()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(get_table_schema(OB_ALL_VIRTUAL_REBALANCE_UNIT_MIGRATE_STAT_TID))) {
LOG_WARN("fail to get table schema", K(ret));
} else if (OB_FAIL(server_balance_plan_.generate_server_balance_plan())) {
LOG_WARN("fail to generate server balance plan", K(ret));
} else {
} // no more to do
return ret;
}
int ObAllRebalanceUnitMigrateStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
ret = server_balance_plan_.get_next_task(task_);
if (OB_ITER_END == ret) {
// to the end
} else if (OB_SUCC(ret)) {
ObArray<Column> columns;
if (OB_FAIL(get_full_row(task_, columns))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("fail to project row", K(ret));
} else {
row = &cur_row_;
}
} else {
LOG_WARN("fail to get next task", K(ret));
}
}
return ret;
}
int ObAllRebalanceUnitMigrateStat::get_full_row(const ServerBalancePlanTask& task, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("virtual table schema ptr is null", K(ret), KP(table_schema_));
} else {
if (!task.src_addr_.ip_to_string(src_ip_buf_, sizeof(src_ip_buf_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to execute ip to string", K(ret));
} else if (!task.dst_addr_.ip_to_string(dst_ip_buf_, sizeof(dst_ip_buf_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail ot exeucte ip to string", K(ret));
} else {
ADD_COLUMN(set_int, table_schema_, "unit_id", task.unit_id_, columns);
ADD_COLUMN(set_varchar, table_schema_, "zone", task.zone_.str(), columns);
ADD_COLUMN(set_varchar, table_schema_, "src_svr_ip", src_ip_buf_, columns);
ADD_COLUMN(set_int, table_schema_, "src_svr_port", task.src_addr_.get_port(), columns);
ADD_COLUMN(set_varchar, table_schema_, "dst_svr_ip", dst_ip_buf_, columns);
ADD_COLUMN(set_int, table_schema_, "dst_svr_port", task.dst_addr_.get_port(), columns);
}
}
return ret;
}

View File

@ -0,0 +1,49 @@
/**
* 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.
*/
#ifndef _OB_ALL_REBALANCE_UNIT_MIGRATE_STAT_H
#define _OB_ALL_REBALANCE_UNIT_MIGRATE_STAT_H 1
#include "share/ob_virtual_table_projector.h"
#include "rootserver/ob_server_balance_plan.h"
namespace oceanbase {
namespace rootserver {
class ObRootBalancer;
class ObAllRebalanceUnitMigrateStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceUnitMigrateStat(ObUnitManager& unit_mgr, ObILeaderCoordinator& leader_coordinator,
ObServerManager& server_mgr, ObZoneManager& zone_mgr);
virtual ~ObAllRebalanceUnitMigrateStat();
int init(common::ObMySQLProxy& proxy, common::ObServerConfig& server_config,
share::schema::ObMultiVersionSchemaService& schema_service, ObRootBalancer& root_balancer);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
int get_full_row(const ServerBalancePlanTask& task, common::ObIArray<Column>& columns);
int get_table_schema(uint64_t tid);
private:
// data members
ObServerBalancePlan server_balance_plan_;
share::schema::ObSchemaGetterGuard schema_guard_;
char src_ip_buf_[common::OB_IP_STR_BUFF];
char dst_ip_buf_[common::OB_IP_STR_BUFF];
ServerBalancePlanTask task_;
bool inited_;
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_REBALANCE_MAP_ITEM_STAT_H */

View File

@ -0,0 +1,140 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_rebalance_unit_stat.h"
#include "share/schema/ob_multi_version_schema_service.h"
using namespace oceanbase::rootserver;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
ObAllRebalanceUnitStat::ObAllRebalanceUnitStat() : cur_unit_idx_(-1)
{}
ObAllRebalanceUnitStat::~ObAllRebalanceUnitStat()
{}
int ObAllRebalanceUnitStat::init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider)
{
return impl_.init(
schema_service, unit_mgr, server_mgr, pt_operator, remote_pt_operator, zone_mgr, task_mgr, check_stop_provider);
}
int ObAllRebalanceUnitStat::inner_open()
{
int ret = OB_SUCCESS;
if (OB_FAIL(impl_.tenant_balance_stat_.reuse_replica_count_mgr())) {
LOG_WARN("reuse_replica_count_mgr failed", K(ret));
} else if (OB_FAIL(impl_.get_all_tenant())) {
} else if (OB_FAIL(impl_.get_table_schema(OB_ALL_VIRTUAL_REBALANCE_UNIT_STAT_TID))) {
} else {
impl_.cur_tenant_idx_ = -1;
impl_.cur_zone_idx_ = -1;
cur_unit_idx_ = -1;
}
return ret;
}
int ObAllRebalanceUnitStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (!impl_.inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
if (OB_FAIL(next())) {
} else if (OB_FAIL(get_row())) {
} else {
row = &cur_row_;
}
}
return ret;
}
int ObAllRebalanceUnitStat::next()
{
int ret = OB_SUCCESS;
bool loop = false;
do {
loop = false;
++cur_unit_idx_; // next unit
if (impl_.cur_zone_idx_ < 0) {
impl_.cur_zone_idx_ = 0; // first zone
}
if (impl_.cur_zone_idx_ >= impl_.tenant_balance_stat_.all_zone_unit_.count()) { // end of zone
++impl_.cur_tenant_idx_; // next tenant
if (impl_.cur_tenant_idx_ >= impl_.all_tenants_.count()) {
ret = OB_ITER_END;
} else {
if (OB_FAIL(impl_.init_tenant_balance_stat(impl_.all_tenants_.at(impl_.cur_tenant_idx_)))) {
} else {
impl_.cur_zone_idx_ = -1;
cur_unit_idx_ = -1;
loop = true;
}
}
} else { // valid zone
const ZoneUnit& zu = impl_.tenant_balance_stat_.all_zone_unit_.at(impl_.cur_zone_idx_);
if (cur_unit_idx_ >= zu.all_unit_.count()) { // end of unit
impl_.cur_zone_idx_++; // next zone
cur_unit_idx_ = -1;
loop = true;
}
}
} while (loop);
return ret;
}
int ObAllRebalanceUnitStat::get_row()
{
int ret = OB_SUCCESS;
impl_.columns_.reuse();
if (OB_FAIL(get_full_row(impl_.table_schema_, impl_.columns_))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(impl_.columns_, cur_row_))) {
LOG_WARN("fail to project row", K_(impl_.columns), K(ret));
}
return ret;
}
int ObAllRebalanceUnitStat::get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (impl_.cur_zone_idx_ >= impl_.tenant_balance_stat_.all_zone_unit_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch");
} else if (cur_unit_idx_ >= impl_.tenant_balance_stat_.all_zone_unit_.at(impl_.cur_zone_idx_).all_unit_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("unexpected branch");
} else {
const ZoneUnit& zu = impl_.tenant_balance_stat_.all_zone_unit_.at(impl_.cur_zone_idx_);
const UnitStat* unit = zu.all_unit_.at(cur_unit_idx_);
// primary key
ADD_COLUMN(set_int, table, "tenant_id", impl_.tenant_balance_stat_.tenant_id_, columns);
ADD_COLUMN(set_varchar, table, "zone", zu.zone_.str(), columns);
ADD_COLUMN(set_int, table, "unit_id", unit->info_.unit_.unit_id_, columns);
// other columns
ADD_COLUMN(set_double, table, "load", unit->load_, columns);
ADD_COLUMN(set_double, table, "cpu_usage_rate", unit->get_cpu_usage_rate(), columns);
ADD_COLUMN(set_double, table, "disk_usage_rate", unit->get_disk_usage_rate(), columns);
ADD_COLUMN(set_double, table, "iops_usage_rate", unit->get_iops_usage_rate(), columns);
ADD_COLUMN(set_double, table, "memory_usage_rate", unit->get_memory_usage_rate(), columns);
}
return ret;
}

View File

@ -0,0 +1,47 @@
/**
* 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.
*/
#ifndef _OB_ALL_REBALANCE_UNIT_STAT_H
#define _OB_ALL_REBALANCE_UNIT_STAT_H 1
#include "ob_all_rebalance_tenant_stat.h"
namespace oceanbase {
namespace rootserver {
class ObAllRebalanceUnitStat : public common::ObVirtualTableProjector {
public:
ObAllRebalanceUnitStat();
virtual ~ObAllRebalanceUnitStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, share::ObPartitionTableOperator& pt_operator,
share::ObRemotePartitionTableOperator& remote_pt_operator, ObZoneManager& zone_mgr, ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObAllRebalanceUnitStat);
// function members
int get_row();
int next();
int get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns);
private:
// data members
ObAllRebalanceTenantStat impl_;
int64_t cur_unit_idx_;
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_REBALANCE_UNIT_STAT_H */

View File

@ -0,0 +1,284 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_replica_task.h"
#include "share/partition_table/ob_partition_table_operator.h"
#include "share/schema/ob_multi_version_schema_service.h"
#include "share/schema/ob_column_schema.h"
#include "share/schema/ob_table_schema.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
using namespace balancer;
ObAllReplicaTask::ObAllReplicaTask()
: inited_(false),
tenant_stat_(),
rereplication_(),
locality_checker_(),
schema_service_(NULL),
results_(),
table_schema_(NULL),
arena_allocator_(),
index_(OB_INVALID_INDEX)
{}
ObAllReplicaTask::~ObAllReplicaTask()
{
tenant_stat_.reuse();
}
int ObAllReplicaTask::init(share::ObPartitionTableOperator& pt_operator,
share::schema::ObMultiVersionSchemaService& schema_service,
share::ObRemotePartitionTableOperator& remote_pt_operator, rootserver::ObServerManager& server_mgr,
rootserver::ObUnitManager& unit_mgr, rootserver::ObZoneManager& zone_mgr, rootserver::ObRebalanceTaskMgr& task_mgr,
share::ObCheckStopProvider& check_stop_provider)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (OB_FAIL(tenant_stat_.init(unit_mgr,
server_mgr,
pt_operator,
remote_pt_operator,
zone_mgr,
task_mgr,
check_stop_provider,
unit_mgr.get_sql_proxy()))) {
LOG_WARN("init tenant stat failed", K(ret));
} else if (OB_FAIL(rereplication_.init(
schema_service, zone_mgr, pt_operator, task_mgr, tenant_stat_, check_stop_provider, unit_mgr))) {
LOG_WARN("init failed", K(ret));
} else if (OB_FAIL(locality_checker_.init(
schema_service, tenant_stat_, task_mgr, zone_mgr, check_stop_provider, server_mgr, unit_mgr))) {
LOG_WARN("fail to init locality checker", K(ret));
} else {
results_.reset();
schema_service_ = &schema_service;
index_ = 0;
table_schema_ = NULL;
inited_ = true;
}
return ret;
}
int ObAllReplicaTask::get_condition(uint64_t& specific_tenant_id)
{
int ret = OB_SUCCESS;
specific_tenant_id = OB_INVALID_TENANT_ID;
LOG_DEBUG("get condition", K(ret), K(specific_tenant_id));
return ret;
}
int ObAllReplicaTask::inner_open()
{
int ret = OB_SUCCESS;
uint64_t specific_tenant_id = OB_INVALID_TENANT_ID;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(get_condition(specific_tenant_id))) {
LOG_WARN("fail to get specific_tenant_id", K(ret));
} else {
ObArray<uint64_t> tenant_ids;
ObSchemaGetterGuard schema_guard;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_REPLICA_TASK_TID);
if (OB_ISNULL(schema_service_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("schema_service is null", K(ret));
} else if (OB_FAIL(schema_service_->get_schema_guard(schema_guard))) {
LOG_WARN("get schema guard failed", K(ret));
} else if (OB_FAIL(schema_guard.get_tenant_ids(tenant_ids))) {
LOG_WARN("get tenant ids failed", K(ret));
} else if (OB_FAIL(schema_guard_->get_table_schema(table_id, table_schema_))) {
LOG_WARN("get_table_schema failed", K(table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
} else {
results_.reuse();
index_ = 0;
for (int i = 0; OB_SUCC(ret) && i < tenant_ids.count(); i++) {
const uint64_t tenant_id = tenant_ids[i];
if (OB_INVALID_TENANT_ID == specific_tenant_id || tenant_id == specific_tenant_id) {
common::ObArenaAllocator allocator(ObModIds::OB_RS_PARTITION_BALANCER);
TenantSchemaGetter stat_finder(tenant_id);
ObLeaderBalanceGroupContainer balance_group_container(schema_guard, stat_finder, allocator);
if (OB_FAIL(balance_group_container.init(tenant_id))) {
LOG_WARN("fail to init balance group container", K(ret), K(tenant_id));
} else if (OB_FAIL(balance_group_container.build())) {
LOG_WARN("fail to build balance index builder", K(ret));
} else if (OB_FAIL(tenant_stat_.reuse_replica_count_mgr())) {
LOG_WARN("reuse_replica_count_mgr failed", K(ret));
} else if (OB_FAIL(tenant_stat_.gather_stat(
tenant_id, &schema_guard, balance_group_container.get_hash_index()))) {
LOG_WARN("gather tenant balance statistics failed", K(ret), K(tenant_id));
} else if (OB_FAIL(locality_checker_.get_filter_result(balance_group_container.get_hash_index(), results_))) {
LOG_WARN("add locality tasks failed", K(ret), K(tenant_id));
}
}
}
}
}
return ret;
}
// TODO: currently only display replicas whose locality are not matched.
// In future, we can display rebuild, migrate and other tasks.
int ObAllReplicaTask::inner_get_next_row(ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (index_ < 0) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("index is invalid", K(ret), K_(index));
} else if (results_.count() == index_) {
ret = OB_ITER_END;
} else {
ObArray<Column> columns;
columns.reuse();
if (OB_FAIL(get_full_row(table_schema_, results_[index_], columns))) {
LOG_WARN("get_full_row failed", "table_schema", table_schema_, "task", results_[index_], K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("project_row failed", K(columns), K(ret));
} else {
row = &cur_row_;
index_++;
}
}
return ret;
}
int ObAllReplicaTask::get_full_row(const ObTableSchema* table, ObReplicaTask& task, ObIArray<Column>& columns)
{
int n = 0;
int ret = OB_SUCCESS;
char* src_ip = NULL;
char* dst_ip = NULL;
char* zone = NULL;
char* region = NULL;
const char* cmd_type_str = NULL;
arena_allocator_.reset();
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (!task.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid task", K(task), K(ret));
} else {
if (NULL == (src_ip = static_cast<char*>(arena_allocator_.alloc(OB_MAX_SERVER_ADDR_SIZE)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc ip buf failed", "size", OB_MAX_SERVER_ADDR_SIZE, K(ret));
} else if (false == task.src_.ip_to_string(src_ip, OB_MAX_SERVER_ADDR_SIZE)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("convert server ip to string failed", K(ret), "server", task.src_);
} else if (NULL == (dst_ip = static_cast<char*>(arena_allocator_.alloc(OB_MAX_SERVER_ADDR_SIZE)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc ip buf failed", "size", OB_MAX_SERVER_ADDR_SIZE, K(ret));
} else if (false == task.dst_.ip_to_string(dst_ip, OB_MAX_SERVER_ADDR_SIZE)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("convert server ip to string failed", K(ret), "server", task.dst_);
} else if (NULL == (zone = static_cast<char*>(arena_allocator_.alloc(MAX_ZONE_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc zone buf failed", "size", MAX_ZONE_LENGTH, K(ret));
} else if (0 > (n = snprintf(zone, MAX_ZONE_LENGTH, "%s", task.zone_.ptr())) || n >= MAX_ZONE_LENGTH) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", "buf_len", MAX_ZONE_LENGTH, "src len", strlen(task.zone_.ptr()), K(ret));
} else if (NULL == (region = static_cast<char*>(arena_allocator_.alloc(MAX_REGION_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc region buf failed", "size", MAX_REGION_LENGTH, K(ret));
} else if (0 > (n = snprintf(region, MAX_REGION_LENGTH, "%s", task.region_.ptr())) || n >= MAX_REGION_LENGTH) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", "buf_len", MAX_REGION_LENGTH, "src len", strlen(task.region_.ptr()), K(ret));
} else if (NULL == task.comment_) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("comment should not be null", K(ret));
} else if (NULL == (cmd_type_str = ObRebalanceTask::get_task_type_str(task.cmd_type_))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("task type str should not be null", K(ret), K_(task.cmd_type));
} else {
ADD_COLUMN(set_int, table, "tenant_id", static_cast<int64_t>(task.tenant_id_), columns);
ADD_COLUMN(set_int, table, "table_id", static_cast<int64_t>(task.table_id_), columns);
ADD_COLUMN(set_int, table, "partition_id", task.partition_id_, columns);
ADD_COLUMN(set_varchar, table, "src_ip", src_ip, columns);
ADD_COLUMN(set_int, table, "src_port", task.src_.get_port(), columns);
ADD_COLUMN(set_int, table, "src_replica_type", task.replica_type_, columns);
ADD_COLUMN(set_varchar, table, "zone", zone, columns);
ADD_COLUMN(set_varchar, table, "region", region, columns);
ADD_COLUMN(set_varchar, table, "dst_ip", dst_ip, columns);
ADD_COLUMN(set_int, table, "dst_port", task.dst_.get_port(), columns);
ADD_COLUMN(set_int, table, "dst_replica_type", task.dst_replica_type_, columns);
ADD_COLUMN(set_varchar, table, "cmd_type", cmd_type_str, columns);
ADD_COLUMN(set_varchar, table, "comment", task.comment_, columns);
}
}
return ret;
}
ObAllReplicaTaskI1::ObAllReplicaTaskI1() : ObAllReplicaTask()
{}
ObAllReplicaTaskI1::~ObAllReplicaTaskI1()
{}
int ObAllReplicaTaskI1::get_condition(uint64_t& specific_tenant_id)
{
int ret = OB_SUCCESS;
specific_tenant_id = OB_INVALID_TENANT_ID;
if (1 == get_key_ranges().count()) {
// optimize speicific cases: specified tenant_id
const int64_t ROW_KEY_COUNT = 1; // index
ObRowkey start_key = get_key_ranges().at(0).start_key_;
ObRowkey end_key = get_key_ranges().at(0).end_key_;
if ((ROW_KEY_COUNT != start_key.get_obj_cnt()) || (ROW_KEY_COUNT != end_key.get_obj_cnt())) {
ret = OB_ERR_UNEXPECTED;
LOG_USER_ERROR(OB_ERR_UNEXPECTED, "row key count not match");
} else {
const ObObj* start_key_obj_ptr = start_key.get_obj_ptr();
const ObObj* end_key_obj_ptr = end_key.get_obj_ptr();
for (int64_t j = 0; OB_SUCC(ret) && j < ROW_KEY_COUNT; ++j) {
if (start_key_obj_ptr[j].is_min_value() || end_key_obj_ptr[j].is_max_value() ||
!start_key_obj_ptr[j].is_integer_type() || !end_key_obj_ptr[j].is_integer_type() ||
(start_key_obj_ptr[j] != end_key_obj_ptr[j])) {
// skip
} else {
switch (j) {
case 0: { // tenant_id
specific_tenant_id = end_key_obj_ptr[j].get_int();
break;
}
default: {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid index", K(ret), K(j));
}
} // end of switch
} // end of else
} // end of for
}
}
LOG_DEBUG("get condition with i1", K(ret), K(specific_tenant_id));
return ret;
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -0,0 +1,92 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_ALL_REPLICA_TASK_H_
#define OCEANBASE_ROOTSERVER_OB_ALL_REPLICA_TASK_H_
#include "lib/container/ob_array.h"
#include "share/ob_virtual_table_projector.h"
#include "share/partition_table/ob_partition_info.h"
#include "share/partition_table/ob_partition_table_iterator.h"
#include "share/schema/ob_multi_version_schema_service.h"
#include "share/ob_check_stop_provider.h"
#include "rootserver/ob_server_manager.h"
#include "rootserver/ob_unit_manager.h"
#include "rootserver/ob_rebalance_task_mgr.h"
#include "rootserver/ob_balance_info.h"
#include "rootserver/ob_locality_checker.h"
#include "rootserver/ob_rereplication.h"
#include "rootserver/ob_root_utils.h"
namespace oceanbase {
namespace share {
class ObPartitionInfo;
class ObPartitionTableIterator;
class ObPartitionTableOperator;
namespace schema {
class ObMultiVersionSchemaService;
class ObTableSchema;
class ObSchemaGetterGuard;
} // namespace schema
} // namespace share
namespace rootserver {
class ObServerManager;
class ObAllReplicaTask : public common::ObVirtualTableProjector {
public:
ObAllReplicaTask();
virtual ~ObAllReplicaTask();
int init(share::ObPartitionTableOperator& pt_operator, share::schema::ObMultiVersionSchemaService& schema_service,
share::ObRemotePartitionTableOperator& remote_pt_operator, rootserver::ObServerManager& server_mgr,
rootserver::ObUnitManager& unit_mgr, rootserver::ObZoneManager& zone_mgr,
rootserver::ObRebalanceTaskMgr& rask_mgr, share::ObCheckStopProvider& check_stop_provider);
virtual int inner_open();
virtual int inner_get_next_row(common::ObNewRow*& row);
protected:
virtual int get_condition(uint64_t& specific_tenant_id);
private:
int get_full_row(const share::schema::ObTableSchema* table, ObReplicaTask& task, common::ObIArray<Column>& columns);
bool inited_;
TenantBalanceStat tenant_stat_;
rootserver::ObRereplication rereplication_;
rootserver::ObLocalityChecker locality_checker_;
share::schema::ObMultiVersionSchemaService* schema_service_;
ObArray<ObReplicaTask> results_;
const share::schema::ObTableSchema* table_schema_;
ObArenaAllocator arena_allocator_;
int64_t index_;
private:
DISALLOW_COPY_AND_ASSIGN(ObAllReplicaTask);
};
class ObAllReplicaTaskI1 : public ObAllReplicaTask {
public:
ObAllReplicaTaskI1();
virtual ~ObAllReplicaTaskI1();
protected:
virtual int get_condition(uint64_t& specific_tenant_id) override;
private:
DISALLOW_COPY_AND_ASSIGN(ObAllReplicaTaskI1);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif // OCEANBASE_ROOTSERVER_OB_ALL_REPLICA_TASK_H_

View File

@ -0,0 +1,431 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_server_stat.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/schema/ob_multi_version_schema_service.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
ObAllServerStat::ServerStat::ServerStat()
{
reset();
}
void ObAllServerStat::ServerStat::reset()
{
server_load_.reset();
cpu_assigned_percent_ = 0;
mem_assigned_percent_ = 0;
disk_assigned_percent_ = 0;
unit_num_ = 0;
migrating_unit_num_ = 0;
merged_version_ = 0;
leader_count_ = 0;
load_ = 0;
cpu_weight_ = 0;
memory_weight_ = 0;
disk_weight_ = 0;
}
int ObAllServerStat::ServerStat::assign(const ObAllServerStat::ServerStat& other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(copy_assign(server_load_, other.server_load_))) {
LOG_WARN("failed to assign server_load_", K(ret));
}
cpu_assigned_percent_ = other.cpu_assigned_percent_;
mem_assigned_percent_ = other.mem_assigned_percent_;
disk_assigned_percent_ = other.disk_assigned_percent_;
unit_num_ = other.unit_num_;
migrating_unit_num_ = other.migrating_unit_num_;
merged_version_ = other.merged_version_;
leader_count_ = other.leader_count_;
load_ = other.load_;
cpu_weight_ = other.cpu_weight_;
memory_weight_ = other.memory_weight_;
disk_weight_ = other.disk_weight_;
return ret;
}
ObAllServerStat::ObAllServerStat()
: inited_(false), schema_service_(NULL), unit_mgr_(NULL), server_mgr_(NULL), leader_coordinator_(NULL)
{}
ObAllServerStat::~ObAllServerStat()
{}
int ObAllServerStat::init(ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, ObILeaderCoordinator& leader_coordinator)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else {
schema_service_ = &schema_service;
unit_mgr_ = &unit_mgr;
server_mgr_ = &server_mgr;
leader_coordinator_ = &leader_coordinator;
inited_ = true;
}
return ret;
}
int ObAllServerStat::inner_get_next_row(ObNewRow*& row)
{
int ret = OB_SUCCESS;
ObSchemaGetterGuard schema_guard;
if (NULL == allocator_) {
ret = OB_NOT_INIT;
LOG_WARN("not init, allocator is null", K(ret));
} else if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
LOG_WARN("get schema guard error", K(ret));
} else if (!start_to_read_) {
ObArray<ServerStat> server_stats;
const ObTableSchema* table_schema = NULL;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_SERVER_STAT_TID);
if (OB_FAIL(schema_guard.get_table_schema(table_id, table_schema))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (OB_FAIL(get_server_stats(server_stats))) {
LOG_WARN("fail to get server load", K(ret));
} else if (server_stats.count() == 0) {
LOG_WARN("fail to get server stat");
} else {
ObArray<Column> columns;
FOREACH_CNT_X(server_stat, server_stats, OB_SUCCESS == ret)
{
columns.reuse();
if (OB_FAIL(get_full_row(table_schema, *server_stat, columns))) {
LOG_WARN("fail to get full row", "table_schema", *table_schema, K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("fail to project row", K(columns), K(ret));
} else if (OB_FAIL(scanner_.add_row(cur_row_))) {
LOG_WARN("fail to add row", K(ret));
}
}
}
if (OB_SUCC(ret)) {
scanner_it_ = scanner_.begin();
start_to_read_ = true;
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) {
if (OB_ITER_END != ret) {
LOG_WARN("fail to get next row", K(ret));
}
} else {
row = &cur_row_;
}
}
return ret;
}
int ObAllServerStat::get_server_stats(ObIArray<ServerStat>& server_stats)
{
int ret = OB_SUCCESS;
ObZone zone;
ObArray<ObUnitManager::ObServerLoad> server_loads;
ObILeaderCoordinator::ServerLeaderStat leader_stat;
double resource_weights[RES_MAX];
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(unit_mgr_->get_server_loads(zone, server_loads, resource_weights, RES_MAX))) {
LOG_WARN("fail to get server loads", K(zone), K(ret));
} else if (OB_FAIL(leader_coordinator_->get_leader_stat(leader_stat))) {
LOG_WARN("get_leader_stat failed", K(ret));
} else {
ServerStat stat;
for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
stat.reset();
if (OB_FAIL(stat.server_load_.assign(server_loads.at(i)))) {
LOG_WARN("failed to assign stat.server_load_", K(ret));
} else if (OB_FAIL(stat.server_load_.get_load(resource_weights, RES_MAX, stat.load_))) {
LOG_WARN("failed to calc server load", K(ret), "server_load", stat.server_load_);
} else {
stat.leader_count_ = 0;
stat.cpu_weight_ = resource_weights[RES_CPU];
stat.memory_weight_ = resource_weights[RES_MEM];
stat.disk_weight_ = resource_weights[RES_DISK];
if (OB_FAIL(server_mgr_->get_merged_version(stat.server_load_.status_.server_, stat.merged_version_))) {
LOG_WARN("get_merged_version failed", "server", stat.server_load_.status_.server_, K(ret));
} else if (OB_FAIL(get_leader_count(leader_stat, stat.server_load_.status_.server_, stat.leader_count_))) {
LOG_WARN("get_leader_count failed", K(leader_stat), "server", stat.server_load_.status_.server_, K(ret));
} else if (OB_FAIL(server_stats.push_back(stat))) {
LOG_WARN("fail to push back server stat", K(ret));
}
}
}
}
return ret;
}
int ObAllServerStat::get_leader_count(
const ObILeaderCoordinator::ServerLeaderStat& leader_stat, const common::ObAddr& server, int64_t& leader_count)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (!server.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid server", K(server), K(ret));
} else if (leader_stat.count() <= 0) {
// leader coordinator hasn't count leader ever
leader_count = INVALID_INT_VALUE;
} else {
leader_count = 0;
bool find = false;
FOREACH_CNT_X(server_leader_count, leader_stat, !find)
{
if (server_leader_count->server_ == server) {
leader_count = server_leader_count->count_;
find = true;
}
}
}
return ret;
}
int ObAllServerStat::calc_server_usage(ServerStat& server_stat)
{
int ret = OB_SUCCESS;
double hard_limit = 0;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(ObUnitManager::calc_sum_load(
&server_stat.server_load_.unit_loads_, server_stat.server_load_.sum_load_))) {
LOG_WARN("calc_sum_load failed", "server_load", server_stat.server_load_, K(ret));
} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
LOG_WARN("get_hard_limit failed", K(ret));
} else {
double cpu_assigned_percent = 0;
double mem_assigned_percent = 0;
double disk_assigned_percent = 0;
if (std::fabs(server_stat.get_cpu_capacity()) < EPSLISON) {
cpu_assigned_percent = INVALID_ASSIGNED_PERCENT;
} else {
server_stat.server_load_.status_.resource_info_.cpu_ =
server_stat.server_load_.status_.resource_info_.cpu_; // just for code layout
cpu_assigned_percent = 100.0 * static_cast<double>(server_stat.get_cpu_assigned()) /
static_cast<double>(server_stat.get_cpu_capacity());
}
if (INVALID_TOTAL_RESOURCE == server_stat.get_mem_capacity()) {
mem_assigned_percent = INVALID_ASSIGNED_PERCENT;
} else {
server_stat.server_load_.status_.resource_info_.mem_total_ =
server_stat.server_load_.status_.resource_info_.mem_total_; // just for code layout
mem_assigned_percent = 100.0 * static_cast<double>(server_stat.get_mem_assigned()) /
static_cast<double>(server_stat.get_mem_capacity());
}
if (INVALID_TOTAL_RESOURCE == server_stat.get_disk_total()) {
disk_assigned_percent = INVALID_ASSIGNED_PERCENT;
} else {
server_stat.server_load_.status_.resource_info_.disk_total_ = static_cast<int64_t>(
static_cast<double>(server_stat.server_load_.status_.resource_info_.disk_total_) * hard_limit);
disk_assigned_percent = 100.0 * static_cast<double>(server_stat.get_disk_assigned()) /
static_cast<double>(server_stat.get_disk_total());
}
server_stat.set_cpu_assigned_percent(static_cast<int64_t>(cpu_assigned_percent));
server_stat.set_mem_assigned_percent(static_cast<int64_t>(mem_assigned_percent));
server_stat.set_disk_assigned_percent(static_cast<int64_t>(disk_assigned_percent));
}
return ret;
}
int ObAllServerStat::calc_server_unit_num(ServerStat& server_stat)
{
int ret = OB_SUCCESS;
int64_t migrating_unit_num = 0;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
ObArray<ObUnitManager::ObUnitLoad>& unit_loads = server_stat.server_load_.unit_loads_;
server_stat.set_unit_num(unit_loads.count());
for (int64_t i = 0; i < unit_loads.count(); ++i) {
ObUnitManager::ObUnitLoad& unit_load = unit_loads.at(i);
ObAddr& server = server_stat.server_load_.status_.server_;
if (unit_load.unit_->migrate_from_server_ == server) {
++migrating_unit_num;
}
}
server_stat.set_migrating_unit_num(migrating_unit_num);
}
return ret;
}
int ObAllServerStat::get_full_row(const ObTableSchema* table, ServerStat& server_stat, ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
double hard_limit = 0.0;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
LOG_WARN("get hard limit failed", K(ret));
} else {
const ObAddr& server = server_stat.server_load_.status_.server_;
char* ip_buf = NULL;
char* zone_buf = NULL;
int n = -1;
char* build_version = NULL;
if (OB_FAIL(calc_server_unit_num(server_stat))) {
LOG_WARN("calc_server_unit_num failed", K(ret));
} else if (OB_FAIL(calc_server_usage(server_stat))) {
LOG_WARN("fail to calculate server usage", K(ret));
} else if (NULL == (ip_buf = static_cast<char*>(allocator_->alloc(MAX_IP_ADDR_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to alloc ip buf", "size", MAX_IP_ADDR_LENGTH, K(ret));
} else if (!server.ip_to_string(ip_buf, MAX_IP_ADDR_LENGTH)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("server ip is invalid", K(server), K(ret));
} else if (NULL == (zone_buf = static_cast<char*>(allocator_->alloc(MAX_ZONE_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to alloc zone buf", K(ret));
} else if (0 > (n = snprintf(zone_buf, MAX_ZONE_LENGTH, "%s", server_stat.get_zone().ptr())) ||
n >= MAX_ZONE_LENGTH) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", "buf_len", MAX_ZONE_LENGTH, "src len", server_stat.get_zone().size(), K(ret));
} else if (NULL == (build_version = static_cast<char*>(allocator_->alloc(OB_SERVER_VERSION_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to alloc build_version", "size", OB_SERVER_VERSION_LENGTH, K(ret));
} else {
ADD_COLUMN(set_varchar, table, "svr_ip", ip_buf, columns);
ADD_COLUMN(set_int, table, "svr_port", server.get_port(), columns);
ADD_COLUMN(set_varchar, table, "zone", zone_buf, columns);
if (std::fabs(server_stat.get_cpu_capacity()) < EPSLISON) {
ADD_NULL_COLUMN(table, "cpu_capacity", columns);
ADD_NULL_COLUMN(table, "cpu_total", columns);
} else {
ADD_COLUMN(set_double, table, "cpu_capacity", server_stat.get_cpu_capacity(), columns);
ADD_COLUMN(set_double, table, "cpu_total", server_stat.get_cpu_capacity() * hard_limit, columns);
}
ADD_COLUMN(set_double, table, "cpu_assigned", server_stat.get_cpu_assigned(), columns);
ADD_COLUMN(set_double, table, "cpu_max_assigned", server_stat.get_cpu_max_assigned(), columns);
if (INVALID_ASSIGNED_PERCENT == server_stat.get_cpu_assigned_percent()) {
ADD_NULL_COLUMN(table, "cpu_assigned_percent", columns);
} else {
ADD_COLUMN(set_int, table, "cpu_assigned_percent", server_stat.get_cpu_assigned_percent(), columns);
}
if (INVALID_TOTAL_RESOURCE == server_stat.get_mem_capacity()) {
ADD_NULL_COLUMN(table, "mem_capacity", columns);
ADD_NULL_COLUMN(table, "mem_total", columns);
} else {
ADD_COLUMN(set_int, table, "mem_capacity", server_stat.get_mem_capacity(), columns);
ADD_COLUMN(set_int,
table,
"mem_total",
static_cast<int64_t>(static_cast<double>(server_stat.get_mem_capacity()) * hard_limit),
columns);
}
ADD_COLUMN(set_int, table, "mem_assigned", server_stat.get_mem_assigned(), columns);
ADD_COLUMN(set_int, table, "mem_max_assigned", server_stat.get_mem_max_assigned(), columns);
if (INVALID_ASSIGNED_PERCENT == server_stat.get_mem_assigned_percent()) {
ADD_NULL_COLUMN(table, "mem_assigned_percent", columns);
} else {
ADD_COLUMN(set_int, table, "mem_assigned_percent", server_stat.get_mem_assigned_percent(), columns);
}
if (INVALID_TOTAL_RESOURCE == server_stat.get_disk_total()) {
ADD_NULL_COLUMN(table, "disk_total", columns);
} else {
ADD_COLUMN(set_int, table, "disk_total", server_stat.get_disk_total(), columns);
}
ADD_COLUMN(set_int, table, "disk_assigned", server_stat.get_disk_assigned(), columns);
if (INVALID_ASSIGNED_PERCENT == server_stat.get_disk_assigned_percent()) {
ADD_NULL_COLUMN(table, "disk_assigned_percent", columns);
} else {
ADD_COLUMN(set_int, table, "disk_assigned_percent", server_stat.get_disk_assigned_percent(), columns);
}
ADD_COLUMN(set_int, table, "unit_num", server_stat.get_unit_num(), columns);
ADD_COLUMN(set_int, table, "migrating_unit_num", server_stat.get_migrating_unit_num(), columns);
ADD_COLUMN(set_int, table, "merged_version", server_stat.merged_version_, columns);
if (INVALID_INT_VALUE == server_stat.leader_count_) {
ADD_NULL_COLUMN(table, "leader_count", columns);
} else {
ADD_COLUMN(set_int, table, "leader_count", server_stat.leader_count_, columns);
}
// fields added on V1.4
ADD_COLUMN(set_double, table, "load", server_stat.load_, columns);
ADD_COLUMN(set_double, table, "cpu_weight", server_stat.cpu_weight_, columns);
ADD_COLUMN(set_double, table, "memory_weight", server_stat.memory_weight_, columns);
ADD_COLUMN(set_double, table, "disk_weight", server_stat.disk_weight_, columns);
// fields added on V1.4.3
ADD_COLUMN(set_int, table, "id", server_stat.server_load_.status_.id_, columns);
ADD_COLUMN(set_int, table, "inner_port", server_stat.server_load_.status_.sql_port_, columns);
ADD_COLUMN(set_int, table, "register_time", server_stat.server_load_.status_.register_time_, columns);
ADD_COLUMN(set_int, table, "last_heartbeat_time", server_stat.server_load_.status_.last_hb_time_, columns);
ADD_COLUMN(
set_int, table, "block_migrate_in_time", server_stat.server_load_.status_.block_migrate_in_time_, columns);
ADD_COLUMN(set_int, table, "stop_time", server_stat.server_load_.status_.stop_time_, columns);
ADD_COLUMN(set_int, table, "start_service_time", server_stat.server_load_.status_.start_service_time_, columns);
ADD_COLUMN(
set_int, table, "ssl_key_expired_time", server_stat.server_load_.status_.ssl_key_expired_time_, columns);
ADD_COLUMN(set_int, table, "force_stop_heartbeat", server_stat.server_load_.status_.force_stop_hb_, columns);
ADD_COLUMN(set_int, table, "last_offline_time", server_stat.server_load_.status_.last_offline_time_, columns);
ADD_COLUMN(set_int, table, "with_rootserver", server_stat.server_load_.status_.with_rootserver_, columns);
ADD_COLUMN(set_int, table, "with_partition", server_stat.server_load_.status_.with_partition_, columns);
ADD_COLUMN(set_int, table, "mem_in_use", server_stat.server_load_.status_.resource_info_.mem_in_use_, columns);
ADD_COLUMN(set_int, table, "disk_in_use", server_stat.server_load_.status_.resource_info_.disk_in_use_, columns);
const char* admin_status_str = NULL;
(void)ObServerStatus::server_admin_status_str(server_stat.server_load_.status_.admin_status_, admin_status_str);
ADD_COLUMN(set_varchar, table, "admin_status", admin_status_str, columns);
const char* hb_status_str = NULL;
(void)ObServerStatus::heartbeat_status_str(server_stat.server_load_.status_.hb_status_, hb_status_str);
ADD_COLUMN(set_varchar, table, "heartbeat_status", hb_status_str, columns);
(void)snprintf(build_version, OB_SERVER_VERSION_LENGTH, "%s", server_stat.server_load_.status_.build_version_);
ADD_COLUMN(set_varchar, table, "build_version", build_version, columns);
ADD_COLUMN(set_int, table, "clock_deviation", server_stat.server_load_.status_.last_server_behind_time_, columns);
ADD_COLUMN(set_int, table, "heartbeat_latency", server_stat.server_load_.status_.last_round_trip_time_, columns);
bool is_sync = std::abs(server_stat.server_load_.status_.last_server_behind_time_) <= GCONF.rpc_timeout;
const char* clock_status_str = NULL;
(void)ObServerStatus::clock_sync_status_str(is_sync, clock_status_str);
ADD_COLUMN(set_varchar, table, "clock_sync_status", clock_status_str, columns);
}
if (OB_FAIL(ret)) {
if (NULL != ip_buf) {
allocator_->free(ip_buf);
ip_buf = NULL;
}
if (NULL != zone_buf) {
allocator_->free(zone_buf);
zone_buf = NULL;
}
}
}
return ret;
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -0,0 +1,171 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_ALL_SERVER_STAT_H_
#define OCEANBASE_ROOTSERVER_OB_ALL_SERVER_STAT_H_
#include "share/ob_virtual_table_projector.h"
#include "share/ob_server_status.h"
#include "rootserver/ob_unit_manager.h"
#include "rootserver/ob_leader_coordinator.h"
namespace oceanbase {
namespace share {
namespace schema {
class ObMultiVersionSchemaService;
class ObTableSchema;
} // namespace schema
} // namespace share
namespace rootserver {
class ObServerManager;
class ObZoneManager;
class ObAllServerStat : public common::ObVirtualTableProjector {
public:
ObAllServerStat();
virtual ~ObAllServerStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, ObUnitManager& unit_mgr,
ObServerManager& server_mgr, ObILeaderCoordinator& leader_coordinator);
virtual int inner_get_next_row(common::ObNewRow*& row);
private:
static constexpr double EPSLISON = 0.000000001;
static const int64_t INVALID_TOTAL_RESOURCE = 0;
static const int64_t INVALID_ASSIGNED_PERCENT = -1;
static const int64_t INVALID_INT_VALUE = -1;
struct ServerStat {
ObUnitManager::ObServerLoad server_load_;
int64_t cpu_assigned_percent_;
int64_t mem_assigned_percent_;
int64_t disk_assigned_percent_;
int64_t unit_num_;
int64_t migrating_unit_num_;
int64_t merged_version_;
int64_t leader_count_;
// the following fields are added at OB 1.4
double load_;
double cpu_weight_;
double memory_weight_;
double disk_weight_;
ServerStat();
void reset();
// get methods
inline double get_cpu_capacity() const
{
return server_load_.status_.resource_info_.cpu_;
}
inline int64_t get_mem_capacity() const
{
return server_load_.status_.resource_info_.mem_total_;
}
inline int64_t get_disk_total() const
{
return server_load_.status_.resource_info_.disk_total_;
}
inline double get_cpu_assigned() const
{
return server_load_.sum_load_.min_cpu_;
}
inline double get_cpu_max_assigned() const
{
return server_load_.sum_load_.max_cpu_;
}
inline int64_t get_mem_assigned() const
{
return server_load_.sum_load_.min_memory_;
}
inline int64_t get_mem_max_assigned() const
{
return server_load_.sum_load_.max_memory_;
}
inline int64_t get_disk_assigned(void) const
{
return server_load_.sum_load_.max_disk_size_;
}
inline int64_t get_cpu_assigned_percent(void) const
{
return cpu_assigned_percent_;
}
inline int64_t get_mem_assigned_percent(void) const
{
return mem_assigned_percent_;
}
inline int64_t get_disk_assigned_percent(void) const
{
return disk_assigned_percent_;
}
inline int64_t get_unit_num(void) const
{
return unit_num_;
}
inline int64_t get_migrating_unit_num(void) const
{
return migrating_unit_num_;
}
const common::ObZone& get_zone(void) const
{
return server_load_.status_.zone_;
}
// set methods
inline void set_cpu_assigned_percent(const int64_t& percent)
{
cpu_assigned_percent_ = percent;
}
inline void set_mem_assigned_percent(const int64_t& percent)
{
mem_assigned_percent_ = percent;
}
inline void set_disk_assigned_percent(const int64_t& percent)
{
disk_assigned_percent_ = percent;
}
inline void set_unit_num(const int64_t& num)
{
unit_num_ = num;
}
inline void set_migrating_unit_num(const int64_t& num)
{
migrating_unit_num_ = num;
}
int assign(const ServerStat& other);
TO_STRING_KV(K_(server_load), K_(cpu_assigned_percent), K_(disk_assigned_percent), K_(unit_num),
K_(migrating_unit_num), K_(merged_version), K_(leader_count));
private:
DISALLOW_COPY_AND_ASSIGN(ServerStat);
};
int get_server_stats(common::ObIArray<ServerStat>& server_stat);
int get_leader_count(
const ObILeaderCoordinator::ServerLeaderStat& leader_stat, const common::ObAddr& server, int64_t& leader_count);
int calc_server_usage(ServerStat& server_stat);
int calc_server_unit_num(ServerStat& server_stat);
int get_full_row(
const share::schema::ObTableSchema* table, ServerStat& server_stat, common::ObIArray<Column>& columns);
private:
bool inited_;
share::schema::ObMultiVersionSchemaService* schema_service_;
ObUnitManager* unit_mgr_;
ObServerManager* server_mgr_;
ObILeaderCoordinator* leader_coordinator_;
};
} // end namespace rootserver
} // end namespace oceanbase
#endif // OCEANBASE_ROOTSERVER_OB_ALL_SERVER_STAT_H_

View File

@ -0,0 +1,393 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_tenant_stat.h"
#include "lib/mysqlclient/ob_mysql_result.h"
#include "lib/string/ob_sql_string.h"
#include "lib/container/ob_array_iterator.h"
#include "common/ob_role.h"
#include "common/ob_partition_key.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/schema/ob_multi_version_schema_service.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
ObAllTenantStat::PartitionStat::PartitionStat()
{
reset();
}
int ObAllTenantStat::PartitionStat::check_same_partition(
const PartitionStat& lhs, const PartitionStat& rhs, bool& same_partition)
{
int ret = OB_SUCCESS;
same_partition = false;
if (!lhs.is_valid() || !rhs.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(lhs), K(rhs), K(ret));
} else {
same_partition = (lhs.table_id_ == rhs.table_id_ && lhs.partition_id_ == rhs.partition_id_ &&
lhs.partition_cnt_ == rhs.partition_cnt_);
}
return ret;
}
int ObAllTenantStat::PartitionStat::cmp_version(const PartitionStat& lhs, const PartitionStat& rhs, int64_t& cmp_ret)
{
int ret = OB_SUCCESS;
cmp_ret = -1;
if (!lhs.is_valid() || !rhs.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(lhs), K(rhs), K(ret));
} else if (lhs.major_version_ != rhs.major_version_) {
if (lhs.major_version_ > rhs.major_version_) {
cmp_ret = 1;
} else {
cmp_ret = -1;
}
} else {
if (lhs.minor_version_ == rhs.minor_version_) {
cmp_ret = 0;
} else if (lhs.minor_version_ < rhs.minor_version_) {
cmp_ret = 1;
} else {
cmp_ret = -1;
}
}
return ret;
}
bool ObAllTenantStat::PartitionStat::is_valid() const
{
return OB_INVALID_ID != table_id_ && OB_INVALID_INDEX != partition_id_ && occupy_size_ >= 0 && row_count_ >= 0 &&
major_version_ >= 0 && minor_version_ >= 0;
}
void ObAllTenantStat::PartitionStat::reset()
{
table_id_ = OB_INVALID_ID;
partition_id_ = OB_INVALID_INDEX;
partition_cnt_ = 0;
occupy_size_ = 0;
row_count_ = 0;
major_version_ = 0;
minor_version_ = 0;
}
bool ObAllTenantStat::ComparePartition::operator()(const PartitionStat& l, const PartitionStat& r)
{
ObPartitionKey l_key(l.table_id_, l.partition_id_, l.partition_cnt_);
ObPartitionKey r_key(r.table_id_, r.partition_id_, l.partition_cnt_);
return l_key < r_key;
}
ObAllTenantStat::TenantStat::TenantStat()
{
reset();
}
bool ObAllTenantStat::TenantStat::is_valid() const
{
return OB_INVALID_ID != tenant_id_ && table_count_ >= 0 && row_count_ >= 0 && total_size_ >= 0;
}
void ObAllTenantStat::TenantStat::reset()
{
tenant_id_ = OB_INVALID_ID;
table_count_ = 0;
row_count_ = 0;
total_size_ = 0;
}
int ObAllTenantStat::TenantStat::add_partition_stat(const PartitionStat& partition_stat)
{
int ret = OB_SUCCESS;
if (!partition_stat.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid partition_stat", K(partition_stat), K(ret));
} else {
if (OB_INVALID_ID == tenant_id_) {
tenant_id_ = extract_tenant_id(partition_stat.table_id_);
}
if (tenant_id_ != extract_tenant_id(partition_stat.table_id_)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("tenant_id not match",
K_(tenant_id),
"partition_stat tenant_id",
extract_tenant_id(partition_stat.table_id_),
K(ret));
} else {
row_count_ += partition_stat.row_count_;
total_size_ += partition_stat.occupy_size_;
if (0 == partition_stat.partition_id_) {
++table_count_;
}
}
}
return ret;
}
ObAllTenantStat::ObAllTenantStat() : inited_(false), schema_service_(NULL), proxy_(NULL)
{}
ObAllTenantStat::~ObAllTenantStat()
{}
int ObAllTenantStat::init(ObMultiVersionSchemaService& schema_service, ObMySQLProxy& proxy)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else {
schema_service_ = &schema_service;
proxy_ = &proxy;
inited_ = true;
}
return ret;
}
int ObAllTenantStat::inner_get_next_row(ObNewRow*& row)
{
int ret = OB_SUCCESS;
ObSchemaGetterGuard schema_guard;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == allocator_) {
ret = OB_NOT_INIT;
LOG_WARN("not init, allocator is null", K(ret));
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
LOG_WARN("get schema guard error", K(ret));
} else if (!start_to_read_) {
ObArray<TenantStat> tenant_stats;
const ObTableSchema* table_schema = NULL;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_TENANT_STAT_TID);
if (OB_FAIL(schema_guard.get_table_schema(table_id, table_schema))) {
LOG_WARN("fail to get table schema", K(table_id), K(ret));
} else if (NULL == table_schema) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table_schema is null", K(ret));
} else if (OB_FAIL(get_all_tenant_stats(tenant_stats))) {
LOG_WARN("get_all_tenant_stats failed", K(ret));
} else {
ObArray<Column> columns;
FOREACH_CNT_X(tenant_stat, tenant_stats, OB_SUCCESS == ret)
{
columns.reuse();
if (OB_FAIL(get_full_row(table_schema, *tenant_stat, columns))) {
LOG_WARN("fail to get full row", "table_schema", *table_schema, K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("fail to project row", K(ret));
} else if (OB_FAIL(scanner_.add_row(cur_row_))) {
LOG_WARN("fail to add row", K(cur_row_), K(ret));
}
}
}
if (OB_SUCC(ret)) {
scanner_it_ = scanner_.begin();
start_to_read_ = true;
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) {
if (OB_ITER_END != ret) {
LOG_WARN("fail to get next row", K(ret));
}
} else {
row = &cur_row_;
}
}
return ret;
}
int ObAllTenantStat::get_all_partition_stats(ObIArray<PartitionStat>& partition_stats)
{
int ret = OB_SUCCESS;
SMART_VAR(ObMySQLProxy::MySQLResult, res)
{
sqlclient::ObMySQLResult* result = NULL;
ObSqlString sql;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(sql.append_fmt("SELECT table_id, partition_id, partition_cnt, "
"occupy_size, row_count, major_version, minor_version "
"FROM %s WHERE role = '%d' ",
OB_ALL_VIRTUAL_STORAGE_STAT_TNAME,
LEADER))) {
LOG_WARN("assign sql string failed", K(ret));
} else if (OB_FAIL(proxy_->read(res, sql.ptr()))) {
LOG_WARN("execute sql failed", K(sql), K(ret));
} else if (NULL == (result = res.get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get result failed", K(ret));
} else if (OB_FAIL(retrieve_partition_stats(*result, partition_stats))) {
LOG_WARN("retrieve partition stat failed", K(ret));
}
}
return ret;
}
int ObAllTenantStat::get_all_tenant_stats(ObIArray<TenantStat>& tenant_stats)
{
int ret = OB_SUCCESS;
TenantStat tenant_stat;
ObArray<PartitionStat> all_partition_stats;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(get_all_partition_stats(all_partition_stats))) {
LOG_WARN("get all partition stats failed", K(ret));
} else if (all_partition_stats.count() <= 0) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("no partition exist", "partition_stat_count", all_partition_stats.count(), K(ret));
} else {
ComparePartition compare;
std::sort(all_partition_stats.begin(), all_partition_stats.end(), compare);
PartitionStat max = all_partition_stats.at(0);
tenant_stat.tenant_id_ = extract_tenant_id(max.table_id_);
for (int64_t i = 1; OB_SUCC(ret) && i < all_partition_stats.count(); ++i) {
const PartitionStat& tmp = all_partition_stats.at(i);
bool same_partition = false;
int64_t cmp_ret = -1;
if (OB_FAIL(PartitionStat::check_same_partition(max, tmp, same_partition))) {
LOG_WARN("check_same_partition failed", K(max), K(tmp), K(ret));
} else if (same_partition) {
if (OB_FAIL(PartitionStat::cmp_version(tmp, max, cmp_ret))) {
LOG_WARN("cmp_version failed", K(tmp), K(max), K(ret));
} else if (cmp_ret > 0) {
max = tmp;
} else {
}
} else {
if (tenant_stat.tenant_id_ != extract_tenant_id(max.table_id_)) {
if (OB_FAIL(tenant_stats.push_back(tenant_stat))) {
LOG_WARN("push back tenant stat failed", K(ret));
} else {
tenant_stat.reset();
tenant_stat.tenant_id_ = extract_tenant_id(max.table_id_);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(tenant_stat.add_partition_stat(max))) {
LOG_WARN("add partition stat failed", K(ret));
} else {
max = tmp;
}
}
}
}
if (OB_SUCC(ret)) {
if (tenant_stat.tenant_id_ != extract_tenant_id(max.table_id_)) {
if (OB_FAIL(tenant_stats.push_back(tenant_stat))) {
LOG_WARN("push back tenant stat failed", K(ret));
} else {
tenant_stat.reset();
tenant_stat.tenant_id_ = extract_tenant_id(max.table_id_);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(tenant_stat.add_partition_stat(max))) {
LOG_WARN("add partition stat failed", K(ret));
} else if (tenant_stats.push_back(tenant_stat)) {
LOG_WARN("add tenant stat failed", K(ret));
}
}
}
}
return ret;
}
int ObAllTenantStat::retrieve_partition_stats(
sqlclient::ObMySQLResult& result, ObIArray<PartitionStat>& partition_stats)
{
int ret = OB_SUCCESS;
PartitionStat partition_stat;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
while (OB_SUCC(ret)) {
if (OB_FAIL(result.next())) {
if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
break;
} else {
LOG_WARN("get next result failed", K(ret));
}
} else if (OB_FAIL(fill_partition_stat(result, partition_stat))) {
LOG_WARN("fill partition_stat failed", K(ret));
} else if (OB_FAIL(partition_stats.push_back(partition_stat))) {
LOG_WARN("push back partition stat failed", K(ret));
}
}
}
return ret;
}
int ObAllTenantStat::fill_partition_stat(const sqlclient::ObMySQLResult& result, PartitionStat& partition_stat)
{
int ret = OB_SUCCESS;
partition_stat.reset();
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else {
EXTRACT_INT_FIELD_TO_CLASS_MYSQL(result, table_id, partition_stat, uint64_t);
EXTRACT_INT_FIELD_TO_CLASS_MYSQL(result, partition_id, partition_stat, int64_t);
EXTRACT_INT_FIELD_TO_CLASS_MYSQL(result, partition_cnt, partition_stat, int64_t);
EXTRACT_INT_FIELD_TO_CLASS_MYSQL(result, occupy_size, partition_stat, int64_t);
EXTRACT_INT_FIELD_TO_CLASS_MYSQL(result, row_count, partition_stat, int64_t);
EXTRACT_INT_FIELD_TO_CLASS_MYSQL(result, major_version, partition_stat, int64_t);
EXTRACT_INT_FIELD_TO_CLASS_MYSQL(result, minor_version, partition_stat, int64_t);
}
return ret;
}
int ObAllTenantStat::get_full_row(
const share::schema::ObTableSchema* table, const TenantStat& tenant_stat, ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (!tenant_stat.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid tenant_stat", K(tenant_stat), K(ret));
} else {
ADD_COLUMN(set_int, table, "tenant_id", tenant_stat.tenant_id_, columns);
ADD_COLUMN(set_int, table, "table_count", tenant_stat.table_count_, columns);
ADD_COLUMN(set_int, table, "row_count", tenant_stat.row_count_, columns);
ADD_COLUMN(set_int, table, "total_size", tenant_stat.total_size_, columns);
}
return ret;
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -0,0 +1,140 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_ALL_TENANT_STAT_H_
#define OCEANBASE_ROOTSERVER_OB_ALL_TENANT_STAT_H_
#include "share/ob_define.h"
#include "share/ob_virtual_table_projector.h"
namespace oceanbase {
namespace common {
class ObMySQLProxy;
namespace sqlclient {
class ObMySQLResult;
}
} // namespace common
namespace share {
namespace schema {
class ObMultiVersionSchemaService;
class ObTableSchema;
} // namespace schema
} // namespace share
namespace rootserver {
class ObAllTenantStat : public common::ObVirtualTableProjector {
public:
ObAllTenantStat();
virtual ~ObAllTenantStat();
int init(share::schema::ObMultiVersionSchemaService& schema_service, common::ObMySQLProxy& proxy);
virtual int inner_get_next_row(common::ObNewRow*& row);
private:
struct PartitionStat {
uint64_t table_id_;
int64_t partition_id_;
int64_t partition_cnt_;
int64_t occupy_size_;
int64_t row_count_;
int64_t major_version_;
int64_t minor_version_;
PartitionStat();
~PartitionStat()
{}
static int check_same_partition(const PartitionStat& lhs, const PartitionStat& rhs, bool& same_partition);
static int cmp_version(const PartitionStat& lhs, const PartitionStat& rhs, int64_t& cmp_ret);
// used by EXTRACT_INT_FIELD_TO_CLASS_MYSQL
inline void set_table_id(const uint64_t table_id)
{
table_id_ = table_id;
}
inline void set_partition_id(const int64_t partition_id)
{
partition_id_ = partition_id;
}
inline void set_partition_cnt(const int64_t partition_cnt)
{
partition_cnt_ = partition_cnt;
}
inline void set_occupy_size(const int64_t occupy_size)
{
occupy_size_ = occupy_size;
}
inline void set_row_count(const int64_t row_count)
{
row_count_ = row_count;
}
inline void set_major_version(const int64_t major_version)
{
major_version_ = major_version;
}
inline void set_minor_version(const int64_t minor_version)
{
minor_version_ = minor_version;
}
bool is_valid() const;
void reset();
TO_STRING_KV(K_(table_id), K_(partition_id), K_(partition_cnt), K_(occupy_size), K_(row_count), K_(major_version),
K_(minor_version));
};
struct ComparePartition {
ComparePartition()
{}
~ComparePartition()
{}
bool operator()(const PartitionStat& l, const PartitionStat& h);
};
struct TenantStat {
uint64_t tenant_id_;
int64_t table_count_;
int64_t row_count_;
int64_t total_size_;
TenantStat();
~TenantStat()
{}
bool is_valid() const;
void reset();
int add_partition_stat(const PartitionStat& partition_stat);
TO_STRING_KV(K_(tenant_id), K_(table_count), K_(row_count), K_(total_size));
};
virtual int get_all_tenant_stats(common::ObIArray<TenantStat>& tenant_stats);
virtual int get_all_partition_stats(common::ObIArray<PartitionStat>& partition_stats);
virtual int retrieve_partition_stats(
common::sqlclient::ObMySQLResult& result, common::ObIArray<PartitionStat>& partition_stats);
virtual int fill_partition_stat(const common::sqlclient::ObMySQLResult& result, PartitionStat& partition_stat);
int get_full_row(
const share::schema::ObTableSchema* table, const TenantStat& tenant_stat, common::ObIArray<Column>& columns);
private:
bool inited_;
share::schema::ObMultiVersionSchemaService* schema_service_;
common::ObMySQLProxy* proxy_;
private:
DISALLOW_COPY_AND_ASSIGN(ObAllTenantStat);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif // OCEANBASE_ROOTSERVER_OB_ALL_TENANT_STAT_H_

View File

@ -0,0 +1,352 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_virtual_leader_stat.h"
#include "observer/ob_server_struct.h"
#include "share/schema/ob_multi_version_schema_service.h"
#include "rootserver/ob_root_utils.h"
using namespace oceanbase;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
namespace oceanbase {
namespace rootserver {
int ObAllVirtualLeaderStat::init(
rootserver::ObLeaderCoordinator& leader_coordinator, share::schema::ObMultiVersionSchemaService& schema_service)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(is_inited_)) {
ret = OB_INIT_TWICE;
LOG_WARN("ObAllVirtualLeaderStat init twice", K(ret));
} else if (OB_FAIL(partition_info_container_.init(GCTX.pt_operator_, &schema_service, &leader_coordinator))) {
LOG_WARN("fail to init partition info container", K(ret));
} else {
leader_coordinator_ = &leader_coordinator;
schema_service_ = &schema_service;
is_inited_ = true;
}
return ret;
}
int ObAllVirtualLeaderStat::inner_open()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret), K(is_inited_));
} else if (OB_FAIL(schema_service_->get_schema_guard(schema_guard_))) {
LOG_WARN("fail to get schema guard", K(ret));
} else if (OB_FAIL(get_all_tenant())) {
LOG_WARN("fail to get all tenant", K(ret));
} else if (OB_FAIL(get_table_schema(OB_ALL_VIRTUAL_LEADER_STAT_TID))) {
LOG_WARN("fail to get table schema", K(ret));
} else {
} // no more to do
return ret;
}
int ObAllVirtualLeaderStat::get_all_tenant()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret), K(is_inited_));
} else if (OB_FAIL(schema_guard_.get_tenant_ids(all_tenants_))) {
LOG_WARN("fail to get_tenant_ids", K(ret));
} else {
} // no more to do
return ret;
}
int ObAllVirtualLeaderStat::get_table_schema(uint64_t table_id)
{
int ret = OB_SUCCESS;
const uint64_t my_table_id = combine_id(OB_SYS_TENANT_ID, table_id);
if (OB_UNLIKELY(!is_inited_)) {
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret));
} else if (OB_FAIL(schema_guard_.get_table_schema(my_table_id, table_schema_))) {
LOG_WARN("fail to get table schema", K(table_id), K(my_table_id), K(ret));
} else if (NULL == table_schema_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table schema is null", K(ret));
} else {
} // no more to do
return ret;
}
int ObAllVirtualLeaderStat::inner_get_next_row(common::ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret));
} else if (OB_FAIL(next())) {
LOG_WARN("fail to go on next", K(ret));
} else if (OB_FAIL(get_row())) {
LOG_WARN("fail to get row", K(ret));
} else {
row = &cur_row_;
}
return ret;
}
int ObAllVirtualLeaderStat::build_partition_group_candidate_leader_array()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret));
} else if (partition_group_idx_ >= tenant_partition_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("partition group idx out of range",
K(ret),
K(partition_group_idx_),
"tenant partition group cnt",
tenant_partition_.count());
} else {
ObLeaderCoordinator::PartitionArray& partitions = *tenant_partition_.at(partition_group_idx_);
ObLeaderCoordinator::CandidateLeaderInfoMap leader_info_map(*leader_coordinator_);
const int64_t MAP_BUCKET_NUM = 64;
bool is_ignore_switch_percent = false;
const common::ObArray<common::ObZone> exclude_zones;
const common::ObArray<common::ObAddr> exclude_servers;
if (OB_FAIL(leader_info_map.create(MAP_BUCKET_NUM, ObModIds::OB_RS_LEADER_COORDINATOR))) {
LOG_WARN("fail to create leader info map", K(ret));
} else if (OB_FAIL(leader_coordinator_->build_partition_statistic(partitions,
tenant_unit_,
exclude_zones,
exclude_servers,
leader_info_map,
is_ignore_switch_percent))) {
LOG_WARN("fail to build partition statistic", K(ret));
} else if (OB_FAIL(leader_coordinator_->update_leader_candidates(partitions, leader_info_map))) {
LOG_WARN("fail to update leader candidates", K(ret));
} else {
candidate_leader_info_array_.reset();
candidate_leader_info_idx_ = -1; // reset back to -1 when a new array is constructed
for (ObLeaderCoordinator::CandidateLeaderInfoMap::const_iterator iter = leader_info_map.begin();
OB_SUCC(ret) && iter != leader_info_map.end();
++iter) {
const ObLeaderCoordinator::CandidateLeaderInfo& info = iter->second;
if (OB_FAIL(candidate_leader_info_array_.push_back(info))) {
LOG_WARN("fail to push back candidate leader info array", K(ret));
} else {
} // ok
}
}
}
return ret;
}
int ObAllVirtualLeaderStat::construct_tenant_partition()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret));
} else if (cur_tenant_idx_ >= all_tenants_.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant idx out of range", K(ret), K(cur_tenant_idx_), "all tenants count", all_tenants_.count());
} else if (OB_FAIL(do_construct_tenant_partition(all_tenants_.at(cur_tenant_idx_)))) {
LOG_WARN("fail to do construct tenant partition", K(ret), "tenant id", all_tenants_.at(cur_tenant_idx_));
} else {
} // no more to do
return ret;
}
int ObAllVirtualLeaderStat::do_construct_tenant_partition(const uint64_t tenant_id)
{
int ret = OB_SUCCESS;
if (OB_INVALID_ID == tenant_id) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(tenant_id));
} else {
candidate_leader_info_idx_ = -1;
candidate_leader_info_array_.reset();
partition_group_idx_ = -1;
tenant_partition_.reset();
inner_allocator_.reset();
tenant_unit_.reset();
if (OB_FAIL(partition_info_container_.build_tenant_partition_info(tenant_id))) {
LOG_WARN("fail to build tenants partition info", K(ret));
} else if (OB_FAIL(leader_coordinator_->build_tenant_partition(
schema_guard_, partition_info_container_, tenant_id, inner_allocator_, tenant_partition_))) {
LOG_WARN("fail to build tenant partition", K(ret));
} else if (OB_FAIL(leader_coordinator_->get_tenant_unit(tenant_id, tenant_unit_))) {
LOG_WARN("fail to get tenant unit", K(ret), K(tenant_id));
} else if (OB_FAIL(leader_coordinator_->build_dm_partition_candidates(tenant_partition_))) {
LOG_WARN("fail to build dm partition candidates", K(ret));
}
}
return ret;
}
int ObAllVirtualLeaderStat::next()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret));
} else {
while (OB_SUCC(ret)) {
if (OB_FAIL(next_candidate_leader())) {
LOG_WARN("fail to move to next candidate leader", K(ret));
} else if (!reach_candidate_leader_array_end()) {
break; // do not reach candidate leader array end, ok
} else if (OB_FAIL(next_partition_group())) {
LOG_WARN("fail to move to next partition group", K(ret));
} else if (!reach_tenant_end()) {
if (OB_FAIL(build_partition_group_candidate_leader_array())) {
LOG_WARN("fail to build partition group candidate leader array", K(ret));
} else {
} // no more
} else if (OB_FAIL(next_tenant())) {
if (OB_ITER_END != ret) {
LOG_WARN("fail to move to next tenant", K(ret));
} else {
} // iter end
} else if (OB_FAIL(construct_tenant_partition())) {
LOG_WARN("fail to construct tenant partition", K(ret));
} else {
} // no more to do
}
}
return ret;
}
int ObAllVirtualLeaderStat::next_candidate_leader()
{
int ret = OB_SUCCESS;
++candidate_leader_info_idx_;
return ret;
}
bool ObAllVirtualLeaderStat::reach_candidate_leader_array_end()
{
bool reach_end = false;
if (tenant_partition_.count() <= 0) {
reach_end = true;
} else if (candidate_leader_info_idx_ >= candidate_leader_info_array_.count()) {
reach_end = true;
} else {
reach_end = false;
}
return reach_end;
}
int ObAllVirtualLeaderStat::next_partition_group()
{
int ret = OB_SUCCESS;
++partition_group_idx_;
return ret;
}
bool ObAllVirtualLeaderStat::reach_tenant_end()
{
bool reach_end = false;
if (partition_group_idx_ >= tenant_partition_.count()) {
reach_end = true;
} else {
reach_end = false;
}
return reach_end;
}
int ObAllVirtualLeaderStat::next_tenant()
{
int ret = OB_SUCCESS;
++cur_tenant_idx_;
if (cur_tenant_idx_ >= all_tenants_.count()) {
ret = OB_ITER_END;
} else {
} // no more to do
return ret;
}
int ObAllVirtualLeaderStat::get_row()
{
int ret = OB_SUCCESS;
columns_.reuse();
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("ObAllVirtualLeaderStat not init", K(ret));
} else if (OB_FAIL(get_full_row(table_schema_, columns_))) {
LOG_WARN("fail to get full row", K(ret));
} else if (OB_FAIL(project_row(columns_, cur_row_))) {
LOG_WARN("fail to project row", K(columns_), K(ret));
} else {
} // no more to do
return ret;
}
int ObAllVirtualLeaderStat::get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_UNLIKELY(NULL == table)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument, table is null", K(ret), KP(table));
} else {
const ObLeaderCoordinator::CandidateLeaderInfo& info = candidate_leader_info_array_.at(candidate_leader_info_idx_);
const ObLeaderCoordinator::PartitionArray& partitions = *tenant_partition_.at(partition_group_idx_);
ObPartitionKey pkey;
bool small_tenant = false;
char ip_buf[MAX_IP_ADDR_LENGTH];
if (partitions.count() <= 0) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("partitions is empty", K(ret), "partition count", partitions.count());
} else if (OB_FAIL(partitions.at(0).get_partition_key(pkey))) {
LOG_WARN("get_partition_key failed", K(ret), "partition", partitions.at(0));
} else if (!pkey.is_valid()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("pkey is invalid", K(ret), K(pkey));
} else if (OB_FAIL(ObTenantUtils::check_small_tenant(pkey.get_tenant_id(), small_tenant))) {
LOG_WARN("fail to check small tenant", K(ret), "tenant_id", pkey.get_tenant_id());
} else if (!info.server_addr_.ip_to_string(ip_buf, MAX_IP_ADDR_LENGTH)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to format server ip", K(ret));
} else {
// primary key
ADD_COLUMN(set_int, table, "tenant_id", pkey.get_tenant_id(), columns);
ADD_COLUMN(set_int, table, "tablegroup_id", partitions.at(0).tg_id_, columns);
ADD_COLUMN(set_int, table, "partition_id", (small_tenant ? 0 : pkey.get_partition_id()), columns);
ADD_COLUMN(set_varchar, table, "svr_ip", ip_buf, columns);
ADD_COLUMN(set_int, table, "svr_port", info.server_addr_.get_port(), columns);
// other columns
bool primary_zone_null = (partitions.get_primary_zone().size() <= 0);
bool region_null = (info.region_score_.region_.size() <= 0);
bool zone_null = (info.zone_score_.zone_.size() <= 0);
ADD_COLUMN(
set_varchar, table, "primary_zone", (primary_zone_null ? "" : partitions.get_primary_zone().ptr()), columns);
ADD_COLUMN(set_varchar, table, "region", (region_null ? "" : info.region_score_.region_.ptr()), columns);
ADD_COLUMN(set_int, table, "region_score", info.region_score_.region_score_, columns);
ADD_COLUMN(set_int, table, "not_merging", static_cast<int64_t>(info.not_merging_), columns);
ADD_COLUMN(set_int, table, "candidate_count", info.candidate_count_, columns);
ADD_COLUMN(set_int, table, "is_candidate", static_cast<int64_t>(info.is_candidate_), columns);
ADD_COLUMN(set_int, table, "migrate_out_or_transform_count", info.migrate_out_or_transform_count_, columns);
ADD_COLUMN(set_int, table, "in_normal_unit_count", info.in_normal_unit_count_, columns);
ADD_COLUMN(set_varchar, table, "zone", (zone_null ? "" : info.zone_score_.zone_.ptr()), columns);
ADD_COLUMN(set_int, table, "zone_score", info.zone_score_.zone_score_, columns);
ADD_COLUMN(set_int, table, "original_leader_count", info.in_normal_unit_count_, columns);
ADD_COLUMN(set_int, table, "random_score", info.random_score_, columns);
}
}
return ret;
}
} // namespace rootserver
} // namespace oceanbase

View File

@ -0,0 +1,98 @@
/**
* 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.
*/
#ifndef _OB_ALL_VIRTUAL_LEADER_STAT_H_
#define _OB_ALL_VIRTUAL_LEADER_STAT_H_ 1
#include "share/ob_virtual_table_projector.h"
#include "rootserver/ob_leader_coordinator.h"
namespace oceanbase {
namespace share {
namespace schema {
class ObMultiVersionSchemaService;
}
} // namespace share
namespace rootserver {
class ObAllVirtualLeaderStat : public common::ObVirtualTableProjector {
public:
ObAllVirtualLeaderStat()
: schema_guard_(),
all_tenants_(),
cur_tenant_idx_(-1),
columns_(),
tenant_partition_(),
partition_group_idx_(-1),
candidate_leader_info_array_(),
candidate_leader_info_idx_(-1),
tenant_unit_(),
partition_info_container_(),
leader_coordinator_(NULL),
schema_service_(NULL),
table_schema_(NULL),
inner_allocator_(),
is_inited_(false)
{}
virtual ~ObAllVirtualLeaderStat()
{}
public:
int init(
rootserver::ObLeaderCoordinator& leader_coordinator, share::schema::ObMultiVersionSchemaService& schema_service);
virtual int inner_open() override;
virtual int inner_get_next_row(common::ObNewRow*& row) override;
private:
// get all_virtual_leader_stat's table_schema
int get_table_schema(uint64_t table_id);
int get_all_tenant();
int next();
int next_candidate_leader();
bool reach_candidate_leader_array_end();
int next_partition_group();
bool reach_tenant_end();
int next_tenant();
int get_row();
int get_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns);
int build_partition_group_candidate_leader_array();
int construct_tenant_partition();
int do_construct_tenant_partition(uint64_t tenant_id);
private:
static const int64_t MAX_COLUMN_NUM = 32; // all_virtual_leader_stat column number now will not be greater than 32
private:
share::schema::ObSchemaGetterGuard schema_guard_;
common::ObArray<uint64_t> all_tenants_;
// cur_tenant_idx_ is current idx of all_tenants_;
int64_t cur_tenant_idx_;
common::ObSEArray<Column, MAX_COLUMN_NUM> columns_;
rootserver::ObLeaderCoordinator::TenantPartition tenant_partition_;
// partition_group_idx_ is current partition group idx of tenant_partitions_
int64_t partition_group_idx_;
common::ObArray<ObLeaderCoordinator::CandidateLeaderInfo> candidate_leader_info_array_;
// idx of candidate_leader_info_array_
int64_t candidate_leader_info_idx_;
rootserver::ObLeaderCoordinator::TenantUnit tenant_unit_;
rootserver::PartitionInfoContainer partition_info_container_;
rootserver::ObLeaderCoordinator* leader_coordinator_;
share::schema::ObMultiVersionSchemaService* schema_service_;
const share::schema::ObTableSchema* table_schema_;
common::ObArenaAllocator inner_allocator_;
bool is_inited_;
private:
// disallow copy and assign
DISALLOW_COPY_AND_ASSIGN(ObAllVirtualLeaderStat);
};
} // namespace rootserver
} // namespace oceanbase
#endif // _OB_ALL_VIRTUAL_LEADER_STAT_H_

View File

@ -0,0 +1,110 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_all_virtual_rootservice_stat.h"
#include "lib/stat/ob_di_cache.h"
#include "lib/statistic_event/ob_stat_event.h"
#include "rootserver/ob_root_service.h"
using namespace oceanbase;
using namespace oceanbase::rootserver;
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
ObAllVirtualRootserviceStat::ObAllVirtualRootserviceStat()
: ObSimpleVirtualTableIterator(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_ROOTSERVICE_STAT_TID),
rootservice_(NULL),
stat_iter_(0)
{}
int ObAllVirtualRootserviceStat::init(ObRootService& rootservice)
{
rootservice_ = &rootservice;
return ObSimpleVirtualTableIterator::init(&rootservice.get_schema_service());
}
int ObAllVirtualRootserviceStat::init_all_data()
{
int ret = OB_SUCCESS;
int64_t high_wait_count = 0;
int64_t high_sched_count = 0;
int64_t low_wait_count = 0;
int64_t low_sched_count = 0;
if (NULL == rootservice_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (OB_FAIL(ObDIGlobalTenantCache::get_instance().get_the_diag_info(OB_SYS_TENANT_ID, sys_tenant_di_))) {
LOG_WARN("failed to get the diagnose info", K(ret));
} else if (OB_FAIL(rootservice_->get_rebalance_task_mgr().get_all_tasks_count(
high_wait_count, high_sched_count, low_wait_count, low_sched_count))) {
LOG_WARN("failed to get task count", K(ret));
} else {
EVENT_SET(RS_TASK_QUEUE_SIZE_HIGH_WAIT, high_wait_count);
EVENT_SET(RS_TASK_QUEUE_SIZE_HIGH_SCHED, high_sched_count);
EVENT_SET(RS_TASK_QUEUE_SIZE_LOW_WAIT, low_wait_count);
EVENT_SET(RS_TASK_QUEUE_SIZE_LOW_SCHED, low_sched_count);
stat_iter_ = 0;
}
return ret;
}
// create table __all_virtual_rootservice_stat (`statistic#` bigint, value bigint, stat_id bigint, name varchar(64),
// `class` bigint, can_visible boolean, primary key(`statistic#`));
int ObAllVirtualRootserviceStat::get_next_full_row(
const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (stat_iter_ < 0 || stat_iter_ >= ObStatEventIds::STAT_EVENT_SET_END) {
ret = OB_ITER_END;
} else {
bool found = false;
int32_t& stat_i = stat_iter_;
for (; stat_i < ObStatEventIds::STAT_EVENT_SET_END && OB_SUCC(ret); ++stat_i) {
if (OB_STAT_EVENTS[stat_i].stat_class_ == ObStatClassIds::RS) {
ADD_COLUMN(set_int, table, "statistic#", stat_i, columns);
ADD_COLUMN(set_int, table, "stat_id", OB_STAT_EVENTS[stat_i].stat_id_, columns);
ADD_COLUMN(set_varchar, table, "name", OB_STAT_EVENTS[stat_i].name_, columns);
ADD_COLUMN(set_int, table, "class", OB_STAT_EVENTS[stat_i].stat_class_, columns);
ADD_COLUMN(set_bool, table, "can_visible", OB_STAT_EVENTS[stat_i].can_visible_, columns);
int64_t stat_value = 0;
if (stat_i < ObStatEventIds::STAT_EVENT_ADD_END) {
ObStatEventAddStat* stat = sys_tenant_di_.get_add_stat_stats().get(stat_i);
if (NULL == stat) {
ret = OB_INVALID_ARGUMENT;
SERVER_LOG(WARN, "The argument is invalid, ", K(stat_i), K(ret));
} else {
stat_value = stat->stat_value_;
}
} else {
ObStatEventSetStat* stat =
sys_tenant_di_.get_set_stat_stats().get(stat_i - ObStatEventIds::STAT_EVENT_ADD_END - 1);
if (NULL == stat) {
ret = OB_INVALID_ARGUMENT;
SERVER_LOG(WARN, "The argument is invalid, ", K(stat_i), K(ret));
} else {
stat_value = stat->stat_value_;
}
}
ADD_COLUMN(set_int, table, "value", stat_value, columns);
found = true;
stat_iter_++;
break;
}
} // end for
if (OB_SUCC(ret) && !found) {
ret = OB_ITER_END;
}
}
return ret;
}

View File

@ -0,0 +1,45 @@
/**
* 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.
*/
#ifndef _OB_ALL_VIRTUAL_ROOTSERVICE_STAT_H
#define _OB_ALL_VIRTUAL_ROOTSERVICE_STAT_H 1
#include "share/ob_virtual_table_projector.h"
#include "lib/stat/ob_diagnose_info.h"
namespace oceanbase {
namespace rootserver {
class ObRootService;
class ObAllVirtualRootserviceStat : public common::ObSimpleVirtualTableIterator {
public:
ObAllVirtualRootserviceStat();
virtual ~ObAllVirtualRootserviceStat()
{}
int init(ObRootService& rootservice);
virtual int init_all_data() override;
virtual int get_next_full_row(const share::schema::ObTableSchema* table, common::ObIArray<Column>& columns) override;
private:
// data members
ObRootService* rootservice_;
common::ObDiagnoseTenantInfo sys_tenant_di_;
int32_t stat_iter_;
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObAllVirtualRootserviceStat);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif /* _OB_ALL_VIRTUAL_ROOTSERVICE_STAT_H */

View File

@ -0,0 +1,218 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_core_meta_table.h"
#include "share/partition_table/ob_partition_table_operator.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/schema/ob_table_schema.h"
#include "share/schema/ob_column_schema.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
ObCoreMetaTable::ObCoreMetaTable() : inited_(false), pt_operator_(NULL), schema_guard_(NULL)
{}
ObCoreMetaTable::~ObCoreMetaTable()
{}
int ObCoreMetaTable::init(ObPartitionTableOperator& pt_operator, ObSchemaGetterGuard* schema_guard)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (NULL == schema_guard) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("schema_guard is null", K(ret));
} else {
pt_operator_ = &pt_operator;
schema_guard_ = schema_guard;
inited_ = true;
}
return ret;
}
int ObCoreMetaTable::inner_get_next_row(ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (NULL == allocator_) {
ret = OB_NOT_INIT;
LOG_WARN("not init, allocator is null", K(ret));
} else if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (!start_to_read_) {
const ObTableSchema* table_schema = NULL;
const uint64_t table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_VIRTUAL_CORE_META_TABLE_TID);
const uint64_t core_table_id = combine_id(OB_SYS_TENANT_ID, OB_ALL_CORE_TABLE_TID);
ObPartitionInfo partition_info;
partition_info.set_allocator(allocator_);
if (OB_FAIL(schema_guard_->get_table_schema(table_id, table_schema)) || NULL == table_schema) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("get_table_schema failed", K(table_id), K(ret));
} else if (OB_FAIL(
pt_operator_->get(core_table_id, ObIPartitionTable::ALL_CORE_TABLE_PARTITION_ID, partition_info))) {
LOG_WARN("pt_operator get failed",
K(core_table_id),
"partition_id",
static_cast<int64_t>(ObIPartitionTable::ALL_CORE_TABLE_PARTITION_ID),
K(ret));
} else {
ObArray<Column> columns;
FOREACH_CNT_X(replica, partition_info.get_replicas_v2(), OB_SUCCESS == ret)
{
columns.reuse();
if (OB_FAIL(get_full_row(table_schema, *replica, columns))) {
LOG_WARN("get_full_row failed", "table_schema", *table_schema, "replica", *replica, K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("project_row failed", K(columns), K(ret));
} else if (OB_FAIL(scanner_.add_row(cur_row_))) {
LOG_WARN("add_row failed", K(cur_row_), K(ret));
}
}
}
if (OB_SUCC(ret)) {
scanner_it_ = scanner_.begin();
start_to_read_ = true;
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) {
if (OB_ITER_END != ret) {
LOG_WARN("get_next_row failed", K(ret));
}
} else {
row = &cur_row_;
}
}
return ret;
}
int ObCoreMetaTable::get_full_row(
const ObTableSchema* table, const ObPartitionReplica& replica, ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
char* ip = NULL;
char* zone = NULL;
char* member_list = NULL;
char* column_checksum = NULL;
const char* column_checksum_tmp = "";
char* fail_list = NULL;
const char* replica_status = ob_replica_status_str(replica.replica_status_);
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else if (!replica.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid replica", K(replica), K(ret));
} else {
if (NULL == (ip = static_cast<char*>(allocator_->alloc(OB_MAX_SERVER_ADDR_SIZE)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc ip buf failed", "size", OB_MAX_SERVER_ADDR_SIZE, K(ret));
} else if (NULL == (zone = static_cast<char*>(allocator_->alloc(MAX_ZONE_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc zone buf failed", "size", MAX_ZONE_LENGTH, K(ret));
} else if (NULL == (member_list = static_cast<char*>(allocator_->alloc(MAX_MEMBER_LIST_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc member_list failed", "size", OB_MAX_SERVER_ADDR_SIZE, K(ret));
} else if (NULL == (column_checksum = static_cast<char*>(allocator_->alloc(COLUMN_CHECKSUM_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc column_checksum failed", "size", COLUMN_CHECKSUM_LENGTH, K(ret));
} else if (NULL == (fail_list = static_cast<char*>(allocator_->alloc(OB_MAX_FAILLIST_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("alloc zone buf failed", "size", OB_MAX_FAILLIST_LENGTH, K(ret));
} else if (false == replica.server_.ip_to_string(ip, OB_MAX_SERVER_ADDR_SIZE)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("convert server ip to string failed", K(ret), "server", replica.server_);
} else if (OB_FAIL(databuff_printf(zone, MAX_ZONE_LENGTH, "%s", replica.zone_.ptr()))) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", "buf_len", MAX_ZONE_LENGTH, "src_len", strlen(replica.zone_.ptr()), K(ret));
} else if (OB_FAIL(
ObPartitionReplica::member_list2text(replica.member_list_, member_list, MAX_MEMBER_LIST_LENGTH))) {
LOG_WARN("member_list2text failed", K(replica), K(ret));
} else if (OB_FAIL(databuff_printf(column_checksum, COLUMN_CHECKSUM_LENGTH, "%s", column_checksum_tmp))) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", "buf_len", COLUMN_CHECKSUM_LENGTH, "src_len", strlen(column_checksum_tmp), K(ret));
} else if (OB_FAIL(databuff_printf(fail_list, OB_MAX_FAILLIST_LENGTH, "%s", replica.fail_list_.ptr()))) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("snprintf failed", K(ret), "buf_len", OB_MAX_FAILLIST_LENGTH, "src_len", replica.fail_list_.length());
} else {
ADD_COLUMN(set_int, table, "tenant_id", static_cast<int64_t>(extract_tenant_id(replica.table_id_)), columns);
ADD_COLUMN(set_int, table, "table_id", static_cast<int64_t>(replica.table_id_), columns);
ADD_COLUMN(set_int, table, "partition_id", replica.partition_id_, columns);
ADD_COLUMN(set_varchar, table, "svr_ip", ip, columns);
ADD_COLUMN(set_int, table, "svr_port", replica.server_.get_port(), columns);
ADD_COLUMN(set_int, table, "sql_port", replica.sql_port_, columns);
ADD_COLUMN(set_int, table, "unit_id", static_cast<int64_t>(replica.unit_id_), columns);
ADD_COLUMN(set_int, table, "partition_cnt", replica.partition_cnt_, columns);
ADD_COLUMN(set_varchar, table, "zone", zone, columns);
ADD_COLUMN(set_int, table, "role", replica.role_, columns);
ADD_COLUMN(set_varchar, table, "member_list", member_list, columns);
ADD_COLUMN(set_int, table, "row_count", replica.row_count_, columns);
ADD_COLUMN(set_int, table, "data_size", replica.data_size_, columns);
ADD_COLUMN(set_int, table, "data_version", replica.data_version_, columns);
ADD_COLUMN(set_int, table, "data_checksum", replica.data_checksum_, columns);
ADD_COLUMN(set_int, table, "row_checksum", static_cast<int64_t>(replica.row_checksum_.checksum_), columns);
ADD_COLUMN(set_varchar, table, "column_checksum", column_checksum, columns);
ADD_COLUMN(set_int, table, "is_original_leader", replica.is_original_leader_, columns);
ADD_COLUMN(set_int, table, "is_previous_leader", replica.to_leader_time_, columns);
ADD_COLUMN(set_int, table, "create_time", 0, columns); // DEPRECATED
ADD_COLUMN(set_int, table, "rebuild", replica.rebuild_, columns);
ADD_COLUMN(set_int, table, "replica_type", replica.replica_type_, columns);
ADD_COLUMN(set_int, table, "required_size", replica.required_size_, columns);
ADD_COLUMN(set_varchar, table, "status", replica_status, columns);
ADD_COLUMN(set_int, table, "is_restore", replica.is_restore_, columns);
ADD_COLUMN(set_int, table, "partition_checksum", replica.partition_checksum_, columns);
ADD_COLUMN(set_int, table, "quorum", replica.quorum_, columns);
ADD_COLUMN(set_varchar, table, "fail_list", fail_list, columns);
ADD_COLUMN(set_int, table, "recovery_timestamp", replica.recovery_timestamp_, columns);
ADD_COLUMN(set_int, table, "memstore_percent", replica.get_memstore_percent(), columns);
ADD_COLUMN(set_int, table, "data_file_id", replica.data_file_id_, columns);
}
if (OB_FAIL(ret)) {
if (NULL != ip) {
allocator_->free(ip);
ip = NULL;
}
if (NULL != zone) {
allocator_->free(zone);
zone = NULL;
}
if (NULL != member_list) {
allocator_->free(member_list);
member_list = NULL;
}
if (NULL != column_checksum) {
allocator_->free(column_checksum);
column_checksum = NULL;
}
if (NULL != fail_list) {
allocator_->free(fail_list);
fail_list = NULL;
}
}
}
return ret;
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -0,0 +1,52 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_CORE_META_TABLE_H_
#define OCEANBASE_ROOTSERVER_OB_CORE_META_TABLE_H_
#include "share/ob_virtual_table_projector.h"
#include "share/partition_table/ob_partition_table_proxy.h"
namespace oceanbase {
namespace share {
class ObPartitionReplica;
class ObPartitionTableOperator;
namespace schema {
class ObTableSchema;
class ObColumnSchemaV2;
} // namespace schema
} // namespace share
namespace rootserver {
class ObCoreMetaTable : public common::ObVirtualTableProjector {
public:
ObCoreMetaTable();
virtual ~ObCoreMetaTable();
int init(share::ObPartitionTableOperator& pt_operator, share::schema::ObSchemaGetterGuard* schema_guard);
virtual int inner_get_next_row(common::ObNewRow*& row);
private:
int get_full_row(const share::schema::ObTableSchema* table, const share::ObPartitionReplica& replica,
common::ObIArray<Column>& columns);
bool inited_;
share::ObPartitionTableOperator* pt_operator_;
share::schema::ObSchemaGetterGuard* schema_guard_;
private:
DISALLOW_COPY_AND_ASSIGN(ObCoreMetaTable);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif // OCEANBASE_ROOTSERVER_OB_CORE_META_TABLE_H_

View File

@ -0,0 +1,179 @@
/**
* 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.
*/
#define USING_LOG_PREFIX RS
#include "ob_virtual_core_inner_table.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/schema/ob_table_schema.h"
#include "share/schema/ob_column_schema.h"
#include "share/ob_core_table_proxy.h"
namespace oceanbase {
using namespace common;
using namespace share;
using namespace share::schema;
namespace rootserver {
ObVritualCoreInnerTable::ObVritualCoreInnerTable()
: inited_(false), sql_proxy_(NULL), table_name_(NULL), table_id_(OB_INVALID_ID), schema_guard_(NULL)
{}
ObVritualCoreInnerTable::~ObVritualCoreInnerTable()
{}
int ObVritualCoreInnerTable::init(
ObMySQLProxy& sql_proxy, const char* table_name, const uint64_t table_id, ObSchemaGetterGuard* schema_guard)
{
int ret = OB_SUCCESS;
if (inited_) {
ret = OB_INIT_TWICE;
LOG_WARN("init twice", K(ret));
} else if (!sql_proxy.is_inited() || NULL == table_name || OB_INVALID_ID == table_id || NULL == schema_guard) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument",
"sql_proxy_inited",
sql_proxy.is_inited(),
KP(table_name),
KT(table_id),
KP(schema_guard),
K(ret));
} else {
sql_proxy_ = &sql_proxy;
table_name_ = table_name;
table_id_ = table_id;
schema_guard_ = schema_guard;
inited_ = true;
}
return ret;
}
int ObVritualCoreInnerTable::inner_get_next_row(ObNewRow*& row)
{
int ret = OB_SUCCESS;
if (NULL == allocator_) {
ret = OB_NOT_INIT;
LOG_WARN("not init, allocator is null", K(ret));
} else if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (!start_to_read_) {
ObCoreTableProxy core_table(table_name_, *sql_proxy_);
const ObTableSchema* table_schema = NULL;
if (OB_FAIL(schema_guard_->get_table_schema(table_id_, table_schema))) {
LOG_WARN("fail to get table schema", K(ret), K_(table_id));
} else if (NULL == table_schema) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("get_table_schema failed", KT_(table_id), K(ret));
} else if (OB_FAIL(core_table.load())) {
LOG_WARN("core_table load failed", K(ret));
} else {
ObArray<Column> columns;
while (OB_SUCCESS == ret && (OB_ITER_END != (ret = core_table.next()))) {
columns.reuse();
if (OB_FAIL(get_full_row(table_schema, core_table, columns))) {
LOG_WARN("get_full_row failed", K(table_schema), K(ret));
} else if (OB_FAIL(project_row(columns, cur_row_))) {
LOG_WARN("project_row failed", K(columns), K(ret));
} else if (OB_FAIL(scanner_.add_row(cur_row_))) {
LOG_WARN("add_row failed", K_(cur_row), K(ret));
}
}
if (OB_ITER_END == ret) {
ret = OB_SUCCESS;
}
}
if (OB_SUCC(ret)) {
scanner_it_ = scanner_.begin();
start_to_read_ = true;
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(scanner_it_.get_next_row(cur_row_))) {
if (OB_ITER_END != ret) {
LOG_WARN("get_next_row failed", K(ret));
}
} else {
row = &cur_row_;
}
}
return ret;
}
int ObVritualCoreInnerTable::get_full_row(
const ObTableSchema* table, const ObCoreTableProxy& core_table, ObIArray<Column>& columns)
{
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;
LOG_WARN("not init", K(ret));
} else if (NULL == table) {
// core_table doesn't need to check
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table is null", K(ret));
} else {
const ObColumnSchemaV2* column_schema = NULL;
const char* column_name = NULL;
ObString str_column;
for (int64_t i = 0; OB_SUCC(ret) && i < output_column_ids_.count(); ++i) {
if (NULL == (column_schema = table->get_column_schema(output_column_ids_.at(i)))) {
ret = OB_SCHEMA_ERROR;
LOG_WARN("column id not exist", "column_id", output_column_ids_.at(i), K(ret));
} else if (NULL == (column_name = column_schema->get_column_name())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column name is null", K(column_schema), K(ret));
} else {
int inner_ret = OB_SUCCESS;
if (ObVarcharType == column_schema->get_data_type() || ObLongTextType == column_schema->get_data_type()) {
str_column.reset();
if (OB_SUCCESS == (inner_ret = core_table.get_varchar(column_name, str_column))) {
if (ObVarcharType == column_schema->get_data_type()) {
ADD_COLUMN(set_varchar, table, column_name, str_column, columns);
} else if (ObLongTextType == column_schema->get_data_type()) {
ADD_TEXT_COLUMN(ObLongTextType, table, column_name, str_column, columns);
}
} else if (OB_ERR_NULL_VALUE == inner_ret) {
ADD_NULL_COLUMN(table, column_name, columns);
} else {
ret = inner_ret;
LOG_WARN("get_varchar failed", K(column_name), K(ret));
}
} else if (ObIntType == column_schema->get_data_type() || ObTinyIntType == column_schema->get_data_type() ||
ObUInt64Type == column_schema->get_data_type()) {
int64_t int_column = 0;
if (OB_SUCCESS == (inner_ret = core_table.get_int(column_name, int_column))) {
if (ObIntType == column_schema->get_data_type()) {
ADD_COLUMN(set_int, table, column_name, int_column, columns);
} else if (ObTinyIntType == column_schema->get_data_type()) {
ADD_COLUMN(set_tinyint, table, column_name, static_cast<int8_t>(int_column), columns);
} else {
ADD_COLUMN(set_uint64, table, column_name, int_column, columns);
}
} else if (OB_ERR_NULL_VALUE == inner_ret) {
ADD_NULL_COLUMN(table, column_name, columns);
} else {
ret = inner_ret;
LOG_WARN("get_int failed", K(column_name), K(ret));
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("data type is not expected", "data_type", column_schema->get_data_type(), K(ret));
}
}
}
}
return ret;
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -0,0 +1,56 @@
/**
* 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.
*/
#ifndef OCEANBASE_ROOTSERVER_OB_ALL_VIRTUAL_CORE_INNER_TABLE_H_
#define OCEANBASE_ROOTSERVER_OB_ALL_VIRTUAL_CORE_INNER_TABLE_H_
#include "share/ob_virtual_table_projector.h"
#include "lib/mysqlclient/ob_mysql_proxy.h"
namespace oceanbase {
namespace share {
class ObCoreTableProxy;
namespace schema {
class ObTableSchema;
class ObColumnSchemaV2;
class ObSchemaGetterGuard;
} // namespace schema
} // namespace share
namespace rootserver {
class ObVritualCoreInnerTable : public common::ObVirtualTableProjector {
public:
ObVritualCoreInnerTable();
virtual ~ObVritualCoreInnerTable();
int init(common::ObMySQLProxy& sql_proxy, const char* table_name, const uint64_t table_id,
share::schema::ObSchemaGetterGuard* schema_guard);
virtual int inner_get_next_row(common::ObNewRow*& row);
private:
int get_full_row(const share::schema::ObTableSchema* table, const share::ObCoreTableProxy& core_table,
common::ObIArray<Column>& columns);
bool inited_;
common::ObMySQLProxy* sql_proxy_;
const char* table_name_;
uint64_t table_id_;
share::schema::ObSchemaGetterGuard* schema_guard_;
private:
DISALLOW_COPY_AND_ASSIGN(ObVritualCoreInnerTable);
};
} // end namespace rootserver
} // end namespace oceanbase
#endif // OCEANBASE_ROOTSERVER_OB_ALL_VIRTUAL_CORE_INNER_TABLE_H_