/** * 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& unit_infos, common::ObArray& 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 unit_infos; common::ObArray 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 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& 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& unit_infos, share::schema::ObSchemaGetterGuard& schema_guard, ObIArray& tmp_ten_unit_reps) { int ret = OB_SUCCESS; common::ObArray unit_ids; common::ObArray 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& 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 table_schemas; common::ObArray tablegroup_schemas; common::ObArray non_partition_tg; ObSEArray zone_score_array; ObSEArray 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& 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& unit_infos, const ObIArray& tmp_ten_unit_reps) { int ret = OB_SUCCESS; int64_t unit_count = 0; bool need_clear = false; ObArray unit_ids; ObArray 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 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& 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& unit_infos, const uint64_t tenant_id) { int ret = OB_SUCCESS; ObArray 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& 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& 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