619 lines
25 KiB
C++
619 lines
25 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX RS
|
|
|
|
#include "ob_single_partition_balance.h"
|
|
#include "lib/container/ob_array.h"
|
|
#include "lib/container/ob_array_iterator.h"
|
|
#include "lib/string/ob_strings.h"
|
|
#include "rootserver/ob_unit_manager.h"
|
|
#include "ob_zone_manager.h"
|
|
#include "share/partition_table/ob_partition_table_operator.h"
|
|
#include "share/partition_table/ob_partition_table_iterator.h"
|
|
|
|
namespace oceanbase {
|
|
using namespace common;
|
|
using namespace share;
|
|
using namespace schema;
|
|
namespace rootserver {
|
|
|
|
ObSinglePartBalance::ObSinglePartBalance()
|
|
: inited_(false),
|
|
unit_mgr_(NULL),
|
|
zone_mgr_(NULL),
|
|
pt_operator_(NULL),
|
|
tenant_unit_rep_cnt_vec_(0, NULL, "TenUnitRepCnt"),
|
|
allocator_("SingParBalance")
|
|
{}
|
|
|
|
int ObSinglePartBalance::init(
|
|
ObUnitManager& unit_mgr, ObZoneManager& zone_mgr, share::ObPartitionTableOperator& pt_operator)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
unit_mgr_ = &unit_mgr;
|
|
zone_mgr_ = &zone_mgr;
|
|
pt_operator_ = &pt_operator;
|
|
inited_ = true;
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::check_inner_stat() const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (!inited_) {
|
|
ret = OB_NOT_INIT;
|
|
LOG_WARN("not init", KR(ret));
|
|
} else if (OB_ISNULL(unit_mgr_)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unit_mgr is null", KR(ret));
|
|
} else if (OB_ISNULL(pt_operator_)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("pt_operator_ is null", KR(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::destory_tenant_unit_array()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
for (int64_t i = 0; i < tenant_unit_rep_cnt_vec_.count() && OB_SUCC(ret); ++i) {
|
|
if (OB_ISNULL(tenant_unit_rep_cnt_vec_.at(i))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("is null", KR(ret));
|
|
} else {
|
|
tenant_unit_rep_cnt_vec_.at(i)->~TenantUnitRepCnt();
|
|
allocator_.free(tenant_unit_rep_cnt_vec_.at(i));
|
|
tenant_unit_rep_cnt_vec_.at(i) = NULL;
|
|
}
|
|
}
|
|
tenant_unit_rep_cnt_vec_.reset();
|
|
return ret;
|
|
}
|
|
|
|
bool ObSinglePartBalance::compare_with_tenant_id(
|
|
const share::TenantUnitRepCnt* lhs, const share::TenantUnitRepCnt& ten_unit_rep)
|
|
{
|
|
return NULL != lhs ? (lhs->tenant_id_ < ten_unit_rep.tenant_id_) : false;
|
|
}
|
|
|
|
bool ObSinglePartBalance::compare_with_tenant_id_up(
|
|
const share::TenantUnitRepCnt& ten_unit_rep, const share::TenantUnitRepCnt* lhs)
|
|
{
|
|
return NULL != lhs ? (ten_unit_rep.tenant_id_ < lhs->tenant_id_) : false;
|
|
}
|
|
|
|
bool ObSinglePartBalance::compare_with_unit_id(const uint64_t lhs, const uint64_t unit_id)
|
|
{
|
|
return lhs < unit_id;
|
|
}
|
|
|
|
int ObSinglePartBalance::sort_and_push_back_unit_ids(
|
|
const common::ObIArray<share::ObUnitInfo>& unit_infos, common::ObArray<uint64_t>& unit_ids)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
for (int64_t i = 0; i < unit_infos.count() && OB_SUCC(ret); ++i) {
|
|
if (OB_FAIL(unit_ids.push_back(unit_infos.at(i).unit_.unit_id_))) {
|
|
LOG_WARN("fail to push back unit id", KR(ret), "unit_id", unit_infos.at(i).unit_.unit_id_);
|
|
}
|
|
}
|
|
std::sort(unit_ids.begin(), unit_ids.end(), compare_with_unit_id);
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::create_unit_replica_counter(const uint64_t tenant_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
common::ObArray<share::ObUnitInfo> unit_infos;
|
|
common::ObArray<uint64_t> unit_ids;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("fail to init", KR(ret));
|
|
} else if (OB_FAIL(unit_mgr_->get_active_unit_infos_by_tenant(tenant_id, unit_infos))) {
|
|
LOG_WARN("fail to get active unit infos by tenant", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(sort_and_push_back_unit_ids(unit_infos, unit_ids))) {
|
|
LOG_WARN("fail to sort and push back unit ids", KR(ret), K(tenant_id));
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
ObArray<share::TenantUnitRepCnt> update_ten_unit_reps;
|
|
share::TenantUnitRepCnt ten_unit_rep;
|
|
ten_unit_rep.tenant_id_ = tenant_id;
|
|
share::TenantUnitRepCntVec::iterator iter_lower =
|
|
tenant_unit_rep_cnt_vec_.lower_bound(ten_unit_rep, compare_with_tenant_id);
|
|
share::TenantUnitRepCntVec::iterator iter_upper =
|
|
tenant_unit_rep_cnt_vec_.upper_bound(ten_unit_rep, compare_with_tenant_id_up);
|
|
if (iter_upper != tenant_unit_rep_cnt_vec_.end()) {
|
|
// There are tenants behind
|
|
if (OB_FAIL(copy_ten_unit_rep_data(update_ten_unit_reps, iter_upper))) {
|
|
LOG_WARN("fail to copy ten unit rep data", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(remove_tenant_unit_rep(iter_lower))) {
|
|
LOG_WARN("fail to remove tenant unit rep", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(create_tenant_unit_rep(unit_ids, tenant_id))) {
|
|
LOG_WARN("fail to update ten unit rep", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(push_back_other_tenant_unit_rep(update_ten_unit_reps))) {
|
|
LOG_WARN("fail to push back other tenant unit rep", KR(ret), K(tenant_id));
|
|
}
|
|
} else {
|
|
// There is no tenant later, just update this tenant
|
|
if (OB_FAIL(create_tenant_unit_rep(unit_ids, tenant_id))) {
|
|
LOG_WARN("fail to update tenant unit rep", KR(ret), K(tenant_id));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::create_tenant_unit_rep(const ObIArray<uint64_t>& unit_ids, const uint64_t tenant_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
for (int64_t i = 0; i < unit_ids.count() && OB_SUCC(ret); ++i) {
|
|
void* buff = allocator_.alloc(sizeof(TenantUnitRepCnt));
|
|
share::TenantUnitRepCnt* tenant_unit_rep_cnt = NULL;
|
|
share::UnitReplicaCounter unit_rep_cnt;
|
|
if (OB_ISNULL(buff)) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("alloc failed", KR(ret));
|
|
} else if (FALSE_IT(tenant_unit_rep_cnt = new (buff) TenantUnitRepCnt(unit_ids.at(i), tenant_id, unit_rep_cnt))) {
|
|
// never be here
|
|
} else if (OB_FAIL(tenant_unit_rep_cnt_vec_.push_back(tenant_unit_rep_cnt))) {
|
|
LOG_WARN("fail to push back tenant unit rep cnt", KR(ret), K(tenant_unit_rep_cnt));
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
if (nullptr != tenant_unit_rep_cnt) {
|
|
tenant_unit_rep_cnt->~TenantUnitRepCnt();
|
|
allocator_.free(tenant_unit_rep_cnt);
|
|
tenant_unit_rep_cnt = nullptr;
|
|
} else if (nullptr != buff) {
|
|
allocator_.free(buff);
|
|
buff = nullptr;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::refresh_unit_replica_counter(const uint64_t tenant_id, const int64_t start,
|
|
const ObIArray<share::ObUnitInfo>& unit_infos, share::schema::ObSchemaGetterGuard& schema_guard,
|
|
ObIArray<share::TenantUnitRepCnt>& tmp_ten_unit_reps)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
common::ObArray<uint64_t> unit_ids;
|
|
common::ObArray<uint64_t> non_partition_table;
|
|
int64_t index_num = 0;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("not init", KR(ret));
|
|
} else if (OB_FAIL(prepare_replica_capacity(tenant_id, schema_guard, index_num, non_partition_table))) {
|
|
LOG_WARN("fail to prepare replica capacity", KR(ret));
|
|
} else {
|
|
int64_t part_cnt = 0;
|
|
if (OB_FAIL(sort_and_push_back_unit_ids(unit_infos, unit_ids))) {
|
|
LOG_WARN("fail to sort and push back unit ids", KR(ret), K(tenant_id));
|
|
} else {
|
|
for (int64_t i = 0; i < unit_ids.count() && OB_SUCC(ret); ++i) {
|
|
share::TenantUnitRepCnt tmp_ten_unit_rep;
|
|
tmp_ten_unit_rep.unit_id_ = unit_ids.at(i);
|
|
tmp_ten_unit_rep.tenant_id_ = tenant_id;
|
|
if (OB_FAIL(tmp_ten_unit_reps.push_back(tmp_ten_unit_rep))) {
|
|
LOG_WARN("fail to push back", KR(ret));
|
|
}
|
|
}
|
|
}
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < non_partition_table.count(); ++i) {
|
|
ObPartitionInfo partition_info;
|
|
ObArenaAllocator partition_allocator(ObModIds::OB_RS_PARTITION_TABLE_TEMP);
|
|
partition_info.set_allocator(&partition_allocator);
|
|
ObTablePartitionIterator iter;
|
|
if (OB_FAIL(iter.init(non_partition_table.at(i), schema_guard, *pt_operator_))) {
|
|
LOG_WARN("fail to init table partition iterator", KR(ret));
|
|
} else if (OB_FAIL(iter.next(partition_info))) {
|
|
LOG_WARN("fail to get partition_info", KR(ret));
|
|
} else if (OB_FAIL(partition_info.get_partition_cnt(part_cnt))) {
|
|
LOG_WARN("fail to get partition cnt", KR(ret));
|
|
} else if (part_cnt > 1) { // single partition or non-partition
|
|
LOG_WARN("part_cnt need <= 1", KR(ret));
|
|
} else {
|
|
FOREACH_CNT_X(r, partition_info.get_replicas_v2(), OB_SUCC(ret))
|
|
{
|
|
// Traverse all replicas in the partition
|
|
for (int64_t i = 0; i < tmp_ten_unit_reps.count() && OB_SUCC(ret); ++i) {
|
|
if (tmp_ten_unit_reps.at(i).unit_id_ == r->unit_id_) {
|
|
if (OB_FAIL(set_unit_replica_capacity(
|
|
*r, tmp_ten_unit_reps.at(i), index_num, start, non_partition_table.count()))) {
|
|
LOG_WARN("fail to set unit replica capacity", KR(ret));
|
|
}
|
|
}
|
|
}
|
|
} // end for each
|
|
}
|
|
} // end for
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::prepare_replica_capacity(const uint64_t tenant_id,
|
|
share::schema::ObSchemaGetterGuard& schema_guard, int64_t& index_num,
|
|
common::ObIArray<uint64_t>& non_partition_table)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("not init", KR(ret));
|
|
} else {
|
|
const share::schema::ObTenantSchema* tenant_schema = NULL;
|
|
common::ObArray<const share::schema::ObTableSchema*> table_schemas;
|
|
common::ObArray<const share::schema::ObTablegroupSchema*> tablegroup_schemas;
|
|
common::ObArray<uint64_t> non_partition_tg;
|
|
ObSEArray<ObRawPrimaryZoneUtil::ZoneScore, MAX_ZONE_NUM> zone_score_array;
|
|
ObSEArray<ObRawPrimaryZoneUtil::RegionScore, MAX_ZONE_NUM> region_score_array;
|
|
if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) {
|
|
LOG_WARN("tenant not exists", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(schema_guard.get_tablegroup_schemas_in_tenant(tenant_id, tablegroup_schemas))) {
|
|
LOG_WARN("fail to get table group schemas in tenant", KR(ret));
|
|
} else {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < tablegroup_schemas.count(); ++i) {
|
|
const share::schema::ObTablegroupSchema* tablegroup_schema = tablegroup_schemas.at(i);
|
|
if (OB_ISNULL(tablegroup_schema)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("schema ptr is null", KR(ret));
|
|
} else if (tablegroup_schema->get_all_part_num() > 1 || !tablegroup_schema->has_self_partition()) { // skip
|
|
} else {
|
|
if (OB_FAIL(non_partition_tg.push_back(tablegroup_schema->get_tablegroup_id()))) {
|
|
LOG_WARN("fail to push back", KR(ret), K(tablegroup_schema->get_tablegroup_id()));
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
if (OB_FAIL(balancer::StatFinderUtil::get_need_balance_table_schemas_in_tenant(
|
|
schema_guard, tenant_id, table_schemas))) {
|
|
LOG_WARN("fail to get table schemas in tenant", KR(ret));
|
|
} else {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < table_schemas.count(); ++i) {
|
|
const share::schema::ObTableSchema* table_schema = table_schemas.at(i);
|
|
if (OB_ISNULL(table_schema)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("schema ptr is null", KR(ret));
|
|
} else if (table_schema->has_self_partition() && table_schema->get_all_part_num() <= 1 &&
|
|
table_schema->get_duplicate_scope() == ObDuplicateScope::DUPLICATE_SCOPE_NONE &&
|
|
share::OB_ALL_DUMMY_TID != extract_pure_id(table_schema->get_table_id()) &&
|
|
OB_INVALID_ID == table_schema->get_tablegroup_id() &&
|
|
rootserver::ObTenantUtils::is_balance_target_schema(*table_schema)) {
|
|
if (OB_FAIL(non_partition_table.push_back(table_schema->get_table_id()))) {
|
|
LOG_WARN("fail to push back", KR(ret), K(table_schema->get_table_id()));
|
|
} else {
|
|
index_num = non_partition_table.count();
|
|
}
|
|
}
|
|
} // end for
|
|
if (OB_SUCC(ret)) {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < non_partition_tg.count(); ++i) {
|
|
if (OB_FAIL(non_partition_table.push_back(non_partition_tg.at(i)))) {
|
|
LOG_WARN("fail to push back", KR(ret), K(non_partition_tg.at(i)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::get_tenant_unit_array(
|
|
ObIArray<share::TenantUnitRepCnt*>& ten_unit_arr, const uint64_t tenant_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
share::TenantUnitRepCnt ten_unit_rep;
|
|
ten_unit_rep.tenant_id_ = tenant_id;
|
|
share::TenantUnitRepCntVec::iterator iter_lower =
|
|
tenant_unit_rep_cnt_vec_.lower_bound(ten_unit_rep, compare_with_tenant_id);
|
|
share::TenantUnitRepCntVec::iterator iter_upper =
|
|
tenant_unit_rep_cnt_vec_.upper_bound(ten_unit_rep, compare_with_tenant_id_up);
|
|
if (iter_lower == tenant_unit_rep_cnt_vec_.end()) {
|
|
// The tenant is not in the cache, create a cache for the tenant
|
|
if (OB_FAIL(create_unit_replica_counter(tenant_id))) {
|
|
LOG_WARN("fail to create unit replica counter", KR(ret), K(tenant_id));
|
|
} else {
|
|
iter_lower = tenant_unit_rep_cnt_vec_.lower_bound(ten_unit_rep, compare_with_tenant_id);
|
|
iter_upper = tenant_unit_rep_cnt_vec_.upper_bound(ten_unit_rep, compare_with_tenant_id_up);
|
|
}
|
|
}
|
|
for (; iter_lower != iter_upper && OB_SUCC(ret); ++iter_lower) {
|
|
if (OB_ISNULL(*iter_lower)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("tenant unit rep cnt is null", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(ten_unit_arr.push_back(*iter_lower))) {
|
|
LOG_WARN("fail to push back ten_unit_arr", KR(ret), K(tenant_id));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::set_tenant_unit_replica_capacity(const uint64_t tenant_id, const int64_t start,
|
|
const ObIArray<share::ObUnitInfo>& unit_infos, const ObIArray<share::TenantUnitRepCnt>& tmp_ten_unit_reps)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t unit_count = 0;
|
|
bool need_clear = false;
|
|
ObArray<uint64_t> unit_ids;
|
|
ObArray<share::TenantUnitRepCnt> update_ten_unit_reps;
|
|
bool need_update = true;
|
|
for (int64_t i = 0; i < tenant_unit_rep_cnt_vec_.count() && OB_SUCC(ret); ++i) {
|
|
if (OB_ISNULL(tenant_unit_rep_cnt_vec_.at(i))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("is null", KR(ret), K(tenant_id), K(tenant_unit_rep_cnt_vec_.count()), "unit sequence", i);
|
|
} else if (tenant_unit_rep_cnt_vec_.at(i)->tenant_id_ == tenant_id) {
|
|
unit_count++;
|
|
if (OB_FAIL(unit_ids.push_back(tenant_unit_rep_cnt_vec_.at(i)->unit_id_))) {
|
|
LOG_WARN("fail to push back", KR(ret), K(tenant_id));
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
for (int64_t i = 0; i < unit_infos.count() && OB_SUCC(ret); ++i) {
|
|
if (has_exist_in_array(unit_ids, unit_infos.at(i).unit_.unit_id_)) {
|
|
// nothing todo
|
|
} else {
|
|
need_clear = true;
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
ObArray<uint64_t> tmp_unit_ids;
|
|
if (OB_FAIL(sort_and_push_back_unit_ids(unit_infos, tmp_unit_ids))) {
|
|
LOG_WARN("fail to sort and push back unit ids", KR(ret), K(tenant_id));
|
|
} else if ((tmp_ten_unit_reps.count() != unit_count || unit_count == 0 || need_clear)) {
|
|
// unit_count==0 may be that all units have been replaced,
|
|
// or it may be that tenant_id is not in the vec
|
|
// Clear the original data first
|
|
share::TenantUnitRepCnt ten_unit_rep;
|
|
ten_unit_rep.tenant_id_ = tenant_id;
|
|
share::TenantUnitRepCntVec::iterator iter_lower =
|
|
tenant_unit_rep_cnt_vec_.lower_bound(ten_unit_rep, compare_with_tenant_id);
|
|
share::TenantUnitRepCntVec::iterator iter_upper =
|
|
tenant_unit_rep_cnt_vec_.upper_bound(ten_unit_rep, compare_with_tenant_id_up);
|
|
if (iter_upper != tenant_unit_rep_cnt_vec_.end()) {
|
|
// There will be tenants in the future
|
|
if (OB_FAIL(copy_ten_unit_rep_data(update_ten_unit_reps, iter_upper))) {
|
|
LOG_WARN("fail to copy ten unit rep data", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(remove_tenant_unit_rep(iter_lower))) {
|
|
LOG_WARN("fail to remove tenant unit rep", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(update_ten_unit_rep(unit_infos, tenant_id))) {
|
|
LOG_WARN("fail to update ten unit rep", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(push_back_other_tenant_unit_rep(update_ten_unit_reps))) {
|
|
LOG_WARN("fail to push back other tenant unit rep", KR(ret), K(tenant_id));
|
|
}
|
|
} else if (iter_lower != tenant_unit_rep_cnt_vec_.end()) {
|
|
// There is no tenant in the future, just update the tenant
|
|
if (OB_FAIL(remove_tenant_unit_rep(iter_lower))) {
|
|
LOG_WARN("fail to remove tenant unit rep cnt vec", KR(ret), K(tenant_id));
|
|
} else if (OB_FAIL(update_ten_unit_rep(unit_infos, tenant_id))) {
|
|
LOG_WARN("fail to update tenant unit rep", KR(ret), K(tenant_id));
|
|
}
|
|
} else {
|
|
if (OB_FAIL(update_ten_unit_rep(unit_infos, tenant_id))) {
|
|
LOG_WARN("fail to update tenant unit rep", KR(ret), K(tenant_id));
|
|
}
|
|
}
|
|
} else {
|
|
share::TenantUnitRepCnt ten_unit_rep;
|
|
ten_unit_rep.tenant_id_ = tenant_id;
|
|
share::TenantUnitRepCntVec::iterator iter_lower =
|
|
tenant_unit_rep_cnt_vec_.lower_bound(ten_unit_rep, compare_with_tenant_id);
|
|
if (OB_ISNULL(*(iter_lower))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("is null", KR(ret), K(tenant_id));
|
|
} else {
|
|
if (iter_lower != tenant_unit_rep_cnt_vec_.end() && start < (*(iter_lower))->now_time_) {
|
|
// nothing todo
|
|
} else {
|
|
for (int64_t j = 0;
|
|
j < tmp_ten_unit_reps.count() && (iter_lower + j != tenant_unit_rep_cnt_vec_.end()) && OB_SUCC(ret);
|
|
++j) {
|
|
(*(iter_lower + j))->unit_id_ = tmp_ten_unit_reps.at(j).unit_id_;
|
|
(*(iter_lower + j))->tenant_id_ = tmp_ten_unit_reps.at(j).tenant_id_;
|
|
(*(iter_lower + j))->unit_rep_cnt_ = tmp_ten_unit_reps.at(j).unit_rep_cnt_;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LOG_INFO("finish set_tenant_unit_replica_capacity",
|
|
KR(ret),
|
|
K(tenant_id),
|
|
"unit_count",
|
|
unit_infos.count(),
|
|
"tenant_vec_count",
|
|
tenant_unit_rep_cnt_vec_.count());
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::copy_ten_unit_rep_data(
|
|
ObIArray<share::TenantUnitRepCnt>& update_ten_unit_reps, share::TenantUnitRepCntVec::iterator& iter_upper)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
for (share::TenantUnitRepCntVec::iterator iter = iter_upper; iter != tenant_unit_rep_cnt_vec_.end() && OB_SUCC(ret);
|
|
iter++) {
|
|
if (OB_ISNULL(*(iter))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("tenant unit rep cnt is null", KR(ret));
|
|
} else {
|
|
share::TenantUnitRepCnt* tenant_unit_rep = *iter;
|
|
if (OB_FAIL(update_ten_unit_reps.push_back(*tenant_unit_rep))) {
|
|
LOG_WARN("fail to update ten unit reps", KR(ret), "tenant_id", (*iter)->tenant_id_);
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::remove_tenant_unit_rep(share::TenantUnitRepCntVec::iterator& iter_lower)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
for (share::TenantUnitRepCntVec::iterator iter = tenant_unit_rep_cnt_vec_.end() - 1;
|
|
iter >= iter_lower && OB_SUCC(ret);
|
|
iter--) {
|
|
if (OB_ISNULL(iter)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("iter is null", KR(ret));
|
|
} else if (OB_FAIL(tenant_unit_rep_cnt_vec_.remove(iter))) {
|
|
LOG_WARN("fail to remove tenant unit rep cnt", KR(ret));
|
|
}
|
|
if (nullptr != *iter) {
|
|
(*iter)->~TenantUnitRepCnt();
|
|
allocator_.free(*iter);
|
|
*iter = nullptr;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::update_ten_unit_rep(const ObIArray<share::ObUnitInfo>& unit_infos, const uint64_t tenant_id)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObArray<uint64_t> unit_ids;
|
|
share::UnitReplicaCounter unit_rep_cnt;
|
|
if (OB_FAIL(sort_and_push_back_unit_ids(unit_infos, unit_ids))) {
|
|
LOG_WARN("fail to sort and push back unit ids", KR(ret), K(tenant_id));
|
|
} else {
|
|
// First insert the unit corresponding to the new tenant
|
|
for (int64_t i = 0; i < unit_ids.count() && OB_SUCC(ret); ++i) {
|
|
void* buff = allocator_.alloc(sizeof(TenantUnitRepCnt));
|
|
share::TenantUnitRepCnt* tenant_unit_rep_cnt = NULL;
|
|
if (OB_ISNULL(buff)) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("alloc failed", KR(ret));
|
|
} else if (FALSE_IT(tenant_unit_rep_cnt = new (buff) TenantUnitRepCnt(unit_ids.at(i), tenant_id, unit_rep_cnt))) {
|
|
// never be here
|
|
} else if (OB_FAIL(tenant_unit_rep_cnt_vec_.push_back(tenant_unit_rep_cnt))) {
|
|
LOG_WARN("fail to push back tenant unit rep cnt", KR(ret), K(tenant_unit_rep_cnt));
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
if (nullptr != tenant_unit_rep_cnt) {
|
|
tenant_unit_rep_cnt->~TenantUnitRepCnt();
|
|
allocator_.free(tenant_unit_rep_cnt);
|
|
tenant_unit_rep_cnt = nullptr;
|
|
} else if (nullptr != buff) {
|
|
allocator_.free(buff);
|
|
buff = nullptr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::push_back_other_tenant_unit_rep(const ObIArray<share::TenantUnitRepCnt>& update_ten_unit_reps)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_SUCC(ret)) {
|
|
// Then insert other tenants
|
|
for (int64_t i = 0; i < update_ten_unit_reps.count() && OB_SUCC(ret); ++i) {
|
|
void* buff = allocator_.alloc(sizeof(TenantUnitRepCnt));
|
|
share::TenantUnitRepCnt* tenant_unit_rep_cnt = NULL;
|
|
const share::TenantUnitRepCnt& tmp_ten_unit_rep = update_ten_unit_reps.at(i);
|
|
if (OB_ISNULL(buff)) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("alloc failed", KR(ret));
|
|
} else if (FALSE_IT(
|
|
tenant_unit_rep_cnt = new (buff) TenantUnitRepCnt(
|
|
tmp_ten_unit_rep.unit_id_, tmp_ten_unit_rep.tenant_id_, tmp_ten_unit_rep.unit_rep_cnt_))) {
|
|
// never be here
|
|
} else if (OB_FAIL(tenant_unit_rep_cnt_vec_.push_back(tenant_unit_rep_cnt))) {
|
|
LOG_WARN("fail to push back tenant unit rep cnt", KR(ret), K(tenant_unit_rep_cnt));
|
|
}
|
|
if (OB_FAIL(ret)) {
|
|
if (nullptr != tenant_unit_rep_cnt) {
|
|
tenant_unit_rep_cnt->~TenantUnitRepCnt();
|
|
allocator_.free(tenant_unit_rep_cnt);
|
|
tenant_unit_rep_cnt = nullptr;
|
|
} else if (nullptr != buff) {
|
|
allocator_.free(buff);
|
|
buff = nullptr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::update_tenant_unit_replica_capacity(
|
|
const uint64_t tenant_id, const ObIArray<share::TenantUnitRepCnt*>& tmp_ten_unit_reps)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const int64_t start = ObTimeUtility::current_time();
|
|
share::TenantUnitRepCnt ten_unit_rep;
|
|
ten_unit_rep.tenant_id_ = tenant_id;
|
|
share::TenantUnitRepCntVec::iterator iter_lower =
|
|
tenant_unit_rep_cnt_vec_.lower_bound(ten_unit_rep, compare_with_tenant_id);
|
|
share::TenantUnitRepCntVec::iterator iter_upper =
|
|
tenant_unit_rep_cnt_vec_.upper_bound(ten_unit_rep, compare_with_tenant_id_up);
|
|
if (OB_ISNULL(*(iter_lower))) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("is null", KR(ret), K(tenant_id));
|
|
} else if (iter_upper - iter_lower != tmp_ten_unit_reps.count()) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unit count different",
|
|
KR(ret),
|
|
K(tenant_id),
|
|
"vec_unit_count",
|
|
iter_upper - iter_lower,
|
|
"actual unit count",
|
|
tmp_ten_unit_reps.count());
|
|
} else if (iter_lower != tenant_unit_rep_cnt_vec_.end() && start < (*(iter_lower))->now_time_) {
|
|
// nothing todo
|
|
} else {
|
|
for (int64_t j = 0;
|
|
j < tmp_ten_unit_reps.count() && (iter_lower + j != tenant_unit_rep_cnt_vec_.end()) && OB_SUCC(ret);
|
|
++j) {
|
|
if (OB_ISNULL(tmp_ten_unit_reps.at(j))) {
|
|
// nothing todo
|
|
LOG_WARN("ten unit rep is null", K(tenant_id), KR(ret));
|
|
} else {
|
|
(*(iter_lower + j))->unit_id_ = tmp_ten_unit_reps.at(j)->unit_id_;
|
|
(*(iter_lower + j))->tenant_id_ = tmp_ten_unit_reps.at(j)->tenant_id_;
|
|
(*(iter_lower + j))->unit_rep_cnt_ = tmp_ten_unit_reps.at(j)->unit_rep_cnt_;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObSinglePartBalance::set_unit_replica_capacity(const share::ObPartitionReplica& r,
|
|
share::TenantUnitRepCnt& tenant_unit_rep_cnt, const int64_t index_num, const int64_t now_time,
|
|
const int64_t non_table_cnt)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (r.replica_type_ == REPLICA_TYPE_FULL && r.get_memstore_percent() != 0) {
|
|
tenant_unit_rep_cnt.unit_rep_cnt_.f_replica_cnt_++;
|
|
} else if (r.replica_type_ == REPLICA_TYPE_FULL && r.get_memstore_percent() == 0) {
|
|
tenant_unit_rep_cnt.unit_rep_cnt_.d_replica_cnt_++;
|
|
} else if (r.replica_type_ == REPLICA_TYPE_LOGONLY) {
|
|
tenant_unit_rep_cnt.unit_rep_cnt_.l_replica_cnt_++;
|
|
} else if (r.replica_type_ == REPLICA_TYPE_READONLY) {
|
|
tenant_unit_rep_cnt.unit_rep_cnt_.r_replica_cnt_++;
|
|
} else {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("not allow replica type", KR(ret), K(r.replica_type_));
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
tenant_unit_rep_cnt.unit_rep_cnt_.index_num_ = index_num;
|
|
tenant_unit_rep_cnt.now_time_ = now_time;
|
|
tenant_unit_rep_cnt.non_table_cnt_ = non_table_cnt;
|
|
if (r.is_leader_like()) {
|
|
// Record leader information
|
|
tenant_unit_rep_cnt.unit_rep_cnt_.leader_cnt_++;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
} // end namespace rootserver
|
|
} // end namespace oceanbase
|