oceanbase
8163 строки · 335.4 Кб
1/**
2* Copyright (c) 2021 OceanBase
3* OceanBase CE is licensed under Mulan PubL v2.
4* You can use this software according to the terms and conditions of the Mulan PubL v2.
5* You may obtain a copy of Mulan PubL v2 at:
6* http://license.coscl.org.cn/MulanPubL-2.0
7* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10* See the Mulan PubL v2 for more details.
11*/
12
13#define USING_LOG_PREFIX RS_LB
14#include "ob_server_balancer.h"
15#include "ob_balance_info.h"
16#include "lib/container/ob_array_iterator.h"
17#include "observer/ob_server_struct.h"
18#include "storage/ob_file_system_router.h"
19#include "rootserver/ob_zone_manager.h"
20#include "rootserver/ob_unit_stat_manager.h"
21#include "rootserver/ob_root_utils.h"
22#include "rootserver/ob_root_service.h"
23#include "storage/ob_file_system_router.h"
24#include "share/ob_all_server_tracer.h"
25#include "share/ob_server_table_operator.h"
26#include "rootserver/ob_heartbeat_service.h"
27#include "share/ob_share_util.h" // ObShareUtil
28#include "lib/utility/ob_tracepoint.h"
29
30using namespace oceanbase::common;
31using namespace oceanbase::common::hash;
32using namespace oceanbase::rootserver;
33using namespace oceanbase::share;
34ObServerBalancer::ObServerBalancer()
35:inited_(false),
36schema_service_(NULL),
37unit_mgr_(NULL),
38zone_mgr_(NULL),
39server_mgr_(NULL),
40unit_stat_mgr_(),
41count_balance_strategy_(*this),
42inner_ttg_balance_strategy_(count_balance_strategy_),
43zone_disk_statistic_()
44{}
45
46ObServerBalancer::~ObServerBalancer() {}
47
48int ObServerBalancer::init(
49share::schema::ObMultiVersionSchemaService &schema_service,
50ObUnitManager &unit_manager,
51ObZoneManager &zone_mgr,
52ObServerManager &server_mgr,
53common::ObMySQLProxy &sql_proxy)
54{
55int ret = OB_SUCCESS;
56if (inited_) {
57ret = OB_INIT_TWICE;
58} else if (OB_FAIL(unit_stat_mgr_.init(sql_proxy))) {
59LOG_WARN("init unit_stat_mgr failed", KR(ret));
60} else {
61schema_service_ = &schema_service;
62unit_mgr_ = &unit_manager;
63zone_mgr_ = &zone_mgr;
64server_mgr_ = &server_mgr;
65inited_ = true;
66}
67return ret;
68}
69
70int ObServerBalancer::get_active_servers_info_and_resource_info_of_zone(
71const ObZone &zone,
72ObIArray<share::ObServerInfoInTable> &servers_info,
73ObIArray<obrpc::ObGetServerResourceInfoResult> &server_resources_info)
74{
75int ret = OB_SUCCESS;
76servers_info.reset();
77server_resources_info.reset();
78ObServerResourceInfo resource_info_in_server_status;
79obrpc::ObGetServerResourceInfoResult resource_info_result;
80if (OB_FAIL(SVR_TRACER.get_active_servers_info(zone, servers_info))) {
81LOG_WARN("fail to execute get_active_servers_info", KR(ret), K(zone));
82} else if (OB_ISNULL(server_mgr_)) {
83ret = OB_ERR_UNEXPECTED;
84LOG_WARN("server_mgr_ is null", KR(ret), KP(server_mgr_));
85} else {
86for (int64_t i = 0; OB_SUCC(ret) && i < servers_info.count(); i++) {
87const ObAddr &server = servers_info.at(i).get_server();
88resource_info_result.reset();
89resource_info_in_server_status.reset();
90if (OB_FAIL(server_mgr_->get_server_resource_info(server, resource_info_in_server_status))) {
91LOG_WARN("fail to get resource_info_in_server_status", KR(ret), K(server));
92} else if (OB_UNLIKELY(!resource_info_in_server_status.is_valid())) {
93ret = OB_INVALID_ARGUMENT;
94LOG_WARN("invalid resource_info_in_server_status", KR(ret), K(server), K(resource_info_in_server_status));
95} else if (OB_FAIL(resource_info_result.init(server,resource_info_in_server_status))) {
96LOG_WARN("fail to init", KR(ret), K(server), K(resource_info_in_server_status));
97} else if (OB_FAIL(server_resources_info.push_back(resource_info_result))) {
98LOG_WARN("fail to push an element into server_resources_info", KR(ret), K(resource_info_result));
99}
100}
101}
102return ret;
103}
104
105int ObServerBalancer::tenant_group_balance()
106{
107int ret = OB_SUCCESS;
108ObRootBalanceHelp::BalanceController balance_controller;
109ObString switch_config_str = GCONF.__balance_controller.str();
110{
111SpinWLockGuard guard(unit_mgr_->get_lock()); // lock!
112ObArray<ObZone> zones;
113if (!check_inner_stat()) {
114ret = OB_INNER_STAT_ERROR;
115LOG_WARN("fail to check inner stat", K(ret));
116} else if (OB_FAIL(unit_stat_mgr_.gather_stat())) {
117LOG_WARN("gather all tenant unit stat failed, refuse to do server_balance", K(ret));
118unit_stat_mgr_.reuse();
119ret = OB_SUCCESS;
120} else if (OB_FAIL(ObRootBalanceHelp::parse_balance_info(
121switch_config_str, balance_controller))) {
122LOG_WARN("fail to parse balance switch", K(ret), "balance switch", switch_config_str);
123} else if (ObShareUtil::is_tenant_enable_rebalance(OB_SYS_TENANT_ID)
124|| balance_controller.at(ObRootBalanceHelp::ENABLE_SERVER_BALANCE)) {
125if (OB_FAIL(zone_mgr_->get_zone(ObZoneStatus::ACTIVE, zones))) {
126LOG_WARN("get_zone failed", "status", ObZoneStatus::ACTIVE, K(ret));
127} else {
128LOG_INFO("start to do tenant group unit balance");
129// The server balance of all zones is completed independently
130for (int64_t i = 0; OB_SUCC(ret) && i < zones.count(); ++i) {
131bool can_execute_rebalance = false;
132if (OB_FAIL(check_can_execute_rebalance(zones.at(i), can_execute_rebalance))) {
133LOG_WARN("fail to check can execute rebalance", K(ret));
134} else if (!can_execute_rebalance) {
135// cannot do rebalance
136} else if (OB_FAIL(rebalance_servers_v2(zones.at(i)))) {
137LOG_WARN("failed to rebalance servers", "zone", zones.at(i), K(ret));
138}
139}
140}
141}
142}
143return ret;
144}
145
146int ObServerBalancer::check_has_unit_in_migration(
147const common::ObIArray<ObUnitManager::ObUnitLoad> *unit_load_array,
148bool &has_unit_in_migration)
149{
150int ret = OB_SUCCESS;
151if (!check_inner_stat()) {
152ret = OB_INNER_STAT_ERROR;
153LOG_WARN("fail to check inner stat", KR(ret));
154} else if (OB_UNLIKELY(nullptr == unit_load_array)) {
155ret = OB_INVALID_ARGUMENT;
156LOG_WARN("invalid argument", KR(ret), KP(unit_load_array));
157} else {
158has_unit_in_migration = false;
159for (int64_t i = 0;
160!has_unit_in_migration && OB_SUCC(ret) && i < unit_load_array->count();
161++i) {
162const ObUnitManager::ObUnitLoad &unit_load = unit_load_array->at(i);
163if (OB_UNLIKELY(!unit_load.is_valid())) {
164ret = OB_INVALID_ARGUMENT;
165LOG_WARN("invalid unit load", KR(ret), K(unit_load));
166} else if (unit_load.unit_->migrate_from_server_.is_valid()) {
167has_unit_in_migration = true;
168} else {
169// bypass
170}
171}
172}
173return ret;
174}
175
176int ObServerBalancer::balance_servers()
177{
178int ret = OB_SUCCESS;
179LOG_INFO("start do unit balance");
180ObRootBalanceHelp::BalanceController balance_controller;
181ObString switch_config_str = GCONF.__balance_controller.str();
182DEBUG_SYNC(START_UNIT_BALANCE);
183{
184SpinWLockGuard guard(unit_mgr_->get_lock()); // lock!
185const bool enable_sys_unit_standalone = GCONF.enable_sys_unit_standalone;
186if (!check_inner_stat()) {
187ret = OB_INNER_STAT_ERROR;
188LOG_WARN("check_inner_stat failed", K(inited_), K(ret));
189} else if (OB_FAIL(ObRootBalanceHelp::parse_balance_info(switch_config_str, balance_controller))) {
190LOG_WARN("fail to parse balance switch", K(ret), "balance_swtich", switch_config_str);
191} else if (OB_FAIL(unit_stat_mgr_.gather_stat())) {
192LOG_WARN("gather all tenant unit stat failed, refuse to do balance for status change", K(ret));
193unit_stat_mgr_.reuse();
194ret = OB_SUCCESS;
195} else {
196// When the server status changes,
197// try to adjust the unit on the server without configuration item control
198if (GCONF.is_rereplication_enabled()
199|| ObShareUtil::is_tenant_enable_rebalance(OB_SYS_TENANT_ID)
200|| balance_controller.at(ObRootBalanceHelp::ENABLE_SERVER_BALANCE)) {
201if (OB_FAIL(distribute_for_server_status_change())) {
202LOG_WARN("fail to distribute for server status change", K(ret));
203}
204}
205
206if (OB_SUCC(ret) && enable_sys_unit_standalone) {
207if (OB_FAIL(distribute_for_standalone_sys_unit())) {
208LOG_WARN("fail to distribute for standalone sys unit");
209}
210}
211}
212}
213LOG_INFO("finish do unit balance", K(ret));
214return ret;
215}
216
217int ObServerBalancer::distribute_pool_for_standalone_sys_unit(
218const share::ObResourcePool &pool,
219const common::ObIArray<common::ObAddr> &sys_unit_server_array)
220{
221int ret = OB_SUCCESS;
222const char *module = "UNIT_BALANCE_FOR_STANDALONE_SYS";
223share::ObUnitConfig *unit_config = nullptr;
224common::ObArray<share::ObUnit *> *pool_unit_array = nullptr;
225if (OB_UNLIKELY(OB_INVALID_ID == pool.resource_pool_id_)) {
226ret = OB_INVALID_ARGUMENT;
227LOG_WARN("invalid argument", K(ret), "pool_id", pool.resource_pool_id_);
228} else if (OB_UNLIKELY(nullptr == unit_mgr_)) {
229ret = OB_ERR_UNEXPECTED;
230LOG_WARN("unit mgr ptr is nullptr", K(ret));
231} else if (OB_FAIL(unit_mgr_->get_units_by_pool(pool.resource_pool_id_, pool_unit_array))) {
232LOG_WARN("fail to get units by pool", K(ret), "pool_id", pool.resource_pool_id_);
233} else if (OB_UNLIKELY(nullptr == pool_unit_array)) {
234ret = OB_ERR_UNEXPECTED;
235LOG_WARN("pool unit array", K(ret));
236} else if (OB_FAIL(unit_mgr_->get_unit_config_by_id(pool.unit_config_id_, unit_config))) {
237LOG_WARN("fail to get unit config by pool name", K(pool));
238} else if (OB_UNLIKELY(nullptr == unit_config)) {
239ret = OB_ERR_UNEXPECTED;
240LOG_WARN("unit config ptr is null", K(ret), K(pool));
241} else {
242ObServerInfoInTable server_info;
243ObUnitStat unit_stat;
244ObArray<ObUnitStat> in_migrate_unit_stat;
245common::ObArray<common::ObAddr> excluded_servers;
246common::ObAddr migrate_server;
247std::string resource_not_enough_reason;
248ObArray<ObServerInfoInTable> servers_info_of_zone;
249ObArray<ObServerInfoInTable> active_servers_info_of_zone;
250ObArray<obrpc::ObGetServerResourceInfoResult> active_servers_resource_info_of_zone;
251for (int64_t i = 0; OB_SUCC(ret) && i < pool_unit_array->count(); ++i) {
252excluded_servers.reset();
253server_info.reset();
254unit_stat.reset();
255migrate_server.reset();
256servers_info_of_zone.reset();
257active_servers_resource_info_of_zone.reset();
258active_servers_info_of_zone.reset();
259share::ObUnit *unit = pool_unit_array->at(i);
260if (OB_UNLIKELY(nullptr == unit)) {
261ret = OB_ERR_UNEXPECTED;
262LOG_WARN("unit ptr is null", K(ret));
263} else if (unit->migrate_from_server_.is_valid()) {
264// unit in migrate, bypass
265} else if (OB_FAIL(SVR_TRACER.get_server_info(unit->server_, server_info))) {
266LOG_WARN("fail to get server status", K(ret), "server", unit->server_);
267} else if (!server_info.is_active()) {
268// Only process servers that are active, skip non-active servers
269LOG_INFO("unit server status not active", K(ret), K(server_info), K(*unit));
270} else if (!has_exist_in_array(sys_unit_server_array, unit->server_)) {
271// bypass
272} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
273unit->unit_id_,
274unit->zone_,
275unit_stat))) {
276LOG_WARN("fail to locate unit", K(ret), "unit", *unit);
277} else if (OB_FAIL(SVR_TRACER.get_servers_info(unit->zone_, servers_info_of_zone))) {
278LOG_WARN("fail to servers_info_of_zone", KR(ret), K(unit->zone_));
279} else if (OB_FAIL(get_active_servers_info_and_resource_info_of_zone(
280unit->zone_,
281active_servers_info_of_zone,
282active_servers_resource_info_of_zone))) {
283LOG_WARN("fail to execute get_active_servers_info_and_resource_info_of_zone", KR(ret), K(unit->zone_));
284} else if (OB_FAIL(unit_mgr_->get_excluded_servers(
285*unit,
286unit_stat,
287module,
288servers_info_of_zone,
289active_servers_resource_info_of_zone,
290excluded_servers))) {
291LOG_WARN("fail to get exclude servers", K(ret), KPC(unit), K(servers_info_of_zone),
292K(active_servers_resource_info_of_zone));
293} else if (OB_FAIL(append(excluded_servers, sys_unit_server_array))) {
294LOG_WARN("fail tp append sys unit server array", K(ret));
295} else if (OB_FAIL(unit_mgr_->choose_server_for_unit(
296unit_config->unit_resource(), unit->zone_,
297excluded_servers,
298module,
299active_servers_info_of_zone,
300active_servers_resource_info_of_zone,
301migrate_server,
302resource_not_enough_reason))) {
303if (OB_ZONE_RESOURCE_NOT_ENOUGH == ret || OB_ZONE_SERVER_NOT_ENOUGH == ret) {
304LOG_WARN("has no place to migrate unit", K(module), KR(ret), "unit", *unit,
305K(excluded_servers), "resource_not_enough_reason", resource_not_enough_reason.c_str());
306ret = OB_SUCCESS;
307} else {
308LOG_WARN("fail to choose server for unit", KR(ret), K(unit), K(excluded_servers));
309}
310} else if (OB_FAIL(get_unit_resource_reservation(unit->unit_id_,
311migrate_server,
312in_migrate_unit_stat))) {
313LOG_WARN("fail to get unit resource reservation", K(ret), K(unit), K(migrate_server));
314} else if (OB_FAIL(try_migrate_unit(unit->unit_id_, pool.tenant_id_, unit_stat,
315in_migrate_unit_stat, migrate_server))) {
316LOG_WARN("fail to migrate unit", K(ret), K(unit), K(unit_stat), K(in_migrate_unit_stat));
317}
318}
319}
320return ret;
321}
322
323int ObServerBalancer::distribute_for_standalone_sys_unit()
324{
325int ret = OB_SUCCESS;
326const bool enable_sys_unit_standalone = GCONF.enable_sys_unit_standalone;
327ObArray<ObAddr> sys_unit_server_array;
328const common::ObZone empty_zone; // means all zones
329LOG_INFO("start distribute for standalone sys unit");
330if (!check_inner_stat()) {
331ret = OB_INNER_STAT_ERROR;
332LOG_WARN("fail to check inner stat", K(ret), K(inited_));
333} else if (!enable_sys_unit_standalone) {
334ret = OB_STATE_NOT_MATCH;
335LOG_WARN("sys unit standalone deployment is disabled", K(ret));
336} else if (OB_FAIL(unit_mgr_->get_tenant_unit_servers(
337OB_SYS_TENANT_ID, empty_zone, sys_unit_server_array))) {
338LOG_WARN("fail to get tenant unit server array", K(ret));
339} else {
340ObHashMap<uint64_t, share::ObResourcePool *>::const_iterator iter = unit_mgr_->get_id_pool_map().begin();
341ObHashMap<uint64_t, share::ObResourcePool *>::const_iterator end = unit_mgr_->get_id_pool_map().end();
342for (; OB_SUCC(ret) && iter != end; ++iter) {
343if (OB_UNLIKELY(OB_INVALID_ID == iter->first)) {
344ret = OB_ERR_UNEXPECTED;
345LOG_WARN("pool id unexpected", K(ret));
346} else if (OB_UNLIKELY(nullptr == iter->second)) {
347ret = OB_ERR_UNEXPECTED;
348LOG_WARN("resource pool is null", K(ret));
349} else if (OB_SYS_TENANT_ID == iter->second->tenant_id_) {
350// no need to distribute for sys tenant
351} else if (OB_FAIL(distribute_pool_for_standalone_sys_unit(
352*iter->second, sys_unit_server_array))) {
353LOG_WARN("fail to distribute pool for standalone sys unit", K(ret));
354}
355}
356}
357return ret;
358}
359
360int ObServerBalancer::distribute_for_server_status_change()
361{
362int ret = OB_SUCCESS;
363LOG_INFO("start distribute for server status change");
364if (!check_inner_stat()) {
365ret = OB_INNER_STAT_ERROR;
366LOG_WARN("check_inner_stat failed", K_(inited), K(ret));
367}
368
369ObHashMap<uint64_t, ObArray<share::ObResourcePool *> *>::const_iterator it =
370unit_mgr_->get_tenant_pools_map().begin();
371ObHashMap<uint64_t, ObArray<share::ObResourcePool *> *>::const_iterator it_end =
372unit_mgr_->get_tenant_pools_map().end();
373// Let the system tenant do it first
374for (; OB_SUCC(ret) && it != it_end; ++it) {
375if (OB_SYS_TENANT_ID != it->first) {
376// bypass, non sys tenant, do later
377} else if (NULL == it->second) {
378ret = OB_ERR_UNEXPECTED;
379LOG_WARN("it->second is null", KP(it->second), K(ret));
380} else if (OB_FAIL(distribute_by_tenant(it->first, *(it->second)))) {
381LOG_WARN("distribute by tenant failed", "tenant_id", it->first, K(ret));
382}
383}
384ObHashMap<uint64_t, ObArray<share::ObResourcePool *> *>::const_iterator it2 =
385unit_mgr_->get_tenant_pools_map().begin();
386ObHashMap<uint64_t, ObArray<share::ObResourcePool *> *>::const_iterator it2_end =
387unit_mgr_->get_tenant_pools_map().end();
388// other tenant
389for (; OB_SUCC(ret) && it2 != it2_end; ++it2) {
390if (OB_SYS_TENANT_ID == it2->first) {
391// bypass, sys tenant has been done before
392} else if (NULL == it2->second) {
393ret = OB_ERR_UNEXPECTED;
394LOG_WARN("it->second is null", KP(it2->second), K(ret));
395} else if (OB_FAIL(distribute_by_tenant(it2->first, *(it2->second)))) {
396LOG_WARN("distribute by tenant failed", "tenant_id", it2->first, K(ret));
397}
398}
399
400ObHashMap<uint64_t, share::ObResourcePool*>::const_iterator pool_it =
401unit_mgr_->get_id_pool_map().begin();
402ObHashMap<uint64_t, share::ObResourcePool*>::const_iterator pool_it_end =
403unit_mgr_->get_id_pool_map().end();
404for (; OB_SUCC(ret) && pool_it != pool_it_end; ++pool_it) {
405if (NULL == pool_it->second) {
406ret = OB_ERR_UNEXPECTED;
407LOG_WARN("pool_it->second is null", KP(pool_it->second), K(ret));
408} else if (OB_INVALID_ID != pool_it->second->tenant_id_) {
409// bypass, already distribute in distribute by tenant
410} else if (OB_FAIL(distribute_by_pool(pool_it->second))) {
411LOG_WARN("distribute by pool failed", "pool", *(pool_it->second), K(ret));
412}
413}
414LOG_INFO("finish distribute for server status change", K(ret));
415return ret;
416}
417
418int ObServerBalancer::distribute_by_tenant(const uint64_t tenant_id,
419const ObArray<share::ObResourcePool *> &pools)
420{
421int ret = OB_SUCCESS;
422ObArray<ObUnitManager::ZoneUnit> zone_units;
423
424if (!check_inner_stat()) {
425ret = OB_INNER_STAT_ERROR;
426LOG_WARN("check_inner_stat failed", K_(inited), K(ret));
427} else if (OB_INVALID_ID == tenant_id || pools.count() <= 0) {
428ret = OB_INVALID_ARGUMENT;
429LOG_WARN("invalid argument", K(tenant_id), K(pools), K(ret));
430} else if (OB_FAIL(unit_mgr_->get_zone_units(pools, zone_units))) {
431LOG_WARN("get_units_of_pools failed", K(pools), K(ret));
432} else {
433FOREACH_CNT_X(zone_unit, zone_units, OB_SUCCESS == ret) {
434if (OB_FAIL(distribute_zone_unit(*zone_unit))) {
435LOG_WARN("distribute zone unit failed", "zone_unit", *zone_unit, K(ret));
436}
437}
438}
439return ret;
440}
441
442int ObServerBalancer::distribute_by_pool(share::ObResourcePool *pool)
443{
444int ret = OB_SUCCESS;
445ObArray<share::ObResourcePool *> pools;
446ObArray<ObUnitManager::ZoneUnit> zone_units;
447if (!check_inner_stat()) {
448ret = OB_INNER_STAT_ERROR;
449LOG_WARN("check_inner_stat failed", K_(inited), K(ret));
450} else if (NULL == pool) {
451ret = OB_INVALID_ARGUMENT;
452LOG_WARN("pool is null", K(ret));
453} else if (OB_FAIL(pools.push_back(pool))) {
454LOG_WARN("push_back failed", K(ret));
455} else if (OB_FAIL(unit_mgr_->get_zone_units(pools, zone_units))) {
456LOG_WARN("get_units_of_pools failed", K(pools), K(ret));
457} else {
458FOREACH_CNT_X(zone_unit, zone_units, OB_SUCCESS == ret) {
459if (OB_FAIL(distribute_zone_unit(*zone_unit))) {
460LOG_WARN("distribute zone unit failed", "zone_unit", *zone_unit, K(ret));
461}
462}
463}
464return ret;
465}
466
467int ObServerBalancer::distribute_zone_unit(const ObUnitManager::ZoneUnit &zone_unit)
468{
469int ret = OB_SUCCESS;
470if (!check_inner_stat()) {
471ret = OB_INNER_STAT_ERROR;
472LOG_WARN("check inner stat failed", K_(inited), K(ret));
473} else if (!zone_unit.is_valid()) {
474ret = OB_INVALID_ARGUMENT;
475LOG_WARN("invalid argument", K(zone_unit), K(ret));
476} else {
477ObServerInfoInTable server_info;
478FOREACH_CNT_X(unit_info, zone_unit.unit_infos_, OB_SUCCESS == ret) {
479server_info.reset();
480if (ObUnit::UNIT_STATUS_ACTIVE != unit_info->unit_.status_) {
481// ignore the unit that is in deleting
482} else if (OB_FAIL(SVR_TRACER.get_server_info(unit_info->unit_.server_, server_info))) {
483LOG_WARN("get_server_info failed", "server", unit_info->unit_.server_, KR(ret));
484} else if (server_info.is_active()) {
485if (OB_FAIL(distribute_for_active(server_info, *unit_info))) {
486LOG_WARN("distribute_for_active failed", K(server_info), "unit_info", *unit_info, K(ret));
487}
488} else if (server_info.is_permanent_offline() || server_info.is_deleting()) {
489if (OB_FAIL(distribute_for_permanent_offline_or_delete(server_info, *unit_info))) {
490LOG_WARN("distribute for permanent offline or delete failed",
491K(server_info), "unit_info", *unit_info, KR(ret));
492}
493}
494}
495}
496return ret;
497}
498
499int ObServerBalancer::distribute_for_active(
500const ObServerInfoInTable &server_info,
501const ObUnitInfo &unit_info)
502{
503int ret = OB_SUCCESS;
504if (!check_inner_stat()) {
505ret = OB_INNER_STAT_ERROR;
506LOG_WARN("check inner stat failed", K_(inited), K(ret));
507} else if (!server_info.is_valid()
508|| !server_info.is_active()
509|| !unit_info.is_valid()
510|| unit_info.unit_.server_ != server_info.get_server()) {
511ret = OB_INVALID_ARGUMENT;
512LOG_WARN("invalid argument", K(server_info), K(unit_info), K(ret));
513} else {
514//When the destination is blocked, cancel this migration
515//Temporary offline does not cancel the task, need to wait for permanent offline
516if ((server_info.is_migrate_in_blocked())
517&& unit_info.unit_.migrate_from_server_.is_valid()) {
518LOG_INFO("find unit server active but can't migrate in, "
519"migrate_from_server is set", "unit", unit_info.unit_);
520if (OB_FAIL(distribute_for_migrate_in_blocked(unit_info))) {
521LOG_WARN("distribute for migrate in blocked failed", K(unit_info), K(ret));
522}
523}
524}
525return ret;
526}
527
528//When the migration destination is permanently offline,
529//need to change to another destination
530//Need to make sure that the member has been kicked out after being permanently offline
531int ObServerBalancer::distribute_for_permanent_offline_or_delete(
532const share::ObServerInfoInTable &server_info,
533const ObUnitInfo &unit_info)
534{
535int ret = OB_SUCCESS;
536const char *module = "UNIT_BALANCE_FOR_SERVER_PERMANENT_OFFLINE_OR_DELETE";
537
538LOG_INFO("find unit server permanent offline or delete, need distribute unit",
539K(module), "unit", unit_info.unit_, K(server_info));
540const bool enable_sys_unit_standalone = GCONF.enable_sys_unit_standalone;
541bool need_migrate_unit = false;
542if (!check_inner_stat()) {
543ret = OB_INNER_STAT_ERROR;
544LOG_WARN("check inner stat failed", K_(inited), K(ret));
545} else if (!server_info.is_valid()
546|| !unit_info.is_valid()
547|| unit_info.unit_.server_ != server_info.get_server()
548|| (!server_info.is_deleting() && !server_info.is_permanent_offline())) {
549ret = OB_INVALID_ARGUMENT;
550LOG_WARN("invalid argument", K(server_info), K(unit_info), KR(ret));
551} else if (!unit_info.unit_.migrate_from_server_.is_valid()) {
552//The current unit is in a stable state, move it out
553need_migrate_unit = true;
554LOG_INFO("server is permanent offline or in deleting status, need migrate unit",
555K(unit_info), K(server_info));
556} else {
557//Currently moving in, try to cancel
558bool is_canceled = false;
559if (OB_FAIL(try_cancel_migrate_unit(unit_info.unit_, is_canceled))) {
560LOG_WARN("fail to cancel migrate unit", K(ret), K(unit_info));
561} else if (!is_canceled) {
562//If cancel fails, wait for the result of the check-in process
563//If the move-in process cannot be ended,
564//the delete server lasts for too long, and manual intervention should be required
565// ** FIXME (linqiucen): now we do not do the following commented process due to the deprecated variable with_partition
566// ** FIXME (linqiucen): in the future, we can do this process again by directly looking up the related table
567// if (!status.is_with_partition()) {
568// //If there is no local replica, cancel this migration directly
569// const ObUnitManager::EndMigrateOp op = ObUnitManager::ABORT;
570// if (OB_FAIL(unit_mgr_->end_migrate_unit(unit_info.unit_.unit_id_, op))) {
571// LOG_WARN("end_migrate_unit failed", "unit_id", unit_info.unit_.unit_id_, K(op), K(ret));
572// } else {
573// need_migrate_unit = true;
574// LOG_INFO("unit has no partition, abort the migration",
575// K(ret), K(unit_info), K(op), K(status));
576// }
577// }
578} else {
579LOG_INFO("revert migrate unit success", K(ret), K(unit_info), K(server_info));
580}
581}
582ObUnitStat unit_stat;
583ObArray<ObAddr> excluded_servers;
584const ObZone zone = unit_info.unit_.zone_;
585ObAddr migrate_server;
586std::string resource_not_enough_reason;
587ObArray<ObServerInfoInTable> servers_info_of_zone;
588ObArray<ObServerInfoInTable> active_servers_info_of_zone;
589ObArray<obrpc::ObGetServerResourceInfoResult> active_servers_resource_info_of_zone;
590if (OB_FAIL(ret) || !need_migrate_unit) {
591//nothing todo
592} else if (OB_ISNULL(unit_mgr_)) {
593ret = OB_ERR_UNEXPECTED;
594LOG_WARN("unit_mgr_ is null", KR(ret), KP(unit_mgr_));
595} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
596unit_info.unit_.unit_id_,
597unit_info.unit_.zone_,
598unit_stat))) {
599LOG_WARN("fail to locate unit", K(ret), "unit", unit_info.unit_);
600} else if (OB_FAIL(SVR_TRACER.get_servers_info(unit_info.unit_.zone_, servers_info_of_zone))) {
601LOG_WARN("fail to servers_info_of_zone", KR(ret), K(unit_info.unit_.zone_));
602} else if (OB_FAIL(get_active_servers_info_and_resource_info_of_zone(
603unit_info.unit_.zone_,
604active_servers_info_of_zone,
605active_servers_resource_info_of_zone))) {
606LOG_WARN("fail to execute get_active_servers_info_and_resource_info_of_zone", KR(ret), K(unit_info.unit_.zone_));
607} else if (OB_FAIL(unit_mgr_->get_excluded_servers(
608unit_info.unit_,
609unit_stat,
610module,
611servers_info_of_zone,
612active_servers_resource_info_of_zone,
613excluded_servers))) {
614LOG_WARN("get_excluded_servers failed", "unit", unit_info.unit_, KR(ret), K(servers_info_of_zone),
615K(active_servers_resource_info_of_zone));
616} else if (OB_FAIL(unit_mgr_->choose_server_for_unit(
617unit_info.config_.unit_resource(),
618zone,
619excluded_servers,
620module,
621active_servers_info_of_zone,
622active_servers_resource_info_of_zone,
623migrate_server,
624resource_not_enough_reason))) {
625if (OB_ZONE_RESOURCE_NOT_ENOUGH == ret || OB_ZONE_SERVER_NOT_ENOUGH == ret) {
626LOG_WARN("has no place to migrate unit", K(module), KR(ret), K(zone), K(excluded_servers),
627K(unit_info), "resource_not_enough_reason", resource_not_enough_reason.c_str());
628// return success when resource not enough to go on next balance task
629ret = OB_SUCCESS;
630} else {
631LOG_WARN("choose_unit_server failed", "config", unit_info.config_,
632K(zone), K(excluded_servers), K(ret));
633}
634} else {
635ObArray<ObUnitStat> in_migrate_unit_stat;
636if (OB_FAIL(get_unit_resource_reservation(unit_info.unit_.unit_id_,
637migrate_server,
638in_migrate_unit_stat))) {
639LOG_WARN("get_unit_resource_reservation failed", K(unit_info), K(ret));
640} else if (OB_FAIL(try_migrate_unit(unit_info.unit_.unit_id_,
641unit_info.pool_.tenant_id_,
642unit_stat,
643in_migrate_unit_stat,
644migrate_server))) {
645LOG_WARN("fail to try migrate unit", "unit", unit_info.unit_, K(migrate_server), K(ret));
646} else {
647LOG_INFO("migrate unit success", K(module), K(unit_info), K(server_info), "dest_server", migrate_server);
648}
649}
650return ret;
651}
652
653// NOTE:
654// When the unit migrates from A to B, if B is down or the disk is full,
655// two strategies will be tried in turn
656// 1. A can move in, cancel this migration, and re-migrate the data back to A
657// 2. A cannot move in, then choose a new machine C, and move unit to C
658int ObServerBalancer::distribute_for_migrate_in_blocked(const ObUnitInfo &unit_info)
659{
660int ret = OB_SUCCESS;
661ObServerInfoInTable server_info;
662if (!check_inner_stat()) {
663ret = OB_INNER_STAT_ERROR;
664LOG_WARN("check inner stat failed", K_(inited), K(ret));
665} else if (!unit_info.is_valid() || !unit_info.unit_.migrate_from_server_.is_valid()) {
666ret = OB_INVALID_ARGUMENT;
667LOG_WARN("invalid argument", K(unit_info), K(ret));
668} else if (OB_FAIL(SVR_TRACER.get_server_info(
669unit_info.unit_.migrate_from_server_, server_info))) {
670LOG_WARN("get_server_status failed",
671"server", unit_info.unit_.migrate_from_server_, K(ret));
672} else if (ObUnit::UNIT_STATUS_ACTIVE != unit_info.unit_.status_) {
673// ignore the unit which is in deleting
674} else {
675if (server_info.can_migrate_in()) {
676LOG_INFO("unit migrate_from_server can migrate in, "
677"migrate unit back to migrate_from_server", "unit", unit_info.unit_);
678const ObUnitManager::EndMigrateOp op = ObUnitManager::REVERSE;
679if (OB_FAIL(unit_mgr_->end_migrate_unit(unit_info.unit_.unit_id_, op))) {
680LOG_WARN("end_migrate_unit failed", "unit_id", unit_info.unit_.unit_id_, K(op), K(ret));
681}
682} else {
683//TODO: @wanhong.wwh need support when dest server is blocked and src server can not migrate in
684//nothing todo
685LOG_WARN("NOTICE: unit migration is hung. dest server is blocked "
686"and source server can not migrate in. NEED to be involved manually.",
687"unit", unit_info.unit_, "migrate_from_server", server_info);
688}
689
690/*
691{
692LOG_INFO("unit migrate_from_server can not migrate in, and unit_server is empty now"
693"migrate unit to new server", "unit", unit_info.unit_);
694ObAddr new_server;
695ObArray<ObAddr> excluded_servers;
696ObUnitStat unit_stat;
697ObArray<ObUnitStat> in_migrate_unit_stat;
698ObUnitManager::EndMigrateOp op = ObUnitManager::ABORT;
699if (OB_FAIL(unit_mgr_->end_migrate_unit(unit_info.unit_.unit_id_, op))) {
700LOG_WARN("fail to end migrate unit", K(ret), "unit", unit_info.unit_);
701} else if (OB_FAIL(unit_stat_mgr_->get_unit_stat(
702unit_info.unit_.unit_id_, unit_info.unit_.zone_, unit_stat))) {
703LOG_WARN("fail to locate unit", K(ret), "unit", unit_info.unit_);
704} else if (OB_FAIL(unit_mgr_->get_excluded_servers(unit_info.unit_, unit_stat, excluded_servers))) {
705LOG_WARN("get_excluded_servers failed", "unit", unit_info.unit_, K(ret));
706} else if (OB_FAIL(unit_mgr_->choose_server_for_unit(unit_info.config_, unit_info.unit_.zone_,
707excluded_servers, new_server))) {
708LOG_WARN("choose_unit_server failed", "config", unit_info.config_,
709"zone", unit_info.unit_.zone_, K(excluded_servers), K(ret));
710} else if (OB_FAIL(get_unit_resource_reservation(unit_info.unit_.unit_id_,
711new_server,
712in_migrate_unit_stat))) {
713LOG_WARN("get_unit_resource_reservation failed", K(unit_info), K(ret));
714} else if (OB_FAIL(try_migrate_unit(unit_info.unit_.unit_id_,
715unit_info.pool_.tenant_id_,
716unit_stat,
717in_migrate_unit_stat,
718new_server))) {
719LOG_WARN("fail to try migrate unit ", "unit", unit_info.unit_, K(new_server), K(ret));
720}
721}
722*/
723}
724return ret;
725}
726
727int ObServerBalancer::get_unit_resource_reservation(uint64_t unit_id,
728const ObAddr &new_server,
729ObIArray<ObUnitStat> &in_migrate_unit_stat)
730{
731int ret = OB_SUCCESS;
732UNUSED(unit_id);
733ObArray<ObUnitManager::ObUnitLoad> *unit_loads = NULL;
734if (!inited_) {
735ret = OB_NOT_INIT;
736LOG_WARN("server balancer not init", K_(inited), K(ret));
737} else {
738if (OB_FAIL(unit_mgr_->get_loads_by_server(new_server, unit_loads))) {
739if (OB_ENTRY_NOT_EXIST != ret) {
740LOG_WARN("fail to get loads by server", K(ret));
741} else {
742ret = OB_SUCCESS;
743}
744} else if (NULL == unit_loads) {
745ret = OB_ERR_UNEXPECTED;
746LOG_WARN("unit loads ptr is null", K(ret));
747} else {
748// Statistics of the units that are being migrated to the new server
749for (int64_t i = 0; OB_SUCC(ret) && i < unit_loads->count(); ++i) {
750ObUnitStat in_mig_stat;
751const ObUnitManager::ObUnitLoad &load = unit_loads->at(i);
752if (!load.is_valid()) {
753ret = OB_ERR_UNEXPECTED;
754LOG_WARN("unit load is invalid", K(ret), K(load));
755} else if (new_server == load.unit_->migrate_from_server_) {
756// by pass
757} else if (!load.unit_->migrate_from_server_.is_valid()) {
758// by pass
759} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
760load.unit_->unit_id_, load.unit_->zone_, in_mig_stat))) {
761LOG_WARN("get unit stat fail", "unit_id", load.unit_->unit_id_, K(ret));
762} else if (OB_FAIL(in_migrate_unit_stat.push_back(in_mig_stat))) {
763LOG_WARN("push back fail", K(in_mig_stat), K(ret));
764}
765}
766}
767}
768return ret;
769}
770
771int ObServerBalancer::try_migrate_unit(const uint64_t unit_id,
772const uint64_t tenant_id,
773const ObUnitStat &unit_stat,
774const ObIArray<ObUnitStat> &migrating_unit_stat,
775const ObAddr &dst)
776{
777int ret = OB_SUCCESS;
778ObServerResourceInfo dst_resource_info;
779if (!inited_) {
780ret = OB_NOT_INIT;
781LOG_WARN("server balancer not init", K_(inited), K(ret));
782} else if (OB_ISNULL(server_mgr_)) {
783ret = OB_ERR_UNEXPECTED;
784LOG_WARN("server_mgr_ is null", KR(ret), KP(server_mgr_));
785} else if (OB_FAIL(server_mgr_->get_server_resource_info(dst, dst_resource_info))) {
786LOG_WARN("fail to get dst_resource_info", KR(ret), K(dst));
787} else {
788ret = unit_mgr_->try_migrate_unit(
789unit_id,
790tenant_id,
791unit_stat,
792migrating_unit_stat,
793dst,
794dst_resource_info);
795}
796return ret;
797}
798
799int ObServerBalancer::try_cancel_migrate_unit(const share::ObUnit &unit, bool &is_canceled)
800{
801int ret = OB_SUCCESS;
802if (!inited_) {
803ret = OB_NOT_INIT;
804LOG_WARN("server balancer not init", K_(inited), K(ret));
805} else {
806ret = unit_mgr_->try_cancel_migrate_unit(unit, is_canceled);
807}
808return ret;
809}
810
811const double ObServerBalancer::CPU_EPSILON = 0.0001;
812const double ObServerBalancer::EPSILON = 0.0000000001;
813
814// the new version server balance
815int ObServerBalancer::UnitMigrateStatCmp::get_ret() const
816{
817return ret_;
818}
819
820bool ObServerBalancer::UnitMigrateStatCmp::operator()(
821const UnitMigrateStat &left,
822const UnitMigrateStat &right)
823{
824bool bool_ret = false;
825if (OB_SUCCESS != ret_) {
826// do nothing
827} else if (left.arranged_pos_ < right.arranged_pos_) {
828bool_ret = true;
829} else if (right.arranged_pos_ < left.arranged_pos_) {
830bool_ret = false;
831} else {
832ret_ = OB_ERR_UNEXPECTED;
833}
834return bool_ret;
835}
836
837int ObServerBalancer::check_can_execute_rebalance(
838const common::ObZone &zone,
839bool &can_execute_rebalance)
840{
841int ret = OB_SUCCESS;
842HEAP_VAR(share::ObZoneInfo, zone_info) {
843common::ObArray<common::ObAddr> server_list;
844common::ObArray<uint64_t> unit_ids;
845if (OB_UNLIKELY(!inited_)) {
846ret = OB_NOT_INIT;
847LOG_WARN("not init", K(ret));
848} else if (OB_UNLIKELY(zone.is_empty())) {
849ret = OB_INVALID_ARGUMENT;
850LOG_WARN("invalid argument", K(ret), K(zone));
851} else if (OB_ISNULL(unit_mgr_) || OB_ISNULL(zone_mgr_) || OB_ISNULL(server_mgr_)) {
852ret = OB_ERR_UNEXPECTED;
853LOG_WARN("unit_mgr_, zone_mgr_ or server_mgr_ is null", KR(ret), KP(unit_mgr_), KP(zone_mgr_), KP(server_mgr_));
854} else if (OB_FAIL(zone_mgr_->get_zone(zone, zone_info))) {
855LOG_WARN("fail to get zone info", K(ret), K(zone));
856} else if (ObZoneStatus::ACTIVE != zone_info.status_) {
857can_execute_rebalance = false;
858LOG_INFO("cannot execute server rebalance: zone inactive", K(zone));
859} else if (OB_FAIL(SVR_TRACER.get_servers_of_zone(zone, server_list))) {
860LOG_WARN("fail to get servers of zone", K(ret), K(zone));
861} else if (OB_FAIL(unit_mgr_->inner_get_unit_ids(unit_ids))) {
862LOG_WARN("fail to get unit ids", K(ret));
863} else {
864can_execute_rebalance = true;
865share::ObUnitConfig sum_load;
866for (int64_t i = 0; can_execute_rebalance && OB_SUCC(ret) && i < server_list.count(); ++i) {
867const common::ObAddr &server = server_list.at(i);
868ObServerInfoInTable server_info;
869ObServerResourceInfo resource_info;
870ObArray<ObUnitManager::ObUnitLoad> *unit_loads = nullptr;
871sum_load.reset();
872if (OB_FAIL(unit_mgr_->get_loads_by_server(server, unit_loads))) {
873if (OB_ENTRY_NOT_EXIST != ret) {
874LOG_WARN("fail to get loads by server", K(ret));
875} else {
876ret = OB_SUCCESS; // unit_loads not exist, no load no this server
877}
878} else if (OB_UNLIKELY(nullptr == unit_loads)) {
879ret = OB_ERR_UNEXPECTED;
880LOG_WARN("unit loads ptr is null", K(ret));
881} else if (OB_FAIL(unit_mgr_->calc_sum_load(unit_loads, sum_load))) {
882LOG_WARN("fail to calc sum load", K(ret));
883}
884if (OB_FAIL(ret)) {
885// failed
886} else if (OB_FAIL(SVR_TRACER.get_server_info(server, server_info))) {
887LOG_WARN("fail to get server status", K(ret));
888} else if (server_info.is_temporary_offline() || server_info.is_stopped()) {
889can_execute_rebalance = false;
890LOG_INFO("cannot execute server rebalance: Server status is not normal", K(zone), K(server_info));
891} else if (OB_FAIL(server_mgr_->get_server_resource_info(server_info.get_server(), resource_info))) {
892LOG_WARN("fail to execute get_server_resource_info", KR(ret), K(server_info.get_server()));
893} else if (fabs(resource_info.report_cpu_assigned_ - sum_load.min_cpu()) > CPU_EPSILON
894|| fabs(resource_info.report_cpu_max_assigned_ - sum_load.max_cpu()) > CPU_EPSILON
895|| resource_info.report_mem_assigned_ != sum_load.memory_size()) {
896can_execute_rebalance = false;
897LOG_INFO("cannot execute server rebalance: "
898"Server resource_info and unit_manager sum_load not equal", K(zone), K(resource_info), K(sum_load));
899} else {} // no more to do
900}
901for (int64_t j = 0; can_execute_rebalance && OB_SUCC(ret) && j < unit_ids.count(); ++j) {
902ObUnit *unit = NULL;
903if (OB_FAIL(unit_mgr_->get_unit_by_id(unit_ids.at(j), unit))) {
904ret = OB_INVALID_ARGUMENT;
905LOG_WARN("unit_load is invalid", K(ret));
906} else if (NULL == unit) {
907ret = OB_ERR_UNEXPECTED;
908LOG_WARN("unit ptr is null", K(ret), KP(unit));
909} else if (ObUnit::UNIT_STATUS_DELETING == unit->status_) {
910can_execute_rebalance = false;
911LOG_INFO("cannot execute server rebalance: unit deleting", K(zone), "unit", *unit);
912} else if (unit->migrate_from_server_.is_valid()) {
913can_execute_rebalance = false;
914LOG_INFO("cannot execute server rebalance: unit migrating", K(zone), "unit", *unit);
915} else {} // unit in stable status
916}
917}
918}
919return ret;
920}
921
922int ObServerBalancer::rebalance_servers_v2(
923const common::ObZone &zone)
924{
925int ret = OB_SUCCESS;
926common::ObArray<Matrix<uint64_t> > group_tenant_array;
927common::ObArray<uint64_t> standalone_tenant_array;
928common::ObArray<ObUnitManager::ObUnitLoad> not_grant_units;
929common::ObArray<ObUnitManager::ObUnitLoad> standalone_units;
930LOG_INFO("start to do tenant group unit balance", K(zone));
931if (OB_UNLIKELY(!inited_)) {
932ret = OB_NOT_INIT;
933LOG_WARN("not init", K(ret));
934} else if (OB_FAIL(generate_zone_server_disk_statistic(zone))) {
935LOG_WARN("fail to generate zone server disk statistic", K(ret), K(zone));
936} else if (OB_FAIL(generate_tenant_array(zone, group_tenant_array, standalone_tenant_array))) {
937LOG_WARN("fail to generate tenant array", K(ret));
938} else if (OB_FAIL(generate_standalone_units(zone, standalone_tenant_array, standalone_units))) {
939LOG_WARN("fail to generate standalone units", K(ret), K(zone));
940} else if (OB_FAIL(generate_not_grant_pool_units(zone, not_grant_units))) {
941LOG_WARN("fail to generate not grant pool units", K(ret), K(zone));
942} else if (OB_FAIL(do_rebalance_servers_v2(
943zone, group_tenant_array, standalone_units, not_grant_units))) {
944LOG_WARN("fail to rebalance servers", K(ret), K(zone));
945} else {} // no more to do
946return ret;
947}
948
949int ObServerBalancer::generate_single_tenant_group(
950Matrix<uint64_t> &tenant_id_matrix,
951const ObTenantGroupParser::TenantNameGroup &tenant_name_group)
952{
953int ret = OB_SUCCESS;
954share::schema::ObSchemaGetterGuard schema_guard;
955if (OB_UNLIKELY(!inited_)) {
956ret = OB_NOT_INIT;
957LOG_WARN("not init", K(ret));
958} else if (OB_UNLIKELY(tenant_name_group.row_ <= 0 || tenant_name_group.column_ <= 0)) {
959ret = OB_INVALID_ARGUMENT;
960LOG_WARN("invalid argument", K(ret), K(tenant_name_group));
961} else if (OB_UNLIKELY(NULL == schema_service_)) {
962ret = OB_ERR_UNEXPECTED;
963LOG_WARN("schema service ptr is null", K(ret), KP(schema_service_));
964} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
965ret = OB_ERR_UNEXPECTED;
966LOG_WARN("unit_mgr_ ptr is null", K(ret), KP(unit_mgr_));
967} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
968LOG_WARN("fail to get schema guard", K(ret));
969} else if (OB_FAIL(tenant_id_matrix.init(tenant_name_group.row_, tenant_name_group.column_))) {
970LOG_WARN("fail to init tenant id matrix", K(ret));
971} else {
972for (int64_t row = 0; OB_SUCC(ret) && row < tenant_name_group.row_; ++row) {
973for (int64_t column = 0; OB_SUCC(ret) && column < tenant_name_group.column_; ++column) {
974const int64_t idx = row * tenant_name_group.column_ + column;
975const share::schema::ObTenantSchema *tenant_schema = NULL;
976if (idx >= tenant_name_group.tenants_.count()) {
977ret = OB_ERR_UNEXPECTED;
978LOG_WARN("idx value unexpected", K(ret), K(idx),
979"tenants_count", tenant_name_group.tenants_.count());
980} else if (OB_FAIL(schema_guard.get_tenant_info(
981tenant_name_group.tenants_.at(idx), tenant_schema))) {
982LOG_WARN("fail to get tenant info", K(ret),
983"tenant_name", tenant_name_group.tenants_.at(idx));
984} else if (OB_UNLIKELY(NULL == tenant_schema)) {
985ret = OB_TENANT_NOT_EXIST;
986LOG_WARN("tenant schema ptr is null", K(ret), KP(tenant_schema));
987} else if (OB_UNLIKELY(OB_SYS_TENANT_ID == tenant_schema->get_tenant_id())) {
988ret = OB_ERR_UNEXPECTED;
989LOG_ERROR("sys tenant cannot be configured in tenant groups", K(ret));
990} else if (OB_FAIL(tenant_id_matrix.set(row, column, tenant_schema->get_tenant_id()))) {
991LOG_WARN("fail to set tenant id matrix", K(ret), K(row), K(column),
992"tenant_id", tenant_schema->get_tenant_id());
993} else {} // next matrix cell
994}
995}
996}
997return ret;
998}
999
1000int ObServerBalancer::generate_group_tenant_array(
1001const common::ObIArray<ObTenantGroupParser::TenantNameGroup> &tenant_groups,
1002common::ObIArray<Matrix<uint64_t> > &group_tenant_array)
1003{
1004int ret = OB_SUCCESS;
1005if (OB_UNLIKELY(!inited_)) {
1006ret = OB_NOT_INIT;
1007LOG_WARN("not init", K(ret));
1008} else {
1009group_tenant_array.reset();
1010for (int64_t i = 0; OB_SUCC(ret) && i < tenant_groups.count(); ++i) {
1011Matrix<uint64_t> tenant_id_matrix;
1012const ObTenantGroupParser::TenantNameGroup &tenant_name_group = tenant_groups.at(i);
1013if (OB_FAIL(generate_single_tenant_group(tenant_id_matrix, tenant_name_group))) {
1014LOG_WARN("fail to generate single tenant group", K(ret));
1015} else if (OB_FAIL(group_tenant_array.push_back(tenant_id_matrix))) {
1016LOG_WARN("fail to push back", K(ret));
1017} else {} // go on next
1018}
1019}
1020return ret;
1021}
1022
1023bool ObServerBalancer::has_exist_in_group_tenant_array(
1024const uint64_t tenant_id,
1025const common::ObIArray<Matrix<uint64_t> > &group_tenant_array)
1026{
1027bool exist = false;
1028for (int64_t i = 0; !exist && i < group_tenant_array.count(); ++i) {
1029const Matrix<uint64_t> &tenant_group = group_tenant_array.at(i);
1030if (tenant_group.is_contain(tenant_id)) {
1031exist = true;
1032} else {} // not contain, go on next
1033}
1034return exist;
1035}
1036
1037int ObServerBalancer::generate_standalone_tenant_array(
1038const common::ObIArray<Matrix<uint64_t> > &group_tenant_array,
1039common::ObIArray<uint64_t> &standalone_tenant_array)
1040{
1041int ret = OB_SUCCESS;
1042share::schema::ObSchemaGetterGuard schema_guard;
1043common::ObArray<uint64_t> tenant_ids;
1044if (OB_UNLIKELY(!inited_)) {
1045ret = OB_NOT_INIT;
1046LOG_WARN("not init", K(ret));
1047} else if (OB_UNLIKELY(NULL == schema_service_)) {
1048ret = OB_ERR_UNEXPECTED;
1049LOG_WARN("schema_service_ ptr is null", K(ret));
1050} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
1051LOG_WARN("fail to get schema guard", K(ret));
1052} else if (OB_FAIL(schema_guard.get_tenant_ids(tenant_ids))) {
1053LOG_WARN("fail to get tenant ids", K(ret));
1054} else {
1055standalone_tenant_array.reset();
1056for (int64_t i = 0; OB_SUCC(ret) && i < tenant_ids.count(); ++i) {
1057if (common::OB_SYS_TENANT_ID == tenant_ids.at(i)) {
1058// System tenant unit scheduling special processing,
1059// does not belong to any tenant group, nor is it standalone
1060} else if (has_exist_in_group_tenant_array(tenant_ids.at(i), group_tenant_array)) {
1061// Included in a tenant group, not standalone
1062} else if (OB_FAIL(standalone_tenant_array.push_back(tenant_ids.at(i)))) {
1063LOG_WARN("fail to push back", K(ret));
1064} else {} // next tenant id
1065}
1066}
1067return ret;
1068}
1069
1070int ObServerBalancer::generate_tenant_array(
1071const common::ObZone &zone,
1072common::ObIArray<Matrix<uint64_t> > &group_tenant_array,
1073common::ObIArray<uint64_t> &standalone_tenant_array)
1074{
1075int ret = OB_SUCCESS;
1076if (OB_UNLIKELY(!inited_)) {
1077ret = OB_NOT_INIT;
1078LOG_WARN("not init", K(ret));
1079} else if (OB_FAIL(generate_standalone_tenant_array(
1080group_tenant_array, standalone_tenant_array))) {
1081LOG_WARN("fail to generate standalone tenant array", K(ret));
1082} else {} // no more to do
1083LOG_INFO("generate tenant array finish", K(ret), K(zone),
1084K(standalone_tenant_array), K(group_tenant_array));
1085return ret;
1086}
1087
1088int ObServerBalancer::fill_pool_units_in_zone(
1089const common::ObZone &zone,
1090share::ObResourcePool &pool,
1091common::ObIArray<ObUnitManager::ObUnitLoad> &unit_loads)
1092{
1093int ret = OB_SUCCESS;
1094if (OB_UNLIKELY(!inited_)) {
1095ret = OB_NOT_INIT;
1096LOG_WARN("not init", K(ret));
1097} else if (OB_UNLIKELY(zone.is_empty())) {
1098ret = OB_INVALID_ARGUMENT;
1099LOG_WARN("invalid argument", K(ret), K(zone));
1100} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
1101ret = OB_ERR_UNEXPECTED;
1102LOG_WARN("unit_mgr_ ptr is null", K(ret));
1103} else {
1104ObArray<ObUnit *> *units = NULL;
1105ObUnitConfig *unit_config = NULL;
1106if (!has_exist_in_array(pool.zone_list_, zone)) {
1107// do not exist in pool zone list
1108} else if (OB_FAIL(unit_mgr_->get_units_by_pool(pool.resource_pool_id_, units))) {
1109LOG_WARN("fail to get units by pool", K(ret));
1110} else if (OB_UNLIKELY(NULL == units)) {
1111ret = OB_ERR_UNEXPECTED;
1112LOG_WARN("units ptr is null", K(ret), KP(units));
1113} else if (OB_FAIL(unit_mgr_->get_unit_config_by_id(pool.unit_config_id_, unit_config))) {
1114LOG_WARN("fail to get unit config by id", K(ret), "config_id", pool.unit_config_id_);
1115} else if (OB_UNLIKELY(NULL == unit_config)) {
1116ret = OB_ERR_UNEXPECTED;
1117LOG_WARN("unit_config ptr is null", K(ret));
1118} else {
1119for (int64_t j = 0; OB_SUCC(ret) && j < units->count(); ++j) {
1120ObUnitManager::ObUnitLoad unit_load;
1121unit_load.unit_ = units->at(j);
1122unit_load.unit_config_ = unit_config;
1123unit_load.pool_ = &pool;
1124if (NULL == units->at(j)) {
1125ret = OB_ERR_UNEXPECTED;
1126LOG_WARN("unit ptr is null", K(ret));
1127} else if (zone != units->at(j)->zone_) {
1128// do not belong to this zone
1129} else if (OB_FAIL(unit_loads.push_back(unit_load))) {
1130LOG_WARN("fail to push back", K(ret));
1131} else {} // no more to do
1132}
1133}
1134}
1135return ret;
1136}
1137
1138int ObServerBalancer::generate_not_grant_pool_units(
1139const common::ObZone &zone,
1140common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units)
1141{
1142int ret = OB_SUCCESS;
1143if (OB_UNLIKELY(!inited_)) {
1144ret = OB_NOT_INIT;
1145LOG_WARN("not init", K(ret));
1146} else if (OB_UNLIKELY(zone.is_empty())) {
1147ret = OB_INVALID_ARGUMENT;
1148LOG_WARN("invalid argument", K(ret), K(zone));
1149} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
1150ret = OB_ERR_UNEXPECTED;
1151LOG_WARN("unit_mgr_ ptr is null", K(ret));
1152} else {
1153not_grant_units.reset();
1154ObHashMap<uint64_t, share::ObResourcePool *>::const_iterator iter;
1155for (iter = unit_mgr_->id_pool_map_.begin();
1156OB_SUCC(ret) && iter != unit_mgr_->id_pool_map_.end();
1157++iter) {
1158share::ObResourcePool *pool = iter->second;
1159if (NULL == pool) {
1160ret = OB_ERR_UNEXPECTED;
1161LOG_WARN("pool is null", KP(pool), K(ret));
1162} else if (OB_INVALID_ID != pool->tenant_id_) {
1163// already grant to some tenant
1164} else if (OB_FAIL(fill_pool_units_in_zone(zone, *pool, not_grant_units))) {
1165LOG_WARN("fail to fill pool units in zone", K(ret));
1166} else {} // no more to do
1167}
1168}
1169return ret;
1170}
1171
1172int ObServerBalancer::generate_standalone_units(
1173const common::ObZone &zone,
1174const common::ObIArray<uint64_t> &standalone_tenant_array,
1175common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units)
1176{
1177int ret = OB_SUCCESS;
1178if (OB_UNLIKELY(!inited_)) {
1179ret = OB_NOT_INIT;
1180LOG_WARN("not init", K(ret));
1181} else if (OB_UNLIKELY(zone.is_empty())) {
1182ret = OB_INVALID_ARGUMENT;
1183LOG_WARN("invalid argument", K(ret), K(zone));
1184} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
1185ret = OB_ERR_UNEXPECTED;
1186LOG_WARN("unit_mgr_ ptr is null", K(ret));
1187} else {
1188standalone_units.reset();
1189for (int64_t i = 0; OB_SUCC(ret) && i < standalone_tenant_array.count(); ++i) {
1190common::ObArray<share::ObResourcePool *> *pools = NULL;
1191const uint64_t tenant_id = standalone_tenant_array.at(i);
1192if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) {
1193ret = OB_ERR_UNEXPECTED;
1194LOG_WARN("tenant id unexpected", K(ret), K(tenant_id));
1195} else if (is_meta_tenant(tenant_id)) {
1196// meta tenant has no unit, do not handle
1197} else if (OB_FAIL(unit_mgr_->get_pools_by_tenant_(tenant_id, pools))) {
1198LOG_WARN("fail to get pools by tenant", K(ret), K(tenant_id));
1199} else if (OB_UNLIKELY(NULL == pools)) {
1200ret = OB_ERR_UNEXPECTED;
1201LOG_WARN("pools ptr is null", K(ret));
1202} else {
1203for (int64_t j = 0; OB_SUCC(ret) && j < pools->count(); ++j) {
1204share::ObResourcePool *pool = pools->at(j);
1205if (NULL == pool) {
1206ret = OB_ERR_UNEXPECTED;
1207LOG_WARN("pool is null", K(ret), KP(pool));
1208} else if (OB_FAIL(fill_pool_units_in_zone(zone, *pool, standalone_units))) {
1209LOG_WARN("fail to fill pool units in zone", K(ret));
1210} else {} // no more to do
1211}
1212}
1213}
1214}
1215return ret;
1216}
1217
1218int ObServerBalancer::generate_available_servers(
1219const common::ObZone &zone,
1220const bool excluded_sys_unit_server,
1221common::ObIArray<common::ObAddr> &available_servers)
1222{
1223int ret = OB_SUCCESS;
1224HEAP_VAR(share::ObZoneInfo, zone_info) {
1225common::ObArray<common::ObAddr> server_list;
1226ObArray<ObAddr> sys_unit_server_array;
1227if (OB_UNLIKELY(!inited_)) {
1228ret = OB_NOT_INIT;
1229LOG_WARN("not init", K(ret));
1230} else if (OB_UNLIKELY(zone.is_empty())) {
1231ret = OB_INVALID_ARGUMENT;
1232LOG_WARN("invalid argument", K(ret), K(zone));
1233} else if (OB_ISNULL(zone_mgr_) || OB_ISNULL(unit_mgr_)) {
1234ret = OB_ERR_UNEXPECTED;
1235LOG_WARN("zone_mgr_ or unit_mgr_ is null", K(ret), KP(unit_mgr_), KP(zone_mgr_));
1236} else if (OB_FAIL(zone_mgr_->get_zone(zone, zone_info))) {
1237LOG_WARN("fail to get zone info", K(ret), K(zone));
1238} else if (ObZoneStatus::ACTIVE != zone_info.status_) {
1239ret = OB_STATE_NOT_MATCH;
1240LOG_WARN("zone is not in active", K(ret), K(zone_info));
1241} else if (OB_FAIL(SVR_TRACER.get_servers_of_zone(zone, server_list))) {
1242LOG_WARN("fail to get servers of zone", K(ret), K(zone));
1243} else if (OB_FAIL(unit_mgr_->get_tenant_unit_servers(
1244OB_SYS_TENANT_ID, zone, sys_unit_server_array))) {
1245LOG_WARN("fail to get tenant unit server array", K(ret));
1246} else {
1247available_servers.reset();
1248for (int64_t i = 0; OB_SUCC(ret) && i < server_list.count(); ++i) {
1249share::ObServerInfoInTable server_info;
1250if (OB_FAIL(SVR_TRACER.get_server_info(server_list.at(i), server_info))) {
1251LOG_WARN("fail to get server status", K(ret));
1252} else if (server_info.is_temporary_offline() || server_info.is_stopped()) {
1253ret = OB_STATE_NOT_MATCH;
1254LOG_WARN("server in zone is not stable, stop balance servers", K(ret), K(server_info),
1255"is_temporary_offline", server_info.is_temporary_offline(),
1256"is_stopped", server_info.is_stopped());
1257} else if (excluded_sys_unit_server
1258&& has_exist_in_array(sys_unit_server_array, server_list.at(i))) {
1259// bypass
1260} else if (server_info.is_active()) {
1261if (OB_FAIL(available_servers.push_back(server_list.at(i)))) {
1262LOG_WARN("fail to push back", K(ret));
1263}
1264} else {}
1265// Permanently offline and deleting servers are not available servers
1266}
1267}
1268LOG_INFO("generate available servers finish", K(ret), K(zone), K(available_servers));
1269}
1270return ret;
1271}
1272
1273int ObServerBalancer::check_need_balance_sys_tenant_units(
1274const common::ObIArray<ObUnitManager::ObUnitLoad> &sys_tenant_units,
1275const common::ObIArray<common::ObAddr> &available_servers,
1276bool &need_balance)
1277{
1278int ret = OB_SUCCESS;
1279need_balance = false;
1280for (int64_t i = 0; OB_SUCC(ret) && !need_balance && i < sys_tenant_units.count(); ++i) {
1281const ObUnitManager::ObUnitLoad &unit_load = sys_tenant_units.at(i);
1282if (!unit_load.is_valid()) {
1283ret = OB_ERR_UNEXPECTED;
1284LOG_WARN("unit load invalid", K(ret), K(unit_load));
1285} else if (!has_exist_in_array(available_servers, unit_load.unit_->server_)) {
1286need_balance = true;
1287LOG_INFO("need to execute sys tenant units balance", "unit", *unit_load.unit_);
1288} else {} // go on to check next
1289}
1290return ret;
1291}
1292
1293int ObServerBalancer::pick_server_load(
1294const common::ObAddr &server,
1295ObIArray<ServerTotalLoad *> &server_load_ptrs_sorted,
1296ServerTotalLoad *&target_ptr)
1297{
1298int ret = OB_SUCCESS;
1299if (OB_UNLIKELY(!inited_)) {
1300ret = OB_NOT_INIT;
1301LOG_WARN("not init", K(ret));
1302} else if (OB_UNLIKELY(!server.is_valid())) {
1303ret = OB_INVALID_ARGUMENT;
1304LOG_WARN("invalid argument", K(ret), K(server));
1305} else {
1306bool find = false;
1307for (int64_t i = 0; !find && i < server_load_ptrs_sorted.count() && OB_SUCC(ret); ++i) {
1308ServerTotalLoad *ptr = server_load_ptrs_sorted.at(i);
1309if (NULL == ptr) {
1310ret = OB_ERR_UNEXPECTED;
1311LOG_WARN("ptr is null", K(ret));
1312} else if (server != ptr->server_) {
1313// go on to check next
1314} else {
1315target_ptr = ptr;
1316find = true;
1317}
1318}
1319if (OB_FAIL(ret)) {
1320} else if (!find) {
1321ret = OB_ENTRY_NOT_EXIST;
1322LOG_WARN("server load not found", K(ret), K(server));
1323}
1324}
1325return ret;
1326}
1327
1328int ObServerBalancer::try_balance_single_unit_by_disk(
1329const ObUnitManager::ObUnitLoad &unit_load,
1330common::ObArray<ServerTotalLoad *> &server_load_ptrs_sorted,
1331common::ObIArray<UnitMigrateStat> &task_array,
1332const common::ObIArray<common::ObAddr> &excluded_servers,
1333common::ObIArray<PoolOccupation> &pool_occupation,
1334bool &do_balance)
1335{
1336int ret = OB_SUCCESS;
1337ObUnitStat unit_stat;
1338if (OB_UNLIKELY(!inited_)) {
1339ret = OB_NOT_INIT;
1340LOG_WARN("not init", K(ret));
1341} else if (OB_UNLIKELY(!unit_load.is_valid())) {
1342ret = OB_INVALID_ARGUMENT;
1343LOG_WARN("invalid unit load", K(ret), K(unit_load));
1344} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
1345unit_load.unit_->unit_id_,
1346unit_load.unit_->zone_,
1347unit_stat))) {
1348LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load.unit_);
1349} else {
1350do_balance = false;
1351for (int64_t i = 0;
1352!do_balance
1353&& OB_SUCC(ret)
1354&& i < zone_disk_statistic_.server_disk_statistic_array_.count();
1355++i) {
1356ServerTotalLoad *server_load = NULL;
1357ServerDiskStatistic &server_disk_statistic
1358= zone_disk_statistic_.server_disk_statistic_array_.at(i);
1359if (server_disk_statistic.wild_server_) {
1360// Can't move unit to wild server
1361} else if (unit_load.unit_->server_ == server_disk_statistic.server_) {
1362// Can't move to oneself
1363} else if (has_exist_in_array(excluded_servers, server_disk_statistic.server_)) {
1364// In the excluded server, it cannot be used as the target machine
1365} else if (OB_FAIL(pick_server_load(
1366server_disk_statistic.server_, server_load_ptrs_sorted, server_load))) {
1367LOG_WARN("fail to pick server load", K(ret));
1368} else if (NULL == server_load) {
1369ret = OB_ERR_UNEXPECTED;
1370LOG_WARN("server load ptr is null", K(ret), KP(server_load));
1371} else {
1372LoadSum this_load;
1373bool enough = true;
1374const bool mind_disk_waterlevel = false;
1375UnitMigrateStat unit_migrate_stat;
1376unit_migrate_stat.original_pos_ = unit_load.unit_->server_;
1377unit_migrate_stat.arranged_pos_ = server_load->server_;
1378unit_migrate_stat.unit_load_ = unit_load;
1379if (OB_FAIL(this_load.append_load(unit_load))) {
1380LOG_WARN("fail to append load", K(ret));
1381} else if (OB_FAIL(check_single_server_resource_enough(
1382this_load, unit_stat, *server_load, enough, mind_disk_waterlevel))) {
1383LOG_WARN("fail to check single server resource enough", K(ret));
1384} else if (!enough) {
1385// no enough
1386} else if (OB_FAIL(do_update_dst_server_load(
1387unit_load, *server_load, unit_stat, pool_occupation))) {
1388LOG_WARN("fail to append migrate unit task", K(ret));
1389} else if (OB_FAIL(task_array.push_back(unit_migrate_stat))) {
1390LOG_WARN("fail to push back", K(ret));
1391} else {
1392ServerTotalLoadCmp cmp;
1393std::sort(server_load_ptrs_sorted.begin(), server_load_ptrs_sorted.end(), cmp);
1394if (OB_FAIL(cmp.get_ret())) {
1395LOG_WARN("fail to sort server loads", K(ret));
1396}
1397do_balance = true;
1398}
1399}
1400}
1401}
1402return ret;
1403}
1404
1405int ObServerBalancer::do_update_src_server_load(
1406const ObUnitManager::ObUnitLoad &unit_load,
1407ServerTotalLoad &this_server_load,
1408const share::ObUnitStat &unit_stat)
1409{
1410int ret = OB_SUCCESS;
1411share::ObUnit *unit = NULL;
1412share::ObUnitStat my_unit_stat = unit_stat;
1413if (OB_UNLIKELY(!inited_)) {
1414ret = OB_NOT_INIT;
1415LOG_WARN("not init", K(ret));
1416} else if (OB_UNLIKELY(!unit_load.is_valid())) {
1417ret = OB_INVALID_ARGUMENT;
1418LOG_WARN("invalid unit load", K(ret));
1419} else if (OB_FAIL(unit_mgr_->get_unit_by_id(unit_stat.get_unit_id(), unit))) {
1420LOG_WARN("fail to get unit by id", K(ret), "unit_id", unit_stat.get_unit_id());
1421} else if (OB_UNLIKELY(NULL == unit)) {
1422ret = OB_ERR_UNEXPECTED;
1423LOG_WARN("unit ptr is null", K(ret));
1424} else if (common::REPLICA_TYPE_LOGONLY == unit->replica_type_) {
1425ret = OB_ERR_UNEXPECTED;
1426LOG_WARN("Replica type LOGONLY is unexpected", KR(ret), KP(unit));
1427}
1428if (OB_FAIL(ret)) {
1429} else if (OB_FAIL(zone_disk_statistic_.reduce_server_disk_use(
1430this_server_load.server_, my_unit_stat.get_required_size()))) {
1431LOG_WARN("fail to reduce server disk use", K(ret));
1432} else if (OB_FAIL(this_server_load.load_sum_.remove_load(unit_load))) {
1433LOG_WARN("fail to remove load", K(ret));
1434} else if (OB_FAIL(this_server_load.update_load_value())) {
1435LOG_WARN("fail to update load value", K(ret));
1436} else {} // no more to do
1437return ret;
1438}
1439
1440int ObServerBalancer::do_update_dst_server_load(
1441const ObUnitManager::ObUnitLoad &unit_load,
1442ServerTotalLoad &this_server_load,
1443const share::ObUnitStat &unit_stat,
1444common::ObIArray<PoolOccupation> &pool_occupation)
1445{
1446int ret = OB_SUCCESS;
1447share::ObUnit *unit = NULL;
1448share::ObUnitStat my_unit_stat = unit_stat;
1449if (OB_UNLIKELY(!inited_)) {
1450ret = OB_NOT_INIT;
1451LOG_WARN("not init", K(ret));
1452} else if (OB_UNLIKELY(!unit_load.is_valid())) {
1453ret = OB_INVALID_ARGUMENT;
1454LOG_WARN("invalid unit load", K(ret), K(unit_load));
1455} else if (OB_FAIL(unit_mgr_->get_unit_by_id(unit_stat.get_unit_id(), unit))) {
1456LOG_WARN("fail to get unit by id", K(ret), "unit_id", unit_stat.get_unit_id());
1457} else if (OB_UNLIKELY(NULL == unit)) {
1458ret = OB_ERR_UNEXPECTED;
1459LOG_WARN("unit ptr is null", K(ret));
1460} else if (common::REPLICA_TYPE_LOGONLY == unit->replica_type_) {
1461ret = OB_ERR_UNEXPECTED;
1462LOG_WARN("Replica type LOGONLY is unexpected", KR(ret), KP(unit));
1463}
1464if (OB_FAIL(ret)) {
1465} else if (OB_FAIL(pool_occupation.push_back(
1466PoolOccupation(unit_load.pool_->tenant_id_,
1467unit_load.pool_->resource_pool_id_,
1468this_server_load.server_)))) {
1469LOG_WARN("fail to push back", K(ret));
1470} else if (OB_FAIL(zone_disk_statistic_.raise_server_disk_use(
1471this_server_load.server_, my_unit_stat.get_required_size()))) {
1472LOG_WARN("fail to raise server disk use", K(ret));
1473} else if (OB_FAIL(this_server_load.load_sum_.append_load(unit_load))) {
1474LOG_WARN("fail to append load", K(ret));
1475} else if (OB_FAIL(this_server_load.update_load_value())) {
1476LOG_WARN("fail to update load value", K(ret));
1477} else {} // no more to do
1478return ret;
1479}
1480
1481int ObServerBalancer::try_balance_single_unit_by_cm(
1482const ObUnitManager::ObUnitLoad &unit_load,
1483common::ObArray<ServerTotalLoad *> &server_load_ptrs_sorted,
1484common::ObIArray<UnitMigrateStat> &task_array,
1485const common::ObIArray<common::ObAddr> &excluded_servers,
1486common::ObIArray<PoolOccupation> &pool_occupation,
1487bool &do_balance)
1488{
1489int ret = OB_SUCCESS;
1490ObUnitStat unit_stat;
1491if (OB_UNLIKELY(!inited_)) {
1492ret = OB_NOT_INIT;
1493LOG_WARN("not init", K(ret));
1494} else if (OB_UNLIKELY(!unit_load.is_valid())) {
1495ret = OB_INVALID_ARGUMENT;
1496LOG_WARN("invalid argument", K(ret), K(unit_load));
1497} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
1498unit_load.unit_->unit_id_,
1499unit_load.unit_->zone_,
1500unit_stat))) {
1501LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load.unit_);
1502} else {
1503do_balance = false;
1504for (int64_t j = server_load_ptrs_sorted.count() - 1;
1505!do_balance && OB_SUCC(ret) && j >= 0;
1506--j) {
1507ServerTotalLoad *server_load = server_load_ptrs_sorted.at(j);
1508if (OB_UNLIKELY(NULL == server_load)) {
1509ret = OB_ERR_UNEXPECTED;
1510LOG_WARN("server load ptr is null", K(ret), KP(server_load));
1511} else {
1512LoadSum this_load;
1513bool enough = true;
1514UnitMigrateStat unit_migrate_stat;
1515unit_migrate_stat.original_pos_ = unit_load.unit_->server_;
1516unit_migrate_stat.arranged_pos_ = server_load->server_;
1517unit_migrate_stat.unit_load_ = unit_load;
1518if (server_load->wild_server_) {
1519// Can't move unit to wild server
1520} else if (server_load->server_ == unit_load.unit_->server_) {
1521// Don't move to oneself
1522} else if (has_exist_in_array(excluded_servers, server_load->server_)) {
1523// it cannot be used as the target machine in the excluded server
1524} else if (OB_FAIL(this_load.append_load(unit_load))) {
1525LOG_WARN("fail to append load", K(ret));
1526} else if (OB_FAIL(check_single_server_resource_enough(
1527this_load, unit_stat, *server_load, enough))) {
1528LOG_WARN("fail to check server resource", K(ret));
1529} else if (!enough) {
1530// The resources of this machine are not enough to support the move of this unit
1531} else if (OB_FAIL(do_update_dst_server_load(
1532unit_load, *server_load, unit_stat, pool_occupation))) {
1533LOG_WARN("fail to append migrate unit task", K(ret));
1534} else if (OB_FAIL(task_array.push_back(unit_migrate_stat))) {
1535LOG_WARN("fail to push back", K(ret));
1536} else {
1537ServerTotalLoadCmp cmp;
1538std::sort(server_load_ptrs_sorted.begin(), server_load_ptrs_sorted.end(), cmp);
1539if (OB_FAIL(cmp.get_ret())) {
1540LOG_WARN("fail to sort server loads", K(ret));
1541}
1542do_balance = true;
1543}
1544}
1545}
1546}
1547return ret;
1548}
1549
1550int ObServerBalancer::do_balance_sys_tenant_single_unit(
1551const ObUnitManager::ObUnitLoad &unit_load,
1552common::ObArray<ServerTotalLoad *> &server_load_ptrs_sorted,
1553common::ObIArray<UnitMigrateStat> &task_array,
1554common::ObIArray<PoolOccupation> &pool_occupation)
1555{
1556int ret = OB_SUCCESS;
1557bool do_balance = false;
1558ObArray<common::ObAddr> excluded_servers;
1559if (OB_UNLIKELY(!inited_)) {
1560ret = OB_NOT_INIT;
1561LOG_WARN("not init", K(ret));
1562} else if (OB_UNLIKELY(!unit_load.is_valid())) {
1563ret = OB_INVALID_ARGUMENT;
1564LOG_WARN("invalid argument", K(ret), K(unit_load));
1565} else if (OB_FAIL(get_pool_occupation_excluded_dst_servers(
1566unit_load, pool_occupation, excluded_servers))) {
1567LOG_WARN("fail to get excluded servers", K(ret));
1568} else if (OB_FAIL(try_balance_single_unit_by_cm(
1569unit_load, server_load_ptrs_sorted, task_array,
1570excluded_servers, pool_occupation, do_balance))) {
1571LOG_WARN("fail to try balance sys single unit by cpu and memory", K(ret));
1572} else if (do_balance) {
1573// do execute balance according to cpu and memory, no more to do
1574} else if (OB_FAIL(try_balance_single_unit_by_disk(
1575unit_load, server_load_ptrs_sorted, task_array,
1576excluded_servers, pool_occupation, do_balance))) {
1577LOG_WARN("fail to do balance sys single unit by disk", K(ret));
1578} else if (do_balance) {
1579// good,
1580} else {
1581ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
1582LOG_WARN("no available server to hold more unit", K(ret),
1583"unit", *unit_load.unit_,
1584"unit_config", *unit_load.unit_config_,
1585"pool", *unit_load.pool_);
1586}
1587return ret;
1588}
1589
1590int ObServerBalancer::do_balance_sys_tenant_units(
1591const common::ObIArray<ObUnitManager::ObUnitLoad> &sys_tenant_units,
1592const common::ObIArray<common::ObAddr> &available_servers,
1593common::ObArray<ServerTotalLoad> &server_loads)
1594{
1595int ret = OB_SUCCESS;
1596ObArray<PoolOccupation> pool_occupation;
1597if (OB_UNLIKELY(!inited_)) {
1598ret = OB_NOT_INIT;
1599LOG_WARN("not init", K(ret));
1600} else if (OB_FAIL(generate_pool_occupation_array(sys_tenant_units, pool_occupation))) {
1601LOG_WARN("fail to generate pool occupation array", K(ret));
1602} else {
1603ObArray<ServerTotalLoad *> server_load_ptrs_sorted;
1604for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
1605if (OB_FAIL(server_load_ptrs_sorted.push_back(&server_loads.at(i)))) {
1606LOG_WARN("fail to push back", K(ret));
1607}
1608}
1609if (OB_SUCC(ret)) {
1610ServerTotalLoadCmp cmp;
1611std::sort(server_load_ptrs_sorted.begin(), server_load_ptrs_sorted.end(), cmp);
1612if (OB_FAIL(cmp.get_ret())) {
1613LOG_WARN("fail to sort", K(ret));
1614}
1615}
1616common::ObArray<UnitMigrateStat> task_array;
1617for (int64_t i = 0; OB_SUCC(ret) && i < sys_tenant_units.count(); ++i) {
1618const ObUnitManager::ObUnitLoad &unit_load = sys_tenant_units.at(i);
1619if (OB_UNLIKELY(!unit_load.is_valid())) {
1620ret = OB_ERR_UNEXPECTED;
1621LOG_WARN("invalid unit load", K(ret), K(unit_load));
1622} else if (has_exist_in_array(available_servers, unit_load.unit_->server_)) {
1623// skip in available server
1624} else if (OB_FAIL(do_balance_sys_tenant_single_unit(
1625unit_load, server_load_ptrs_sorted, task_array, pool_occupation))) {
1626LOG_WARN("fail to do balance sys tenant single unit", K(ret));
1627} else {} // no more to do
1628}
1629if (OB_FAIL(ret)) {
1630} else if (task_array.count() <= 0) {
1631} else if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
1632LOG_WARN("fail to check and do migrate unit task", KR(ret), K(task_array));
1633} else {} // no more to do
1634}
1635return ret;
1636}
1637
1638int ObServerBalancer::try_balance_sys_tenant_units(
1639const common::ObZone &zone,
1640bool &do_execute)
1641{
1642int ret = OB_SUCCESS;
1643common::ObArray<ObUnitManager::ObUnitLoad> sys_tenant_units;
1644common::ObArray<common::ObAddr> available_servers;
1645do_execute = false;
1646bool need_balance = false;
1647double g_res_weights[RES_MAX];
1648ObArray<ServerTotalLoad> server_loads;
1649if (OB_UNLIKELY(!inited_)) {
1650ret = OB_NOT_INIT;
1651LOG_WARN("not init", K(ret));
1652} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
1653ret = OB_ERR_UNEXPECTED;
1654LOG_WARN("unit_mgr_ ptr is null", K(ret));
1655} else if (OB_UNLIKELY(zone.is_empty())) {
1656ret = OB_INVALID_ARGUMENT;
1657LOG_WARN("invalid argument", K(ret), K(zone));
1658} else if (OB_FAIL(generate_available_servers(
1659zone, false /* sys unit not excluded*/ , available_servers))) {
1660LOG_WARN("fail to generate available servers", K(ret), K(zone));
1661} else if (available_servers.count() <= 0) {
1662LOG_INFO("no available servers, bypass", K(zone));
1663} else if (OB_FAIL(unit_mgr_->get_tenant_zone_all_unit_loads(
1664common::OB_SYS_TENANT_ID, zone, sys_tenant_units))) {
1665if (OB_ENTRY_NOT_EXIST == ret) {
1666ret = OB_SUCCESS;
1667} else {
1668LOG_WARN("fail to get tenant zone unit loads", K(ret), K(zone));
1669}
1670} else if (OB_FAIL(check_need_balance_sys_tenant_units(
1671sys_tenant_units, available_servers, need_balance))) {
1672LOG_WARN("fail to check need balance sys tenant units", K(ret));
1673} else if (!need_balance) {
1674do_execute = false;
1675} else if (OB_FAIL(calc_global_balance_resource_weights(
1676zone, available_servers, g_res_weights, RES_MAX))) {
1677LOG_WARN("fail to calc whole balance resource weights", K(ret));
1678} else if (OB_FAIL(generate_complete_server_loads(
1679zone, available_servers, g_res_weights, RES_MAX, server_loads))) {
1680LOG_WARN("fail to generate complete server loads", K(ret));
1681} else if (OB_FAIL(do_balance_sys_tenant_units(
1682sys_tenant_units, available_servers, server_loads))) {
1683LOG_WARN("fail to do balance sys tenant units", K(ret));
1684} else {
1685do_execute = true;
1686}
1687return ret;
1688}
1689
1690int ObServerBalancer::try_balance_non_sys_tenant_units(
1691const common::ObZone &zone,
1692const common::ObIArray<Matrix<uint64_t> > &group_tenant_array,
1693const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
1694const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units)
1695{
1696int ret = OB_SUCCESS;
1697ObArray<TenantGroupBalanceInfo> balance_info_array;
1698ObArray<Matrix<uint64_t> > degraded_tenant_group_array;
1699common::ObArray<common::ObAddr> available_servers;
1700const bool enable_sys_unit_standalone = GCONF.enable_sys_unit_standalone;
1701if (OB_UNLIKELY(!inited_)) {
1702ret = OB_NOT_INIT;
1703LOG_WARN("not init", K(ret));
1704} else if (OB_UNLIKELY(zone.is_empty())) {
1705ret = OB_INVALID_ARGUMENT;
1706LOG_WARN("invalid argument", K(ret), K(zone), K(available_servers));
1707} else if (OB_FAIL(balance_info_array.reserve(2 * group_tenant_array.count()))) {
1708LOG_WARN("ObArray fail to reserve", K(ret), "capacity", group_tenant_array.count());
1709} else if (OB_FAIL(generate_tenant_balance_info_array(
1710zone, group_tenant_array, degraded_tenant_group_array, balance_info_array))) {
1711LOG_WARN("fail to generate tenant balance info array", K(ret));
1712} else if (OB_FAIL(generate_available_servers(
1713zone, enable_sys_unit_standalone, available_servers))) {
1714LOG_WARN("fail to generate available servers", K(ret));
1715} else if (available_servers.count() <= 0) {
1716LOG_INFO("no available servers, bypass", K(zone));
1717} else {
1718for (int64_t i = 0; OB_SUCC(ret) && i < balance_info_array.count(); ++i) {
1719TenantGroupBalanceInfo &balance_info = balance_info_array.at(i);
1720if (OB_UNLIKELY(NULL == balance_info.tenant_id_matrix_)) {
1721ret = OB_ERR_UNEXPECTED;
1722LOG_WARN("tenant id matrix in balance info is null", K(ret));
1723} else if (OB_FAIL(generate_original_unit_matrix(
1724*balance_info.tenant_id_matrix_, zone, balance_info.column_unit_num_array_,
1725balance_info.unit_migrate_stat_matrix_))) {
1726LOG_WARN("fail to generate original unit matrix", K(ret));
1727} else if (OB_FAIL(single_unit_migrate_stat_matrix_balance(
1728balance_info, available_servers))) {
1729LOG_WARN("fail to do migrate stat matrix balance", K(ret));
1730} else {
1731LOG_INFO("finish single ttg balance",
1732"tenant_id_matrix", *balance_info.tenant_id_matrix_);
1733}
1734}
1735if (OB_FAIL(ret)) {
1736} else if (OB_FAIL(try_amend_and_execute_unit_balance_task(
1737zone, balance_info_array, standalone_units,
1738not_grant_units, available_servers))) {
1739LOG_WARN("fail to do global unit balance", K(ret));
1740} else {} // no more to do
1741}
1742return ret;
1743}
1744
1745int ObServerBalancer::generate_tenant_balance_info_array(
1746const common::ObZone &zone,
1747const common::ObIArray<Matrix<uint64_t> > &group_tenant_array,
1748common::ObIArray<Matrix<uint64_t> > °raded_tenant_group_array,
1749common::ObIArray<TenantGroupBalanceInfo> &balance_info_array)
1750{
1751int ret = OB_SUCCESS;
1752ObArray<const Matrix<uint64_t> *> unit_num_not_match_array;
1753if (OB_UNLIKELY(!inited_)) {
1754ret = OB_NOT_INIT;
1755LOG_WARN("not init", K(ret));
1756} else if (OB_UNLIKELY(zone.is_empty())) {
1757ret = OB_INVALID_ARGUMENT;
1758LOG_WARN("invalid argument", K(ret), K(zone));
1759} else {
1760for (int64_t i = 0; OB_SUCC(ret) && i < group_tenant_array.count(); ++i) {
1761bool unit_num_match = false;
1762TenantGroupBalanceInfo balance_info;
1763balance_info.tenant_id_matrix_ = &group_tenant_array.at(i);
1764if (OB_FAIL(check_and_get_tenant_matrix_unit_num(
1765group_tenant_array.at(i), zone, unit_num_match,
1766balance_info.column_unit_num_array_))) {
1767LOG_WARN("fail to check and get tenant matrix unit num", K(ret));
1768} else if (!unit_num_match) {
1769// Suppose the tenant group has m rows and n columns.
1770// When the unit num of the tenant group does not match,
1771// the tenant group will degenerate into m tenant groups with 1 row and n columns.
1772if (OB_FAIL(unit_num_not_match_array.push_back(&group_tenant_array.at(i)))) {
1773LOG_WARN("fail to push back", K(ret));
1774}
1775} else if (balance_info.column_unit_num_array_.count() > 0) {
1776if (OB_FAIL(balance_info_array.push_back(balance_info))) {
1777LOG_WARN("fail to push back", K(ret));
1778}
1779} else {} // no tenant of this group exists in this zone
1780}
1781if (OB_FAIL(ret)) {
1782} else if (OB_FAIL(try_generate_degraded_balance_info_array(
1783zone, unit_num_not_match_array, degraded_tenant_group_array, balance_info_array))) {
1784LOG_WARN("fail to try generate degraded balance info array", K(ret));
1785} else {} // no more to do
1786}
1787return ret;
1788}
1789
1790int ObServerBalancer::do_degrade_tenant_group_matrix(
1791const Matrix<uint64_t> &source_tenant_group,
1792common::ObIArray<Matrix<uint64_t> > °raded_tenant_group_array)
1793{
1794int ret = OB_SUCCESS;
1795if (OB_UNLIKELY(!inited_)) {
1796ret = OB_NOT_INIT;
1797LOG_WARN("not init", K(ret));
1798} else {
1799LOG_INFO("start degrade tenant group matrix", K(source_tenant_group));
1800for (int64_t i = 0; OB_SUCC(ret) && i < source_tenant_group.get_row_count(); ++i) {
1801Matrix<uint64_t> tenant_id_vector;
1802const int64_t VECTOR_ROW_CNT = 1;
1803const int64_t VECTOR_ROW_IDX = 0;
1804if (OB_FAIL(tenant_id_vector.init(VECTOR_ROW_CNT, source_tenant_group.get_column_count()))) {
1805LOG_WARN("fail to init tenant id vector", K(ret));
1806} else {
1807for (int64_t j = 0; OB_SUCC(ret) && j < source_tenant_group.get_column_count(); ++j) {
1808uint64_t tenant_id = OB_INVALID_ID;
1809if (OB_FAIL(source_tenant_group.get(i, j, tenant_id))) {
1810LOG_WARN("fail to get tenant id", K(ret), K(i), K(j));
1811} else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) {
1812ret = OB_ERR_UNEXPECTED;
1813LOG_WARN("invalid tenant id", K(ret), K(tenant_id));
1814} else if (OB_FAIL(tenant_id_vector.set(VECTOR_ROW_IDX, j, tenant_id))) {
1815LOG_WARN("fail to set tenant id vector", K(ret), K(j), K(tenant_id));
1816} else {} // no more to do
1817}
1818if (OB_FAIL(ret)) {
1819} else if (OB_FAIL(degraded_tenant_group_array.push_back(tenant_id_vector))) {
1820LOG_WARN("fail to push back", K(ret));
1821} else {
1822LOG_INFO("output vector tenant group", K(i), "vector_ttg", tenant_id_vector);
1823}
1824}
1825}
1826}
1827return ret;
1828}
1829
1830int ObServerBalancer::try_generate_degraded_balance_info_array(
1831const common::ObZone &zone,
1832const common::ObIArray<const Matrix<uint64_t> *> &unit_num_not_match_array,
1833common::ObIArray<Matrix<uint64_t> > °raded_tenant_group_array,
1834common::ObIArray<TenantGroupBalanceInfo> &balance_info_array)
1835{
1836int ret = OB_SUCCESS;
1837if (OB_UNLIKELY(!inited_)) {
1838ret = OB_NOT_INIT;
1839LOG_WARN("not init", K(ret));
1840} else if (OB_UNLIKELY(zone.is_empty())) {
1841ret = OB_INVALID_ARGUMENT;
1842LOG_WARN("invalid argument", K(ret), K(zone));
1843} else {
1844for (int64_t i = 0; OB_SUCC(ret) && i < unit_num_not_match_array.count(); ++i) {
1845const Matrix<uint64_t> *this_tenant_group = unit_num_not_match_array.at(i);
1846if (OB_UNLIKELY(NULL == this_tenant_group)) {
1847ret = OB_ERR_UNEXPECTED;
1848LOG_WARN("this tenant group ptr is null", K(ret));
1849} else if (OB_FAIL(do_degrade_tenant_group_matrix(
1850*this_tenant_group, degraded_tenant_group_array))) {
1851LOG_WARN("fail to do degraded tenant group matrix", K(ret), "source", *this_tenant_group);
1852} else {} // no more to do
1853}
1854for (int64_t i = 0; OB_SUCC(ret) && i < degraded_tenant_group_array.count(); ++i) {
1855bool unit_num_match = false;
1856TenantGroupBalanceInfo balance_info;
1857balance_info.tenant_id_matrix_ = °raded_tenant_group_array.at(i);
1858if (OB_FAIL(check_and_get_tenant_matrix_unit_num(
1859degraded_tenant_group_array.at(i), zone, unit_num_match,
1860balance_info.column_unit_num_array_))) {
1861LOG_WARN("fail to check and get tenant matrix unit num", K(ret));
1862} else if (!unit_num_match) {
1863ret = OB_ERR_UNEXPECTED;
1864LOG_WARN("unit num not match unexpected, since this tenant group is a vector",
1865K(ret), "vector tenant group", degraded_tenant_group_array.at(i));
1866} else if (balance_info.column_unit_num_array_.count() > 0) {
1867if (OB_FAIL(balance_info_array.push_back(balance_info))) {
1868LOG_WARN("fail to push back", K(ret));
1869}
1870} else {} // no tenant of this group exists in this zone
1871}
1872}
1873return ret;
1874}
1875
1876int ObServerBalancer::do_rebalance_servers_v2(
1877const common::ObZone &zone,
1878const common::ObIArray<Matrix<uint64_t> > &group_tenant_array,
1879const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
1880const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units)
1881{
1882int ret = OB_SUCCESS;
1883bool do_sys_unit_balanced = false;
1884if (OB_UNLIKELY(!inited_)) {
1885ret = OB_NOT_INIT;
1886LOG_WARN("not init", K(ret));
1887} else if (OB_UNLIKELY(zone.is_empty())) {
1888ret = OB_INVALID_ARGUMENT;
1889LOG_WARN("invalid argument", K(ret), K(zone));
1890} else if (OB_FAIL(try_balance_sys_tenant_units(zone, do_sys_unit_balanced))) {
1891LOG_WARN("fail to try balance sys tenant units", K(ret));
1892} else if (do_sys_unit_balanced) {
1893// bypass, first balance sys unit
1894} else if (OB_FAIL(try_balance_non_sys_tenant_units(
1895zone, group_tenant_array, standalone_units, not_grant_units))) {
1896LOG_WARN("fail to try balance non sys tenant units", K(ret));
1897}
1898return ret;
1899}
1900
1901int ObServerBalancer::try_amend_and_execute_unit_balance_task(
1902const common::ObZone &zone,
1903common::ObIArray<TenantGroupBalanceInfo> &balance_info_array,
1904const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
1905const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
1906const common::ObIArray<common::ObAddr> &available_servers)
1907{
1908int ret = OB_SUCCESS;
1909common::ObArray<TenantGroupBalanceInfo *> stable_tenant_group;
1910common::ObArray<TenantGroupBalanceInfo *> unstable_tenant_group;
1911bool do_amend_unstable_ttg = false;
1912bool do_amend_stable_ttg = false;
1913if (OB_UNLIKELY(!inited_)) {
1914ret = OB_NOT_INIT;
1915LOG_WARN("not init", K(ret));
1916} else if (OB_UNLIKELY(available_servers.count() <= 0)) {
1917ret = OB_INVALID_ARGUMENT;
1918LOG_WARN("invalid argument", K(ret));
1919} else if (OB_FAIL(divide_tenantgroup_balance_info(
1920balance_info_array, stable_tenant_group, unstable_tenant_group))) {
1921LOG_WARN("fail to divide tenantgroup balance info", K(ret));
1922} else if (OB_FAIL(try_amend_and_execute_stable_tenantgroup(
1923zone, unstable_tenant_group, stable_tenant_group, standalone_units,
1924not_grant_units, available_servers, do_amend_stable_ttg))) {
1925LOG_WARN("fail to amend and execute stable tenantgroup", K(ret));
1926} else if (do_amend_stable_ttg) {
1927// The stable tenant group has been adjusted between groups and no further operations will be performed
1928} else {
1929if (unstable_tenant_group.count() > 0) {
1930if (OB_FAIL(try_amend_and_execute_unstable_tenantgroup(
1931zone, unstable_tenant_group, stable_tenant_group, standalone_units,
1932not_grant_units, available_servers, do_amend_unstable_ttg))) {
1933LOG_WARN("fail to do amend and execute unit balance info", K(ret));
1934}
1935} else {} // do as follows
1936
1937if (OB_FAIL(ret)) {
1938} else if (unstable_tenant_group.count() <= 0 || !do_amend_unstable_ttg) {
1939bool do_balance_disk = false;
1940if (OB_FAIL(try_balance_disk_by_stable_tenantgroup(
1941zone, stable_tenant_group, available_servers, do_balance_disk))) {
1942LOG_WARN("fail to do disk balance", K(ret));
1943} else if (do_balance_disk) {
1944// Disk adjustment is made, and no need to do non-tenantgroup balance
1945} else if (OB_FAIL(do_non_tenantgroup_unit_balance_task(
1946zone, standalone_units, not_grant_units, available_servers))) {
1947LOG_WARN("fail to do non tenantgroup unit balance task", K(ret));
1948}
1949}
1950}
1951return ret;
1952}
1953
1954int ObServerBalancer::generate_simple_ug_loads(
1955common::ObIArray<SimpleUgLoad> &simple_ug_loads,
1956TenantGroupBalanceInfo &balance_info)
1957{
1958int ret = OB_SUCCESS;
1959if (OB_UNLIKELY(!inited_)) {
1960ret = OB_NOT_INIT;
1961LOG_WARN("not init", K(ret));
1962} else if (balance_info.unitgroup_load_array_.count()
1963!= balance_info.unit_migrate_stat_matrix_.get_column_count()) {
1964ret = OB_ERR_UNEXPECTED;
1965LOG_WARN("unitgroup load count and unit migrate stat matrix column not match", K(ret),
1966"unitgroup_count", balance_info.unitgroup_load_array_.count(),
1967"unit_matrix_column", balance_info.unit_migrate_stat_matrix_.get_column_count());
1968} else if (balance_info.unit_migrate_stat_matrix_.get_row_count() <= 0) {
1969ret = OB_ERR_UNEXPECTED;
1970LOG_WARN("unit matrix row unexpected", K(ret),
1971"unit_matrix_row", balance_info.unit_migrate_stat_matrix_.get_row_count());
1972} else {
1973simple_ug_loads.reset();
1974for (int64_t column = 0;
1975OB_SUCC(ret) && column < balance_info.unit_migrate_stat_matrix_.get_column_count();
1976++column) {
1977UnitGroupLoad &unitgroup_load = balance_info.unitgroup_load_array_.at(column);
1978UnitMigrateStat unit_migrate_stat;
1979if (OB_FAIL(balance_info.unit_migrate_stat_matrix_.get(0, column, unit_migrate_stat))) {
1980LOG_WARN("fail to get from matrix", K(ret));
1981} else {
1982SimpleUgLoad simple_ug_load;
1983simple_ug_load.column_tenant_id_ = unitgroup_load.column_tenant_id_;
1984simple_ug_load.original_server_ = unit_migrate_stat.original_pos_;
1985simple_ug_load.arranged_server_ = unit_migrate_stat.arranged_pos_;
1986simple_ug_load.load_sum_ = unitgroup_load.load_sum_;
1987if (OB_FAIL(simple_ug_loads.push_back(simple_ug_load))) {
1988LOG_WARN("fail to push back", K(ret));
1989}
1990}
1991}
1992}
1993return ret;
1994}
1995
1996int ObServerBalancer::get_ug_exchange_excluded_dst_servers(
1997const int64_t ug_idx,
1998const Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
1999common::ObIArray<common::ObAddr> &excluded_servers)
2000{
2001int ret = OB_SUCCESS;
2002excluded_servers.reset();
2003common::ObArray<ObUnitManager::ObUnitLoad> zone_units;
2004if (OB_UNLIKELY(!inited_)) {
2005ret = OB_NOT_INIT;
2006LOG_WARN("not init", K(ret));
2007} else if (OB_UNLIKELY(ug_idx >= unit_migrate_stat_matrix.get_column_count())) {
2008ret = OB_INVALID_ARGUMENT;
2009LOG_WARN("invalid argument", K(ret), K(ug_idx),
2010"unit migrate stat matrix column", unit_migrate_stat_matrix.get_column_count());
2011} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
2012ret = OB_ERR_UNEXPECTED;
2013LOG_WARN("unit_mgr_ ptr is null", K(ret));
2014}
2015for (int64_t row = 0; OB_SUCC(ret) && row < unit_migrate_stat_matrix.get_row_count(); ++row) {
2016zone_units.reset();
2017UnitMigrateStat unit_migrate_stat;
2018if (OB_FAIL(unit_migrate_stat_matrix.get(row, ug_idx, unit_migrate_stat))) {
2019LOG_WARN("fail to get unit migrate stat", K(ret));
2020} else if (OB_FAIL(unit_mgr_->get_tenant_zone_all_unit_loads(
2021unit_migrate_stat.tenant_id_, zone_disk_statistic_.zone_, zone_units))) {
2022LOG_WARN("fail to get tenant zone all unit loads", K(ret), K(unit_migrate_stat));
2023} else {
2024for (int64_t i = 0; OB_SUCC(ret) && i < zone_units.count(); ++i) {
2025ObUnitManager::ObUnitLoad &unit_load = zone_units.at(i);
2026if (!unit_load.is_valid()) {
2027ret = OB_ERR_UNEXPECTED;
2028LOG_WARN("unit load is invalid", K(ret), K(unit_load));
2029}
2030
2031if (OB_FAIL(ret)) {
2032} else if (has_exist_in_array(excluded_servers, unit_load.unit_->server_)) {
2033// already exist in excluded servers
2034} else if (OB_FAIL(excluded_servers.push_back(unit_load.unit_->server_))) {
2035LOG_WARN("fail to push back", K(ret));
2036}
2037
2038if (OB_FAIL(ret)) {
2039} else if (!unit_load.unit_->migrate_from_server_.is_valid()) {
2040// migrate from invalid, no need to put into excluded servers
2041} else if (has_exist_in_array(excluded_servers, unit_load.unit_->migrate_from_server_)) {
2042// already exist in excluded servers
2043} else if (OB_FAIL(excluded_servers.push_back(unit_load.unit_->migrate_from_server_))) {
2044LOG_WARN("fail to push back", K(ret));
2045}
2046}
2047}
2048}
2049return ret;
2050}
2051
2052int ObServerBalancer::check_cm_resource_enough(
2053const LoadSum &this_load,
2054const ServerTotalLoad &server_load,
2055bool &enough)
2056{
2057int ret = OB_SUCCESS;
2058double hard_limit = 0.0;
2059if (OB_UNLIKELY(!inited_)) {
2060ret = OB_NOT_INIT;
2061LOG_WARN("not init", K(ret));
2062} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
2063ret = OB_ERR_UNEXPECTED;
2064LOG_WARN("unit_mgr_ ptr is null", K(ret));
2065} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
2066LOG_WARN("fail to get hard limit", K(ret));
2067} else {
2068enough = ((this_load.load_sum_.max_cpu() + server_load.load_sum_.load_sum_.max_cpu()
2069<= server_load.resource_info_.cpu_ * hard_limit)
2070&& (this_load.load_sum_.min_cpu() + server_load.load_sum_.load_sum_.min_cpu()
2071<= server_load.resource_info_.cpu_)
2072&& (static_cast<double>(this_load.load_sum_.memory_size())
2073+ static_cast<double>(server_load.load_sum_.load_sum_.memory_size())
2074<= static_cast<double>(server_load.resource_info_.mem_total_))
2075&& (static_cast<double>(this_load.load_sum_.log_disk_size())
2076+ static_cast<double>(server_load.load_sum_.load_sum_.log_disk_size())
2077<= static_cast<double>(server_load.resource_info_.log_disk_total_)));
2078
2079LOG_INFO("[SERVER_BALANCE] check_cm_resource_enough", K(enough), K(this_load.load_sum_),
2080K(server_load.load_sum_.load_sum_), K(server_load.resource_info_), K(hard_limit));
2081}
2082return ret;
2083}
2084
2085int ObServerBalancer::check_exchange_ug_make_sense(
2086common::ObIArray<ServerTotalLoad> &server_loads,
2087const int64_t left_idx,
2088const int64_t right_idx,
2089common::ObIArray<SimpleUgLoad> &simple_ug_loads,
2090Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
2091bool &do_make_sense)
2092{
2093int ret = OB_SUCCESS;
2094double disk_waterlevel = 0.0;
2095double disk_usage_limit = 0.0;
2096if (OB_UNLIKELY(!inited_)) {
2097ret = OB_NOT_INIT;
2098LOG_WARN("not init", K(ret));
2099} else if (left_idx >= simple_ug_loads.count()
2100|| right_idx >= simple_ug_loads.count()
2101|| simple_ug_loads.count() != unit_migrate_stat_matrix.get_column_count()) {
2102ret = OB_INVALID_ARGUMENT;
2103LOG_WARN("invalid argument", K(ret), K(left_idx), K(right_idx),
2104"ug_loads_count", simple_ug_loads.count(),
2105"unit_matrix_column", unit_migrate_stat_matrix.get_column_count());
2106} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
2107LOG_WARN("fail to get disk waterlevel", K(ret));
2108} else if (OB_FAIL(get_server_data_disk_usage_limit(disk_usage_limit))) {
2109LOG_WARN("fail to get data disk usage limit", K(ret));
2110} else {
2111ObArray<ServerTotalLoad *> server_load_ptrs;
2112for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
2113if (OB_FAIL(server_load_ptrs.push_back(&server_loads.at(i)))) {
2114LOG_WARN("fail to push back", K(ret));
2115}
2116}
2117int64_t left_unit_use = 0;
2118int64_t right_unit_use = 0;
2119ServerDiskStatistic left_disk_statistic;
2120ServerDiskStatistic right_disk_statistic;
2121ServerTotalLoad *left_server_load = NULL;
2122ServerTotalLoad *right_server_load = NULL;
2123for (int64_t row = 0; OB_SUCC(ret) && row < unit_migrate_stat_matrix.get_row_count(); ++row) {
2124UnitMigrateStat left_unit_migrate;
2125ObUnitStat left_unit_stat;
2126UnitMigrateStat right_unit_migrate;
2127ObUnitStat right_unit_stat;
2128if (OB_FAIL(unit_migrate_stat_matrix.get(row, left_idx, left_unit_migrate))) {
2129LOG_WARN("fail to get from matrix", K(ret), K(row), "column", left_idx);
2130} else if (OB_UNLIKELY(!left_unit_migrate.unit_load_.is_valid())) {
2131ret = OB_ERR_UNEXPECTED;
2132LOG_WARN("unit load is invalid", K(ret));
2133} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
2134left_unit_migrate.unit_load_.unit_->unit_id_,
2135left_unit_migrate.unit_load_.unit_->zone_,
2136left_unit_stat))) {
2137LOG_WARN("fail to get unit stat", K(ret));
2138} else if (OB_FAIL(unit_migrate_stat_matrix.get(row, right_idx, right_unit_migrate))) {
2139LOG_WARN("fail to get from matrix", K(ret), K(row), "column", right_idx);
2140} else if (OB_UNLIKELY(!right_unit_migrate.unit_load_.is_valid())) {
2141ret = OB_ERR_UNEXPECTED;
2142LOG_WARN("unit load is invalid", K(ret));
2143} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
2144right_unit_migrate.unit_load_.unit_->unit_id_,
2145right_unit_migrate.unit_load_.unit_->zone_,
2146right_unit_stat))) {
2147LOG_WARN("fail to get unit stat", K(ret));
2148} else {
2149left_unit_use += left_unit_stat.get_required_size();
2150right_unit_use += right_unit_stat.get_required_size();
2151}
2152}
2153if (OB_SUCC(ret)) {
2154bool enough = false;
2155if (OB_FAIL(zone_disk_statistic_.get_server_disk_statistic(
2156simple_ug_loads.at(left_idx).original_server_, left_disk_statistic))) {
2157LOG_WARN("fail to get server disk statistic", K(ret));
2158} else if (OB_FAIL(zone_disk_statistic_.get_server_disk_statistic(
2159simple_ug_loads.at(right_idx).original_server_, right_disk_statistic))) {
2160LOG_WARN("fail to get server disk statistic", K(ret));
2161} else if (OB_FAIL(pick_server_load(
2162simple_ug_loads.at(left_idx).original_server_,
2163server_load_ptrs, left_server_load))) {
2164LOG_WARN("fail to get server load", K(ret));
2165} else if (OB_FAIL(pick_server_load(
2166simple_ug_loads.at(right_idx).original_server_,
2167server_load_ptrs, right_server_load))) {
2168LOG_WARN("fail to get server load", K(ret));
2169} else if (NULL == left_server_load || NULL == right_server_load) {
2170ret = OB_ERR_UNEXPECTED;
2171LOG_WARN("left server or right server load ptr is null", K(ret));
2172} else if (OB_FAIL(check_cm_resource_enough(
2173simple_ug_loads.at(left_idx).load_sum_, *right_server_load, enough))) {
2174LOG_WARN("fail to check cpu memory resource enough", K(ret));
2175} else if (!enough) {
2176do_make_sense = false;
2177} else if (OB_FAIL(check_cm_resource_enough(
2178simple_ug_loads.at(right_idx).load_sum_, *left_server_load, enough))) {
2179LOG_WARN("fail to check cpu memory resource enough", K(ret));
2180} else if (!enough) {
2181do_make_sense = false;
2182} else if (left_unit_use < right_unit_use) {
2183do_make_sense = false; // Cannot lower the left disk after swap
2184} else if (
2185static_cast<double>(right_disk_statistic.disk_in_use_ - right_unit_use + left_unit_use)
2186> disk_waterlevel * static_cast<double>(right_disk_statistic.disk_total_)) {
2187do_make_sense = false; // The right disk exceeds the water mark after swapping
2188} else if (
2189static_cast<double>(right_disk_statistic.disk_in_use_ + left_unit_use)
2190> disk_usage_limit * static_cast<double>(right_disk_statistic.disk_total_)) {
2191do_make_sense = false; // Exceeded the upper limit of the right disk during the exchange
2192} else if (
2193static_cast<double>(left_disk_statistic.disk_in_use_ + right_unit_use)
2194> disk_usage_limit * static_cast<double>(left_disk_statistic.disk_total_)) {
2195do_make_sense = false;
2196} else if (
2197static_cast<double>(left_unit_use - right_unit_use)
2198< static_cast<double>(left_disk_statistic.disk_total_) / static_cast<double>(200)) {
2199do_make_sense = false; // The disk on the left side is not significantly reduced after swapping
2200} else {
2201do_make_sense = true;
2202}
2203}
2204}
2205return ret;
2206}
2207
2208int ObServerBalancer::coordinate_unit_migrate_stat_matrix(
2209const int64_t left_idx,
2210const int64_t right_idx,
2211common::ObIArray<SimpleUgLoad> &simple_ug_loads,
2212Matrix<UnitMigrateStat> &unit_migrate_stat_matrix)
2213{
2214int ret = OB_SUCCESS;
2215if (OB_UNLIKELY(!inited_)) {
2216ret = OB_NOT_INIT;
2217LOG_WARN("not init", K(ret));
2218} else if (OB_UNLIKELY(left_idx >= simple_ug_loads.count()
2219|| right_idx >= simple_ug_loads.count())) {
2220ret = OB_INVALID_ARGUMENT;
2221LOG_WARN("invalid argument", K(ret), K(left_idx), K(right_idx),
2222"simple ug loads count", simple_ug_loads.count());
2223} else {
2224SimpleUgLoad &left_ug = simple_ug_loads.at(left_idx);
2225SimpleUgLoad &right_ug = simple_ug_loads.at(right_idx);
2226for (int64_t row = 0; OB_SUCC(ret) && row < unit_migrate_stat_matrix.get_row_count(); ++row) {
2227UnitMigrateStat left_unit_migrate;
2228UnitMigrateStat right_unit_migrate;
2229if (OB_FAIL(unit_migrate_stat_matrix.get(row, left_idx, left_unit_migrate))) {
2230LOG_WARN("fail to get from matrix", K(ret), K(row), "column", left_idx);
2231} else if (OB_FAIL(unit_migrate_stat_matrix.get(row, right_idx, right_unit_migrate))) {
2232LOG_WARN("fail to get from matrix", K(ret), K(row), "column", right_idx);
2233} else {
2234left_unit_migrate.arranged_pos_ = right_ug.original_server_;
2235right_unit_migrate.arranged_pos_ = left_ug.original_server_;
2236if (OB_FAIL(unit_migrate_stat_matrix.set(row, left_idx, left_unit_migrate))) {
2237LOG_WARN("fail to set", K(ret), K(row), "column", left_idx);
2238} else if (OB_FAIL(unit_migrate_stat_matrix.set(row, right_idx, right_unit_migrate))) {
2239LOG_WARN("fail to set", K(ret), K(row), "column", right_idx);
2240} else {} // no more to do
2241}
2242}
2243if (OB_SUCC(ret)) {
2244left_ug.arranged_server_ = right_ug.original_server_;
2245right_ug.arranged_server_ = left_ug.original_server_;
2246}
2247}
2248return ret;
2249}
2250
2251int ObServerBalancer::generate_exchange_ug_migrate_task(
2252const int64_t left_idx,
2253const int64_t right_idx,
2254common::ObIArray<SimpleUgLoad> &simple_ug_loads,
2255Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
2256common::ObIArray<UnitMigrateStat> &task_array)
2257{
2258int ret = OB_SUCCESS;
2259if (OB_UNLIKELY(!inited_)) {
2260ret = OB_NOT_INIT;
2261LOG_WARN("not init", K(ret));
2262} else if (OB_UNLIKELY(left_idx >= unit_migrate_stat_matrix.get_column_count()
2263|| right_idx >= unit_migrate_stat_matrix.get_column_count())) {
2264ret = OB_INVALID_ARGUMENT;
2265LOG_WARN("invalid argument", K(ret), K(left_idx), K(right_idx),
2266"unit_matrix_column", unit_migrate_stat_matrix.get_column_count());
2267} else {
2268int64_t left_unit_use = 0;
2269int64_t right_unit_use = 0;
2270ServerDiskStatistic left_disk_statistic;
2271ServerDiskStatistic right_disk_statistic;
2272for (int64_t row = 0; OB_SUCC(ret) && row < unit_migrate_stat_matrix.get_row_count(); ++row) {
2273UnitMigrateStat left_unit_migrate;
2274ObUnitStat left_unit_stat;
2275UnitMigrateStat right_unit_migrate;
2276ObUnitStat right_unit_stat;
2277if (OB_FAIL(unit_migrate_stat_matrix.get(row, left_idx, left_unit_migrate))) {
2278LOG_WARN("fail to get from matrix", K(ret), K(row), "column", left_idx);
2279} else if (OB_UNLIKELY(!left_unit_migrate.unit_load_.is_valid())) {
2280ret = OB_ERR_UNEXPECTED;
2281LOG_WARN("unit load is invalid", K(ret));
2282} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
2283left_unit_migrate.unit_load_.unit_->unit_id_,
2284left_unit_migrate.unit_load_.unit_->zone_,
2285left_unit_stat))) {
2286LOG_WARN("fail to get unit stat", K(ret));
2287} else if (OB_FAIL(unit_migrate_stat_matrix.get(row, right_idx, right_unit_migrate))) {
2288LOG_WARN("fail to get from matrix", K(ret), K(row), "column", right_idx);
2289} else if (OB_UNLIKELY(!right_unit_migrate.unit_load_.is_valid())) {
2290ret = OB_ERR_UNEXPECTED;
2291LOG_WARN("unit load is invalid", K(ret));
2292} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
2293right_unit_migrate.unit_load_.unit_->unit_id_,
2294right_unit_migrate.unit_load_.unit_->zone_,
2295right_unit_stat))) {
2296LOG_WARN("fail to get unit stat", K(ret));
2297} else if (OB_FAIL(task_array.push_back(left_unit_migrate))) {
2298LOG_WARN("fail to push back", K(ret));
2299} else if (OB_FAIL(task_array.push_back(right_unit_migrate))) {
2300LOG_WARN("fail to push back", K(ret));
2301} else {
2302left_unit_use += left_unit_stat.get_required_size();
2303right_unit_use += right_unit_stat.get_required_size();
2304}
2305}
2306if (OB_SUCC(ret)) {
2307if (OB_FAIL(zone_disk_statistic_.get_server_disk_statistic(
2308simple_ug_loads.at(left_idx).original_server_, left_disk_statistic))) {
2309LOG_WARN("fail to get server disk statistic", K(ret));
2310} else if (OB_FAIL(zone_disk_statistic_.reduce_server_disk_use(
2311simple_ug_loads.at(left_idx).original_server_, left_unit_use))) {
2312LOG_WARN("fail to reduce server disk", K(ret));
2313} else if (OB_FAIL(zone_disk_statistic_.raise_server_disk_use(
2314simple_ug_loads.at(left_idx).original_server_, right_unit_use))) {
2315LOG_WARN("fail to reduce server disk", K(ret));
2316} else if (OB_FAIL(zone_disk_statistic_.get_server_disk_statistic(
2317simple_ug_loads.at(right_idx).original_server_, right_disk_statistic))) {
2318LOG_WARN("fail to get server disk statistic", K(ret));
2319} else if (OB_FAIL(zone_disk_statistic_.reduce_server_disk_use(
2320simple_ug_loads.at(right_idx).original_server_, right_unit_use))) {
2321LOG_WARN("fail to reduce server disk", K(ret));
2322} else if (OB_FAIL(zone_disk_statistic_.raise_server_disk_use(
2323simple_ug_loads.at(right_idx).original_server_, left_unit_use))) {
2324LOG_WARN("fail to reduce server disk", K(ret));
2325} else {} // no more to do
2326}
2327}
2328return ret;
2329}
2330
2331int ObServerBalancer::try_balance_server_disk_onebyone(
2332common::ObIArray<ServerTotalLoad> &server_loads,
2333TenantGroupBalanceInfo &balance_info,
2334common::ObIArray<SimpleUgLoad> &simple_ug_loads,
2335const int64_t ug_idx,
2336const common::ObIArray<common::ObAddr> &available_servers,
2337const common::ObIArray<common::ObAddr> &disk_over_servers,
2338common::ObIArray<UnitMigrateStat> &task_array,
2339bool &do_balance_disk)
2340{
2341int ret = OB_SUCCESS;
2342common::ObArray<common::ObAddr> left_excluded_servers;
2343common::ObArray<common::ObAddr> right_excluded_servers;
2344if (OB_UNLIKELY(!inited_)) {
2345ret = OB_NOT_INIT;
2346LOG_WARN("not init", K(ret));
2347} else if (OB_UNLIKELY(ug_idx >= simple_ug_loads.count())) {
2348ret = OB_ERR_UNEXPECTED;
2349LOG_WARN("ug_idx unexpected", K(ret), K(ug_idx), "ug_load count", simple_ug_loads.count());
2350} else if (OB_FAIL(get_ug_exchange_excluded_dst_servers(
2351ug_idx, balance_info.unit_migrate_stat_matrix_, left_excluded_servers))) {
2352LOG_WARN("fail to get ug exchange dst servers", K(ret));
2353} else {
2354SimpleUgLoad &left_ug_load = simple_ug_loads.at(ug_idx);
2355do_balance_disk = false;
2356for (int64_t i = 0;
2357!do_balance_disk
2358&& OB_SUCC(ret)
2359&& i < zone_disk_statistic_.server_disk_statistic_array_.count();
2360++i) {
2361ServerDiskStatistic &disk_statistic
2362= zone_disk_statistic_.server_disk_statistic_array_.at(i);
2363if (has_exist_in_array(left_excluded_servers, disk_statistic.server_)) {
2364// bypass, since in excluded
2365} else if (has_exist_in_array(disk_over_servers, disk_statistic.server_)) {
2366// bypass, since in disk over servers
2367} else if (!has_exist_in_array(available_servers, disk_statistic.server_)) {
2368// bypass, since not in available servers
2369} else if (disk_statistic.wild_server_) {
2370// bypass, wild server
2371} else {
2372for (int64_t j = 0; !do_balance_disk && OB_SUCC(ret) && j < simple_ug_loads.count(); ++j) {
2373SimpleUgLoad &right_ug_load = simple_ug_loads.at(j);
2374bool do_make_sense = false;
2375if (left_ug_load.column_tenant_id_ == right_ug_load.column_tenant_id_) {
2376// by pass, come from the same tenant column
2377} else if (right_ug_load.original_server_ != right_ug_load.arranged_server_) {
2378// already in migrating, ignore
2379} else if (right_ug_load.original_server_ != disk_statistic.server_) {
2380// not in this server
2381} else if ((left_ug_load.load_sum_.load_sum_.min_cpu()
2382!= right_ug_load.load_sum_.load_sum_.min_cpu())
2383|| (left_ug_load.load_sum_.load_sum_.memory_size()
2384!= right_ug_load.load_sum_.load_sum_.memory_size())) {
2385// cpu and memory not match, exchange will violate the balance result
2386} else if (OB_FAIL(get_ug_exchange_excluded_dst_servers(
2387j, balance_info.unit_migrate_stat_matrix_, right_excluded_servers))) {
2388LOG_WARN("fail to get ug exchange dst servers", K(ret));
2389} else if (has_exist_in_array(right_excluded_servers, left_ug_load.original_server_)) {
2390// left ug server in right excluded servers
2391} else if (OB_FAIL(check_exchange_ug_make_sense(
2392server_loads, ug_idx, j, simple_ug_loads,
2393balance_info.unit_migrate_stat_matrix_, do_make_sense))) {
2394LOG_WARN("fail to check exchange ug make sence", K(ret));
2395} else if (!do_make_sense) {
2396// do not make sence
2397} else if (OB_FAIL(coordinate_unit_migrate_stat_matrix(
2398ug_idx, j, simple_ug_loads, balance_info.unit_migrate_stat_matrix_))) {
2399LOG_WARN("fail to coordinate unit migrate stat matrix", K(ret));
2400} else if (OB_FAIL(generate_exchange_ug_migrate_task(
2401ug_idx, j, simple_ug_loads,
2402balance_info.unit_migrate_stat_matrix_, task_array))) {
2403LOG_WARN("fail to generate exchange ug migrate task", K(ret));
2404} else {
2405do_balance_disk = true;
2406}
2407}
2408}
2409}
2410}
2411return ret;
2412}
2413
2414int ObServerBalancer::try_balance_server_disk_by_ttg(
2415common::ObIArray<ServerTotalLoad> &server_loads,
2416const common::ObAddr &src_server,
2417TenantGroupBalanceInfo &balance_info,
2418const common::ObIArray<common::ObAddr> &available_servers,
2419const common::ObIArray<common::ObAddr> &disk_over_servers,
2420common::ObIArray<UnitMigrateStat> &task_array,
2421bool &do_balance_disk)
2422{
2423int ret = OB_SUCCESS;
2424ObArray<SimpleUgLoad> simple_ug_loads;
2425double disk_waterlevel = 0.0;
2426if (OB_UNLIKELY(!inited_)) {
2427ret = OB_NOT_INIT;
2428LOG_WARN("not init", K(ret));
2429} else if (OB_UNLIKELY(!src_server.is_valid())) {
2430ret = OB_INVALID_ARGUMENT;
2431LOG_WARN("invalid argument", K(ret), K(src_server));
2432} else if (OB_FAIL(generate_simple_ug_loads(simple_ug_loads, balance_info))) {
2433LOG_WARN("fail to generate simple ug loads", K(ret));
2434} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
2435LOG_WARN("fail to get disk waterlevel", K(ret));
2436} else {
2437do_balance_disk = false;
2438for (int64_t i = 0; OB_SUCC(ret) && i < simple_ug_loads.count(); ++i) {
2439bool my_do_balance_disk = false;
2440SimpleUgLoad &simple_ug_load = simple_ug_loads.at(i);
2441if (simple_ug_load.original_server_ != simple_ug_load.arranged_server_) {
2442// bypass, since this has already been migrated by others
2443} else if (src_server != simple_ug_load.original_server_) {
2444// bypass, since server not match
2445} else if (OB_FAIL(try_balance_server_disk_onebyone(
2446server_loads, balance_info, simple_ug_loads, i, available_servers,
2447disk_over_servers, task_array, my_do_balance_disk))) {
2448LOG_WARN("fail to try balance server disk onebyone", K(ret));
2449} else {
2450do_balance_disk |= my_do_balance_disk;
2451}
2452if (OB_FAIL(ret)) {
2453} else if (do_balance_disk) {
2454break; // Performed a set of disk swaps
2455}
2456}
2457}
2458return ret;
2459}
2460
2461int ObServerBalancer::try_balance_disk_by_stable_tenantgroup(
2462const common::ObZone &zone,
2463common::ObIArray<TenantGroupBalanceInfo *> &stable_ttg,
2464const common::ObIArray<common::ObAddr> &available_servers,
2465bool &do_balance_disk)
2466{
2467int ret = OB_SUCCESS;
2468common::ObArray<common::ObAddr> disk_over_servers;
2469common::ObArray<ServerTotalLoad> server_loads;
2470double g_res_weights[RES_MAX];
2471double disk_waterlevel = 0.0;
2472if (OB_UNLIKELY(!inited_)) {
2473ret = OB_NOT_INIT;
2474LOG_WARN("not init", K(ret));
2475} else if (!zone_disk_statistic_.over_disk_waterlevel()) {
2476do_balance_disk = false; // The disk is within the water mark, no need to adjust
2477} else if (stable_ttg.count() <= 0) {
2478do_balance_disk = false; // stable ttg is empty, bypass
2479} else if (OB_UNLIKELY(available_servers.count() <= 0)) {
2480ret = OB_INVALID_ARGUMENT;
2481LOG_WARN("invalid argument", K(ret), K(available_servers));
2482} else if (OB_FAIL(get_disk_over_available_servers(disk_over_servers))) {
2483LOG_WARN("fail to get disk over servers", K(ret));
2484} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
2485LOG_WARN("fail to get disk waterlevel", K(ret));
2486} else if (OB_FAIL(calc_global_balance_resource_weights(
2487zone, available_servers, g_res_weights, RES_MAX))) {
2488LOG_WARN("fail to calc whole balance resource weights", K(ret));
2489} else if (OB_FAIL(generate_complete_server_loads(
2490zone, available_servers, g_res_weights, RES_MAX, server_loads))) {
2491LOG_WARN("fail to generate complete server loads", K(ret));
2492} else {
2493LOG_INFO("do balance disk by stable tenantgroup", K(ret), K(disk_over_servers));
2494common::ObArray<UnitMigrateStat> task_array;
2495do_balance_disk = false;
2496for (int64_t i = 0; OB_SUCC(ret) && i < disk_over_servers.count(); ++i) {
2497common::ObAddr &src_server = disk_over_servers.at(i);
2498for (int64_t j = 0; OB_SUCC(ret) && j < stable_ttg.count(); ++j) {
2499bool my_do_balance_disk = false;
2500TenantGroupBalanceInfo *balance_info = stable_ttg.at(j);
2501if (NULL == balance_info) {
2502ret = OB_ERR_UNEXPECTED;
2503LOG_WARN("balance info ptr is null", K(ret));
2504} else if (OB_FAIL(try_balance_server_disk_by_ttg(
2505server_loads, src_server, *balance_info, available_servers,
2506disk_over_servers, task_array, my_do_balance_disk))) {
2507LOG_WARN("fail to try balance server disk onebyone", K(ret));
2508} else {
2509do_balance_disk |= my_do_balance_disk;
2510}
2511if (OB_FAIL(ret)) {
2512} else if (do_balance_disk) {
2513break; // Exchange
2514}
2515}
2516}
2517if (OB_SUCC(ret) && task_array.count() > 0) {
2518if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
2519LOG_WARN("fail to check and do migrate unit task array", KR(ret), K(task_array));
2520}
2521}
2522}
2523return ret;
2524}
2525
2526int ObServerBalancer::try_amend_and_execute_stable_tenantgroup(
2527const common::ObZone &zone,
2528const common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group,
2529const common::ObIArray<TenantGroupBalanceInfo *> &stable_tenant_group,
2530const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
2531const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
2532const common::ObIArray<common::ObAddr> &available_servers,
2533bool &do_amend)
2534{
2535int ret = OB_SUCCESS;
2536TenantGroupBalanceInfo *info_may_amend = NULL;
2537ObArray<TenantGroupBalanceInfo *> other_stable_ttg;
2538const bool is_stable_ttg = true;
2539if (OB_UNLIKELY(!inited_)) {
2540ret = OB_NOT_INIT;
2541LOG_WARN("not init", K(ret));
2542} else if (stable_tenant_group.count() <= 0) {
2543do_amend = false;
2544} else if (OB_FAIL(choose_balance_info_amend(
2545stable_tenant_group, is_stable_ttg, info_may_amend, other_stable_ttg))) {
2546LOG_WARN("fail to choose stable balance info amend", K(ret));
2547} else if (NULL == info_may_amend) {
2548ret = OB_INVALID_ARGUMENT;
2549LOG_WARN("invalid argument", K(ret), KP(info_may_amend));
2550} else if (OB_FAIL(try_amend_and_execute_tenantgroup(
2551zone, info_may_amend, other_stable_ttg, unstable_tenant_group,
2552standalone_units, not_grant_units, available_servers, do_amend))) {
2553LOG_WARN("fail to amend and execute tenantgroup", K(ret));
2554} else {} // no more to do
2555return ret;
2556}
2557
2558int ObServerBalancer::try_amend_and_execute_unstable_tenantgroup(
2559const common::ObZone &zone,
2560const common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group,
2561const common::ObIArray<TenantGroupBalanceInfo *> &stable_tenant_group,
2562const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
2563const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
2564const common::ObIArray<common::ObAddr> &available_servers,
2565bool &do_amend)
2566{
2567int ret = OB_SUCCESS;
2568TenantGroupBalanceInfo *info_need_amend = NULL;
2569ObArray<TenantGroupBalanceInfo *> other_unstable_ttg;
2570const bool is_stable_ttg = false;
2571if (OB_UNLIKELY(!inited_)) {
2572ret = OB_NOT_INIT;
2573LOG_WARN("not init", K(ret));
2574} else if (unstable_tenant_group.count() <= 0) {
2575do_amend = false;
2576} else if (OB_FAIL(choose_balance_info_amend(
2577unstable_tenant_group, is_stable_ttg, info_need_amend, other_unstable_ttg))) {
2578LOG_WARN("fail to choose unstable balance info amend", K(ret));
2579} else if (OB_UNLIKELY(NULL == info_need_amend)) {
2580ret = OB_INVALID_ARGUMENT;
2581LOG_WARN("invalid argument", K(ret), KP(info_need_amend));
2582} else if (OB_FAIL(try_amend_and_execute_tenantgroup(
2583zone, info_need_amend, stable_tenant_group, other_unstable_ttg,
2584standalone_units, not_grant_units, available_servers, do_amend))) {
2585LOG_WARN("fail to amend and execute tenantgroup", K(ret));
2586} else {} // no more to do
2587return ret;
2588}
2589
2590int ObServerBalancer::get_sys_tenant_unitgroup_loads(
2591const common::ObZone &zone,
2592common::ObIArray<UnitGroupLoad> &sys_tenant_ug_loads)
2593{
2594int ret = OB_SUCCESS;
2595sys_tenant_ug_loads.reset();
2596common::ObArray<ObUnitManager::ObUnitLoad> unit_loads;
2597common::ObReplicaType replica_type = common::REPLICA_TYPE_FULL;
2598if (OB_UNLIKELY(!inited_)) {
2599ret = OB_NOT_INIT;
2600LOG_WARN("not init", K(ret));
2601} else if (OB_UNLIKELY(zone.is_empty())) {
2602ret = OB_INVALID_ARGUMENT;
2603LOG_WARN("invalid argument", K(ret));
2604} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
2605ret = OB_ERR_UNEXPECTED;
2606LOG_WARN("unit_mgr_ ptr is null", K(ret));
2607} else if (OB_FAIL(unit_mgr_->get_tenant_zone_unit_loads(
2608common::OB_SYS_TENANT_ID, zone, replica_type, unit_loads))) {
2609if (OB_ENTRY_NOT_EXIST == ret) {
2610ret = OB_SUCCESS;
2611} else {
2612LOG_WARN("fail to get tenant zone unit infos", K(ret));
2613}
2614} else {
2615for (int64_t i = 0; OB_SUCC(ret) && i < unit_loads.count(); ++i) {
2616ObUnitManager::ObUnitLoad &unit_load = unit_loads.at(i);
2617if (OB_UNLIKELY(!unit_load.is_valid())) {
2618ret = OB_ERR_UNEXPECTED;
2619LOG_WARN("unit load is valid", K(ret));
2620} else {
2621UnitGroupLoad ug_load;
2622ug_load.column_tenant_id_ = common::OB_SYS_TENANT_ID;
2623ug_load.start_column_idx_ = 0; // dummy for sys tenant
2624ug_load.column_count_ = 1; // dummy for sys tenant
2625ug_load.server_ = unit_load.unit_->server_;
2626// assign server_load_ ptr in append\_alien\_ug\_loads()
2627ug_load.server_load_ = NULL;
2628if (OB_UNLIKELY(ug_load.unit_loads_.push_back(*unit_load.unit_config_))) {
2629LOG_WARN("fail to push back", K(ret));
2630} else if (OB_FAIL(ug_load.sum_group_load())) {
2631LOG_WARN("fail to sum group load", K(ret));
2632} else if (OB_FAIL(sys_tenant_ug_loads.push_back(ug_load))) {
2633LOG_WARN("fail to push back", K(ret));
2634} else {} // no more to do
2635}
2636}
2637}
2638return ret;
2639}
2640
2641int ObServerBalancer::try_amend_and_execute_tenantgroup(
2642const common::ObZone &zone,
2643TenantGroupBalanceInfo *info_amend,
2644const common::ObIArray<TenantGroupBalanceInfo *> &stable_tenant_group,
2645const common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group,
2646const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
2647const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
2648const common::ObIArray<common::ObAddr> &available_servers,
2649bool &do_amend)
2650{
2651int ret = OB_SUCCESS;
2652common::ObArray<UnitGroupLoad> sys_tenant_ug_loads;
2653if (OB_UNLIKELY(!inited_)) {
2654ret = OB_NOT_INIT;
2655LOG_WARN("not init", K(ret));
2656} else if (OB_UNLIKELY(NULL == info_amend)) {
2657ret = OB_INVALID_ARGUMENT;
2658LOG_WARN("invalid argument", K(ret));
2659} else if (OB_FAIL(get_sys_tenant_unitgroup_loads(zone, sys_tenant_ug_loads))) {
2660LOG_WARN("fail to get sys tenant unitgroup_loads", K(ret));
2661} else if (OB_FAIL(calc_inter_ttg_weights(
2662info_amend, stable_tenant_group, sys_tenant_ug_loads,
2663available_servers, info_amend->inter_weights_, RES_MAX))) {
2664LOG_WARN("fail to calc inter ttg weights", K(ret));
2665} else if (OB_FAIL(generate_inter_ttg_server_loads(
2666info_amend, stable_tenant_group, sys_tenant_ug_loads, available_servers))) {
2667LOG_WARN("fail to generate inter ttg server loads", K(ret));
2668} else if (OB_FAIL(do_amend_inter_ttg_balance(
2669info_amend, stable_tenant_group, info_amend->server_load_array_))) {
2670LOG_WARN("fail to do amend inter ttg balance", K(ret));
2671} else if (OB_FAIL(try_execute_unit_balance_task(
2672zone, info_amend, standalone_units, not_grant_units,
2673unstable_tenant_group, available_servers, do_amend))) {
2674LOG_WARN("fail to do exuecte unit balance task", K(ret));
2675} else {} // no more to do
2676return ret;
2677}
2678
2679int ObServerBalancer::calc_inter_ttg_weights(
2680TenantGroupBalanceInfo *info_need_amend,
2681const common::ObIArray<TenantGroupBalanceInfo *> &stable_tenant_group,
2682const common::ObIArray<UnitGroupLoad> &sys_tenant_ug_loads,
2683const common::ObIArray<common::ObAddr> &available_servers,
2684double *const resource_weights,
2685const int64_t weights_count)
2686{
2687int ret = OB_SUCCESS;
2688if (OB_UNLIKELY(!inited_)) {
2689ret = OB_NOT_INIT;
2690LOG_WARN("not init", K(ret));
2691} else if (OB_UNLIKELY(NULL == resource_weights
2692|| RES_MAX != weights_count
2693|| NULL == info_need_amend)) {
2694ret = OB_INVALID_ARGUMENT;
2695LOG_WARN("invalid argument", K(ret), KP(info_need_amend));
2696} else if (OB_ISNULL(server_mgr_)) {
2697ret = OB_ERR_UNEXPECTED;
2698LOG_WARN("server_mgr_ is null", KR(ret), KP(server_mgr_));
2699} else {
2700LoadSum load_sum;
2701for (int64_t i = 0;
2702OB_SUCC(ret) && i < info_need_amend->unitgroup_load_array_.count();
2703++i) {
2704const UnitGroupLoad &unitgroup_load = info_need_amend->unitgroup_load_array_.at(i);
2705if (OB_UNLIKELY(!unitgroup_load.is_valid())) {
2706ret = OB_ERR_UNEXPECTED;
2707LOG_WARN("unitgroup_load is invalid, unexpected", K(ret), K(unitgroup_load));
2708} else if (OB_FAIL(load_sum.append_load(unitgroup_load.load_sum_))) {
2709LOG_WARN("append load failed", K(ret));
2710} else {} // no more to do
2711}
2712for (int64_t i = 0; OB_SUCC(ret) && i < sys_tenant_ug_loads.count(); ++i) {
2713const UnitGroupLoad &unitgroup_load = sys_tenant_ug_loads.at(i);
2714if (OB_UNLIKELY(!unitgroup_load.is_valid())) {
2715ret = OB_ERR_UNEXPECTED;
2716LOG_WARN("unitgroup_load is invalid, unexpected", K(ret), K(unitgroup_load));
2717} else if (OB_FAIL(load_sum.append_load(unitgroup_load.load_sum_))) {
2718LOG_WARN("append load failed", K(ret));
2719} else {} // no more to do
2720}
2721for (int64_t i = 0;
2722OB_SUCC(ret) && i < stable_tenant_group.count();
2723++i) {
2724const TenantGroupBalanceInfo *balance_info = stable_tenant_group.at(i);
2725if (OB_UNLIKELY(NULL == balance_info)) {
2726ret = OB_ERR_UNEXPECTED;
2727LOG_WARN("balance info ptr is null", K(ret));
2728} else {
2729for (int64_t j = 0;
2730OB_SUCC(ret) && j < balance_info->unitgroup_load_array_.count();
2731++j) {
2732const UnitGroupLoad &unitgroup_load = balance_info->unitgroup_load_array_.at(j);
2733if (OB_UNLIKELY(!unitgroup_load.is_valid())) {
2734ret = OB_ERR_UNEXPECTED;
2735LOG_WARN("unit_load is invalid, unexpected", K(ret), K(unitgroup_load));
2736} else if (OB_FAIL(load_sum.append_load(unitgroup_load.load_sum_))) {
2737LOG_WARN("append load failed", K(ret));
2738} else {} // no more to do
2739}
2740}
2741}
2742ResourceSum resource_sum;
2743for (int64_t i = 0; OB_SUCC(ret) && i < available_servers.count(); ++i) {
2744const common::ObAddr &server = available_servers.at(i);
2745share::ObServerResourceInfo resource_info;
2746if (OB_FAIL(server_mgr_->get_server_resource_info(server, resource_info))) {
2747LOG_WARN("fail to get server resource_info", KR(ret), K(server));
2748} else if (OB_FAIL(resource_sum.append_resource(resource_info))) {
2749LOG_WARN("fail to append resource", K(ret));
2750} else {} // no more to do
2751}
2752for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
2753ObResourceType resource_type = static_cast<ObResourceType>(i);
2754const double required = load_sum.get_required(resource_type);
2755const double capacity = resource_sum.get_capacity(resource_type);
2756if (required <= 0 || capacity <= 0) {
2757resource_weights[resource_type] = 0.0;
2758} else if (required >= capacity) {
2759resource_weights[resource_type] = 1.0;
2760} else {
2761resource_weights[resource_type] = required / capacity;
2762}
2763}
2764if (OB_SUCC(ret)) { // Weight normalization
2765double sum = 0.0;
2766const int64_t N = available_servers.count();
2767for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
2768resource_weights[i] /= static_cast<double>(N);
2769sum += resource_weights[i];
2770if (resource_weights[i] < 0 || resource_weights[i] > 1) {
2771ret = common::OB_ERR_UNEXPECTED;
2772LOG_ERROR("weight shall be in interval [0,1]", K(i), "w", resource_weights[i]);
2773}
2774}
2775if (OB_SUCC(ret) && sum > 0) {
2776for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
2777resource_weights[i] /= sum;
2778}
2779}
2780}
2781}
2782return ret;
2783}
2784
2785int ObServerBalancer::append_alien_ug_loads(
2786ServerLoad &server_load,
2787const common::ObIArray<TenantGroupBalanceInfo *> &tenant_groups,
2788common::ObIArray<UnitGroupLoad> &sys_tenant_ug_loads)
2789{
2790int ret = OB_SUCCESS;
2791if (OB_UNLIKELY(!inited_)) {
2792ret = OB_NOT_INIT;
2793LOG_WARN("not init", K(ret));
2794} else {
2795for (int64_t i = 0; OB_SUCC(ret) && i < sys_tenant_ug_loads.count(); ++i) {
2796UnitGroupLoad &unitgroup_load = sys_tenant_ug_loads.at(i);
2797if (server_load.server_ != unitgroup_load.server_) {
2798// not the same server
2799} else if (FALSE_IT(unitgroup_load.server_load_ = &server_load)) {
2800// will never be here
2801} else if (OB_FAIL(server_load.alien_ug_loads_.push_back(&unitgroup_load))) {
2802LOG_WARN("fail to push back", K(ret));
2803} else {} // no more to do
2804}
2805for (int64_t i = 0; OB_SUCC(ret) && i < tenant_groups.count(); ++i) {
2806TenantGroupBalanceInfo *balance_info = tenant_groups.at(i);
2807if (OB_UNLIKELY(NULL == balance_info)) {
2808ret = OB_ERR_UNEXPECTED;
2809LOG_WARN("balance info ptr is null", K(ret), KP(balance_info));
2810} else {
2811for (int64_t i = 0;
2812OB_SUCC(ret) && i < balance_info->unitgroup_load_array_.count();
2813++i) {
2814UnitGroupLoad &unitgroup_load = balance_info->unitgroup_load_array_.at(i);
2815if (OB_UNLIKELY(!unitgroup_load.is_valid())) {
2816ret = OB_ERR_UNEXPECTED;
2817LOG_WARN("unitgroup load is invalid, unexpected", K(ret), K(unitgroup_load));
2818} else if (server_load.server_ != unitgroup_load.server_) {
2819// not the same server
2820} else if (OB_FAIL(server_load.alien_ug_loads_.push_back(&unitgroup_load))) {
2821LOG_WARN("fail to push back", K(ret));
2822} else {} // no more to do
2823}
2824}
2825}
2826}
2827return ret;
2828}
2829
2830int ObServerBalancer::generate_inter_ttg_server_loads(
2831TenantGroupBalanceInfo *info_need_amend,
2832const common::ObIArray<TenantGroupBalanceInfo *> &stable_tenant_group,
2833common::ObIArray<UnitGroupLoad> &sys_tenant_ug_loads,
2834const common::ObIArray<common::ObAddr> &available_servers)
2835{
2836int ret = OB_SUCCESS;
2837UNUSED(available_servers);
2838if (OB_UNLIKELY(!inited_)) {
2839ret = OB_NOT_INIT;
2840LOG_WARN("not init", K(ret));
2841} else if (OB_UNLIKELY(NULL == info_need_amend || available_servers.count() <= 0)) {
2842ret = OB_INVALID_ARGUMENT;
2843LOG_WARN("invalid argument", K(ret), KP(info_need_amend),
2844"server_count", available_servers.count());
2845} else {
2846common::ObArray<ServerLoad> &target_server_loads = info_need_amend->server_load_array_;
2847for (int64_t i = 0; OB_SUCC(ret) && i < target_server_loads.count(); ++i) {
2848ServerLoad &server_load = target_server_loads.at(i);
2849if (!server_load.is_valid()) {
2850ret = OB_ERR_UNEXPECTED;
2851LOG_WARN("should be a valid server load here", K(ret), K(server_load));
2852} else {
2853for (int32_t j = RES_CPU; j < RES_MAX; ++j) {
2854server_load.inter_weights_[j] = info_need_amend->inter_weights_[j];
2855}
2856}
2857}
2858for (int64_t i = 0; OB_SUCC(ret) && i < target_server_loads.count(); ++i) {
2859target_server_loads.at(i).alien_ug_loads_.reset();
2860if (OB_FAIL(append_alien_ug_loads(
2861target_server_loads.at(i), stable_tenant_group, sys_tenant_ug_loads))) {
2862LOG_WARN("fail to append alien ug loads", K(ret));
2863} else if (OB_FAIL(target_server_loads.at(i).update_load_value())) {
2864LOG_WARN("fail to update load value", K(ret));
2865}
2866}
2867}
2868return ret;
2869}
2870
2871int ObServerBalancer::do_amend_inter_ttg_balance(
2872TenantGroupBalanceInfo *balance_info,
2873const common::ObIArray<TenantGroupBalanceInfo *> &stable_tenant_group,
2874common::ObIArray<ServerLoad> &server_loads)
2875{
2876int ret = OB_SUCCESS;
2877UNUSED(stable_tenant_group);
2878common::ObArray<ServerLoad *> server_load_ptrs_sorted;
2879common::ObArray<ServerLoad *> over_server_loads;
2880common::ObArray<ServerLoad *> under_server_loads;
2881double upper_lmt = 0.0;
2882if (OB_UNLIKELY(!inited_)) {
2883ret = OB_NOT_INIT;
2884LOG_WARN("not init", K(ret));
2885} else if (OB_UNLIKELY(NULL == balance_info
2886|| server_loads.count() <= 0)) {
2887ret = OB_INVALID_ARGUMENT;
2888LOG_WARN("invalid argument", K(ret), KP(balance_info),
2889"server_load_count", server_loads.count());
2890} else if (OB_FAIL(server_load_ptrs_sorted.reserve(server_loads.count()))) {
2891LOG_WARN("fail to reserve", K(ret));
2892} else if (OB_FAIL(over_server_loads.reserve(server_loads.count()))) {
2893LOG_WARN("fail to reserve", K(ret));
2894} else if (OB_FAIL(under_server_loads.reserve(server_loads.count()))) {
2895LOG_WARN("fail to reserve", K(ret));
2896} else {
2897for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
2898ServerLoad &server_load = server_loads.at(i);
2899if (OB_FAIL(server_load_ptrs_sorted.push_back(&server_load))) {
2900LOG_WARN("fail to push back", K(ret));
2901}
2902}
2903if (OB_SUCC(ret)) {
2904InterServerLoadCmp cmp;
2905std::sort(server_load_ptrs_sorted.begin(), server_load_ptrs_sorted.end(), cmp);
2906if (OB_FAIL(cmp.get_ret())) {
2907LOG_WARN("fail to sort server load ptrs", K(ret));
2908} else if (OB_FAIL(sort_server_loads_for_balance(
2909server_load_ptrs_sorted, over_server_loads, under_server_loads, upper_lmt))) {
2910LOG_WARN("fail to sort server loads for inter ttg balance", K(ret));
2911} else if (OB_FAIL(make_inter_ttg_server_under_load(
2912balance_info, over_server_loads, under_server_loads, upper_lmt))) {
2913LOG_WARN("fail to make inter ttg server under load", K(ret));
2914} else if (OB_FAIL(inner_ttg_balance_strategy_.coordinate_all_column_unit_group(
2915balance_info->column_unit_num_array_, balance_info->unit_migrate_stat_matrix_,
2916balance_info->unitgroup_load_array_))) {
2917LOG_WARN("fail to coordinate column units", K(ret));
2918}
2919}
2920}
2921return ret;
2922}
2923
2924int ObServerBalancer::sort_server_loads_for_balance(
2925common::ObIArray<ServerLoad *> &complete_server_loads,
2926common::ObIArray<ServerLoad *> &over_server_loads,
2927common::ObIArray<ServerLoad *> &under_server_loads,
2928double &upper_lmt)
2929{
2930int ret = OB_SUCCESS;
2931if (OB_UNLIKELY(!inited_)) {
2932ret = OB_NOT_INIT;
2933LOG_WARN("not init", K(ret));
2934} else if (OB_UNLIKELY(complete_server_loads.count() <= 0)) {
2935ret = OB_INVALID_ARGUMENT;
2936LOG_WARN("invalid argument", K(ret), "server_load_count", complete_server_loads.count());
2937} else {
2938over_server_loads.reset();
2939under_server_loads.reset();
2940double sum_load = 0.0;
2941for (int64_t i = 0; OB_SUCC(ret) && i < complete_server_loads.count(); ++i) {
2942const ServerLoad *server_load = complete_server_loads.at(i);
2943if (OB_UNLIKELY(NULL == server_load)) {
2944ret = OB_ERR_UNEXPECTED;
2945LOG_WARN("server load ptr is null", K(ret), KP(server_load));
2946} else {
2947sum_load += server_load->inter_ttg_load_value_;
2948}
2949}
2950const int64_t cpu_mem_tolerance = GCONF.server_balance_cpu_mem_tolerance_percent;
2951const double delta_percent = static_cast<double>(cpu_mem_tolerance) / static_cast<double>(100);
2952const double average_load = sum_load / static_cast<double>(complete_server_loads.count());
2953upper_lmt = average_load + delta_percent * average_load;
2954for (int64_t i = 0; OB_SUCC(ret) && i < complete_server_loads.count(); ++i) {
2955ServerLoad *server_load = complete_server_loads.at(i);
2956if (OB_UNLIKELY(NULL == server_load)) {
2957ret = OB_ERR_UNEXPECTED;
2958LOG_WARN("server load ptr is null", K(ret), KP(server_load));
2959} else if (server_load->inter_ttg_load_value_ >= upper_lmt) {
2960if (OB_FAIL(over_server_loads.push_back(server_load))) {
2961LOG_WARN("fail to push back", K(ret));
2962}
2963} else {
2964if (OB_FAIL(under_server_loads.push_back(server_load))) {
2965LOG_WARN("fail to push back", K(ret));
2966}
2967}
2968}
2969}
2970return ret;
2971}
2972
2973int ObServerBalancer::make_inter_ttg_server_under_load(
2974TenantGroupBalanceInfo *balance_info,
2975common::ObIArray<ServerLoad *> &over_server_loads,
2976common::ObIArray<ServerLoad *> &under_server_loads,
2977const double inter_ttg_upper_lmt)
2978{
2979int ret = OB_SUCCESS;
2980double hard_limit = 0.0;
2981if (OB_UNLIKELY(!inited_)) {
2982ret = OB_NOT_INIT;
2983LOG_WARN("not init", K(ret));
2984} else if (OB_UNLIKELY(NULL == balance_info)) {
2985ret = OB_INVALID_ARGUMENT;
2986LOG_WARN("invalid balance info", K(ret), KP(balance_info));
2987} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
2988ret = OB_ERR_UNEXPECTED;
2989LOG_WARN("unit_mgr_ ptr is null", K(ret));
2990} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
2991LOG_WARN("fail to get hard limit", K(ret));
2992} else {
2993double upper_limit = std::min(inter_ttg_upper_lmt, hard_limit);
2994for (int64_t i = 0; OB_SUCC(ret) && i < over_server_loads.count(); ++i) {
2995ServerLoad *over_server_load = over_server_loads.at(i);
2996for (int64_t j = under_server_loads.count() - 1; OB_SUCC(ret) && j >= 0; --j) {
2997ServerLoad *under_server_load = under_server_loads.at(j);
2998if (OB_FAIL(amend_ug_inter_ttg_server_load(
2999over_server_load, under_server_load, balance_info, upper_limit))) {
3000LOG_WARN("fail to amend ug inter ttg server load", K(ret));
3001}
3002}
3003}
3004}
3005return ret;
3006}
3007
3008int ObServerBalancer::amend_ug_inter_ttg_server_load(
3009ServerLoad *src_inter_load,
3010ServerLoad *dst_inter_load,
3011TenantGroupBalanceInfo *balance_info,
3012const double inter_ttg_upper_lmt)
3013{
3014int ret = OB_SUCCESS;
3015if (OB_UNLIKELY(!inited_)) {
3016ret = OB_NOT_INIT;
3017LOG_WARN("not init", K(ret));
3018} else if (OB_UNLIKELY(NULL == src_inter_load
3019|| NULL == dst_inter_load
3020|| NULL == balance_info)) {
3021ret = OB_INVALID_ARGUMENT;
3022LOG_WARN("invalid argument", K(ret), KP(src_inter_load),
3023KP(dst_inter_load), KP(balance_info));
3024} else if (OB_FAIL(inner_ttg_balance_strategy_.amend_ug_inter_ttg_server_load(
3025src_inter_load, dst_inter_load, balance_info, inter_ttg_upper_lmt))) {
3026LOG_WARN("fail to amend ug inter ttg server load", K(ret));
3027}
3028return ret;
3029}
3030
3031int ObServerBalancer::CountBalanceStrategy::amend_ug_inter_ttg_server_load(
3032ServerLoad *src_inter_load,
3033ServerLoad *dst_inter_load,
3034TenantGroupBalanceInfo *balance_info,
3035const double inter_ttg_upper_lmt)
3036{
3037int ret = OB_SUCCESS;
3038UNUSED(inter_ttg_upper_lmt);
3039if (OB_UNLIKELY(NULL == src_inter_load
3040|| NULL == dst_inter_load
3041|| NULL == balance_info)) {
3042ret = OB_INVALID_ARGUMENT;
3043LOG_WARN("invalid argument", K(ret), KP(src_inter_load),
3044KP(dst_inter_load), KP(balance_info));
3045} else {
3046ObIArray<UnitGroupLoad> &unitgroup_loads = balance_info->unitgroup_load_array_;
3047if (unitgroup_loads.count() <= 0) {
3048ret = OB_ERR_UNEXPECTED;
3049LOG_WARN("unit group load or server load empty", K(ret), K(unitgroup_loads));
3050} else {
3051if (src_inter_load->unitgroup_loads_.count() == dst_inter_load->unitgroup_loads_.count()) {
3052if (OB_FAIL(try_exchange_ug_balance_inter_ttg_load(
3053*src_inter_load, *dst_inter_load, balance_info,
3054unitgroup_loads, inter_ttg_upper_lmt))) {
3055LOG_WARN("fail to exchange ug balance inter ttg load", K(ret));
3056}
3057} else if (OB_FAIL(try_move_single_ug_balance_inter_ttg_load(
3058*src_inter_load, *dst_inter_load, balance_info, inter_ttg_upper_lmt))) {
3059LOG_WARN("fail to try move ug balance inter ttg load", K(ret));
3060} else if (OB_FAIL(try_exchange_ug_balance_inter_ttg_load(
3061*src_inter_load, *dst_inter_load, balance_info,
3062unitgroup_loads, inter_ttg_upper_lmt))) {
3063LOG_WARN("fail to try exchange ug balance inter ttg load", K(ret));
3064}
3065}
3066}
3067return ret;
3068}
3069
3070int ObServerBalancer::CountBalanceStrategy::try_exchange_ug_balance_inter_ttg_load(
3071ServerLoad &src_inter_load,
3072ServerLoad &dst_inter_load,
3073TenantGroupBalanceInfo *balance_info,
3074common::ObIArray<UnitGroupLoad> &unitgroup_loads,
3075const double inter_ttg_upper_lmt)
3076{
3077int ret = OB_SUCCESS;
3078if (OB_UNLIKELY(NULL == balance_info)) {
3079ret = OB_INVALID_ARGUMENT;
3080LOG_WARN("invalid argument", K(ret), KP(balance_info));
3081} else {
3082int64_t max_times = src_inter_load.unitgroup_loads_.count()
3083+ dst_inter_load.unitgroup_loads_.count();
3084if (max_times >= INT32_MAX) {
3085ret = OB_ERR_UNEXPECTED;
3086LOG_WARN("unitgroup loads cnt is so large", K(ret));
3087} else {
3088max_times = max_times * max_times;
3089}
3090int64_t times = 0;
3091while (OB_SUCC(ret)
3092&& times < max_times
3093&& src_inter_load.inter_ttg_load_value_ - dst_inter_load.inter_ttg_load_value_ > EPSILON) {
3094bool do_exchange = false;
3095if (OB_FAIL(try_exchange_ug_balance_inter_ttg_load_foreach(
3096src_inter_load, dst_inter_load, balance_info,
3097unitgroup_loads, inter_ttg_upper_lmt, do_exchange))) {
3098LOG_WARN("fail to exchange ug balance inter ttg load foreach", K(ret));
3099} else if (!do_exchange) {
3100break;
3101} else {
3102times++;
3103}
3104}
3105}
3106return ret;
3107}
3108
3109int ObServerBalancer::CountBalanceStrategy::try_exchange_ug_balance_inter_ttg_load_foreach(
3110ServerLoad &left_inter_load,
3111ServerLoad &right_inter_load,
3112TenantGroupBalanceInfo *balance_info,
3113common::ObIArray<UnitGroupLoad> &unitgroup_loads,
3114const double inter_ttg_upper_lmt,
3115bool &do_exchange)
3116{
3117int ret = OB_SUCCESS;
3118do_exchange = false;
3119if (OB_UNLIKELY(NULL == balance_info)) {
3120ret = OB_INVALID_ARGUMENT;
3121LOG_WARN("invalid argument", K(ret), KP(balance_info));
3122} else if (left_inter_load.inter_ttg_load_value_
3123- right_inter_load.inter_ttg_load_value_ <= EPSILON) {
3124// ignore, since this almost has no effect for load balance
3125} else {
3126for (int64_t i = 0;
3127!do_exchange && OB_SUCC(ret) && i < left_inter_load.unitgroup_loads_.count();
3128++i) {
3129common::ObArray<common::ObAddr> excluded_servers;
3130UnitGroupLoad *left_ug = left_inter_load.unitgroup_loads_.at(i);
3131if (OB_UNLIKELY(NULL == left_ug)) {
3132ret = OB_ERR_UNEXPECTED;
3133LOG_WARN("src ug ptr is null", K(ret), KP(left_ug));
3134} else if (left_inter_load.inter_ttg_load_value_ < inter_ttg_upper_lmt) {
3135break;
3136} else if (OB_FAIL(get_ug_balance_excluded_dst_servers(
3137*left_ug, unitgroup_loads, excluded_servers))) {
3138LOG_WARN("fail to get excluded server", K(ret));
3139} else if (has_exist_in_array(excluded_servers, right_inter_load.server_)) {
3140// ignore this
3141} else {
3142for (int64_t j = right_inter_load.unitgroup_loads_.count() - 1;
3143!do_exchange && OB_SUCC(ret) && j >= 0;
3144--j) {
3145// When calculating ug load, the denominator used is right server load
3146double left_ug_load_value = 0.0;
3147double right_ug_load_value = 0.0;
3148UnitGroupLoad *right_ug = right_inter_load.unitgroup_loads_.at(j);
3149bool can_exchange = false;
3150if (NULL == right_ug) {
3151ret = OB_ERR_UNEXPECTED;
3152LOG_WARN("src or dst ug ptr is null", K(ret), KP(right_ug));
3153} else if (left_ug->column_tenant_id_ == right_ug->column_tenant_id_) {
3154// ignore this
3155} else if (OB_FAIL(get_ug_balance_excluded_dst_servers(
3156*right_ug, unitgroup_loads, excluded_servers))) {
3157LOG_WARN("fail to get excluded servers", K(ret));
3158} else if (has_exist_in_array(excluded_servers, left_inter_load.server_)) {
3159// ignore this
3160} else if (left_ug->get_inter_ttg_load_value(right_inter_load, left_ug_load_value)) {
3161LOG_WARN("fail to get inter ttg load value", K(ret));
3162} else if (right_ug->get_inter_ttg_load_value(right_inter_load, right_ug_load_value)) {
3163LOG_WARN("fail to get inter ttg load value", K(ret));
3164} else if (left_ug_load_value - right_ug_load_value <= EPSILON) {
3165// ignore this, since this almost has no effect for load balance
3166} else if (right_inter_load.inter_ttg_load_value_
3167+ left_ug_load_value - right_ug_load_value >= inter_ttg_upper_lmt) {
3168// ignore this
3169} else if (OB_FAIL(check_can_exchange_ug_balance_inter_ttg_load(
3170*left_ug, left_inter_load, *right_ug, right_inter_load, can_exchange))) {
3171LOG_WARN("fail to check can exchange ug balance inter ttg load", K(ret));
3172} else if (!can_exchange) {
3173// ignore this
3174} else if (OB_FAIL(exchange_ug_between_server_loads(
3175*left_ug, i, left_inter_load, *right_ug, j, right_inter_load))) {
3176LOG_WARN("fail to exchange ug between server loads", K(ret));
3177} else if (OB_FAIL(coordinate_single_column_unit_group(
3178left_ug->start_column_idx_, left_ug->column_count_,
3179balance_info->unit_migrate_stat_matrix_,
3180balance_info->unitgroup_load_array_))) {
3181LOG_WARN("fail to coordinate single column unit", K(ret));
3182} else if (OB_FAIL(coordinate_single_column_unit_group(
3183right_ug->start_column_idx_, right_ug->column_count_,
3184balance_info->unit_migrate_stat_matrix_,
3185balance_info->unitgroup_load_array_))) {
3186LOG_WARN("fail to coordinate single column unit", K(ret));
3187} else {
3188do_exchange = true;
3189}
3190}
3191}
3192}
3193if (OB_SUCC(ret)) {
3194UnitGroupLoadCmp unitgroup_load_cmp(left_inter_load);
3195std::sort(left_inter_load.unitgroup_loads_.begin(),
3196left_inter_load.unitgroup_loads_.end(),
3197unitgroup_load_cmp);
3198if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
3199LOG_WARN("fail to sort", K(ret));
3200}
3201}
3202if (OB_SUCC(ret)) {
3203UnitGroupLoadCmp unitgroup_load_cmp(right_inter_load);
3204std::sort(right_inter_load.unitgroup_loads_.begin(),
3205right_inter_load.unitgroup_loads_.end(),
3206unitgroup_load_cmp);
3207if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
3208LOG_WARN("fail to sort", K(ret));
3209}
3210}
3211}
3212return ret;
3213}
3214
3215int ObServerBalancer::CountBalanceStrategy::try_move_single_ug_balance_inter_ttg_load(
3216ServerLoad &src_inter_load,
3217ServerLoad &dst_inter_load,
3218TenantGroupBalanceInfo *balance_info,
3219const double inter_ttg_upper_lmt)
3220{
3221int ret = OB_SUCCESS;
3222if (OB_UNLIKELY(NULL == balance_info)) {
3223ret = OB_INVALID_ARGUMENT;
3224LOG_WARN("invalid argument", K(ret), KP(balance_info));
3225} else {
3226common::ObIArray<UnitGroupLoad> &unitgroup_loads = balance_info->unitgroup_load_array_;
3227if (src_inter_load.unitgroup_loads_.count() <= dst_inter_load.unitgroup_loads_.count()) {
3228// ignore since, src intra cnt is not greater than dst
3229} else if (src_inter_load.inter_ttg_load_value_ <= dst_inter_load.inter_ttg_load_value_) {
3230// ignore since src intra load is not greater than dst
3231} else {
3232ObArray<common::ObAddr> excluded_dst_servers;
3233for (int64_t i = src_inter_load.unitgroup_loads_.count() - 1;
3234OB_SUCC(ret) && i >= 0;
3235--i) {
3236UnitGroupLoad &ug_load = *src_inter_load.unitgroup_loads_.at(i);
3237double ug_load_value = 0.0;
3238bool can_move = false;
3239excluded_dst_servers.reset();
3240if (OB_FAIL(get_ug_balance_excluded_dst_servers(
3241ug_load, unitgroup_loads, excluded_dst_servers))) {
3242LOG_WARN("fail to get excluded server", K(ret));
3243} else if (has_exist_in_array(excluded_dst_servers, dst_inter_load.server_)) {
3244// in excluded servers, ignore
3245} else if (OB_FAIL(ug_load.get_inter_ttg_load_value(dst_inter_load, ug_load_value))) {
3246LOG_WARN("fail to get inter ttg load value", K(ret));
3247} else if (dst_inter_load.inter_ttg_load_value_ + ug_load_value >= inter_ttg_upper_lmt) {
3248// ignore, since this amendment will violate the balance in terms of inter ttg
3249} else if (OB_FAIL(check_can_move_ug_balance_inter_ttg_load(
3250src_inter_load, ug_load, dst_inter_load, can_move))) {
3251LOG_WARN("fail to check can move ug balance inter ttg load", K(ret));
3252} else if (!can_move) {
3253// ignore
3254} else if (OB_FAIL(move_ug_between_server_loads(
3255src_inter_load, dst_inter_load, ug_load, i))) {
3256LOG_WARN("fail to move ug between server loads", K(ret));
3257} else if (OB_FAIL(coordinate_single_column_unit_group(
3258ug_load.start_column_idx_, ug_load.column_count_,
3259balance_info->unit_migrate_stat_matrix_,
3260balance_info->unitgroup_load_array_))) {
3261LOG_WARN("fail to coordinate single column unit", K(ret));
3262} else {
3263break;
3264}
3265}
3266if (OB_SUCC(ret)) {
3267UnitGroupLoadCmp unitgroup_load_cmp(src_inter_load);
3268std::sort(src_inter_load.unitgroup_loads_.begin(),
3269src_inter_load.unitgroup_loads_.end(),
3270unitgroup_load_cmp);
3271if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
3272LOG_WARN("fail to sort", K(ret));
3273}
3274}
3275if (OB_SUCC(ret)) {
3276UnitGroupLoadCmp unitgroup_load_cmp(dst_inter_load);
3277std::sort(dst_inter_load.unitgroup_loads_.begin(),
3278dst_inter_load.unitgroup_loads_.end(),
3279unitgroup_load_cmp);
3280if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
3281LOG_WARN("fail to sort", K(ret));
3282}
3283}
3284}
3285}
3286return ret;
3287}
3288
3289int ObServerBalancer::try_execute_unit_balance_task(
3290const common::ObZone &zone,
3291TenantGroupBalanceInfo *info_need_amend,
3292const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
3293const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
3294const common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group,
3295const common::ObIArray<common::ObAddr> &available_servers,
3296bool &do_amend)
3297{
3298int ret = OB_SUCCESS;
3299common::ObArray<UnitMigrateStat *> task_array;
3300if (OB_UNLIKELY(!inited_)) {
3301ret = OB_NOT_INIT;
3302LOG_WARN("not init", K(ret));
3303} else if (OB_UNLIKELY(NULL == info_need_amend)) {
3304ret = OB_INVALID_ARGUMENT;
3305LOG_WARN("invalid argument", K(ret));
3306} else if (info_need_amend->is_stable()) {
3307do_amend = false; // balance info is stable, no need to execute unit balance task
3308} else if (info_need_amend->unit_migrate_stat_matrix_.get_element_count() <= 0
3309|| info_need_amend->unit_migrate_stat_matrix_.get_element_count() >= INT32_MAX) {
3310ret = OB_INVALID_ARGUMENT;
3311LOG_WARN("invalid argument", K(ret), K(*info_need_amend));
3312} else if (OB_FAIL(task_array.reserve(
3313info_need_amend->unit_migrate_stat_matrix_.get_element_count()))) {
3314LOG_WARN("fail to reserve", K(ret));
3315} else if (OB_FAIL(generate_unit_balance_task(*info_need_amend, task_array))) {
3316LOG_WARN("fail to generate unit balance task", K(ret));
3317} else if (task_array.count() <= 0) {
3318if (OB_FAIL(vacate_space_for_ttg_balance(
3319zone, *info_need_amend, standalone_units, not_grant_units,
3320unstable_tenant_group, available_servers, do_amend))) {
3321LOG_WARN("fail to vacate space for ttg balance", K(ret));
3322}
3323} else if (OB_FAIL(do_migrate_unit_task(task_array))) {
3324LOG_WARN("fail to do migrate unit task array", K(ret));
3325} else {
3326do_amend = true; // A migration task is executed
3327}
3328return ret;
3329}
3330
3331int ObServerBalancer::do_migrate_unit_task(
3332const common::ObIArray<UnitMigrateStat> &task_array)
3333{
3334int ret = OB_SUCCESS;
3335if (OB_UNLIKELY(!inited_)) {
3336ret = OB_NOT_INIT;
3337LOG_WARN("not init", K(ret));
3338} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
3339ret = OB_ERR_UNEXPECTED;
3340LOG_WARN("unit_mgr_ ptr is null", K(ret), KP(unit_mgr_));
3341} else {
3342for (int64_t i = 0; OB_SUCC(ret) && i < task_array.count(); ++i) {
3343ObUnitStat unit_stat;
3344ObArray<ObUnitStat> in_migrate_unit_stat;
3345const UnitMigrateStat &unit_migrate_stat = task_array.at(i);
3346bool can_migrate_in = false;
3347if (!unit_migrate_stat.unit_load_.is_valid()) {
3348ret = OB_ERR_UNEXPECTED;
3349LOG_WARN("invalid argument", K(ret), "unit_load", unit_migrate_stat.unit_load_);
3350} else if (OB_FAIL(SVR_TRACER.check_server_can_migrate_in(
3351unit_migrate_stat.arranged_pos_, can_migrate_in))) {
3352LOG_WARN("fail to check can migrate in", K(ret));
3353} else if (!can_migrate_in) {
3354// bypass
3355} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
3356unit_migrate_stat.unit_load_.unit_->unit_id_,
3357unit_migrate_stat.unit_load_.unit_->zone_,
3358unit_stat))) {
3359LOG_WARN("fail to get unit stat", K(ret));
3360} else if (OB_FAIL(get_unit_resource_reservation(
3361unit_migrate_stat.unit_load_.unit_->unit_id_, unit_migrate_stat.arranged_pos_,
3362in_migrate_unit_stat))) {
3363LOG_WARN("fail to get unit resource reservation", K(ret));
3364} else if (OB_FAIL(try_migrate_unit(
3365unit_migrate_stat.unit_load_.unit_->unit_id_,
3366unit_migrate_stat.unit_load_.pool_->tenant_id_, unit_stat,
3367in_migrate_unit_stat, unit_migrate_stat.arranged_pos_))) {
3368if (OB_OP_NOT_ALLOW == ret) {
3369LOG_INFO("cannot migrate unit, server full",
3370"unit", *unit_migrate_stat.unit_load_.unit_,
3371"dst_server", unit_migrate_stat.arranged_pos_);
3372ret = OB_SUCCESS; // ingore this unit
3373} else {
3374LOG_WARN("fail to migrate unit", K(ret),
3375"unit", *unit_migrate_stat.unit_load_.unit_,
3376"dst_server", unit_migrate_stat.arranged_pos_);
3377}
3378} else {} // no more to do
3379}
3380}
3381return ret;
3382}
3383
3384int ObServerBalancer::do_migrate_unit_task(
3385const common::ObIArray<UnitMigrateStat *> &task_array)
3386{
3387int ret = OB_SUCCESS;
3388if (OB_UNLIKELY(!inited_)) {
3389ret = OB_NOT_INIT;
3390LOG_WARN("not init", K(ret));
3391} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
3392ret = OB_ERR_UNEXPECTED;
3393LOG_WARN("unit_mgr_ ptr is null", K(ret), KP(unit_mgr_));
3394} else {
3395for (int64_t i = 0; OB_SUCC(ret) && i < task_array.count(); ++i) {
3396ObUnitStat unit_stat;
3397ObArray<ObUnitStat> in_migrate_unit_stat;
3398const UnitMigrateStat *unit_migrate_stat = task_array.at(i);
3399bool can_migrate_in = false;
3400if (OB_UNLIKELY(NULL == unit_migrate_stat)) {
3401ret = OB_ERR_UNEXPECTED;
3402LOG_WARN("unit migrate stat ptr is null", K(ret), KP(unit_migrate_stat));
3403} else if (!unit_migrate_stat->unit_load_.is_valid()) {
3404ret = OB_ERR_UNEXPECTED;
3405LOG_WARN("invalid argument", K(ret), "unit_load", unit_migrate_stat->unit_load_);
3406} else if (OB_FAIL(SVR_TRACER.check_server_can_migrate_in(
3407unit_migrate_stat->arranged_pos_,
3408can_migrate_in))) {
3409LOG_WARN("fail to check can migrate in", K(ret));
3410} else if (!can_migrate_in) {
3411// bypass
3412} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
3413unit_migrate_stat->unit_load_.unit_->unit_id_,
3414unit_migrate_stat->unit_load_.unit_->zone_,
3415unit_stat))) {
3416LOG_WARN("fail to get unit stat", K(ret));
3417} else if (OB_FAIL(get_unit_resource_reservation(
3418unit_migrate_stat->unit_load_.unit_->unit_id_, unit_migrate_stat->arranged_pos_,
3419in_migrate_unit_stat))) {
3420LOG_WARN("fail to get unit resource reservation", K(ret));
3421} else if (OB_FAIL(try_migrate_unit(
3422unit_migrate_stat->unit_load_.unit_->unit_id_,
3423unit_migrate_stat->unit_load_.pool_->tenant_id_, unit_stat,
3424in_migrate_unit_stat, unit_migrate_stat->arranged_pos_))) {
3425if (OB_OP_NOT_ALLOW == ret) {
3426LOG_INFO("cannot migrate unit, server full",
3427"unit", *unit_migrate_stat->unit_load_.unit_,
3428"dst_server", unit_migrate_stat->arranged_pos_);
3429ret = OB_SUCCESS; // ingore this unit
3430} else {
3431LOG_WARN("fail to migrate unit", K(ret),
3432"unit", *unit_migrate_stat->unit_load_.unit_,
3433"dst_server", unit_migrate_stat->arranged_pos_);
3434}
3435} else {} // no more to do
3436}
3437}
3438return ret;
3439}
3440
3441// 1. Try to perform all tasks in the matrix, if all tasks cannot be performed
3442// 2. Try to execute the first row of tasks in the matrix,
3443// if the first row of tasks cannot be executed
3444// 3. Try to execute the first task in the matrix,
3445// if the first one cannot be executed, give up
3446int ObServerBalancer::generate_unit_balance_task(
3447TenantGroupBalanceInfo &balance_info,
3448common::ObIArray<UnitMigrateStat *> &task_array)
3449{
3450int ret = OB_SUCCESS;
3451LOG_INFO("tenant group migrate unit stat matrix",
3452"unit migrate stat matrix", balance_info.unit_migrate_stat_matrix_);
3453if (OB_UNLIKELY(!inited_)) {
3454ret = OB_NOT_INIT;
3455LOG_WARN("not init", K(ret));
3456} else if (OB_FAIL(try_generate_square_task_from_ttg_matrix(
3457balance_info.unit_migrate_stat_matrix_, task_array))) {
3458LOG_WARN("fail to generate balance task from ttg matrix", K(ret));
3459} else if (task_array.count() > 0) {
3460// good, has task generated
3461} else if (OB_FAIL(try_generate_line_task_from_ttg_matrix(
3462balance_info.unit_migrate_stat_matrix_, task_array))) {
3463LOG_WARN("fail to generate balance task from ttg matrix", K(ret));
3464} else if (task_array.count() > 0) {
3465// good, has task generated
3466} else if (OB_FAIL(try_generate_dot_task_from_ttg_matrix(
3467balance_info.unit_migrate_stat_matrix_, task_array))) {
3468LOG_WARN("fail to generate balance task from ttg matrix", K(ret));
3469} else if (task_array.count() > 0) {
3470// good, has task generated
3471} else {
3472// no task generated, sad
3473}
3474return ret;
3475}
3476
3477int ObServerBalancer::check_unit_migrate_stat_unit_collide(
3478UnitMigrateStat &unit_migrate_stat,
3479ObUnitManager::ObUnitLoad &collide_unit,
3480bool &tenant_unit_collide)
3481{
3482int ret = OB_SUCCESS;
3483common::ObArray<ObUnitManager::ObUnitLoad> zone_units;
3484if (OB_UNLIKELY(!inited_)) {
3485ret = OB_NOT_INIT;
3486LOG_WARN("not init", K(ret));
3487} else if (OB_UNLIKELY(common::OB_INVALID_ID == unit_migrate_stat.tenant_id_)) {
3488ret = OB_INVALID_ARGUMENT;
3489LOG_WARN("invalid argument", K(ret), K(unit_migrate_stat));
3490} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
3491ret = OB_ERR_UNEXPECTED;
3492LOG_WARN("unit_mgr_ ptr is null", K(ret));
3493} else if (OB_FAIL(unit_mgr_->get_tenant_zone_all_unit_loads(
3494unit_migrate_stat.tenant_id_, zone_disk_statistic_.zone_, zone_units))) {
3495LOG_WARN("fail to get tenant zone all unit loads", K(ret), K(unit_migrate_stat));
3496} else {
3497tenant_unit_collide = false;
3498for (int64_t i = 0; !tenant_unit_collide && OB_SUCC(ret) && i < zone_units.count(); ++i) {
3499ObUnitManager::ObUnitLoad &unit_load = zone_units.at(i);
3500if (!unit_load.is_valid()) {
3501ret = OB_ERR_UNEXPECTED;
3502LOG_WARN("unit load is invalid", K(ret), K(unit_load));
3503} else if (unit_load.unit_->server_ == unit_migrate_stat.arranged_pos_) {
3504tenant_unit_collide = true;
3505collide_unit = unit_load;
3506} else {} // good, go on to check next
3507}
3508}
3509return ret;
3510}
3511
3512int ObServerBalancer::accumulate_balance_task_loadsum(
3513const UnitMigrateStat &unit_migrate_stat,
3514common::ObIArray<ServerLoadSum> &server_load_sums)
3515{
3516int ret = OB_SUCCESS;
3517if (OB_UNLIKELY(!inited_)) {
3518ret = OB_NOT_INIT;
3519LOG_WARN("not init", K(ret));
3520} else if (OB_UNLIKELY(!unit_migrate_stat.unit_load_.is_valid())) {
3521ret = OB_INVALID_ARGUMENT;
3522LOG_WARN("invalid argument", K(ret));
3523} else {
3524ObUnitStat unit_stat;
3525int64_t idx = 0;
3526for (; idx < server_load_sums.count(); ++idx) {
3527ServerLoadSum &server_load_sum = server_load_sums.at(idx);
3528if (server_load_sum.server_ != unit_migrate_stat.arranged_pos_) {
3529// next
3530} else {
3531break; // find one
3532}
3533}
3534if (idx >= server_load_sums.count()) {
3535ServerLoadSum server_load_sum;
3536server_load_sum.server_ = unit_migrate_stat.arranged_pos_;
3537if (OB_FAIL(server_load_sums.push_back(server_load_sum))) {
3538LOG_WARN("fail to push back", K(ret));
3539}
3540}
3541if (OB_FAIL(ret)) {
3542} else if (idx >= server_load_sums.count()) {
3543ret = OB_ERR_UNEXPECTED;
3544LOG_WARN("server load sums count unexpecte", K(ret), K(idx));
3545} else if (OB_FAIL(server_load_sums.at(idx).load_sum_.append_load(
3546*unit_migrate_stat.unit_load_.unit_config_))) {
3547LOG_WARN("fail to append load", K(ret));
3548} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
3549unit_migrate_stat.unit_load_.unit_->unit_id_,
3550unit_migrate_stat.unit_load_.unit_->zone_,
3551unit_stat))) {
3552LOG_WARN("fail to get unit stat", K(ret));
3553} else {
3554server_load_sums.at(idx).disk_in_use_ += unit_stat.get_required_size();
3555}
3556}
3557return ret;
3558}
3559
3560int ObServerBalancer::check_servers_resource_enough(
3561const common::ObIArray<ServerLoadSum> &server_load_sums,
3562bool &enough)
3563{
3564int ret = OB_SUCCESS;
3565double hard_limit = 0.0;
3566double disk_waterlevel = 0.0;
3567if (OB_UNLIKELY(!inited_)) {
3568ret = OB_NOT_INIT;
3569LOG_WARN("not init", K(ret));
3570} else if (OB_ISNULL(unit_mgr_) || OB_ISNULL(server_mgr_)) {
3571ret = OB_ERR_UNEXPECTED;
3572LOG_WARN("unit_mgr_ or server_mgr_is null", K(ret), KP(unit_mgr_), KP(server_mgr_));
3573} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
3574LOG_WARN("fail to hard limit", K(ret));
3575} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
3576LOG_WARN("fail to get critical disk waterlevel", K(ret));
3577} else {
3578enough = true;
3579for (int64_t i = 0; OB_SUCC(ret) && enough && i < server_load_sums.count(); ++i) {
3580ObArray<ObUnitManager::ObUnitLoad> *unit_loads = NULL;
3581share::ObServerResourceInfo server_resource_info;
3582const common::ObAddr &server = server_load_sums.at(i).server_;
3583LoadSum load_sum = server_load_sums.at(i).load_sum_;
3584int64_t disk_in_use = server_load_sums.at(i).disk_in_use_;
3585ServerDiskStatistic disk_statistic;
3586if (OB_FAIL(zone_disk_statistic_.get_server_disk_statistic(server, disk_statistic))) {
3587LOG_WARN("fail to get disk statistic", K(ret), K(server));
3588} else if (OB_FAIL(server_mgr_->get_server_resource_info(server, server_resource_info))) {
3589// **TODO (linqiucen.lqc): temp.solution
3590LOG_WARN("fail to get server resource info", KR(ret), K(server));
3591} else if (OB_FAIL(unit_mgr_->get_loads_by_server(server, unit_loads))) {
3592if (OB_ENTRY_NOT_EXIST != ret) {
3593LOG_WARN("fail to get loads by server", K(ret));
3594} else {
3595ret = OB_SUCCESS;
3596// unit_loads does not exist, there is no load on this server
3597}
3598} else if (NULL == unit_loads) {
3599ret = OB_ERR_UNEXPECTED;
3600LOG_WARN("unit loads ptr is null", K(ret));
3601} else {
3602for (int64_t j = 0; OB_SUCC(ret) && j < unit_loads->count(); ++j) {
3603const ObUnitManager::ObUnitLoad &load = unit_loads->at(j);
3604if (!load.is_valid()) {
3605ret = OB_ERR_UNEXPECTED;
3606LOG_WARN("load is invalid", K(ret));
3607} else if (OB_FAIL(load_sum.append_load(*load.unit_config_))) {
3608LOG_WARN("fail to append", K(ret));
3609} else {} // no more to do
3610}
3611}
3612if (OB_SUCC(ret)) {
3613if (load_sum.load_sum_.max_cpu()
3614> server_resource_info.cpu_ * hard_limit
3615|| load_sum.load_sum_.min_cpu()
3616> server_resource_info.cpu_
3617|| static_cast<double>(load_sum.load_sum_.memory_size())
3618> static_cast<double>(server_resource_info.mem_total_)
3619|| static_cast<double>(load_sum.load_sum_.log_disk_size())
3620> static_cast<double>(server_resource_info.log_disk_total_)
3621|| static_cast<double>(disk_in_use + disk_statistic.disk_in_use_)
3622> static_cast<double>(disk_statistic.disk_total_) * disk_waterlevel) {
3623enough = false;
3624LOG_INFO("resource not enough", K(load_sum), K(hard_limit), K(disk_waterlevel),
3625K(disk_in_use), K(disk_statistic),
3626"server_load_sum", server_load_sums.at(i));
3627}
3628}
3629}
3630}
3631return ret;
3632}
3633
3634int ObServerBalancer::try_generate_square_task_from_ttg_matrix(
3635Matrix<UnitMigrateStat> &unit_migrate_stat_task,
3636common::ObIArray<UnitMigrateStat *> &task_array)
3637{
3638int ret = OB_SUCCESS;
3639task_array.reset();
3640common::ObArray<ServerLoadSum> server_load_sums;
3641if (OB_UNLIKELY(!inited_)) {
3642ret = OB_NOT_INIT;
3643LOG_WARN("not init", K(ret));
3644} else {
3645ObUnitManager::ObUnitLoad dummy_collide_unit;
3646bool tenant_unit_collide = false;
3647for (int64_t i = 0;
3648!tenant_unit_collide && OB_SUCC(ret) && i < unit_migrate_stat_task.get_row_count();
3649++i) {
3650for (int64_t j = 0;
3651!tenant_unit_collide && OB_SUCC(ret) && j < unit_migrate_stat_task.get_column_count();
3652++j) {
3653UnitMigrateStat *ptr = unit_migrate_stat_task.get(i, j);
3654if (OB_UNLIKELY(NULL == ptr)) {
3655ret = OB_ERR_UNEXPECTED;
3656LOG_WARN("unit migrate stat ptr is null", K(ret));
3657} else if (ptr->original_pos_ == ptr->arranged_pos_) {
3658// ignore since this do not need to migrate
3659} else if (OB_FAIL(check_unit_migrate_stat_unit_collide(
3660*ptr, dummy_collide_unit, tenant_unit_collide))) {
3661LOG_WARN("fail to check unit migrate stat unit collide", K(ret));
3662} else if (tenant_unit_collide) {
3663LOG_INFO("migrate unit collide", "migrate_unit", *ptr,
3664"collide_unit", dummy_collide_unit);
3665} else if (OB_FAIL(accumulate_balance_task_loadsum(*ptr, server_load_sums))) {
3666LOG_WARN("fail to accumulate balance task loadsum", K(ret));
3667} else if (OB_FAIL(task_array.push_back(ptr))) {
3668LOG_WARN("fail to push back", K(ret));
3669} else {} // no more to do
3670}
3671}
3672bool enough = true;
3673if (OB_FAIL(ret)) {
3674// previous procedure failed
3675} else if (tenant_unit_collide) {
3676task_array.reset();
3677// Matrix task cannot be executed at the same time, clear task
3678} else if (OB_FAIL(check_servers_resource_enough(server_load_sums, enough))) {
3679LOG_WARN("fail to check server resource capacity", K(ret));
3680} else if (enough) {
3681// good, return the task array
3682} else {
3683LOG_INFO("server resource not enough");
3684task_array.reset();
3685// Matrix task cannot be executed at the same time, clear task
3686}
3687}
3688return ret;
3689}
3690
3691int ObServerBalancer::try_generate_line_task_from_ttg_matrix(
3692Matrix<UnitMigrateStat> &unit_migrate_stat_task,
3693common::ObIArray<UnitMigrateStat *> &task_array)
3694{
3695int ret = OB_SUCCESS;
3696task_array.reset();
3697common::ObArray<ServerLoadSum> server_load_sums;
3698if (OB_UNLIKELY(!inited_)) {
3699ret = OB_NOT_INIT;
3700LOG_WARN("not init", K(ret));
3701} else {
3702ObUnitManager::ObUnitLoad dummy_collide_unit;
3703for (int64_t i = 0; OB_SUCC(ret) && i < unit_migrate_stat_task.get_row_count(); ++i) {
3704server_load_sums.reset();
3705bool enough = true;
3706bool tenant_unit_collide = false;
3707for (int64_t j = 0;
3708!tenant_unit_collide && OB_SUCC(ret) && j < unit_migrate_stat_task.get_column_count();
3709++j) {
3710UnitMigrateStat *ptr = unit_migrate_stat_task.get(i, j);
3711if (OB_UNLIKELY(NULL == ptr)) {
3712ret = OB_ERR_UNEXPECTED;
3713LOG_WARN("unit migrate stat ptr is null", K(ret));
3714} else if (ptr->original_pos_ == ptr->arranged_pos_) {
3715// ignore since this do not need to migrate
3716} else if (OB_FAIL(check_unit_migrate_stat_unit_collide(
3717*ptr, dummy_collide_unit, tenant_unit_collide))) {
3718LOG_WARN("fail to check unit migrate stat unit collide", K(ret));
3719} else if (tenant_unit_collide) {
3720LOG_INFO("migrate unit collide", "migrate_unit", *ptr,
3721"collide_unit", dummy_collide_unit);
3722} else if (OB_FAIL(accumulate_balance_task_loadsum(*ptr, server_load_sums))) {
3723LOG_WARN("fail to accumulate balance task loadsum", K(ret));
3724} else if (OB_FAIL(task_array.push_back(ptr))) {
3725LOG_WARN("fail to push back", K(ret));
3726} else {} // no more to do
3727}
3728if (OB_FAIL(ret)) {
3729} else if (tenant_unit_collide) {
3730task_array.reset();
3731break;
3732} else if (task_array.count() <= 0) {
3733// do nothing
3734} else if (OB_FAIL(check_servers_resource_enough(server_load_sums, enough))) {
3735LOG_WARN("fail to check server resource capacity", K(ret));
3736} else {
3737if (enough) {
3738// good, return the task array
3739} else {
3740LOG_INFO("server resource not enough");
3741task_array.reset();
3742// row task cannot be executed at the same time, clear task
3743}
3744break;
3745}
3746}
3747}
3748return ret;
3749}
3750
3751int ObServerBalancer::try_generate_dot_task_from_migrate_stat(
3752UnitMigrateStat &unit_migrate_stat,
3753common::ObIArray<UnitMigrateStat *> &task_array)
3754{
3755int ret = OB_SUCCESS;
3756common::ObArray<ServerLoadSum> server_load_sums;
3757ObUnitManager::ObUnitLoad dummy_collide_unit;
3758bool tenant_unit_collide = false;
3759bool enough = true;
3760if (OB_UNLIKELY(!inited_)) {
3761ret = OB_NOT_INIT;
3762LOG_WARN("not init", K(ret));
3763} else if (unit_migrate_stat.original_pos_ == unit_migrate_stat.arranged_pos_) {
3764// ignore since this do not need to migrate
3765} else if (OB_FAIL(check_unit_migrate_stat_unit_collide(
3766unit_migrate_stat, dummy_collide_unit, tenant_unit_collide))) {
3767LOG_WARN("fail to check unit migrate stat unit", K(ret));
3768} else if (tenant_unit_collide) {
3769LOG_INFO("migrate unit collide", K(unit_migrate_stat), K(dummy_collide_unit));
3770task_array.reset();
3771} else if (OB_FAIL(accumulate_balance_task_loadsum(unit_migrate_stat, server_load_sums))) {
3772LOG_WARN("fail to accumulate balance task loadsum", K(ret));
3773} else if (OB_FAIL(task_array.push_back(&unit_migrate_stat))) {
3774LOG_WARN("fail to push back", K(ret));
3775} else if (OB_FAIL(check_servers_resource_enough(server_load_sums, enough))) {
3776LOG_WARN("fail to check server resource capacity", K(ret));
3777} else if (enough) {
3778// good
3779} else {
3780LOG_INFO("server resource not enough", K(server_load_sums));
3781task_array.reset();
3782}
3783return ret;
3784}
3785
3786int ObServerBalancer::try_generate_dot_task_from_ttg_matrix(
3787Matrix<UnitMigrateStat> &unit_migrate_stat_task,
3788common::ObIArray<UnitMigrateStat *> &task_array)
3789{
3790int ret = OB_SUCCESS;
3791task_array.reset();
3792if (OB_UNLIKELY(!inited_)) {
3793ret = OB_NOT_INIT;
3794LOG_WARN("not init", K(ret));
3795} else if (unit_migrate_stat_task.get_row_count() <= 0
3796|| unit_migrate_stat_task.get_column_count() <= 0) {
3797ret = OB_ERR_UNEXPECTED;
3798LOG_WARN("unit migrate stat task array unexpected", K(ret), K(unit_migrate_stat_task));
3799} else {
3800bool first_row_stable = true;
3801for (int64_t column = 0;
3802first_row_stable && OB_SUCC(ret) && column < unit_migrate_stat_task.get_column_count();
3803++column) {
3804UnitMigrateStat *ptr = unit_migrate_stat_task.get(0, column);
3805if (OB_UNLIKELY(NULL == ptr)) {
3806ret = OB_ERR_UNEXPECTED;
3807LOG_WARN("unit migrate stat ptr is null", K(ret));
3808} else if (ptr->original_pos_ == ptr->arranged_pos_) {
3809// good, and bypass
3810} else {
3811first_row_stable = false;
3812}
3813}
3814if (OB_FAIL(ret)) {
3815} else if (first_row_stable) {
3816// The first line is the reference line, no migration is required, starting from the second line
3817bool finish = false;
3818for (int64_t i = 1;
3819!finish && OB_SUCC(ret) && i < unit_migrate_stat_task.get_row_count();
3820++i) {
3821for (int64_t j = 0;
3822!finish && OB_SUCC(ret) && j < unit_migrate_stat_task.get_column_count();
3823++j) {
3824UnitMigrateStat *ptr = unit_migrate_stat_task.get(i, j);
3825if (OB_UNLIKELY(NULL == ptr)) {
3826ret = OB_ERR_UNEXPECTED;
3827LOG_WARN("unit migrate stat ptr is null", K(ret));
3828} else if (OB_FAIL(try_generate_dot_task_from_migrate_stat(*ptr, task_array))) {
3829LOG_WARN("fail to try generate dot task from migrate stat", K(ret));
3830} else if (task_array.count() > 0) {
3831finish = true;
3832} else {} // not finish, go on next
3833}
3834}
3835} else {
3836bool finish = false;
3837for (int64_t column = 0;
3838!finish && OB_SUCC(ret) && column < unit_migrate_stat_task.get_column_count();
3839++column) {
3840UnitMigrateStat *ptr = unit_migrate_stat_task.get(0, column);
3841if (OB_UNLIKELY(NULL == ptr)) {
3842ret = OB_ERR_UNEXPECTED;
3843LOG_WARN("unit migrate stat ptr is null", K(ret));
3844} else if (OB_FAIL(try_generate_dot_task_from_migrate_stat(*ptr, task_array))) {
3845LOG_WARN("fail to try generate dot task from migrate stat", K(ret));
3846} else if (task_array.count() > 0) {
3847finish = true;
3848} else {} // not finish, go on next
3849}
3850}
3851}
3852return ret;
3853}
3854
3855int ObServerBalancer::vacate_space_for_ttg_balance(
3856const common::ObZone &zone,
3857TenantGroupBalanceInfo &balance_info,
3858const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
3859const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
3860const common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group,
3861const common::ObIArray<common::ObAddr> &available_servers,
3862bool &do_amend)
3863{
3864int ret = OB_SUCCESS;
3865double g_res_weights[RES_MAX];
3866ObArray<ServerTotalLoad> server_loads;
3867if (OB_UNLIKELY(!inited_)) {
3868ret = OB_NOT_INIT;
3869LOG_WARN("not init", K(ret));
3870} else if (OB_FAIL(calc_global_balance_resource_weights(
3871zone, available_servers, g_res_weights, RES_MAX))) {
3872LOG_WARN("fail to calc whole balance resource weights", K(ret));
3873} else if (OB_FAIL(generate_complete_server_loads(
3874zone, available_servers, g_res_weights, RES_MAX, server_loads))) {
3875LOG_WARN("fail to generate complete server loads", K(ret));
3876} else {
3877bool find = false;
3878Matrix<UnitMigrateStat> &migrate_matrix = balance_info.unit_migrate_stat_matrix_;
3879for (int64_t i = 0;
3880!find && OB_SUCC(ret) && i < migrate_matrix.get_row_count();
3881++i) {
3882for (int64_t j = 0;
3883!find && OB_SUCC(ret) && j < migrate_matrix.get_column_count();
3884++j) {
3885UnitMigrateStat *unit_migrate_stat = migrate_matrix.get(i, j);
3886bool tenant_unit_collide = false;
3887ObUnitManager::ObUnitLoad collide_unit;
3888if (OB_UNLIKELY(NULL == unit_migrate_stat)) {
3889ret = OB_ERR_UNEXPECTED;
3890LOG_WARN("migrate stat ptr is null", K(ret), KP(unit_migrate_stat));
3891} else if (unit_migrate_stat->original_pos_ == unit_migrate_stat->arranged_pos_) {
3892// ignore this, since this do not need to amend
3893} else if (OB_FAIL(check_unit_migrate_stat_unit_collide(
3894*unit_migrate_stat, collide_unit, tenant_unit_collide))) {
3895LOG_WARN("fail to check unit migrate stat unit collide", K(ret));
3896} else if (tenant_unit_collide) {
3897if (OB_FAIL(do_migrate_out_collide_unit(
3898*unit_migrate_stat, collide_unit, server_loads, do_amend))) {
3899LOG_WARN("fail to do migrate out collide unit", K(ret));
3900} else {
3901find = true;
3902}
3903} else {
3904if (OB_FAIL(do_vacate_space_for_ttg_balance(
3905*unit_migrate_stat, standalone_units, not_grant_units,
3906unstable_tenant_group, server_loads, do_amend))) {
3907LOG_WARN("fail to do vacate space for ttg balance", K(ret));
3908} else {
3909find = true;
3910}
3911}
3912}
3913}
3914}
3915return ret;
3916}
3917
3918int ObServerBalancer::do_migrate_out_collide_unit(
3919UnitMigrateStat &unit_migrate_stat,
3920ObUnitManager::ObUnitLoad &collide_unit_load,
3921common::ObArray<ServerTotalLoad> &server_loads,
3922bool &do_amend)
3923{
3924int ret = OB_SUCCESS;
3925common::ObArray<ObUnitManager::ObUnitLoad> zone_units;
3926common::ObArray<PoolOccupation> pool_occupation;
3927common::ObArray<ServerTotalLoad *> server_load_ptrs_sorted;
3928ObArray<common::ObAddr> excluded_servers;
3929ServerTotalLoad *server_load_to_vacate = NULL;
3930ObUnitStat unit_stat;
3931if (OB_UNLIKELY(!inited_)) {
3932ret = OB_NOT_INIT;
3933LOG_WARN("not init", K(ret));
3934} else if (OB_UNLIKELY(common::OB_INVALID_ID == unit_migrate_stat.tenant_id_
3935|| !collide_unit_load.is_valid())) {
3936ret = OB_INVALID_ARGUMENT;
3937LOG_WARN("invalid argument", K(ret), K(unit_migrate_stat), K(collide_unit_load));
3938} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
3939ret = OB_ERR_UNEXPECTED;
3940LOG_WARN("unit_mgr_ ptr is null", K(ret));
3941} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
3942collide_unit_load.unit_->unit_id_, collide_unit_load.unit_->zone_, unit_stat))) {
3943LOG_WARN("fail to get unit stat", K(ret), K(collide_unit_load));
3944} else if (OB_FAIL(unit_mgr_->get_tenant_zone_all_unit_loads(
3945unit_migrate_stat.tenant_id_, zone_disk_statistic_.zone_, zone_units))) {
3946LOG_WARN("fail to get tenant zone all unit loads", K(ret), K(unit_migrate_stat));
3947} else if (OB_FAIL(generate_pool_occupation_array(zone_units, pool_occupation))) {
3948LOG_WARN("fail to generate pool occupation", K(ret));
3949} else if (OB_FAIL(pick_vacate_server_load(
3950server_loads, server_load_ptrs_sorted, unit_migrate_stat, server_load_to_vacate))) {
3951LOG_WARN("fail to pick vacate server load", K(ret));
3952} else if (OB_UNLIKELY(NULL == server_load_to_vacate)) {
3953ret = OB_ERR_UNEXPECTED;
3954LOG_WARN("vacate server load ptr is null", K(ret));
3955} else if (server_load_to_vacate->server_ != collide_unit_load.unit_->server_) {
3956ret = OB_ERR_UNEXPECTED;
3957LOG_WARN("server not match", K(ret),
3958"left_server", server_load_to_vacate->server_,
3959"right_server", collide_unit_load.unit_->server_);
3960} else if (OB_FAIL(get_pool_occupation_excluded_dst_servers(
3961collide_unit_load, pool_occupation, excluded_servers))) {
3962LOG_WARN("fail to get excluded servers", K(ret));
3963} else {
3964do_amend = false;
3965ObArray<UnitMigrateStat> task_array;
3966for (int64_t j = server_load_ptrs_sorted.count() - 1; OB_SUCC(ret) && j >= 0; --j) {
3967LoadSum this_load;
3968ServerTotalLoad *server_load = server_load_ptrs_sorted.at(j);
3969bool enough = false;
3970if (OB_UNLIKELY(NULL == server_load)) {
3971ret = OB_ERR_UNEXPECTED;
3972LOG_WARN("server load ptr is null", K(ret));
3973} else if (server_load->wild_server_) {
3974} else if (server_load->server_ == collide_unit_load.unit_->server_) {
3975} else if (has_exist_in_array(excluded_servers, server_load->server_)) {
3976} else if (OB_FAIL(this_load.append_load(collide_unit_load))) {
3977LOG_WARN("fail to append load", K(ret));
3978} else if (OB_FAIL(check_single_server_resource_enough(
3979this_load, unit_stat, *server_load, enough))) {
3980LOG_WARN("fail to check server resource", K(ret));
3981} else if (!enough) {
3982} else {
3983const common::ObAddr &server = server_load->server_;
3984UnitMigrateStat unit_migrate_stat;
3985unit_migrate_stat.original_pos_ = collide_unit_load.unit_->server_;
3986unit_migrate_stat.arranged_pos_ = server;
3987unit_migrate_stat.unit_load_ = collide_unit_load;
3988if (OB_FAIL(do_update_src_server_load(
3989collide_unit_load, *server_load_to_vacate, unit_stat))) {
3990LOG_WARN("fail to update src server load", K(ret));
3991} else if (OB_FAIL(do_update_dst_server_load(
3992collide_unit_load, *server_load, unit_stat, pool_occupation))) {
3993LOG_WARN("fail to do update dst server load", K(ret));
3994} else if (OB_FAIL(task_array.push_back(unit_migrate_stat))) {
3995LOG_WARN("fail to push back", K(ret));
3996} else {
3997ServerTotalLoadCmp cmp;
3998std::sort(server_load_ptrs_sorted.begin(), server_load_ptrs_sorted.end(), cmp);
3999if (OB_FAIL(cmp.get_ret())) {
4000LOG_WARN("fail to sort server loads", K(ret));
4001}
4002break;
4003}
4004}
4005}
4006if (OB_FAIL(ret)) {
4007} else if (task_array.count() <= 0) {
4008} else if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
4009LOG_WARN("fail to check and do migrate task", KR(ret), K(task_array));
4010} else {
4011do_amend = true;
4012}
4013}
4014return ret;
4015}
4016
4017int ObServerBalancer::pick_vacate_server_load(
4018common::ObIArray<ServerTotalLoad> &server_loads,
4019common::ObArray<ServerTotalLoad *> &server_load_ptrs_sorted,
4020UnitMigrateStat &unit_migrate_stat,
4021ServerTotalLoad *&vacate_server_load)
4022{
4023int ret = OB_SUCCESS;
4024if (OB_UNLIKELY(!inited_)) {
4025ret = OB_NOT_INIT;
4026LOG_WARN("not init", K(ret));
4027} else {
4028vacate_server_load = NULL;
4029for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
4030ServerTotalLoad &server_load = server_loads.at(i);
4031if (server_load.server_ == unit_migrate_stat.arranged_pos_ && !server_load.wild_server_) {
4032vacate_server_load = &server_load;
4033break;
4034} else {} // go on next
4035}
4036for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
4037ServerTotalLoad &server_load = server_loads.at(i);
4038if (OB_FAIL(server_load_ptrs_sorted.push_back(&server_load))) {
4039LOG_WARN("fail to push back", K(ret));
4040}
4041}
4042if (OB_SUCC(ret)) {
4043ServerTotalLoadCmp cmp;
4044if (FALSE_IT(std::sort(server_load_ptrs_sorted.begin(),
4045server_load_ptrs_sorted.end(),
4046cmp))) {
4047} else if (OB_FAIL(cmp.get_ret())) {
4048LOG_WARN("fail to sort", K(ret));
4049}
4050}
4051}
4052return ret;
4053}
4054
4055int ObServerBalancer::do_vacate_space_for_ttg_balance(
4056UnitMigrateStat &unit_migrate_stat,
4057const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
4058const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
4059const common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group,
4060common::ObArray<ServerTotalLoad> &server_loads,
4061bool &do_amend)
4062{
4063int ret = OB_SUCCESS;
4064double hard_limit = 0.0;
4065ServerTotalLoad *server_load_to_vacate = NULL;
4066common::ObArray<ServerTotalLoad *> server_load_ptrs_sorted;
4067ObUnitStat unit_stat;
4068ObUnitManager::ObUnitLoad &unit_load_to_vacate = unit_migrate_stat.unit_load_;
4069if (OB_UNLIKELY(!inited_)) {
4070ret = OB_NOT_INIT;
4071LOG_WARN("not init", K(ret));
4072} else if (OB_UNLIKELY(!unit_load_to_vacate.is_valid())) {
4073ret = OB_INVALID_ARGUMENT;
4074LOG_WARN("invalid argument", K(ret), K(unit_load_to_vacate));
4075} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
4076ret = OB_ERR_UNEXPECTED;
4077LOG_WARN("unit_mgr_ is null", K(ret), KP(unit_mgr_));
4078} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
4079LOG_WARN("fail to get hard limit", K(ret));
4080} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
4081unit_load_to_vacate.unit_->unit_id_, unit_load_to_vacate.unit_->zone_, unit_stat))) {
4082LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load_to_vacate.unit_);
4083} else if (OB_FAIL(pick_vacate_server_load(
4084server_loads, server_load_ptrs_sorted, unit_migrate_stat, server_load_to_vacate))) {
4085LOG_WARN("fail to pick vacate server load", K(ret));
4086} else if (OB_UNLIKELY(NULL == server_load_to_vacate)) {
4087ret = OB_ERR_UNEXPECTED;
4088LOG_WARN("vacate server load ptr is null", K(ret));
4089} else {
4090ObArray<UnitMigrateStat> task_array;
4091bool vacate_enough = false;
4092LoadSum load_to_vacate;
4093if (OB_FAIL(load_to_vacate.append_load(unit_migrate_stat.unit_load_))) {
4094LOG_WARN("fail to append load", K(ret));
4095} else if (OB_FAIL(vacate_space_by_unit_array(
4096load_to_vacate, unit_load_to_vacate, *server_load_to_vacate,
4097task_array, not_grant_units, server_load_ptrs_sorted))) {
4098LOG_WARN("fail to vacate space by not grant units", K(ret));
4099} else if (OB_FAIL(check_single_server_resource_enough(
4100load_to_vacate, unit_stat, *server_load_to_vacate, vacate_enough))) {
4101LOG_WARN("fail to check single server resource enough", K(ret));
4102} else if (vacate_enough) {
4103// good, enough
4104} else if (OB_FAIL(vacate_space_by_unit_array(
4105load_to_vacate, unit_load_to_vacate, *server_load_to_vacate,
4106task_array, standalone_units, server_load_ptrs_sorted))) {
4107LOG_WARN("fail to vacate space by not grant units", K(ret));
4108} else if (OB_FAIL(check_single_server_resource_enough(
4109load_to_vacate, unit_stat, *server_load_to_vacate, vacate_enough))) {
4110LOG_WARN("fail to check single server resource enough", K(ret));
4111} else if (vacate_enough) {
4112// good, enough
4113} else if (OB_FAIL(vacate_space_by_tenantgroup(
4114load_to_vacate, unit_load_to_vacate, *server_load_to_vacate,
4115task_array, unstable_tenant_group, server_load_ptrs_sorted))) {
4116LOG_WARN("fail to vacate space by tenantgroup", K(ret));
4117} else if (OB_FAIL(check_single_server_resource_enough(
4118load_to_vacate, unit_stat, *server_load_to_vacate, vacate_enough))) {
4119LOG_WARN("fail to check single server resource enough", K(ret));
4120} else if (vacate_enough) {
4121// good, enough
4122} else {
4123do_amend = false; // resource not enough
4124}
4125if (OB_SUCC(ret) && vacate_enough) {
4126if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
4127LOG_WARN("fail to check and do migrate task", KR(ret), K(task_array));
4128} else {
4129do_amend = true;
4130}
4131}
4132}
4133return ret;
4134}
4135
4136int ObServerBalancer::generate_pool_occupation_array(
4137const common::ObIArray<ObUnitManager::ObUnitLoad> &unit_loads,
4138common::ObIArray<PoolOccupation> &pool_occupation)
4139{
4140int ret = OB_SUCCESS;
4141pool_occupation.reset();
4142for (int64_t i = 0; OB_SUCC(ret) && i < unit_loads.count(); ++i) {
4143const ObUnitManager::ObUnitLoad &unit_load = unit_loads.at(i);
4144if (OB_UNLIKELY(!unit_load.is_valid())) {
4145ret = OB_ERR_UNEXPECTED;
4146LOG_WARN("unit load unexpected", K(ret), K(unit_load));
4147} else if (OB_FAIL(pool_occupation.push_back(
4148PoolOccupation(unit_load.pool_->tenant_id_,
4149unit_load.pool_->resource_pool_id_,
4150unit_load.unit_->server_)))) {
4151LOG_WARN("fail to push back", K(ret));
4152} else {}
4153}
4154return ret;
4155}
4156
4157int ObServerBalancer::vacate_space_by_tenantgroup(
4158LoadSum &load_to_vacate,
4159const ObUnitManager::ObUnitLoad &unit_load_to_vacate,
4160ServerTotalLoad &server_load_to_vacate,
4161common::ObIArray<UnitMigrateStat> &task_array,
4162const common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group,
4163common::ObArray<ServerTotalLoad *> &server_load_ptrs_sorted)
4164{
4165int ret = OB_SUCCESS;
4166ObUnitStat unit_stat;
4167if (OB_UNLIKELY(!inited_)) {
4168ret = OB_NOT_INIT;
4169LOG_WARN("not init", K(ret));
4170} else if (OB_UNLIKELY(!unit_load_to_vacate.is_valid())) {
4171ret = OB_INVALID_ARGUMENT;
4172LOG_WARN("invalid argument", K(ret), K(unit_load_to_vacate));
4173} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
4174unit_load_to_vacate.unit_->unit_id_, unit_load_to_vacate.unit_->zone_, unit_stat))) {
4175LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load_to_vacate.unit_);
4176} else {
4177for (int64_t i = 0; OB_SUCC(ret) && i < unstable_tenant_group.count(); ++i) {
4178bool vacate_enough = false;
4179common::ObArray<ObUnitManager::ObUnitLoad> unit_loads;
4180TenantGroupBalanceInfo *ptr = unstable_tenant_group.at(i);
4181if (OB_UNLIKELY(NULL == ptr)) {
4182ret = OB_ERR_UNEXPECTED;
4183LOG_WARN("ptr is null", K(ret));
4184} else if (OB_FAIL(ptr->get_all_unit_loads(unit_loads))) {
4185LOG_WARN("fail to get all unit loads", K(ret));
4186} else if (OB_FAIL(vacate_space_by_unit_array(
4187load_to_vacate, unit_load_to_vacate, server_load_to_vacate,
4188task_array, unit_loads, server_load_ptrs_sorted))) {
4189LOG_WARN("fail to vacate space by unit array", K(ret));
4190} else if (OB_FAIL(check_single_server_resource_enough(
4191load_to_vacate, unit_stat, server_load_to_vacate, vacate_enough))) {
4192LOG_WARN("fail to check single server resource enough", K(ret));
4193} else if (vacate_enough) {
4194break;
4195} else {} // go on to the next
4196}
4197}
4198return ret;
4199}
4200
4201int ObServerBalancer::vacate_space_by_unit_array(
4202LoadSum &load_to_vacate,
4203const ObUnitManager::ObUnitLoad &unit_load_to_vacate,
4204ServerTotalLoad &server_load_to_vacate,
4205common::ObIArray<UnitMigrateStat> &task_array,
4206const common::ObIArray<ObUnitManager::ObUnitLoad> &units,
4207common::ObArray<ServerTotalLoad *> &server_load_ptrs_sorted)
4208{
4209int ret = OB_SUCCESS;
4210ObUnitStat unit_stat;
4211ObArray<PoolOccupation> pool_occupation;
4212if (OB_UNLIKELY(!inited_)) {
4213ret = OB_NOT_INIT;
4214LOG_WARN("not init", K(ret));
4215} else if (OB_UNLIKELY(!unit_load_to_vacate.is_valid())) {
4216ret = OB_INVALID_ARGUMENT;
4217LOG_WARN("invalid unit load", K(ret), K(unit_load_to_vacate));
4218} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
4219unit_load_to_vacate.unit_->unit_id_, unit_load_to_vacate.unit_->zone_, unit_stat))) {
4220LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load_to_vacate.unit_);
4221} else if (OB_FAIL(generate_pool_occupation_array(units, pool_occupation))) {
4222LOG_WARN("fail to generate pool occupation array", K(ret));
4223} else {
4224for (int64_t i = 0; OB_SUCC(ret) && i < units.count(); ++i) {
4225bool vacate_enough = false;
4226const ObUnitManager::ObUnitLoad &unit_load = units.at(i);
4227if (OB_UNLIKELY(!unit_load.is_valid())) {
4228ret = OB_ERR_UNEXPECTED;
4229LOG_WARN("unit load is invalid", K(ret), K(unit_load));
4230} else if (unit_load.unit_->server_ != server_load_to_vacate.server_) {
4231// unit is not belong to vacate, skip
4232} else if (OB_FAIL(vacate_space_by_single_unit(
4233server_load_to_vacate, unit_load,
4234task_array, pool_occupation, server_load_ptrs_sorted))) {
4235LOG_WARN("fail to vacate space by single unit", K(ret));
4236} else if (OB_FAIL(check_single_server_resource_enough(
4237load_to_vacate, unit_stat, server_load_to_vacate, vacate_enough))) {
4238LOG_WARN("fail to check single server resource enough", K(ret));
4239} else if (vacate_enough) {
4240break; // good, enough
4241} else {} // go on
4242}
4243}
4244return ret;
4245}
4246
4247int ObServerBalancer::check_single_server_resource_enough(
4248const LoadSum &this_load,
4249const ObUnitStat &unit_stat,
4250const ServerTotalLoad &server_load,
4251bool &enough,
4252const bool mind_disk_waterlevel)
4253{
4254int ret = OB_SUCCESS;
4255ServerDiskStatistic disk_statistic;
4256double hard_limit = 0.0;
4257double disk_waterlevel = 0.0;
4258ObUnitStat my_unit_stat = unit_stat;
4259if (OB_UNLIKELY(!inited_)) {
4260ret = OB_NOT_INIT;
4261LOG_WARN("not init", K(ret));
4262} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
4263ret = OB_ERR_UNEXPECTED;
4264LOG_WARN("unit_mgr_ is null", K(ret), KP(unit_mgr_));
4265} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
4266LOG_WARN("fail to get hard limit", K(ret));
4267} else if (OB_FAIL(zone_disk_statistic_.get_server_disk_statistic(
4268server_load.server_, disk_statistic))) {
4269LOG_WARN("fail to get disk statistic", K(ret), "server", server_load.server_);
4270} else if (mind_disk_waterlevel) {
4271if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
4272LOG_WARN("fail to get server balance critical disk waterlevle", K(ret));
4273}
4274} else {
4275disk_waterlevel = 1.0;
4276}
4277if (OB_SUCC(ret)) {
4278ObUnit *unit = NULL;
4279if (OB_FAIL(unit_mgr_->get_unit_by_id(unit_stat.get_unit_id(), unit))) {
4280LOG_WARN("fail to get unit by id", K(ret), "unit_id", unit_stat.get_unit_id());
4281} else if (OB_UNLIKELY(NULL == unit)) {
4282ret = OB_ERR_UNEXPECTED;
4283LOG_WARN("unit ptr is null", K(ret));
4284} else if (common::REPLICA_TYPE_LOGONLY == unit->replica_type_) {
4285ret = OB_ERR_UNEXPECTED;
4286LOG_WARN("Replica type LOGONLY is unexpected", KR(ret), KP(unit));
4287}
4288}
4289if (OB_SUCC(ret)) {
4290enough = ((this_load.load_sum_.max_cpu() + server_load.load_sum_.load_sum_.max_cpu()
4291<= server_load.resource_info_.cpu_ * hard_limit)
4292&& (this_load.load_sum_.min_cpu() + server_load.load_sum_.load_sum_.min_cpu()
4293<= server_load.resource_info_.cpu_)
4294&& (static_cast<double>(this_load.load_sum_.memory_size())
4295+ static_cast<double>(server_load.load_sum_.load_sum_.memory_size())
4296<= static_cast<double>(server_load.resource_info_.mem_total_))
4297&& (static_cast<double>(this_load.load_sum_.log_disk_size())
4298+ static_cast<double>(server_load.load_sum_.load_sum_.log_disk_size())
4299<= static_cast<double>(server_load.resource_info_.log_disk_total_))
4300&& (static_cast<double>(my_unit_stat.get_required_size() + disk_statistic.disk_in_use_)
4301<= static_cast<double>(disk_statistic.disk_total_) * disk_waterlevel));
4302}
4303return ret;
4304}
4305
4306int ObServerBalancer::vacate_space_by_single_unit(
4307ServerTotalLoad &server_load_to_vacate,
4308const ObUnitManager::ObUnitLoad &unit_load,
4309common::ObIArray<UnitMigrateStat> &task_array,
4310common::ObIArray<PoolOccupation> &pool_occupation,
4311common::ObArray<ServerTotalLoad *> &server_load_ptrs_sorted)
4312{
4313int ret = OB_SUCCESS;
4314ObUnitStat unit_stat;
4315ObArray<common::ObAddr> excluded_servers;
4316if (OB_UNLIKELY(!inited_)) {
4317ret = OB_NOT_INIT;
4318LOG_WARN("not init", K(ret));
4319} else if (OB_UNLIKELY(!unit_load.is_valid()
4320|| server_load_to_vacate.server_ != unit_load.unit_->server_)) {
4321ret = OB_INVALID_ARGUMENT;
4322LOG_WARN("invalid argument", K(ret), "unit_server", unit_load.unit_->server_,
4323"server", server_load_to_vacate.server_);
4324} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
4325unit_load.unit_->unit_id_, unit_load.unit_->zone_, unit_stat))) {
4326LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load.unit_);
4327} else if (OB_FAIL(get_pool_occupation_excluded_dst_servers(
4328unit_load, pool_occupation, excluded_servers))) {
4329LOG_WARN("fail to get excluded servers", K(ret));
4330} else {
4331for (int64_t j = server_load_ptrs_sorted.count() - 1; OB_SUCC(ret) && j >= 0; --j) {
4332LoadSum this_load;
4333bool enough = true;
4334ServerTotalLoad *server_load = server_load_ptrs_sorted.at(j);
4335if (OB_UNLIKELY(NULL == server_load)) {
4336ret = OB_ERR_UNEXPECTED;
4337LOG_WARN("server load ptr is null", K(ret));
4338} else if (server_load->wild_server_) {
4339} else if (server_load->server_ == server_load_to_vacate.server_) {
4340} else if (has_exist_in_array(excluded_servers, server_load->server_)) {
4341} else if (OB_FAIL(this_load.append_load(unit_load))) {
4342LOG_WARN("fail to append load", K(ret));
4343} else if (OB_FAIL(check_single_server_resource_enough(
4344this_load, unit_stat, *server_load_ptrs_sorted.at(j), enough))) {
4345LOG_WARN("fail to check server resource", K(ret));
4346} else if (!enough) {
4347} else {
4348const common::ObAddr &server = server_load->server_;
4349UnitMigrateStat unit_migrate_stat;
4350unit_migrate_stat.original_pos_ = unit_load.unit_->server_;
4351unit_migrate_stat.arranged_pos_ = server;
4352unit_migrate_stat.unit_load_ = unit_load;
4353if (OB_FAIL(do_update_src_server_load(unit_load, server_load_to_vacate, unit_stat))) {
4354LOG_WARN("fail to update src server load", K(ret));
4355} else if (OB_FAIL(do_update_dst_server_load(
4356unit_load, *server_load, unit_stat, pool_occupation))) {
4357LOG_WARN("fail to do update dst server load", K(ret));
4358} else if (OB_FAIL(task_array.push_back(unit_migrate_stat))) {
4359LOG_WARN("fail to push back", K(ret));
4360} else {
4361ServerTotalLoadCmp cmp;
4362std::sort(server_load_ptrs_sorted.begin(), server_load_ptrs_sorted.end(), cmp);
4363if (OB_FAIL(cmp.get_ret())) {
4364LOG_WARN("fail to sort server loads", K(ret));
4365}
4366break;
4367}
4368}
4369}
4370}
4371return ret;
4372}
4373
4374int ObServerBalancer::get_pool_occupation_excluded_dst_servers(
4375const ObUnitManager::ObUnitLoad &this_load,
4376const common::ObIArray<PoolOccupation> &pool_occupation,
4377common::ObIArray<common::ObAddr> &excluded_servers)
4378{
4379int ret = OB_SUCCESS;
4380excluded_servers.reset();
4381if (OB_UNLIKELY(!inited_)) {
4382ret = OB_NOT_INIT;
4383LOG_WARN("not init", K(ret));
4384} else if (OB_UNLIKELY(!this_load.is_valid())) {
4385ret = OB_INVALID_ARGUMENT;
4386LOG_WARN("invalid argument", K(ret), K(this_load));
4387} else {
4388// not grant to any tenant
4389for (int64_t i = 0; OB_SUCC(ret) && i < pool_occupation.count(); ++i) {
4390const PoolOccupation &po = pool_occupation.at(i);
4391if (common::OB_INVALID_ID == this_load.pool_->tenant_id_
4392&& this_load.pool_->resource_pool_id_ != po.resource_pool_id_) {
4393// not grant to any tenant, compare resource pool id
4394} else if (common::OB_INVALID_ID != this_load.pool_->tenant_id_
4395&& this_load.pool_->tenant_id_ != po.tenant_id_) {
4396// already grant to any tenant, compare tenant id
4397} else if (OB_FAIL(excluded_servers.push_back(po.server_))) {
4398LOG_WARN("fail to push back", K(ret));
4399} else {} // no more to do
4400}
4401}
4402return ret;
4403}
4404
4405int ObServerBalancer::generate_complete_server_loads(
4406const common::ObZone &zone,
4407const common::ObIArray<common::ObAddr> &available_servers,
4408double *const resource_weights,
4409const int64_t weights_count,
4410common::ObArray<ServerTotalLoad> &server_loads)
4411{
4412int ret = OB_SUCCESS;
4413common::ObArray<common::ObAddr> zone_servers;
4414if (OB_UNLIKELY(!inited_)) {
4415ret = OB_NOT_INIT;
4416LOG_WARN("not init", K(ret));
4417} else if (OB_UNLIKELY(NULL == resource_weights
4418|| RES_MAX != weights_count
4419|| zone.is_empty())) {
4420ret = OB_INVALID_ARGUMENT;
4421LOG_WARN("invalid argument", K(ret), KP(resource_weights), K(weights_count));
4422} else if (OB_ISNULL(unit_mgr_) || OB_ISNULL(server_mgr_)) {
4423ret = OB_ERR_UNEXPECTED;
4424LOG_WARN("unit_mgr_ or server_mgr_ is null", K(ret), KP(unit_mgr_), KP(server_mgr_));
4425} else if (OB_FAIL(SVR_TRACER.get_servers_of_zone(zone, zone_servers))) {
4426LOG_WARN("fail to get servers of zone", K(ret), K(zone));
4427} else {
4428for (int64_t i = 0; OB_SUCC(ret) && i < zone_servers.count(); ++i) {
4429const common::ObAddr &server = zone_servers.at(i);
4430ServerTotalLoad server_load;
4431server_load.server_ = server;
4432share::ObServerResourceInfo server_resource_info;
4433ObArray<ObUnitManager::ObUnitLoad> *unit_loads = NULL;
4434LoadSum load_sum;
4435server_load.wild_server_ = !has_exist_in_array(available_servers, server);
4436if (OB_FAIL(server_mgr_->get_server_resource_info(server, server_resource_info))) {
4437LOG_WARN("fail to get server status", K(ret), K(server));
4438} else if (OB_FAIL(unit_mgr_->get_loads_by_server(server, unit_loads))) {
4439if (OB_ENTRY_NOT_EXIST != ret) {
4440LOG_WARN("get loads by server failed", K(ret), K(server));
4441} else {
4442ret = OB_SUCCESS;
4443}
4444} else if (OB_UNLIKELY(NULL == unit_loads)) {
4445ret = OB_ERR_UNEXPECTED;
4446LOG_WARN("unit_loads is null", K(ret), KP(unit_loads));
4447} else if (OB_FAIL(load_sum.append_load(*unit_loads))) {
4448LOG_WARN("fail to append load", K(ret));
4449}
4450if (OB_SUCC(ret)) {
4451for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
4452server_load.resource_weights_[i] = resource_weights[i];
4453}
4454server_load.load_sum_ = load_sum;
4455server_load.resource_info_ = server_resource_info;
4456if (OB_FAIL(server_load.update_load_value())) {
4457LOG_WARN("fail to update load value", K(ret));
4458} else if (OB_FAIL(server_loads.push_back(server_load))) {
4459LOG_WARN("fail to push back", K(ret));
4460} else {} // no more to do
4461}
4462if (OB_SUCC(ret)) {
4463ServerTotalLoadCmp cmp;
4464std::sort(server_loads.begin(), server_loads.end(), cmp);
4465if (OB_FAIL(cmp.get_ret())) {
4466LOG_WARN("fail to sort", K(ret));
4467}
4468}
4469}
4470if (OB_SUCC(ret)) { // Defensive inspection
4471for (int64_t i = 0; OB_SUCC(ret) && i < available_servers.count(); ++i) {
4472if (!has_exist_in_array(zone_servers, available_servers.at(i))) {
4473ret = OB_ERR_UNEXPECTED;
4474LOG_WARN("available server is not a member of zone servers", K(zone_servers),
4475"available server", available_servers.at(i));
4476} else {} // good, in zone servers array
4477}
4478}
4479}
4480return ret;
4481}
4482
4483int ObServerBalancer::divide_complete_server_loads_for_balance(
4484const common::ObIArray<common::ObAddr> &available_servers,
4485common::ObIArray<ServerTotalLoad> &server_loads,
4486common::ObIArray<ServerTotalLoad *> &wild_server_loads,
4487common::ObIArray<ServerTotalLoad *> &over_server_loads,
4488common::ObIArray<ServerTotalLoad *> &under_server_loads,
4489double &upper_lmt)
4490{
4491int ret = OB_SUCCESS;
4492if (OB_UNLIKELY(!inited_)) {
4493ret = OB_NOT_INIT;
4494LOG_WARN("not init", K(ret));
4495} else if (OB_UNLIKELY(server_loads.count() <= 0
4496|| available_servers.count() <= 0)) {
4497ret = OB_INVALID_ARGUMENT;
4498LOG_WARN("invalid argument", K(ret), "server_load_count", server_loads.count(),
4499"available_servers count", available_servers.count());
4500} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
4501ret = OB_ERR_UNEXPECTED;
4502LOG_WARN("unit_mgr_ ptr is null", K(ret));
4503} else {
4504wild_server_loads.reset();
4505over_server_loads.reset();
4506under_server_loads.reset();
4507double sum_load = 0.0;
4508for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
4509const ServerTotalLoad &server_load = server_loads.at(i);
4510sum_load += server_load.inter_ttg_load_value_;
4511}
4512const int64_t cpu_mem_tolerance = GCONF.server_balance_cpu_mem_tolerance_percent;
4513const double delta_percent = static_cast<double>(cpu_mem_tolerance) / static_cast<double>(100);
4514const double average_load = sum_load / static_cast<double>(available_servers.count());
4515upper_lmt = average_load + delta_percent * average_load;
4516for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
4517ServerTotalLoad &server_load = server_loads.at(i);
4518if (server_load.wild_server_) {
4519ObArray<ObUnitManager::ObUnitLoad> *loads = NULL;
4520if (OB_FAIL(unit_mgr_->get_loads_by_server(server_load.server_, loads))) {
4521if (OB_ENTRY_NOT_EXIST == ret) {
4522ret = OB_SUCCESS; // good, has no load, no need to put into array
4523} else {
4524LOG_WARN("fail to get load by server", K(ret), "server", server_load.server_);
4525}
4526} else if (OB_UNLIKELY(NULL == loads)) {
4527ret = OB_ERR_UNEXPECTED;
4528LOG_WARN("loads ptr is null", K(ret));
4529} else if (OB_FAIL(wild_server_loads.push_back(&server_load))) {
4530LOG_WARN("fail to push back", K(ret));
4531}
4532} else if (server_load.inter_ttg_load_value_ >= upper_lmt) {
4533if (OB_FAIL(over_server_loads.push_back(&server_load))) {
4534LOG_WARN("fail to push back", K(ret));
4535}
4536} else {
4537if (OB_FAIL(under_server_loads.push_back(&server_load))) {
4538LOG_WARN("fail to push back", K(ret));
4539}
4540}
4541}
4542
4543LOG_INFO("divide complete server loads for balance", KR(ret), K(server_loads),
4544K(available_servers),
4545K(wild_server_loads), K(over_server_loads), K(under_server_loads));
4546}
4547return ret;
4548}
4549
4550int ObServerBalancer::generate_available_server_loads(
4551ObIArray<ServerTotalLoad *> &over_server_loads,
4552ObIArray<ServerTotalLoad *> &under_server_loads,
4553ObIArray<ServerTotalLoad *> &available_server_loads)
4554{
4555int ret = OB_SUCCESS;
4556available_server_loads.reset();
4557for (int64_t i = 0; OB_SUCC(ret) && i < over_server_loads.count(); ++i) {
4558if (OB_FAIL(available_server_loads.push_back(over_server_loads.at(i)))) {
4559LOG_WARN("fail to push back", K(ret));
4560}
4561}
4562for (int64_t i = 0; OB_SUCC(ret) && i < under_server_loads.count(); ++i) {
4563if (OB_FAIL(available_server_loads.push_back(under_server_loads.at(i)))) {
4564LOG_WARN("fail to push back", K(ret));
4565}
4566}
4567return ret;
4568}
4569
4570int ObServerBalancer::make_single_wild_server_empty_by_units(
4571common::ObIArray<PoolOccupation> &pool_occupation,
4572ServerTotalLoad &wild_server_load,
4573const common::ObIArray<ObUnitManager::ObUnitLoad> &units,
4574common::ObArray<ServerTotalLoad *> &available_server_loads,
4575common::ObIArray<UnitMigrateStat> &task_array)
4576{
4577int ret = OB_SUCCESS;
4578for (int64_t i = 0; OB_SUCC(ret) && i < units.count(); ++i) {
4579bool do_balance = false;
4580ObArray<common::ObAddr> excluded_servers;
4581LoadSum this_load;
4582ServerTotalLoadCmp cmp;
4583const ObUnitManager::ObUnitLoad &unit_load = units.at(i);
4584if (OB_UNLIKELY(!unit_load.is_valid())) {
4585ret = OB_ERR_UNEXPECTED;
4586LOG_WARN("unit load is invalid", K(ret), K(unit_load));
4587} else if (wild_server_load.server_ != unit_load.unit_->server_) {
4588// not in this wild server, ignore
4589} else if (OB_FAIL(get_pool_occupation_excluded_dst_servers(
4590unit_load, pool_occupation, excluded_servers))) {
4591LOG_WARN("fail to get excluded servers", K(ret));
4592} else if (FALSE_IT(std::sort(available_server_loads.begin(),
4593available_server_loads.end(),
4594cmp))) {
4595// sort cannot fail
4596} else if (OB_FAIL(cmp.get_ret())) {
4597LOG_WARN("fail to sort", K(ret));
4598} else if (OB_FAIL(try_balance_single_unit_by_cm(
4599unit_load, available_server_loads, task_array,
4600excluded_servers, pool_occupation, do_balance))) {
4601LOG_WARN("fail to try balance single unit by cmp and memory", K(ret));
4602} else if (do_balance) {
4603// do execute balance according to cpu and memory, no more to do
4604} else if (OB_FAIL(try_balance_single_unit_by_disk(
4605unit_load, available_server_loads, task_array,
4606excluded_servers, pool_occupation, do_balance))) {
4607LOG_WARN("fail to do balance single unit by disk", K(ret));
4608} else if (do_balance) {
4609// good
4610} else {
4611ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
4612LOG_WARN("no available server to hold more unit", K(ret),
4613"unit", *unit_load.unit_,
4614"unit_config", *unit_load.unit_config_,
4615"pool", *unit_load.pool_);
4616}
4617}
4618return ret;
4619}
4620
4621int ObServerBalancer::make_wild_servers_empty(
4622const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
4623const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
4624common::ObIArray<ServerTotalLoad *> &wild_server_loads,
4625common::ObIArray<ServerTotalLoad *> &over_server_loads,
4626common::ObIArray<ServerTotalLoad *> &under_server_loads)
4627{
4628int ret = OB_SUCCESS;
4629ObArray<ServerTotalLoad *> available_server_loads;
4630common::ObArray<UnitMigrateStat> task_array;
4631if (OB_UNLIKELY(!inited_)) {
4632ret = OB_NOT_INIT;
4633LOG_WARN("not init", K(ret));
4634} else if (OB_FAIL(generate_available_server_loads(
4635over_server_loads, under_server_loads, available_server_loads))) {
4636LOG_WARN("fail to generate available server loads", K(ret));
4637} else if (OB_FAIL(make_wild_servers_empty_by_units(
4638wild_server_loads, not_grant_units, available_server_loads, task_array))) {
4639LOG_WARN("fail to make wild servers empty by units", K(ret));
4640} else if (OB_FAIL(make_wild_servers_empty_by_units(
4641wild_server_loads, standalone_units, available_server_loads, task_array))) {
4642LOG_WARN("fail to make wild servers empty by units", K(ret));
4643} else if (task_array.count() <= 0) {
4644// no task generate
4645} else if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
4646LOG_WARN("fail to check and do migrate unit task", KR(ret), K(task_array));
4647} else {} // no more to do
4648return ret;
4649}
4650
4651int ObServerBalancer::make_wild_servers_empty_by_units(
4652common::ObIArray<ServerTotalLoad *> &wild_server_loads,
4653const common::ObIArray<ObUnitManager::ObUnitLoad> &units,
4654common::ObArray<ServerTotalLoad *> &available_server_loads,
4655common::ObIArray<UnitMigrateStat> &task_array)
4656{
4657int ret = OB_SUCCESS;
4658// pool_occupation is a placeholder for unit on the server
4659common::ObArray<PoolOccupation> pool_occupation;
4660if (OB_UNLIKELY(!inited_)) {
4661ret = OB_NOT_INIT;
4662LOG_WARN("not init", K(ret));
4663} else if (OB_FAIL(generate_pool_occupation_array(units, pool_occupation))) {
4664LOG_WARN("fail to generate pool occupation array", K(ret));
4665} else {
4666for (int64_t i = 0; OB_SUCC(ret) && i < wild_server_loads.count(); ++i) {
4667ServerTotalLoad *wild_server_load = wild_server_loads.at(i);
4668if (OB_UNLIKELY(NULL == wild_server_load)) {
4669ret = OB_ERR_UNEXPECTED;
4670LOG_WARN("wild server load ptr is null", K(ret), KP(wild_server_load));
4671} else if (OB_FAIL(make_single_wild_server_empty_by_units(
4672pool_occupation, *wild_server_load, units, available_server_loads, task_array))) {
4673LOG_WARN("fail to make single wild server empty by units", K(ret));
4674} else {} // no more to do
4675}
4676}
4677return ret;
4678}
4679
4680int ObServerBalancer::get_disk_over_available_servers(
4681common::ObIArray<common::ObAddr> &disk_over_servers)
4682{
4683int ret = OB_SUCCESS;
4684double disk_waterlevel = 0.0;
4685if (OB_UNLIKELY(!inited_)) {
4686ret = OB_NOT_INIT;
4687LOG_WARN("not init", K(ret));
4688} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
4689LOG_WARN("fail to get critical disk waterlevel", K(ret));
4690} else {
4691disk_over_servers.reset();
4692for (int64_t i = 0;
4693OB_SUCC(ret) && i < zone_disk_statistic_.server_disk_statistic_array_.count(); ++i) {
4694ServerDiskStatistic &disk_statistic
4695= zone_disk_statistic_.server_disk_statistic_array_.at(i);
4696if (static_cast<double>(disk_statistic.disk_in_use_)
4697> static_cast<double>(disk_statistic.disk_total_) * disk_waterlevel) {
4698if (OB_FAIL(disk_over_servers.push_back(disk_statistic.server_))) {
4699LOG_WARN("fail to push back", K(ret));
4700}
4701} else {} // still ok
4702}
4703}
4704return ret;
4705}
4706
4707int ObServerBalancer::make_non_ttg_balance_under_load_by_disk(
4708common::ObIArray<PoolOccupation> &pool_occupation,
4709common::ObIArray<UnitMigrateStat> &task_array,
4710const ObUnitManager::ObUnitLoad &unit_load,
4711ServerTotalLoad *src_server_load,
4712const common::ObIArray<common::ObAddr> &disk_over_servers,
4713common::ObIArray<ServerTotalLoad *> &available_server_loads)
4714{
4715int ret = OB_SUCCESS;
4716common::ObArray<common::ObAddr> excluded_servers;
4717double disk_waterlevel = 0.0;
4718bool is_disk_over_waterlevel = true;
4719ObUnitStat unit_stat;
4720LoadSum this_load;
4721if (OB_UNLIKELY(!inited_)) {
4722ret = OB_NOT_INIT;
4723LOG_WARN("not init", K(ret));
4724} else if (NULL == src_server_load || !unit_load.is_valid()) {
4725ret = OB_INVALID_ARGUMENT;
4726LOG_WARN("invalid argument", K(ret), KP(src_server_load), K(unit_load));
4727} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
4728LOG_WARN("fail to get server balance critical disk waterlevel", K(ret));
4729} else if (OB_FAIL(zone_disk_statistic_.check_server_over_disk_waterlevel(
4730src_server_load->server_, disk_waterlevel, is_disk_over_waterlevel))) {
4731LOG_WARN("fail to check disk over waterlevel", K(ret));
4732} else if (!is_disk_over_waterlevel) {
4733// do_nothing, it is already below the water mark, no need to migrate out unit
4734} else if (OB_FAIL(get_pool_occupation_excluded_dst_servers(
4735unit_load, pool_occupation, excluded_servers))) {
4736LOG_WARN("fail to get excluded servers", K(ret));
4737} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
4738unit_load.unit_->unit_id_, unit_load.unit_->zone_, unit_stat))) {
4739LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load.unit_);
4740} else if (0 == unit_stat.get_required_size()) {
4741// do nothing, skip unit with 0 data disk usage
4742} else if (OB_FAIL(this_load.append_load(unit_load))) {
4743LOG_WARN("fail to append load", K(ret));
4744} else {
4745for (int64_t i = 0;
4746OB_SUCC(ret) && i < zone_disk_statistic_.server_disk_statistic_array_.count();
4747++i) {
4748ServerDiskStatistic &disk_statistic = zone_disk_statistic_.server_disk_statistic_array_.at(i);
4749bool enough = true;
4750UnitMigrateStat unit_migrate;
4751unit_migrate.unit_load_ = unit_load;
4752unit_migrate.original_pos_ = src_server_load->server_;
4753unit_migrate.arranged_pos_ = disk_statistic.server_;
4754ServerTotalLoad *dst_server_load = NULL;
4755if (disk_statistic.wild_server_) {
4756// skip, wild server
4757} else if (has_exist_in_array(excluded_servers, disk_statistic.server_)) {
4758// skip, dst in excluded servers
4759} else if (has_exist_in_array(disk_over_servers, disk_statistic.server_)) {
4760// skip, dst in disk over servers
4761} else if (OB_FAIL(pick_server_load(
4762disk_statistic.server_, available_server_loads, dst_server_load))) {
4763LOG_WARN("fail to pick server load", K(ret));
4764} else if (OB_UNLIKELY(NULL == dst_server_load)) {
4765ret = OB_ERR_UNEXPECTED;
4766LOG_WARN("dst server load ptr is null", K(ret), KP(dst_server_load));
4767} else if (OB_FAIL(check_single_server_resource_enough(
4768this_load, unit_stat, *dst_server_load, enough))) {
4769LOG_WARN("fail to check server resource enough", K(ret));
4770} else if (!enough) {
4771// resource not enough
4772} else if (OB_FAIL(do_update_src_server_load(unit_load, *src_server_load, unit_stat))) {
4773LOG_WARN("fail to do update src server load", K(ret));
4774} else if (OB_FAIL(do_update_dst_server_load(
4775unit_load, *dst_server_load, unit_stat, pool_occupation))) {
4776LOG_WARN("fail to update dst server load", K(ret));
4777} else if (OB_FAIL(task_array.push_back(unit_migrate))) {
4778LOG_WARN("fail to push back", K(ret));
4779} else {
4780LOG_INFO("unit migration task generated for disk in use over waterlevel", KR(ret), K(unit_stat), K(unit_migrate));
4781break;
4782// unit migrate success
4783}
4784}
4785}
4786return ret;
4787}
4788
4789int ObServerBalancer::make_available_servers_balance_by_disk(
4790const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
4791common::ObIArray<ServerTotalLoad *> &available_server_loads,
4792int64_t &task_count)
4793{
4794int ret = OB_SUCCESS;
4795ObArray<PoolOccupation> pool_occupation;
4796common::ObArray<common::ObAddr> disk_over_servers;
4797task_count = 0;
4798if (OB_UNLIKELY(!inited_)) {
4799ret = OB_NOT_INIT;
4800LOG_WARN("not init", K(ret));
4801} else if (OB_FAIL(get_disk_over_available_servers(disk_over_servers))) {
4802LOG_WARN("fail to get disk over servers", K(ret));
4803} else if (OB_FAIL(generate_pool_occupation_array(standalone_units, pool_occupation))) {
4804LOG_WARN("fail to generate pool occupation array", K(ret));
4805} else {
4806common::ObArray<const ObUnitManager::ObUnitLoad *> standalone_unit_ptrs;
4807for (int64_t i = 0; OB_SUCC(ret) && i < standalone_units.count(); ++i) {
4808if (OB_FAIL(standalone_unit_ptrs.push_back(&standalone_units.at(i)))) {
4809LOG_WARN("fail to push back", K(ret));
4810}
4811}
4812if (OB_SUCC(ret)) {
4813UnitLoadDiskCmp cmp(unit_stat_mgr_);
4814std::sort(standalone_unit_ptrs.begin(), standalone_unit_ptrs.end(), cmp);
4815if (OB_FAIL(cmp.get_ret())) {
4816LOG_WARN("fail to get ret", K(ret));
4817}
4818}
4819common::ObArray<UnitMigrateStat> task_array;
4820for (int64_t i = 0; OB_SUCC(ret) && i < disk_over_servers.count(); ++i) {
4821common::ObAddr &src_server = disk_over_servers.at(i);
4822for (int64_t j = 0; OB_SUCC(ret) && j < standalone_unit_ptrs.count(); ++j) {
4823const ObUnitManager::ObUnitLoad *unit_load = standalone_unit_ptrs.at(j);
4824ServerTotalLoad *src_server_load = NULL;
4825if (OB_UNLIKELY(NULL == unit_load)) {
4826ret = OB_ERR_UNEXPECTED;
4827LOG_WARN("unit load ptr is null", K(ret));
4828} else if (OB_UNLIKELY(!unit_load->is_valid())) {
4829ret = OB_ERR_UNEXPECTED;
4830LOG_WARN("unit load is invalid", K(ret), K(*unit_load));
4831} else if (src_server != unit_load->unit_->server_) {
4832// no this server
4833} else if (common::REPLICA_TYPE_LOGONLY == unit_load->unit_->replica_type_) {
4834ret = OB_ERR_UNEXPECTED;
4835LOG_WARN("Replica type LOGONLY is unexpected", KR(ret), KP(unit_load));
4836} else if (OB_FAIL(pick_server_load(
4837src_server, available_server_loads, src_server_load))) {
4838LOG_WARN("fail to pick server load", K(ret));
4839} else if (NULL == src_server_load) {
4840ret = OB_ERR_UNEXPECTED;
4841LOG_WARN("dst server load ptr is null", K(ret));
4842} else if (OB_FAIL(make_non_ttg_balance_under_load_by_disk(
4843pool_occupation, task_array, *unit_load,
4844src_server_load, disk_over_servers, available_server_loads))) {
4845LOG_WARN("fail to make non ttg balance under load by disk", K(ret));
4846} else {} // no more to do
4847}
4848}
4849
4850if (OB_SUCC(ret) && task_array.count() > 0) {
4851task_count = task_array.count();
4852if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
4853LOG_WARN("fail to check and do migrate task", KR(ret), K(task_array));
4854}
4855}
4856}
4857return ret;
4858}
4859
4860// DO NOT migrate unit for CREATING tenant
4861int ObServerBalancer::check_and_do_migrate_unit_task_(
4862const common::ObIArray<UnitMigrateStat> &task_array)
4863{
4864int ret = OB_SUCCESS;
4865share::schema::ObSchemaGetterGuard schema_guard;
4866ObArray<UnitMigrateStat> new_task_array;
4867
4868if (OB_ISNULL(schema_service_)) {
4869ret = OB_ERR_UNEXPECTED;
4870LOG_WARN("schema service ptr is null", KR(ret), KP(schema_service_));
4871} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
4872LOG_WARN("fail to get sys schema guard", KR(ret));
4873} else {
4874for (int64_t idx = 0; OB_SUCC(ret) && idx < task_array.count(); idx++) {
4875const UnitMigrateStat &task = task_array.at(idx);
4876const share::schema::ObSimpleTenantSchema *tenant_schema = NULL;
4877bool can_do_unit_migrate = true;
4878uint64_t tenant_id = task.unit_load_.get_tenant_id();
4879
4880if (OB_INVALID_ID == tenant_id || OB_INVALID_TENANT_ID == tenant_id) {
4881LOG_INFO("[SERVER_BALANCE] [CHECK_CAN_DO] not-grant unit can always migrate", K(idx),
4882K(task), K(lbt()));
4883can_do_unit_migrate = true;
4884} else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) {
4885LOG_WARN("fail to get tenant info", KR(ret), K(tenant_id));
4886} else if (OB_ISNULL(tenant_schema)) {
4887// tenant not exist, ignore this unit
4888LOG_WARN("[SERVER_BALANCE] [CHECK_CAN_DO] tenant not exist, ignore this unit migrate task",
4889K(idx), K(task));
4890can_do_unit_migrate = false;
4891} else if (tenant_schema->is_creating()) {
4892LOG_INFO("[SERVER_BALANCE] [CHECK_CAN_DO] unit of creating tenant can not do migrate",
4893K(idx), K(task), K(lbt()));
4894can_do_unit_migrate = false;
4895} else {
4896LOG_INFO("[SERVER_BALANCE] [CHECK_CAN_DO] unit can do migrate", K(idx), K(task), K(lbt()));
4897// other tenant unit can do migrate
4898can_do_unit_migrate = true;
4899}
4900
4901if (OB_SUCC(ret) && can_do_unit_migrate && OB_FAIL(new_task_array.push_back(task))) {
4902LOG_WARN("push task into array fail", KR(ret), K(task));
4903}
4904}
4905
4906if (OB_FAIL(ret)) {
4907} else if (new_task_array.count() > 0 && OB_FAIL(do_migrate_unit_task(new_task_array))) {
4908LOG_WARN("do migrate unit task fail", KR(ret), K(new_task_array), K(task_array));
4909}
4910}
4911return ret;
4912}
4913
4914int ObServerBalancer::make_available_servers_balance_by_cm(
4915const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
4916const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
4917common::ObIArray<ServerTotalLoad *> &over_server_loads,
4918common::ObIArray<ServerTotalLoad *> &under_server_loads,
4919const double upper_lmt,
4920double *const g_res_weights,
4921const int64_t weights_count,
4922int64_t &task_count)
4923{
4924int ret = OB_SUCCESS;
4925task_count = 0;
4926if (OB_UNLIKELY(!inited_)) {
4927ret = OB_NOT_INIT;
4928LOG_WARN("not init", K(ret));
4929} else {
4930common::ObArray<UnitMigrateStat> task_array;
4931if (OB_FAIL(do_non_ttg_unit_balance_by_cm(
4932task_array, not_grant_units, over_server_loads, under_server_loads,
4933upper_lmt, g_res_weights, weights_count))) {
4934LOG_WARN("fail to do non ttg unit balance by units", K(ret));
4935} else if (OB_FAIL(do_non_ttg_unit_balance_by_cm(
4936task_array, standalone_units, over_server_loads, under_server_loads,
4937upper_lmt, g_res_weights, weights_count))) {
4938LOG_WARN("fail to do non ttg unit balance by units", K(ret));
4939} else if (task_array.count() > 0) {
4940task_count = task_array.count();
4941
4942if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
4943LOG_WARN("fail to check and do migrate task", KR(ret), K(task_array));
4944}
4945} else {} // no more to do
4946}
4947return ret;
4948}
4949
4950int ObServerBalancer::generate_sort_available_servers_disk_statistic(
4951common::ObArray<ServerDiskStatistic> &server_disk_statistic_array,
4952common::ObArray<ServerDiskStatistic *> &available_servers_disk_statistic)
4953{
4954int ret = OB_SUCCESS;
4955if (OB_UNLIKELY(!inited_)) {
4956ret = OB_NOT_INIT;
4957LOG_WARN("not init", K(ret));
4958} else {
4959available_servers_disk_statistic.reset();
4960for (int64_t i = 0; OB_SUCC(ret) && i < server_disk_statistic_array.count(); ++i) {
4961ServerDiskStatistic &disk_statistic = server_disk_statistic_array.at(i);
4962if (disk_statistic.wild_server_) {
4963// a wild server, bypass
4964} else if (OB_FAIL(available_servers_disk_statistic.push_back(&disk_statistic))) {
4965LOG_WARN("fail to push back", K(ret));
4966} else {} // no more to do
4967}
4968if (OB_SUCC(ret)) {
4969ServerDiskPercentCmp cmp;
4970std::sort(available_servers_disk_statistic.begin(),
4971available_servers_disk_statistic.end(),
4972cmp);
4973if (OB_FAIL(cmp.get_ret())) {
4974LOG_WARN("fail to sort", K(ret));
4975}
4976}
4977}
4978return ret;
4979}
4980
4981int ObServerBalancer::divide_available_servers_disk_statistic(
4982common::ObIArray<ServerDiskStatistic *> &available_servers_disk_statistic,
4983common::ObIArray<ServerDiskStatistic *> &over_disk_statistic,
4984common::ObIArray<ServerDiskStatistic *> &under_disk_statistic,
4985double &upper_lmt)
4986{
4987int ret = OB_SUCCESS;
4988if (OB_UNLIKELY(!inited_)) {
4989ret = OB_NOT_INIT;
4990LOG_WARN("not init", K(ret));
4991} else if (available_servers_disk_statistic.count() <= 0) {
4992ret = OB_INVALID_ARGUMENT;
4993LOG_WARN("invalid argument", K(ret), K(available_servers_disk_statistic));
4994} else {
4995double total_value = 0.0;
4996for (int64_t i = 0; OB_SUCC(ret) && i < available_servers_disk_statistic.count(); ++i) {
4997ServerDiskStatistic *disk_statistic = available_servers_disk_statistic.at(i);
4998if (OB_UNLIKELY(NULL == disk_statistic)) {
4999ret = OB_ERR_UNEXPECTED;
5000LOG_WARN("disk statistic ptr is null", K(ret));
5001} else {
5002total_value += disk_statistic->get_disk_used_percent();
5003}
5004}
5005if (OB_SUCC(ret)) {
5006const int64_t disk_tolerance = GCONF.server_balance_disk_tolerance_percent;
5007const double delta = static_cast<double>(disk_tolerance) / static_cast<double>(100);
5008const double average_value
5009= total_value / static_cast<double>(available_servers_disk_statistic.count());
5010upper_lmt = average_value + delta;
5011for (int64_t i = 0; OB_SUCC(ret) && i < available_servers_disk_statistic.count(); ++i) {
5012ServerDiskStatistic *disk_statistic = available_servers_disk_statistic.at(i);
5013if (OB_UNLIKELY(NULL == disk_statistic)) {
5014ret = OB_ERR_UNEXPECTED;
5015LOG_WARN("disk statistic ptr is null", K(ret));
5016} else if (disk_statistic->get_disk_used_percent() >= upper_lmt) {
5017if (OB_FAIL(over_disk_statistic.push_back(disk_statistic))) {
5018LOG_WARN("fail to push back", K(ret));
5019}
5020} else {
5021if (OB_FAIL(under_disk_statistic.push_back(disk_statistic))) {
5022LOG_WARN("fail to push back", K(ret));
5023}
5024}
5025}
5026}
5027}
5028return ret;
5029}
5030
5031int ObServerBalancer::make_server_disk_underload_by_unit(
5032ServerTotalLoad *src_server_load,
5033const ObUnitManager::ObUnitLoad &unit_load,
5034const double upper_lmt,
5035common::ObIArray<PoolOccupation> &pool_occupation,
5036common::ObIArray<ServerTotalLoad *> &available_server_loads,
5037common::ObArray<ServerDiskStatistic *> &under_disk_statistic,
5038common::ObIArray<UnitMigrateStat> &task_array)
5039{
5040int ret = OB_SUCCESS;
5041if (OB_UNLIKELY(!inited_)) {
5042ret = OB_NOT_INIT;
5043LOG_WARN("not init", K(ret));
5044} else if (OB_UNLIKELY(NULL == src_server_load || !unit_load.is_valid())) {
5045ret = OB_INVALID_ARGUMENT;
5046LOG_WARN("invalid argument", K(ret), KP(src_server_load), K(unit_load));
5047} else if (src_server_load->server_ != unit_load.unit_->server_) {
5048ret = OB_ERR_UNEXPECTED;
5049LOG_WARN("server not match", K(ret),
5050"left_server", src_server_load->server_,
5051"right_server", unit_load.unit_->server_);
5052} else {
5053ObArray<common::ObAddr> excluded_servers;
5054ObUnitStat unit_stat;
5055LoadSum this_load;
5056if (OB_FAIL(get_pool_occupation_excluded_dst_servers(
5057unit_load, pool_occupation, excluded_servers))) {
5058LOG_WARN("fail to get excluded dst servers", K(ret));
5059} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
5060unit_load.unit_->unit_id_, unit_load.unit_->zone_, unit_stat))) {
5061LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load.unit_);
5062} else if (OB_FAIL(this_load.append_load(unit_load))) {
5063LOG_WARN("fail to append load", K(ret));
5064} else {
5065for (int64_t j = under_disk_statistic.count() - 1; OB_SUCC(ret) && j >= 0; --j) {
5066ServerTotalLoad *dst_server_load = NULL;
5067ServerDiskStatistic *under_server = under_disk_statistic.at(j);
5068const bool mind_disk_waterlevel = false;
5069bool enough = true;
5070if (OB_UNLIKELY(NULL == under_server)) {
5071ret = OB_ERR_UNEXPECTED;
5072LOG_WARN("under server ptr is null", K(ret));
5073} else if (has_exist_in_array(excluded_servers, under_server->server_)) {
5074// in excluded server
5075} else if (OB_FAIL(pick_server_load(
5076under_server->server_, available_server_loads, dst_server_load))) {
5077LOG_WARN("fail to pick server load", K(ret));
5078} else if (NULL == dst_server_load) {
5079ret = OB_ERR_UNEXPECTED;
5080LOG_WARN("dst server load ptr is null", K(ret));
5081} else if (OB_FAIL(check_single_server_resource_enough(
5082this_load, unit_stat, *dst_server_load, enough, mind_disk_waterlevel))) {
5083LOG_WARN("fail to check server resource enough", K(ret));
5084} else if (!enough) {
5085// resource not enough
5086} else if (under_server->get_disk_used_percent_if_add(unit_stat.get_required_size())
5087> upper_lmt) {
5088// Exceeds the upper_lmt value
5089} else {
5090UnitMigrateStat unit_migrate;
5091unit_migrate.unit_load_ = unit_load;
5092unit_migrate.original_pos_ = src_server_load->server_;
5093unit_migrate.arranged_pos_ = dst_server_load->server_;
5094ServerDiskPercentCmp cmp;
5095if (OB_FAIL(do_update_src_server_load(unit_load, *src_server_load, unit_stat))) {
5096LOG_WARN("fail to do update srce server load", K(ret));
5097} else if (OB_FAIL(do_update_dst_server_load(
5098unit_load, *dst_server_load, unit_stat, pool_occupation))) {
5099LOG_WARN("fail to update dst server load", K(ret));
5100} else if (OB_FAIL(task_array.push_back(unit_migrate))) {
5101LOG_WARN("fail to push back", K(ret));
5102} else if (FALSE_IT(std::sort(under_disk_statistic.begin(),
5103under_disk_statistic.end(),
5104cmp))) {
5105} else if (OB_FAIL(cmp.get_ret())) {
5106LOG_WARN("fail to sort", K(ret));
5107} else {
5108break;
5109}
5110}
5111}
5112}
5113}
5114return ret;
5115}
5116
5117int ObServerBalancer::make_server_disk_underload(
5118ServerDiskStatistic &src_disk_statistic,
5119const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
5120const double upper_lmt,
5121common::ObIArray<PoolOccupation> &pool_occupation,
5122common::ObIArray<ServerTotalLoad *> &available_server_loads,
5123common::ObArray<ServerDiskStatistic *> &under_disk_statistic,
5124common::ObIArray<UnitMigrateStat> &task_array)
5125{
5126int ret = OB_SUCCESS;
5127if (OB_UNLIKELY(!inited_)) {
5128ret = OB_NOT_INIT;
5129LOG_WARN("not init", K(ret));
5130} else {
5131common::ObArray<const ObUnitManager::ObUnitLoad *> standalone_unit_ptrs;
5132for (int64_t i = 0; OB_SUCC(ret) && i < standalone_units.count(); ++i) {
5133if (OB_FAIL(standalone_unit_ptrs.push_back(&standalone_units.at(i)))) {
5134LOG_WARN("fail to push back", K(ret));
5135}
5136}
5137if (OB_SUCC(ret)) {
5138UnitLoadDiskCmp cmp(unit_stat_mgr_);
5139std::sort(standalone_unit_ptrs.begin(), standalone_unit_ptrs.end(), cmp);
5140if (OB_FAIL(cmp.get_ret())) {
5141LOG_WARN("fail to get ret", K(ret));
5142}
5143}
5144for (int64_t i = 0; OB_SUCC(ret) && i < standalone_unit_ptrs.count(); ++i) {
5145const ObUnitManager::ObUnitLoad *unit_load = standalone_unit_ptrs.at(i);
5146ServerTotalLoad *src_server_load = NULL;
5147if (src_disk_statistic.get_disk_used_percent() < upper_lmt) {
5148break; // src already lower than limit
5149} else if (NULL == unit_load) {
5150ret = OB_ERR_UNEXPECTED;
5151LOG_WARN("unit load ptr is null", K(ret));
5152} else if (OB_FAIL(pick_server_load(
5153src_disk_statistic.server_, available_server_loads, src_server_load))) {
5154LOG_WARN("fail to pick server load", K(ret));
5155} else if (OB_UNLIKELY(NULL == src_server_load)) {
5156ret = OB_ERR_UNEXPECTED;
5157LOG_WARN("src server load ptr is null", K(ret));
5158} else if (!unit_load->is_valid()) {
5159ret = OB_ERR_UNEXPECTED;
5160LOG_WARN("unit load is invalid", K(ret));
5161} else if (unit_load->unit_->server_ != src_disk_statistic.server_) {
5162// bypass
5163} else if (OB_FAIL(make_server_disk_underload_by_unit(
5164src_server_load, *unit_load, upper_lmt, pool_occupation,
5165available_server_loads, under_disk_statistic, task_array))) {
5166LOG_WARN("fail to make server disk underload by disk", K(ret));
5167} else {} // no more to do
5168}
5169}
5170return ret;
5171}
5172
5173int ObServerBalancer::make_available_servers_disk_balance(
5174const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
5175common::ObIArray<ServerTotalLoad *> &available_server_loads,
5176int64_t &task_count)
5177{
5178common::ObArray<ServerDiskStatistic *> available_servers_disk_statistic;
5179common::ObArray<ServerDiskStatistic *> over_disk_statistic;
5180common::ObArray<ServerDiskStatistic *> under_disk_statistic;
5181common::ObArray<PoolOccupation> pool_occupation;
5182int ret = OB_SUCCESS;
5183double upper_limit = 0.0;
5184task_count = 0;
5185if (OB_UNLIKELY(!inited_)) {
5186ret = OB_NOT_INIT;
5187LOG_WARN("not init", K(ret));
5188} else if (OB_FAIL(generate_pool_occupation_array(standalone_units, pool_occupation))) {
5189LOG_WARN("fail to generate pool occupation array", K(ret));
5190} else if (OB_FAIL(generate_sort_available_servers_disk_statistic(
5191zone_disk_statistic_.server_disk_statistic_array_, available_servers_disk_statistic))) {
5192LOG_WARN("fail to generate sort available server disk statistic", K(ret));
5193} else if (OB_FAIL(divide_available_servers_disk_statistic(
5194available_servers_disk_statistic, over_disk_statistic,
5195under_disk_statistic, upper_limit))) {
5196LOG_WARN("fail to divide available servers disk statistic", K(ret));
5197} else {
5198common::ObArray<UnitMigrateStat> task_array;
5199for (int64_t i = 0; OB_SUCC(ret) && i < over_disk_statistic.count(); ++i) {
5200ServerDiskStatistic *src_disk_statistic = over_disk_statistic.at(i);
5201if (OB_UNLIKELY(NULL == src_disk_statistic)) {
5202ret = OB_ERR_UNEXPECTED;
5203LOG_WARN("disk statistic ptr is null", K(ret));
5204} else if (OB_FAIL(make_server_disk_underload(
5205*src_disk_statistic, standalone_units, upper_limit, pool_occupation,
5206available_server_loads, under_disk_statistic, task_array))) {
5207LOG_WARN("fail to make server disk underload", K(ret));
5208}
5209}
5210if (OB_SUCC(ret) && task_array.count() > 0) {
5211task_count = task_array.count();
5212if (OB_FAIL(check_and_do_migrate_unit_task_(task_array))) {
5213LOG_WARN("fail to check and do migrate task", KR(ret), K(task_array));
5214}
5215}
5216}
5217return ret;
5218}
5219
5220int ObServerBalancer::make_available_servers_balance(
5221const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
5222const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
5223common::ObIArray<ServerTotalLoad *> &over_server_loads,
5224common::ObIArray<ServerTotalLoad *> &under_server_loads,
5225const double upper_lmt,
5226double *const g_res_weights,
5227const int64_t weights_count)
5228{
5229int ret = OB_SUCCESS;
5230double disk_waterlevel = 0.0;
5231bool all_available_servers_disk_over = false;
5232int64_t balance_task_count = 0;
5233const char *balance_reason = "NONE";
5234if (OB_UNLIKELY(!inited_)) {
5235ret = OB_NOT_INIT;
5236LOG_WARN("not init", K(ret));
5237} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
5238LOG_WARN("fail to get disk waterlevel", K(ret));
5239} else if (OB_FAIL(zone_disk_statistic_.check_all_available_servers_over_disk_waterlevel(
5240disk_waterlevel, all_available_servers_disk_over))) {
5241LOG_WARN("fail to check all available servers over disk waterlevel", K(ret));
5242} else if (all_available_servers_disk_over) {
5243// The disk usage of all servers exceeds the warning water mark,
5244// used a complete disk balancing strategy.
5245// balance the disk usage when the cpu and memory can be accommodated.
5246ObArray<ServerTotalLoad *> available_server_loads;
5247if (OB_FAIL(generate_available_server_loads(
5248over_server_loads, under_server_loads, available_server_loads))) {
5249LOG_WARN("fail to generate available server loads", K(ret));
5250} else if (OB_FAIL(make_available_servers_disk_balance(
5251standalone_units, available_server_loads, balance_task_count))) {
5252LOG_WARN("fail to make available servers disk balance", K(ret));
5253} else {
5254balance_reason = "disk_balance_as_all_server_disk_over";
5255}
5256} else if (zone_disk_statistic_.over_disk_waterlevel()) {
5257// No need to deal with not grant, because they do not occupy disk
5258ObArray<ServerTotalLoad *> available_server_loads;
5259if (OB_FAIL(generate_available_server_loads(
5260over_server_loads, under_server_loads, available_server_loads))) {
5261LOG_WARN("fail to generate available server loads", K(ret));
5262} else if (OB_FAIL(make_available_servers_balance_by_disk(
5263standalone_units, available_server_loads, balance_task_count))) {
5264LOG_WARN("fail to make available servers balance by disk", K(ret));
5265} else {
5266balance_reason = "disk_balance_as_over_disk_waterlevel";
5267}
5268} else {
5269if (OB_FAIL(make_available_servers_balance_by_cm(
5270standalone_units, not_grant_units, over_server_loads, under_server_loads,
5271upper_lmt, g_res_weights, weights_count, balance_task_count))) {
5272LOG_WARN("fail to make available servers balance by cpu and memory", K(ret));
5273} else {
5274balance_reason = "load_balance";
5275}
5276}
5277
5278LOG_INFO("finish zone servers balance", KR(ret), K(disk_waterlevel),
5279K(balance_task_count), K(balance_reason),
5280K(all_available_servers_disk_over),
5281"zone_over_disk_waterlevel", zone_disk_statistic_.over_disk_waterlevel(),
5282K(standalone_units.count()), K(not_grant_units.count()));
5283return ret;
5284}
5285
5286int ObServerBalancer::do_non_tenantgroup_unit_balance_task(
5287const common::ObZone &zone,
5288const common::ObIArray<ObUnitManager::ObUnitLoad> &standalone_units,
5289const common::ObIArray<ObUnitManager::ObUnitLoad> ¬_grant_units,
5290const common::ObIArray<common::ObAddr> &available_servers)
5291{
5292int ret = OB_SUCCESS;
5293double g_res_weights[RES_MAX];
5294ObArray<ServerTotalLoad> server_loads;
5295common::ObArray<ServerTotalLoad *> wild_server_loads;
5296common::ObArray<ServerTotalLoad *> over_server_loads;
5297common::ObArray<ServerTotalLoad *> under_server_loads;
5298double upper_lmt = 0.0;
5299
5300LOG_INFO("start do non-tenantgroup unit balance task", K(zone));
5301
5302if (OB_UNLIKELY(!inited_)) {
5303ret = OB_NOT_INIT;
5304LOG_WARN("not init", K(ret));
5305} else if (OB_UNLIKELY(available_servers.count() <= 0)) {
5306ret = OB_INVALID_ARGUMENT;
5307LOG_WARN("invalid argument", K(ret));
5308} else if (OB_FAIL(calc_global_balance_resource_weights(
5309zone, available_servers, g_res_weights, RES_MAX))) {
5310LOG_WARN("fail to calc whole balance resource weights", K(ret));
5311} else if (OB_FAIL(generate_complete_server_loads(
5312zone, available_servers, g_res_weights, RES_MAX, server_loads))) {
5313LOG_WARN("fail to generate complete server loads", K(ret));
5314} else if (OB_FAIL(divide_complete_server_loads_for_balance(
5315available_servers, server_loads, wild_server_loads,
5316over_server_loads, under_server_loads, upper_lmt))) {
5317LOG_WARN("fail to sort server loads for inter ttg balance", K(ret));
5318} else if (wild_server_loads.count() > 0) {
5319if (OB_FAIL(make_wild_servers_empty(
5320standalone_units, not_grant_units, wild_server_loads,
5321over_server_loads, under_server_loads))) {
5322LOG_WARN("fail to make wild servers empty", K(ret));
5323}
5324} else {
5325if (OB_FAIL(make_available_servers_balance(
5326standalone_units, not_grant_units, over_server_loads,
5327under_server_loads, upper_lmt, g_res_weights, RES_MAX))) {
5328LOG_WARN("fail to make available servers balance", K(ret));
5329}
5330}
5331
5332LOG_INFO("finish do non-tenantgroup unit balance task", KR(ret), K(zone),
5333K(upper_lmt),
5334K(wild_server_loads.count()),
5335K(over_server_loads.count()),
5336K(under_server_loads.count()),
5337K(standalone_units), K(not_grant_units), K(available_servers));
5338return ret;
5339}
5340
5341int ObServerBalancer::do_non_ttg_unit_balance_by_cm(
5342common::ObIArray<UnitMigrateStat> &task_array,
5343const common::ObIArray<ObUnitManager::ObUnitLoad> &units,
5344common::ObIArray<ServerTotalLoad *> &over_server_loads,
5345common::ObIArray<ServerTotalLoad *> &under_server_loads,
5346const double upper_lmt,
5347double *const g_res_weights,
5348const int64_t weights_count)
5349{
5350int ret = OB_SUCCESS;
5351common::ObArray<PoolOccupation> pool_occupation;
5352if (OB_UNLIKELY(!inited_)) {
5353ret = OB_NOT_INIT;
5354LOG_WARN("not init", K(ret));
5355} else if (OB_FAIL(generate_pool_occupation_array(units, pool_occupation))) {
5356LOG_WARN("fail to generate pool occupation array", K(ret));
5357} else {
5358for (int64_t i = 0; OB_SUCC(ret) && i < over_server_loads.count(); ++i) {
5359ServerTotalLoad *src = over_server_loads.at(i);
5360for (int64_t j = under_server_loads.count() - 1;
5361OB_SUCC(ret) && j >= 0;
5362--j) {
5363ServerTotalLoad *dst = under_server_loads.at(j);
5364if (OB_FAIL(make_non_ttg_balance_under_load_by_cm(
5365pool_occupation, task_array, units, src, dst,
5366upper_lmt, g_res_weights, weights_count))) {
5367LOG_WARN("fail to make non ttg balance under load", K(ret));
5368} else {} // no more to do
5369}
5370}
5371}
5372return ret;
5373}
5374
5375int ObServerBalancer::make_non_ttg_balance_under_load_by_cm(
5376common::ObIArray<PoolOccupation> &pool_occupation,
5377common::ObIArray<UnitMigrateStat> &task_array,
5378const common::ObIArray<ObUnitManager::ObUnitLoad> &units,
5379ServerTotalLoad *src_server_load,
5380ServerTotalLoad *dst_server_load,
5381const double upper_lmt,
5382double *const g_res_weights,
5383const int64_t weights_count)
5384{
5385int ret = OB_SUCCESS;
5386double hard_limit = 0.0;
5387ObArray<common::ObAddr> excluded_servers;
5388if (OB_UNLIKELY(!inited_)) {
5389ret = OB_NOT_INIT;
5390LOG_WARN("not init", K(ret));
5391} else if (NULL == src_server_load || NULL == dst_server_load
5392|| NULL == g_res_weights || RES_MAX != weights_count) {
5393ret = OB_INVALID_ARGUMENT;
5394LOG_WARN("invalid argument", K(ret), KP(src_server_load), K(dst_server_load));
5395} else if (OB_UNLIKELY(src_server_load->wild_server_)) {
5396ret = OB_ERR_UNEXPECTED;
5397LOG_WARN("should not be here", K(ret), "wild_server", src_server_load->wild_server_);
5398} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
5399ret = OB_ERR_UNEXPECTED;
5400LOG_WARN("unit_mgr_ ptr is null", K(ret), K(unit_mgr_));
5401} else if (OB_FAIL(unit_mgr_->get_hard_limit(hard_limit))) {
5402LOG_WARN("fail to get hard limit", K(ret));
5403} else {
5404double upper_limit = std::min(upper_lmt, hard_limit);
5405for (int64_t i = 0; OB_SUCC(ret) && i < units.count(); ++i) {
5406LoadSum this_load;
5407ObUnitStat unit_stat;
5408const ObUnitManager::ObUnitLoad &unit_load = units.at(i);
5409double dst_load_value = 0.0;
5410UnitMigrateStat unit_migrate;
5411unit_migrate.unit_load_ = unit_load;
5412unit_migrate.original_pos_ = src_server_load->server_;
5413unit_migrate.arranged_pos_ = dst_server_load->server_;
5414bool enough = true;
5415if (src_server_load->inter_ttg_load_value_ < upper_limit) {
5416break;
5417} else if (!unit_load.is_valid()) {
5418ret = OB_ERR_UNEXPECTED;
5419LOG_WARN("unit load is invalid", K(ret), K(unit_load));
5420} else if (src_server_load->server_ != unit_load.unit_->server_) {
5421// not in this src, ignore
5422} else if (OB_FAIL(unit_stat_mgr_.get_unit_stat(
5423unit_load.unit_->unit_id_, unit_load.unit_->zone_, unit_stat))) {
5424LOG_WARN("fail to get unit stat", K(ret), "unit", *unit_load.unit_);
5425} else if (OB_FAIL(get_pool_occupation_excluded_dst_servers(
5426unit_load, pool_occupation, excluded_servers))) {
5427LOG_WARN("fail to get excluded servers", K(ret));
5428} else if (has_exist_in_array(excluded_servers, dst_server_load->server_)) {
5429// in excluded server
5430} else if (OB_FAIL(this_load.append_load(unit_load))) {
5431LOG_WARN("fail to append load", K(ret));
5432} else if (OB_FAIL(check_single_server_resource_enough(
5433this_load, unit_stat, *dst_server_load, enough))) {
5434LOG_WARN("fail to check server resource enough", K(ret));
5435} else if (!enough) {
5436} else if (OB_FAIL(this_load.calc_load_value(
5437g_res_weights, weights_count, *dst_server_load, dst_load_value))) {
5438LOG_WARN("fail to calc load value", K(ret));
5439} else if (dst_server_load->inter_ttg_load_value_ + dst_load_value >= upper_limit) {
5440// Unbalanced results
5441} else if (OB_FAIL(do_update_src_server_load(unit_load, *src_server_load, unit_stat))) {
5442LOG_WARN("fail to do update src server load", K(ret));
5443} else if (OB_FAIL(do_update_dst_server_load(
5444unit_load, *dst_server_load, unit_stat, pool_occupation))) {
5445LOG_WARN("fail to update dst server load", K(ret));
5446} else if (OB_FAIL(task_array.push_back(unit_migrate))) {
5447LOG_WARN("fail to push back", K(ret));
5448} else {} // no more to do
5449}
5450}
5451return ret;
5452}
5453
5454int ObServerBalancer::choose_balance_info_amend(
5455const common::ObIArray<TenantGroupBalanceInfo *> &tenant_group,
5456const bool is_stable_tenantgroup,
5457TenantGroupBalanceInfo *&info_need_amend,
5458common::ObIArray<TenantGroupBalanceInfo *> &other_ttg)
5459{
5460int ret = OB_SUCCESS;
5461if (OB_UNLIKELY(!inited_)) {
5462ret = OB_NOT_INIT;
5463LOG_WARN("not init", K(ret));
5464} else if (tenant_group.count() <= 0) {
5465ret = OB_INVALID_ARGUMENT;
5466LOG_WARN("tenant group count is zero", K(ret));
5467} else {
5468int64_t idx = -1;
5469info_need_amend = NULL;
5470for (int64_t i = 0; OB_SUCC(ret) && i < tenant_group.count(); ++i) {
5471uint64_t amend_id = UINT64_MAX;
5472uint64_t this_id = UINT64_MAX;
5473TenantGroupBalanceInfo *this_info = tenant_group.at(i);
5474if (OB_UNLIKELY(NULL == this_info)) {
5475ret = OB_ERR_UNEXPECTED;
5476LOG_WARN("tenant group balance info ptr is null", K(ret), KP(this_info));
5477} else if (NULL == info_need_amend) {
5478info_need_amend = this_info;
5479idx = i;
5480} else if (OB_FAIL(info_need_amend->get_trick_id(amend_id))) {
5481LOG_WARN("fail to get trick id", K(ret));
5482} else if (OB_FAIL(this_info->get_trick_id(this_id))) {
5483LOG_WARN("fail to get trick id", K(ret));
5484} else if (UINT64_MAX == amend_id || UINT64_MAX == this_id) {
5485ret = OB_ERR_UNEXPECTED;
5486LOG_WARN("get invalid info id", K(ret), K(amend_id), K(this_id));
5487} else if (!is_stable_tenantgroup) {
5488if (amend_id > this_id) {
5489info_need_amend = this_info;
5490idx = i;
5491}
5492} else {
5493if (amend_id < this_id) {
5494info_need_amend = this_info;
5495idx = i;
5496}
5497}
5498}
5499if (-1 == idx) {
5500ret = OB_ERR_UNEXPECTED;
5501LOG_WARN("fail to get info", K(ret));
5502} else {
5503other_ttg.reset();
5504for (int64_t i = 0; OB_SUCC(ret) && i < tenant_group.count(); ++i) {
5505if (idx == i) {
5506// do nothing
5507} else if (OB_FAIL(other_ttg.push_back(tenant_group.at(i)))) {
5508LOG_WARN("fail to push back", K(ret));
5509}
5510}
5511}
5512}
5513return ret;
5514}
5515
5516int ObServerBalancer::divide_tenantgroup_balance_info(
5517common::ObIArray<TenantGroupBalanceInfo> &balance_info_array,
5518common::ObIArray<TenantGroupBalanceInfo *> &stable_tenant_group,
5519common::ObIArray<TenantGroupBalanceInfo *> &unstable_tenant_group)
5520{
5521int ret = OB_SUCCESS;
5522if (OB_UNLIKELY(!inited_)) {
5523ret = OB_NOT_INIT;
5524LOG_WARN("not init", K(ret));
5525} else {
5526stable_tenant_group.reset();
5527unstable_tenant_group.reset();
5528for (int64_t i = 0; OB_SUCC(ret) && i < balance_info_array.count(); ++i) {
5529TenantGroupBalanceInfo &balance_info = balance_info_array.at(i);
5530if (balance_info.is_stable()) {
5531if (OB_FAIL(stable_tenant_group.push_back(&balance_info))) {
5532LOG_WARN("fail to push back", K(ret));
5533}
5534} else {
5535if (OB_FAIL(unstable_tenant_group.push_back(&balance_info))) {
5536LOG_WARN("fail to push back", K(ret));
5537}
5538}
5539}
5540}
5541return ret;
5542}
5543
5544int ObServerBalancer::calc_global_balance_resource_weights(
5545const common::ObZone &zone,
5546const common::ObIArray<common::ObAddr> &available_servers,
5547double *const resource_weights,
5548const int64_t weights_count)
5549{
5550int ret = OB_SUCCESS;
5551common::ObArray<ObUnitManager::ObUnitLoad> zone_unit_loads;
5552common::ObArray<common::ObAddr> zone_servers;
5553if (OB_UNLIKELY(!inited_)) {
5554ret = OB_NOT_INIT;
5555LOG_WARN("not init", K(ret));
5556} else if (OB_UNLIKELY(zone.is_empty()
5557|| NULL == resource_weights
5558|| RES_MAX != weights_count)) {
5559ret = OB_INVALID_ARGUMENT;
5560LOG_WARN("invalid argument", K(ret), K(zone));
5561} else if (OB_ISNULL(unit_mgr_) || OB_ISNULL(server_mgr_)) {
5562ret = OB_ERR_UNEXPECTED;
5563LOG_WARN("unit_mgr_ or server_mgr_ is null", KR(ret), KP(unit_mgr_), KP(server_mgr_));
5564} else if (OB_FAIL(SVR_TRACER.get_servers_of_zone(zone, zone_servers))) {
5565LOG_WARN("fail to get zone servers", K(ret), K(zone));
5566} else {
5567LoadSum load_sum;
5568for (int64_t i = 0; OB_SUCC(ret) && i < zone_servers.count(); ++i) {
5569ObArray<ObUnitManager::ObUnitLoad> *unit_loads = NULL;
5570if (OB_FAIL(unit_mgr_->get_loads_by_server(zone_servers.at(i), unit_loads))) {
5571if (OB_ENTRY_NOT_EXIST != ret) {
5572LOG_WARN("fail to get loads by server", K(ret));
5573} else {
5574ret = OB_SUCCESS;
5575}
5576} else if (OB_UNLIKELY(NULL == unit_loads)) {
5577ret = OB_ERR_UNEXPECTED;
5578LOG_WARN("unit_loads ptr is null", K(ret), KP(unit_loads));
5579} else if (OB_FAIL(load_sum.append_load(*unit_loads))) {
5580LOG_WARN("fail to append load", K(ret));
5581} else {} // no more to do
5582}
5583ResourceSum resource_sum;
5584for (int64_t i = 0; OB_SUCC(ret) && i < available_servers.count(); ++i) {
5585const common::ObAddr &server = available_servers.at(i);
5586share::ObServerResourceInfo resource_info;
5587if (OB_FAIL(server_mgr_->get_server_resource_info(server, resource_info))) {
5588LOG_WARN("fail to get resource_info", KR(ret), K(server));
5589} else if (OB_FAIL(resource_sum.append_resource(resource_info))) {
5590LOG_WARN("fail to append resource", K(ret));
5591} else {} // no more to do
5592}
5593for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
5594ObResourceType resource_type = static_cast<ObResourceType>(i);
5595const double required = load_sum.get_required(resource_type);
5596const double capacity = resource_sum.get_capacity(resource_type);
5597if (required <= 0 || capacity <= 0) {
5598resource_weights[resource_type] = 0.0;
5599} else if (required >= capacity) {
5600resource_weights[resource_type] = 1.0;
5601} else {
5602resource_weights[resource_type] = required / capacity;
5603}
5604}
5605if (OB_SUCC(ret)) {
5606double sum = 0.0;
5607const int64_t N = available_servers.count();
5608for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
5609resource_weights[i] /= static_cast<double>(N);
5610sum += resource_weights[i];
5611if (resource_weights[i] < 0 || resource_weights[i] > 1) {
5612ret = common::OB_ERR_UNEXPECTED;
5613LOG_ERROR("weight shall be in interval [0,1]", K(i), "w", resource_weights[i]);
5614}
5615}
5616if (OB_SUCC(ret) && sum > 0) {
5617for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
5618resource_weights[i] /= sum;
5619}
5620}
5621}
5622}
5623
5624LOG_INFO("finish calc global balance resource weights", KR(ret), K(zone),
5625"cpu_weights", resource_weights[RES_CPU],
5626"mem_weights", resource_weights[RES_MEM],
5627"log_disk_weights", resource_weights[RES_LOG_DISK],
5628K(available_servers));
5629return ret;
5630}
5631
5632int ObServerBalancer::check_and_get_tenant_matrix_unit_num(
5633const Matrix<uint64_t> &tenant_id_matrix,
5634const common::ObZone &zone,
5635bool &unit_num_match,
5636ObIArray<int64_t> &column_unit_num_array)
5637{
5638int ret = OB_SUCCESS;
5639if (OB_UNLIKELY(!inited_)) {
5640ret = OB_NOT_INIT;
5641LOG_WARN("not init", K(ret));
5642} else if (OB_UNLIKELY(!tenant_id_matrix.is_valid() || zone.is_empty())) {
5643ret = OB_INVALID_ARGUMENT;
5644LOG_WARN("invalid argument", K(ret), K(tenant_id_matrix), K(zone));
5645} else {
5646column_unit_num_array.reset();
5647unit_num_match = true;
5648const int64_t row_count = tenant_id_matrix.get_row_count();
5649const int64_t column_count = tenant_id_matrix.get_column_count();
5650for (int64_t i = 0; OB_SUCC(ret) && unit_num_match && i < column_count; ++i) {
5651ObArray<uint64_t> tenant_column;
5652for (int64_t j = 0; OB_SUCC(ret) && j < row_count; ++j) {
5653uint64_t tenant_id = OB_INVALID_ID;
5654if (OB_FAIL(tenant_id_matrix.get(j, i, tenant_id))) {
5655LOG_WARN("fail to get element", K(ret));
5656} else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) {
5657ret = OB_ERR_UNEXPECTED;
5658LOG_WARN("tenant id value unexpected", K(ret), K(tenant_id));
5659} else if (OB_FAIL(tenant_column.push_back(tenant_id))) {
5660LOG_WARN("fail to push back", K(ret));
5661} else {} // no more to do
5662}
5663if (OB_SUCC(ret)) {
5664int64_t unit_num = 0;
5665if (OB_FAIL(check_and_get_tenant_column_unit_num(
5666tenant_column, zone, unit_num_match, unit_num))) {
5667LOG_WARN("fail to check and get tenant column unit num", K(ret));
5668} else if (!unit_num_match || 0 == unit_num) {
5669// unit num not match or unit num is zero on this zone
5670} else if (OB_FAIL(column_unit_num_array.push_back(unit_num))) {
5671LOG_WARN("fail to push back", K(ret));
5672} else {} // no more to do
5673}
5674}
5675}
5676return ret;
5677}
5678
5679int ObServerBalancer::check_and_get_tenant_column_unit_num(
5680const ObIArray<uint64_t> &tenant_id_column,
5681const common::ObZone &zone,
5682bool &unit_num_match,
5683int64_t &unit_num)
5684{
5685int ret = OB_SUCCESS;
5686if (OB_UNLIKELY(!inited_)) {
5687ret = OB_NOT_INIT;
5688LOG_WARN("not init", K(ret));
5689} else if (OB_UNLIKELY(tenant_id_column.count() <= 0 || zone.is_empty())) {
5690ret = OB_INVALID_ARGUMENT;
5691LOG_WARN("invalid argument", K(ret), K(zone));
5692} else {
5693unit_num_match = true;
5694bool is_first = true;
5695int64_t prev_unit_num = -1;
5696for (int64_t i = 0; unit_num_match && OB_SUCC(ret) && i < tenant_id_column.count(); ++i) {
5697int64_t this_unit_num = -1;
5698const uint64_t tenant_id = tenant_id_column.at(i);
5699if (OB_UNLIKELY(NULL == unit_mgr_)) {
5700ret = OB_ERR_UNEXPECTED;
5701LOG_WARN("unit_mgr_ is null", K(ret), KP(unit_mgr_));
5702} else if (OB_FAIL(unit_mgr_->inner_get_tenant_zone_full_unit_num(
5703tenant_id, zone, this_unit_num))) {
5704LOG_WARN("fail to get tenant zone unit num", K(ret));
5705} else if (is_first || this_unit_num == prev_unit_num) {
5706is_first = false;
5707prev_unit_num = this_unit_num;
5708} else {
5709unit_num_match = false;
5710}
5711}
5712if (OB_SUCC(ret) && unit_num_match) {
5713unit_num = prev_unit_num;
5714}
5715}
5716return ret;
5717}
5718
5719int ObServerBalancer::generate_original_unit_matrix(
5720const Matrix<uint64_t> &tenant_id_matrix,
5721const common::ObZone &zone,
5722const ObIArray<int64_t> &column_unit_num_array,
5723Matrix<UnitMigrateStat> &unit_migrate_stat_matrix)
5724{
5725int ret = OB_SUCCESS;
5726if (OB_UNLIKELY(!inited_)) {
5727ret = OB_NOT_INIT;
5728LOG_WARN("not init", K(ret));
5729} else if (OB_UNLIKELY(zone.is_empty())) {
5730ret = OB_INVALID_ARGUMENT;
5731LOG_WARN("invalid argument", K(ret), K(zone));
5732} else {
5733const int64_t tenant_matrix_row_count = tenant_id_matrix.get_row_count();
5734const int64_t tenant_matrix_column_count = tenant_id_matrix.get_column_count();
5735const int64_t unit_matrix_row_count = tenant_id_matrix.get_row_count();
5736int64_t unit_matrix_column_count = 0;
5737for (int64_t i = 0; i < column_unit_num_array.count(); ++i) {
5738unit_matrix_column_count += column_unit_num_array.at(i);
5739}
5740if (tenant_matrix_row_count <= 0 || tenant_matrix_row_count >= INT32_MAX
5741|| tenant_matrix_column_count <= 0 || tenant_matrix_column_count >= INT32_MAX) {
5742ret = OB_ERR_UNEXPECTED;
5743LOG_WARN("tenant matrix row or column count unexpected", K(ret),
5744K(tenant_matrix_row_count), K(tenant_matrix_column_count));
5745} else if (unit_matrix_column_count <= 0 || unit_matrix_column_count >= INT32_MAX) {
5746ret = OB_ERR_UNEXPECTED;
5747LOG_WARN("unit matrix column count value unexpected", K(ret));
5748} else if (OB_FAIL(unit_migrate_stat_matrix.init(
5749unit_matrix_row_count, unit_matrix_column_count))) {
5750LOG_WARN("fail to init unit migrate stat", K(ret));
5751} else {
5752common::ObArray<ObUnitManager::ObUnitLoad> unit_loads;
5753const common::ObReplicaType replica_type = common::REPLICA_TYPE_FULL;
5754for (int64_t row = 0; OB_SUCC(ret) && row < tenant_matrix_row_count; ++row) {
5755int64_t acc_column_idx = 0;
5756for (int64_t column = 0; OB_SUCC(ret) && column < tenant_matrix_column_count; ++column) {
5757unit_loads.reset();
5758uint64_t tenant_id = OB_INVALID_ID;
5759if (OB_FAIL(tenant_id_matrix.get(row, column, tenant_id))) {
5760LOG_WARN("fail to get tenant id", K(ret));
5761} else if (OB_INVALID_ID == tenant_id) {
5762ret = OB_ERR_UNEXPECTED;
5763LOG_WARN("tenant id unexpected", K(ret), K(tenant_id));
5764} else if (OB_UNLIKELY(NULL == unit_mgr_)) {
5765ret = OB_ERR_UNEXPECTED;
5766LOG_WARN("unit_mgr_ is null", K(ret), KP(unit_mgr_));
5767} else if (OB_FAIL(unit_mgr_->get_tenant_zone_unit_loads(
5768tenant_id, zone, replica_type, unit_loads))) {
5769if (OB_ENTRY_NOT_EXIST != ret) {
5770LOG_WARN("fail to get tenant zone unit infos", K(ret));
5771} else {
5772ret = OB_SUCCESS;
5773}
5774} else if (OB_FAIL(fill_unit_migrate_stat_matrix(
5775unit_migrate_stat_matrix, tenant_id, row, acc_column_idx, unit_loads))) {
5776LOG_WARN("fail to fill unit migrate stat matrix", K(ret));
5777} else {
5778acc_column_idx += unit_loads.count();
5779}
5780}
5781}
5782}
5783}
5784return ret;
5785}
5786
5787int ObServerBalancer::fill_unit_migrate_stat_matrix(
5788Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
5789const uint64_t tenant_id,
5790const int64_t row,
5791const int64_t start_column_id,
5792const common::ObIArray<ObUnitManager::ObUnitLoad> &unit_loads)
5793{
5794int ret = OB_SUCCESS;
5795if (OB_UNLIKELY(!inited_)) {
5796ret = OB_NOT_INIT;
5797LOG_WARN("not init", K(ret));
5798} else {
5799const int64_t unit_matrix_row_count = unit_migrate_stat_matrix.get_row_count();
5800const int64_t unit_matrix_column_count = unit_migrate_stat_matrix.get_column_count();
5801if (row >= unit_matrix_row_count
5802|| start_column_id >= unit_matrix_column_count
5803|| start_column_id + unit_loads.count() > unit_matrix_column_count) {
5804ret = OB_INVALID_ARGUMENT;
5805LOG_WARN("invalid argument", K(ret), K(row), K(start_column_id), K(unit_loads),
5806K(unit_matrix_row_count), K(unit_matrix_column_count));
5807} else {
5808for (int64_t i = 0; OB_SUCC(ret) && i < unit_loads.count(); ++i) {
5809const ObUnitManager::ObUnitLoad &unit_load = unit_loads.at(i);
5810if (!unit_load.is_valid()) {
5811ret = OB_ERR_UNEXPECTED;
5812LOG_WARN("unit load invalid", K(ret), K(unit_load));
5813} else {
5814UnitMigrateStat stat;
5815stat.tenant_id_ = tenant_id;
5816stat.original_pos_ = unit_load.unit_->server_;
5817stat.arranged_pos_ = unit_load.unit_->server_;
5818stat.unit_load_ = unit_load;
5819if (OB_FAIL(unit_migrate_stat_matrix.set(row, start_column_id + i, stat))) {
5820LOG_WARN("fail to set", K(ret));
5821} else {} // no more to do
5822}
5823}
5824}
5825}
5826return ret;
5827}
5828
5829int ObServerBalancer::single_unit_migrate_stat_matrix_balance(
5830TenantGroupBalanceInfo &balance_info,
5831const common::ObIArray<common::ObAddr> &available_servers)
5832{
5833int ret = OB_SUCCESS;
5834const ObIArray<int64_t> &column_unit_num_array = balance_info.column_unit_num_array_;
5835Matrix<UnitMigrateStat> &unit_migrate_stat_matrix = balance_info.unit_migrate_stat_matrix_;
5836ObIArray<UnitGroupLoad> &unitgroup_loads = balance_info.unitgroup_load_array_;
5837ObIArray<ServerLoad> &server_loads = balance_info.server_load_array_;
5838if (OB_UNLIKELY(!inited_)) {
5839ret = OB_NOT_INIT;
5840LOG_WARN("not init", K(ret));
5841} else if (column_unit_num_array.count() <= 0) {
5842ret = OB_INVALID_ARGUMENT;
5843LOG_WARN("invalid argument", K(ret));
5844} else if (OB_FAIL(balance_row_units(
5845balance_info, column_unit_num_array, unit_migrate_stat_matrix,
5846unitgroup_loads, server_loads, available_servers))) {
5847LOG_WARN("fail to balance row units", K(ret));
5848} else if (OB_FAIL(inner_ttg_balance_strategy_.coordinate_all_column_unit_group(
5849column_unit_num_array, unit_migrate_stat_matrix, unitgroup_loads))) {
5850LOG_WARN("fail to coordinate column units", K(ret));
5851} else {} // no more to do
5852return ret;
5853}
5854
5855int ObServerBalancer::InnerTenantGroupBalanceStrategy::coordinate_all_column_unit_group(
5856const common::ObIArray<int64_t> &column_unit_num_array,
5857Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
5858const common::ObIArray<UnitGroupLoad> &unitgroup_loads)
5859{
5860int ret = OB_SUCCESS;
5861if (column_unit_num_array.count() <= 0
5862|| unit_migrate_stat_matrix.get_row_count() <= 0
5863|| unitgroup_loads.count() <= 0) {
5864ret = OB_INVALID_ARGUMENT;
5865LOG_WARN("invalid argument", K(ret), K(column_unit_num_array),
5866K(unit_migrate_stat_matrix), K(unitgroup_loads));
5867} else {
5868int64_t accumulate_column_idx = 0;
5869for (int64_t i = 0; OB_SUCC(ret) && i < column_unit_num_array.count(); ++i) {
5870if (OB_FAIL(coordinate_single_column_unit_group(
5871accumulate_column_idx, column_unit_num_array.at(i),
5872unit_migrate_stat_matrix, unitgroup_loads))) {
5873LOG_WARN("fail to coordinate single column unit", K(ret));
5874} else {
5875accumulate_column_idx += column_unit_num_array.at(i);
5876}
5877}
5878}
5879return ret;
5880}
5881
5882int ObServerBalancer::InnerTenantGroupBalanceStrategy::coordinate_single_column_unit_group(
5883const int64_t start_column_idx,
5884const int64_t this_column_count,
5885Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
5886const common::ObIArray<UnitGroupLoad> &unitgroup_loads)
5887{
5888int ret = OB_SUCCESS;
5889if (start_column_idx < 0
5890|| this_column_count <= 0
5891|| start_column_idx + this_column_count > unit_migrate_stat_matrix.get_column_count()
5892|| unit_migrate_stat_matrix.get_row_count() <= 0
5893|| unit_migrate_stat_matrix.get_column_count() <= 0
5894|| unitgroup_loads.count() <= 0
5895|| unitgroup_loads.count() != unit_migrate_stat_matrix.get_column_count()) {
5896ret = OB_INVALID_ARGUMENT;
5897LOG_WARN("invalid argument", K(ret), K(start_column_idx), K(this_column_count),
5898K(unit_migrate_stat_matrix), K(unitgroup_loads));
5899} else {
5900const int64_t end_column_idx = start_column_idx + this_column_count;
5901ObArray<common::ObAddr> dest_server_array;
5902for (int64_t i = start_column_idx; OB_SUCC(ret) && i < end_column_idx; ++i) {
5903if (OB_FAIL(dest_server_array.push_back(unitgroup_loads.at(i).server_))) {
5904LOG_WARN("fail to push back", K(ret));
5905}
5906}
5907if (OB_SUCC(ret)) {
5908if (OB_FAIL(do_coordinate_single_column_unit_group(
5909start_column_idx, this_column_count,
5910unit_migrate_stat_matrix, dest_server_array))) {
5911LOG_WARN("fail to coordinate single column unit group", K(ret));
5912} else {} // no more to do
5913}
5914}
5915return ret;
5916}
5917
5918int ObServerBalancer::InnerTenantGroupBalanceStrategy::do_coordinate_single_column_unit_group(
5919const int64_t start_column_idx,
5920const int64_t column_count,
5921Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
5922const common::ObIArray<common::ObAddr> &dest_servers)
5923{
5924int ret = OB_SUCCESS;
5925if (start_column_idx < 0
5926|| column_count <= 0
5927|| dest_servers.count() <= 0
5928|| start_column_idx + column_count > unit_migrate_stat_matrix.get_column_count()
5929|| unit_migrate_stat_matrix.get_row_count() <= 0
5930|| unit_migrate_stat_matrix.get_column_count() <= 0
5931|| dest_servers.count() != column_count) {
5932ret = OB_INVALID_ARGUMENT;
5933LOG_WARN("invalid argument", K(ret), K(start_column_idx), K(column_count),
5934K(unit_migrate_stat_matrix), K(dest_servers));
5935} else {
5936for (int64_t row = 0;
5937OB_SUCC(ret) && row < unit_migrate_stat_matrix.get_row_count();
5938++row) {
5939if (OB_FAIL(do_coordinate_single_unit_row(
5940row, start_column_idx, column_count,
5941dest_servers, unit_migrate_stat_matrix))) {
5942LOG_WARN("fail to coordinate single unit row", K(ret));
5943}
5944}
5945}
5946// After the above operation is over, the actual unit has been aggregated.
5947// In order to be more tidy in the form,
5948// the matrix is sorted vertically according to the server to facilitate the observation of information during debugging.
5949UnitMigrateStatCmp cmp_operator;
5950if (OB_FAIL(ret)) {
5951// failed in the previous procedure
5952} else if (OB_FAIL(unit_migrate_stat_matrix.sort_column_group(
5953start_column_idx, column_count, cmp_operator))) {
5954LOG_WARN("fail to sort unit group by arranged pos", K(ret));
5955} else if (OB_FAIL(cmp_operator.get_ret())) {
5956LOG_WARN("fail to sort column group", K(ret));
5957} else {} // no more to do
5958return ret;
5959}
5960
5961int ObServerBalancer::InnerTenantGroupBalanceStrategy::do_coordinate_single_unit_row(
5962const int64_t row,
5963const int64_t start_column_idx,
5964const int64_t column_count,
5965const common::ObIArray<common::ObAddr> &candidate_servers,
5966Matrix<UnitMigrateStat> &unit_migrate_stat_matrix)
5967{
5968int ret = OB_SUCCESS;
5969if (row < 0 || start_column_idx < 0 || column_count <= 0
5970|| start_column_idx + column_count > unit_migrate_stat_matrix.get_column_count()
5971|| unit_migrate_stat_matrix.get_row_count() <= 0
5972|| unit_migrate_stat_matrix.get_column_count() <= 0
5973|| row >= unit_migrate_stat_matrix.get_row_count()
5974|| candidate_servers.count() <= 0) {
5975ret = OB_INVALID_ARGUMENT;
5976LOG_WARN("invalid argument", K(ret), K(row), K(start_column_idx), K(column_count),
5977K(unit_migrate_stat_matrix), K(candidate_servers));
5978} else {
5979const int64_t end_column_idx = start_column_idx + column_count;
5980ObArray<common::ObAddr> excluded_array;
5981// Need to run twice, in the first pass, throw the ones that meet the requirements into the exclude array
5982// The second pass will adjust those that do not meet the requirements
5983for (int64_t column = start_column_idx; OB_SUCC(ret) && column < end_column_idx; ++column) {
5984UnitMigrateStat unit_migrate_stat;
5985if (OB_FAIL(unit_migrate_stat_matrix.get(row, column, unit_migrate_stat))) {
5986LOG_WARN("fail to get unit migrate stat", K(ret));
5987} else if (!has_exist_in_array(candidate_servers, unit_migrate_stat.original_pos_)) {
5988// The current location is not in the candidate servers and needs to be re-allocated,
5989// so the first pass will not be processed here
5990} else {
5991unit_migrate_stat.arranged_pos_ = unit_migrate_stat.original_pos_;
5992if (OB_FAIL(unit_migrate_stat_matrix.set(row, column, unit_migrate_stat))) {
5993LOG_WARN("fail to set unit migrate stat", K(ret));
5994} else if (OB_FAIL(excluded_array.push_back(unit_migrate_stat.original_pos_))) {
5995LOG_WARN("fail to push back", K(ret));
5996}
5997}
5998}
5999for (int64_t column = start_column_idx; OB_SUCC(ret) && column < end_column_idx; ++column) {
6000UnitMigrateStat unit_migrate_stat;
6001if (OB_FAIL(unit_migrate_stat_matrix.get(row, column, unit_migrate_stat))) {
6002LOG_WARN("fail to get unit migrate stat", K(ret));
6003} else if (has_exist_in_array(candidate_servers, unit_migrate_stat.original_pos_)) {
6004// The current position is already in the candidate servers,
6005// it has been processed in the first pass, skip it
6006} else {
6007// The current position is not in the candidate servers and needs to be re-allocated
6008if (OB_FAIL(arrange_unit_migrate_stat_pos(
6009candidate_servers, unit_migrate_stat, excluded_array))) {
6010LOG_WARN("fail to arrange unit migrate stat pos", K(ret));
6011} else if (OB_FAIL(unit_migrate_stat_matrix.set(row, column, unit_migrate_stat))) {
6012LOG_WARN("fail to set unit migrate stat", K(ret));
6013} else if (OB_FAIL(excluded_array.push_back(unit_migrate_stat.arranged_pos_))) {
6014LOG_WARN("fail to push back", K(ret));
6015} else {} // fine, no more to do
6016}
6017}
6018}
6019return ret;
6020}
6021
6022int ObServerBalancer::InnerTenantGroupBalanceStrategy::arrange_unit_migrate_stat_pos(
6023const common::ObIArray<common::ObAddr> &candidate_servers,
6024UnitMigrateStat &unit_migrate_stat,
6025const common::ObIArray<common::ObAddr> &excluded_array)
6026{
6027int ret = OB_SUCCESS;
6028if (OB_UNLIKELY(candidate_servers.count() <= 0)) {
6029ret = OB_INVALID_ARGUMENT;
6030LOG_WARN("invalid argument", K(ret), K(candidate_servers));
6031} else if (has_exist_in_array(candidate_servers, unit_migrate_stat.original_pos_)) {
6032ret = OB_INVALID_ARGUMENT;
6033LOG_WARN("unit migrate stat already in candidate", K(ret),
6034K(unit_migrate_stat), K(candidate_servers));
6035} else {
6036bool find = false;
6037for (int64_t i = 0; !find && OB_SUCC(ret) && i < candidate_servers.count(); ++i) {
6038const common::ObAddr &this_candidate = candidate_servers.at(i);
6039if (has_exist_in_array(excluded_array, this_candidate)) {
6040// Cannot be used as a new pos in the excluded array
6041} else {
6042unit_migrate_stat.arranged_pos_ = this_candidate;
6043find = true;
6044}
6045}
6046if (OB_FAIL(ret)) {
6047} else if (!find) {
6048ret = OB_ERR_UNEXPECTED;
6049LOG_WARN("cannot find a new pos for unit migrate stat", K(ret),
6050K(candidate_servers), K(excluded_array));
6051} else { /* good */ }
6052}
6053return ret;
6054}
6055
6056int ObServerBalancer::balance_row_units(
6057TenantGroupBalanceInfo &balance_info,
6058const common::ObIArray<int64_t> &column_unit_num_array,
6059Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
6060common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6061common::ObIArray<ServerLoad> &server_loads,
6062const common::ObIArray<common::ObAddr> &available_servers)
6063{
6064int ret = OB_SUCCESS;
6065if (OB_UNLIKELY(!inited_)) {
6066ret = OB_NOT_INIT;
6067LOG_WARN("not init", K(ret));
6068} else if (column_unit_num_array.count() <= 0
6069|| unit_migrate_stat_matrix.get_row_count() <= 0
6070|| unit_migrate_stat_matrix.get_column_count() <= 0
6071|| available_servers.count() <= 0) {
6072ret = OB_INVALID_ARGUMENT;
6073LOG_WARN("invalid argument", K(ret), K(column_unit_num_array),
6074K(available_servers), K(unit_migrate_stat_matrix));
6075} else if (OB_FAIL(generate_unitgroup_and_server_load(
6076unit_migrate_stat_matrix, column_unit_num_array, available_servers,
6077unitgroup_loads, server_loads))) {
6078LOG_WARN("fail to generate server and unitgroup load", K(ret));
6079} else if (OB_FAIL(calc_row_balance_resource_weights(
6080server_loads, unitgroup_loads, balance_info.intra_weights_, RES_MAX))) {
6081LOG_WARN("fail to calc resource weights", K(ret));
6082} else if (OB_FAIL(update_server_load_value(
6083balance_info.intra_weights_, RES_MAX, server_loads))) {
6084LOG_WARN("fail to update unitgroup and server load value", K(ret));
6085} else if (OB_FAIL(do_balance_row_units(
6086balance_info, unit_migrate_stat_matrix, unitgroup_loads, server_loads))) {
6087LOG_WARN("fail to do balance row units", K(ret));
6088} else {} // no more to do
6089return ret;
6090}
6091
6092int ObServerBalancer::generate_unitgroup_and_server_load(
6093const Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
6094const common::ObIArray<int64_t> &column_unit_num_array,
6095const common::ObIArray<common::ObAddr> &available_servers,
6096common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6097common::ObIArray<ServerLoad> &server_loads)
6098{
6099int ret = OB_SUCCESS;
6100if (OB_UNLIKELY(!inited_)) {
6101ret = OB_NOT_INIT;
6102LOG_WARN("not init", K(ret));
6103} else if (unit_migrate_stat_matrix.get_row_count() <= 0
6104|| unit_migrate_stat_matrix.get_column_count() <= 0
6105|| column_unit_num_array.count() <= 0
6106|| available_servers.count() <= 0) {
6107ret = OB_INVALID_ARGUMENT;
6108LOG_WARN("invalid argument", K(ret), K(unit_migrate_stat_matrix), K(available_servers));
6109} else if (OB_FAIL(generate_unitgroup_load(
6110unit_migrate_stat_matrix, column_unit_num_array, unitgroup_loads))) {
6111LOG_WARN("fail to generate unitgroup load", K(ret));
6112} else if (OB_FAIL(generate_server_load(available_servers, unitgroup_loads, server_loads))) {
6113LOG_WARN("fail to generate server load");
6114} else {} // finish
6115return ret;
6116}
6117
6118int ObServerBalancer::generate_unitgroup_load(
6119const Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
6120const common::ObIArray<int64_t> &column_unit_num_array,
6121common::ObIArray<UnitGroupLoad> &unitgroup_loads)
6122{
6123int ret = OB_SUCCESS;
6124if (OB_UNLIKELY(!inited_)) {
6125ret = OB_NOT_INIT;
6126LOG_WARN("not init", K(ret));
6127} else {
6128unitgroup_loads.reset();
6129// A separate unitgroup_loads is generated for each column of the unit matrix
6130int64_t accumulate_idx = 0;
6131for (int64_t i = 0; OB_SUCC(ret) && i < column_unit_num_array.count(); ++i) {
6132for (int64_t j = 0; OB_SUCC(ret) && j < column_unit_num_array.at(i); ++j) {
6133int64_t column = accumulate_idx + j;
6134if (OB_FAIL(generate_column_unitgroup_load(
6135column, unit_migrate_stat_matrix, accumulate_idx,
6136column_unit_num_array.at(i), unitgroup_loads))) {
6137LOG_WARN("fail to generate unit group load", K(ret));
6138}
6139}
6140if (OB_SUCC(ret)) {
6141accumulate_idx += column_unit_num_array.at(i);
6142}
6143}
6144}
6145return ret;
6146}
6147
6148int ObServerBalancer::generate_column_unitgroup_load(
6149const int64_t column,
6150const Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
6151const int64_t start_column_idx,
6152const int64_t column_count,
6153common::ObIArray<UnitGroupLoad> &unitgroup_loads)
6154{
6155int ret = OB_SUCCESS;
6156if (OB_UNLIKELY(!inited_)) {
6157ret = OB_NOT_INIT;
6158LOG_WARN("not init", K(ret));
6159} else if (column < 0 || start_column_idx < 0 || column_count <= 0
6160|| start_column_idx + column_count > unit_migrate_stat_matrix.get_column_count()
6161|| column >= unit_migrate_stat_matrix.get_column_count()) {
6162ret = OB_INVALID_ARGUMENT;
6163LOG_WARN("invalid argument", K(ret), K(start_column_idx), K(column),
6164K(column_count), K(unit_migrate_stat_matrix));
6165} else {
6166UnitGroupLoad unitgroup_load;
6167common::ObAddr server_addr;
6168uint64_t column_tenant_id = OB_INVALID_ID;
6169bool is_first = true;
6170for (int64_t row = 0; row < unit_migrate_stat_matrix.get_row_count(); ++row) {
6171UnitMigrateStat unit_migrate_stat;
6172if (OB_FAIL(unit_migrate_stat_matrix.get(row, column, unit_migrate_stat))) {
6173LOG_WARN("fail to get unit migrate stat matrix", K(ret));
6174} else if (OB_FAIL(unitgroup_load.unit_loads_.push_back(
6175*unit_migrate_stat.unit_load_.unit_config_))) {
6176LOG_WARN("fail to append unit load", K(ret));
6177} else {
6178if (is_first) {
6179column_tenant_id = unit_migrate_stat.tenant_id_;
6180server_addr = unit_migrate_stat.arranged_pos_;
6181}
6182is_first = false;
6183}
6184}
6185if (OB_FAIL(ret)) {
6186} else if (!server_addr.is_valid() || OB_INVALID_ID == column_tenant_id) {
6187ret = OB_ERR_UNEXPECTED;
6188LOG_WARN("server addr unexpected", K(ret), K(column),
6189K(server_addr), K(column_tenant_id), K(unit_migrate_stat_matrix));
6190} else {
6191unitgroup_load.server_ = server_addr;
6192unitgroup_load.column_tenant_id_ = column_tenant_id;
6193unitgroup_load.start_column_idx_ = start_column_idx;
6194unitgroup_load.column_count_ = column_count;
6195if (OB_FAIL(unitgroup_load.sum_group_load())) {
6196LOG_WARN("fail to sum group load", K(ret));
6197} else if (OB_FAIL(unitgroup_loads.push_back(unitgroup_load))) {
6198LOG_WARN("fail to push back", K(ret));
6199} else {} // good
6200}
6201}
6202return ret;
6203}
6204
6205// When balancing within a group,
6206// it is necessary to virtually set the resources (cpu, memory) of each server in the zone to the same value.
6207// Here is actually directly taking the resources of the first server
6208int ObServerBalancer::try_regulate_intra_ttg_resource_info(
6209const share::ObServerResourceInfo &this_resource_info,
6210share::ObServerResourceInfo &intra_ttg_resource_info)
6211{
6212int ret = OB_SUCCESS;
6213
6214if (OB_UNLIKELY(!inited_)) {
6215ret = OB_NOT_INIT;
6216LOG_WARN("not init", K(ret));
6217} else if (OB_UNLIKELY(!this_resource_info.is_valid())) {
6218ret = OB_INVALID_ARGUMENT;
6219LOG_WARN("invalid argument", K(ret), K(this_resource_info));
6220} else if (intra_ttg_resource_info.is_valid()) {
6221// bypass
6222} else {
6223intra_ttg_resource_info = this_resource_info;
6224}
6225
6226return ret;
6227}
6228
6229int ObServerBalancer::generate_server_load(
6230const common::ObIArray<common::ObAddr> &available_servers,
6231common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6232common::ObIArray<ServerLoad> &server_loads)
6233{
6234int ret = OB_SUCCESS;
6235if (OB_UNLIKELY(!inited_)) {
6236ret = OB_NOT_INIT;
6237LOG_WARN("not init", K(ret));
6238} else if (available_servers.count() <= 0) {
6239ret = OB_INVALID_ARGUMENT;
6240LOG_WARN("invalid argument", K(ret), K(available_servers));
6241} else if (OB_ISNULL(server_mgr_)) {
6242ret = OB_ERR_UNEXPECTED;
6243LOG_WARN("server_mgr_ is null", KR(ret), KP(server_mgr_));
6244} else {
6245// Place the generated unitgroup load into the corresponding server load
6246server_loads.reset();
6247ServerLoad server_load;
6248share::ObServerResourceInfo resource_info;
6249share::ObServerResourceInfo intra_ttg_resource_info;
6250// Pre-fill the server first, and fill in the server resource info
6251for (int64_t i = 0; OB_SUCC(ret) && i < available_servers.count(); ++i) {
6252server_load.reset();
6253resource_info.reset();
6254server_load.server_ = available_servers.at(i);
6255if (OB_FAIL(server_mgr_->get_server_resource_info(server_load.server_, resource_info))) {
6256LOG_WARN("fail to get server status", KR(ret), K(server_load.server_));
6257} else if (OB_FAIL(try_regulate_intra_ttg_resource_info(
6258resource_info,
6259intra_ttg_resource_info))) {
6260LOG_WARN("fail to try regulate intra resource info", K(ret));
6261} else {
6262server_load.resource_info_ = resource_info;
6263if (OB_FAIL(server_loads.push_back(server_load))) {
6264LOG_WARN("fail to push back", K(ret));
6265} else {} // no more to do
6266}
6267}
6268// Then fill in the intra ttg resource info of each server
6269for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
6270ServerLoad &server_load = server_loads.at(i);
6271if (OB_UNLIKELY(!intra_ttg_resource_info.is_valid())) {
6272ret = OB_ERR_UNEXPECTED;
6273LOG_WARN("invalid intra ttg resource info", K(ret), K(intra_ttg_resource_info));
6274} else {
6275server_load.intra_ttg_resource_info_ = intra_ttg_resource_info;
6276}
6277}
6278// Then fill the unitgroup load into the corresponding server load
6279const int64_t server_load_count = server_loads.count();
6280common::ObArray<UnitGroupLoad *> wild_ug_loads; // the ug not in available servers
6281for (int64_t i = 0; OB_SUCC(ret) && i < unitgroup_loads.count(); ++i) {
6282bool find = false;
6283UnitGroupLoad &unitgroup_load = unitgroup_loads.at(i);
6284for (int64_t j = 0; !find && OB_SUCC(ret) && j < server_load_count; ++j) {
6285ServerLoad &server_load = server_loads.at(j);
6286if (server_load.server_ != unitgroup_load.server_) {
6287// go on to check next
6288} // NOTE: Push in here is the pointer
6289else if (OB_FAIL(server_load.unitgroup_loads_.push_back(&unitgroup_load))) {
6290LOG_WARN("fail to push back", K(ret));
6291} else {
6292unitgroup_load.server_load_ = &server_load;
6293find = true;
6294}
6295}
6296if (OB_FAIL(ret)) {
6297} else if (server_load_count <= 0) {
6298ret = OB_ERR_UNEXPECTED;
6299LOG_WARN("server load count unexpected", K(ret), K(server_load_count));
6300} else if (!find) {
6301if (OB_FAIL(wild_ug_loads.push_back(&unitgroup_load))) {
6302LOG_WARN("fail to push back", K(ret));
6303}
6304} else {} // find one, good
6305}
6306for (int64_t i = 0; OB_SUCC(ret) && i < wild_ug_loads.count(); ++i) {
6307UnitGroupLoad *ug_load = wild_ug_loads.at(i);
6308if (OB_UNLIKELY(NULL == ug_load)) {
6309ret = OB_ERR_UNEXPECTED;
6310LOG_WARN("ug ptr is null", K(ret));
6311} else if (OB_FAIL(arrange_server_load_for_wild_unitgroup(*ug_load, server_loads))) {
6312LOG_WARN("cannot arrange server load for wild unitgroup", K(ret));
6313} else {} // no more to do
6314}
6315}
6316return ret;
6317}
6318
6319int ObServerBalancer::arrange_server_load_for_wild_unitgroup(
6320UnitGroupLoad &unitgroup_load,
6321common::ObIArray<ServerLoad> &server_loads)
6322{
6323int ret = OB_SUCCESS;
6324bool find = false;
6325for (int64_t i = 0; !find && OB_SUCC(ret) && i < server_loads.count(); ++i) {
6326ServerLoad &server_load = server_loads.at(i);
6327bool same_pool_found = false;
6328for (int64_t j = 0;
6329!same_pool_found && OB_SUCC(ret) && j < server_load.unitgroup_loads_.count();
6330++j) {
6331UnitGroupLoad *this_ug = server_load.unitgroup_loads_.at(j);
6332if (OB_UNLIKELY(NULL == this_ug)) {
6333ret = OB_ERR_UNEXPECTED;
6334LOG_WARN("ug ptr is null", K(ret));
6335} else if (this_ug->column_tenant_id_ != unitgroup_load.column_tenant_id_) {
6336// good, go on to check next
6337} else {
6338same_pool_found = true;
6339}
6340}
6341if (OB_FAIL(ret)) {
6342} else if (same_pool_found) {
6343// A ug from the same resource pool as unitgroup_load was found on the server,
6344// and the server is not suitable
6345} else if (OB_FAIL(server_load.unitgroup_loads_.push_back(&unitgroup_load))) {
6346LOG_WARN("fail to push back", K(ret));
6347} else {
6348unitgroup_load.server_ = server_load.server_;
6349unitgroup_load.server_load_ = &server_load;
6350find = true;
6351}
6352}
6353if (OB_FAIL(ret)) {
6354} else if (!find) {
6355ret = OB_MACHINE_RESOURCE_NOT_ENOUGH;
6356LOG_WARN("no available server to hold more unit",
6357K(ret), "tenant_id", unitgroup_load.column_tenant_id_);
6358}
6359return ret;
6360}
6361
6362int ObServerBalancer::calc_row_balance_resource_weights(
6363const common::ObIArray<ServerLoad> &server_loads,
6364const common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6365double *const resource_weights,
6366const int64_t weights_count)
6367{
6368int ret = OB_SUCCESS;
6369if (OB_UNLIKELY(!inited_)) {
6370ret = OB_NOT_INIT;
6371LOG_WARN("not init", K(ret));
6372} else if (OB_UNLIKELY(server_loads.count() <= 0
6373|| unitgroup_loads.count() <= 0
6374|| NULL == resource_weights
6375|| RES_MAX != weights_count)) {
6376ret = OB_INVALID_ARGUMENT;
6377LOG_WARN("invalid argument", K(ret), K(server_loads), K(unitgroup_loads));
6378} else {
6379for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
6380ObResourceType resource_type = static_cast<ObResourceType>(i);
6381double sum_capacity = 0.0;
6382for (int64_t j = 0; j < server_loads.count(); ++j) {
6383sum_capacity += server_loads.at(j).get_intra_ttg_resource_capacity(resource_type);
6384}
6385double sum_assigned = 0.0;
6386for (int64_t j = 0; j < unitgroup_loads.count(); ++j) {
6387sum_assigned += unitgroup_loads.at(j).load_sum_.get_required(resource_type);
6388}
6389if (sum_assigned <= 0 || sum_capacity <= 0) {
6390resource_weights[resource_type] = 0.0;
6391} else if (sum_assigned >= sum_capacity) {
6392resource_weights[resource_type] = 1.0;
6393} else {
6394resource_weights[resource_type] = sum_assigned / sum_capacity;
6395}
6396}
6397if (OB_SUCC(ret)) { // Weight normalization
6398double sum = 0.0;
6399const int64_t N = server_loads.count();
6400for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
6401resource_weights[i] /= static_cast<double>(N);
6402sum += resource_weights[i];
6403if (resource_weights[i] < 0 || resource_weights[i] > 1) {
6404ret = common::OB_ERR_UNEXPECTED;
6405LOG_ERROR("weight shall be in interval [0,1]", K(i), "w", resource_weights[i]);
6406}
6407}
6408if (OB_SUCC(ret) && sum > 0) {
6409for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
6410resource_weights[i] /= sum;
6411}
6412}
6413}
6414}
6415return ret;
6416}
6417
6418int ObServerBalancer::update_server_load_value(
6419const double *const resource_weights,
6420const int64_t weights_count,
6421common::ObIArray<ServerLoad> &server_loads)
6422{
6423int ret = OB_SUCCESS;
6424if (OB_UNLIKELY(!inited_)) {
6425ret = OB_NOT_INIT;
6426LOG_WARN("not init", K(ret));
6427} else if (weights_count != RES_MAX || NULL == resource_weights) {
6428ret = OB_INVALID_ARGUMENT;
6429LOG_WARN("invalid argument", K(ret), K(weights_count), KP(resource_weights));
6430} else {
6431for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
6432ServerLoad &server_load = server_loads.at(i);
6433if (!server_load.is_valid()) {
6434ret = OB_ERR_UNEXPECTED;
6435LOG_WARN("should be a valid server load here", K(ret), K(server_load));
6436} else {
6437for (int32_t j = RES_CPU; j < RES_MAX; ++j) {
6438server_load.intra_weights_[j] = resource_weights[j];
6439}
6440}
6441}
6442for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
6443ServerLoad &server_load = server_loads.at(i);
6444if (!server_load.is_valid()) {
6445ret = OB_ERR_UNEXPECTED;
6446LOG_WARN("should be a valid server load here", K(ret), K(server_load));
6447} else if (OB_FAIL(server_load.update_load_value())) {
6448LOG_WARN("server fails to update load value", K(ret));
6449} else {} // no more to do
6450}
6451}
6452return ret;
6453}
6454
6455int ObServerBalancer::do_balance_row_units(
6456TenantGroupBalanceInfo &balance_info,
6457Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
6458common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6459common::ObIArray<ServerLoad> &server_loads)
6460{
6461int ret = OB_SUCCESS;
6462if (OB_UNLIKELY(!inited_)) {
6463ret = OB_NOT_INIT;
6464LOG_WARN("not init", K(ret));
6465} else if (OB_FAIL(inner_ttg_balance_strategy_.do_balance_row_units(
6466balance_info, unit_migrate_stat_matrix, unitgroup_loads, server_loads))) {
6467LOG_WARN("fail to do balance row units", K(ret));
6468} else {}
6469return ret;
6470}
6471
6472int ObServerBalancer::CountBalanceStrategy::do_balance_row_units(
6473TenantGroupBalanceInfo &balance_info,
6474Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
6475common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6476common::ObIArray<ServerLoad> &server_loads)
6477{
6478int ret = OB_SUCCESS;
6479if (OB_UNLIKELY(unitgroup_loads.count() <= 0 || server_loads.count() <= 0)) {
6480ret = OB_INVALID_ARGUMENT;
6481LOG_WARN("invalid argument", K(ret), K(server_loads), K(unitgroup_loads));
6482} else if (OB_FAIL(make_count_balanced(
6483balance_info, unit_migrate_stat_matrix, unitgroup_loads, server_loads))) {
6484LOG_WARN("fail to make count balanced", K(ret));
6485} else if (OB_FAIL(move_or_exchange_ug_balance_ttg_load(
6486balance_info, unitgroup_loads, server_loads))) {
6487LOG_WARN("fail to balance load", K(ret));
6488} else {} // no more to do
6489return ret;
6490}
6491
6492// Continue to exchange the unitgroups on the maximum server load and the minimum server load
6493// until the exchange cannot reduce the difference between the two or the difference between the two is less than tolerance
6494int ObServerBalancer::CountBalanceStrategy::move_or_exchange_ug_balance_ttg_load(
6495TenantGroupBalanceInfo &balance_info,
6496common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6497common::ObIArray<ServerLoad> &server_loads)
6498{
6499int ret = OB_SUCCESS;
6500UNUSED(balance_info);
6501if (OB_UNLIKELY(unitgroup_loads.count() <= 0 || server_loads.count() <= 0)) {
6502ret = OB_INVALID_ARGUMENT;
6503LOG_WARN("invalid argument", K(ret), K(unitgroup_loads), K(server_loads));
6504} else {
6505double sum_load = 0.0;
6506ObArray<ServerLoad *> server_load_ptrs_sorted;
6507for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
6508if (OB_FAIL(server_load_ptrs_sorted.push_back(&server_loads.at(i)))) {
6509LOG_WARN("fail to push back", K(ret));
6510} else {
6511sum_load += server_loads.at(i).intra_ttg_load_value_;
6512}
6513}
6514if (OB_SUCC(ret)) {
6515double tolerance = sum_load / 100;
6516// Sort by intra load descending order
6517IntraServerLoadCmp cmp;
6518std::sort(server_load_ptrs_sorted.begin(),
6519server_load_ptrs_sorted.end(),
6520cmp);
6521if (OB_FAIL(cmp.get_ret())) {
6522LOG_WARN("fail to sorted", K(ret));
6523} else if (OB_FAIL(do_move_or_exchange_ug_balance_ttg_load(
6524server_load_ptrs_sorted, unitgroup_loads, tolerance))) {
6525LOG_WARN("fail to exchange ug", K(ret));
6526} else {} // no more to do
6527}
6528}
6529return ret;
6530}
6531
6532int ObServerBalancer::CountBalanceStrategy::do_move_or_exchange_ug_balance_ttg_load(
6533common::ObArray<ServerLoad *> &server_load_ptrs_sorted,
6534common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6535const double tolerance)
6536{
6537int ret = OB_SUCCESS;
6538if (server_load_ptrs_sorted.count() <= 0
6539|| unitgroup_loads.count() <= 0
6540|| unitgroup_loads.count() >= INT32_MAX) {
6541ret = OB_INVALID_ARGUMENT;
6542LOG_WARN("invalid argument", K(ret), K(server_load_ptrs_sorted), K(unitgroup_loads));
6543} else {
6544const int64_t max_times = unitgroup_loads.count() * unitgroup_loads.count();
6545int64_t times = 0;
6546bool do_operate = true;
6547while (OB_SUCC(ret) && do_operate && times < max_times) {
6548ServerLoad *max_load_server = NULL;
6549ServerLoad *min_load_server = NULL;
6550const int64_t server_cnt = server_load_ptrs_sorted.count();
6551if (server_cnt <= 0) {
6552ret = OB_ERR_UNEXPECTED;
6553LOG_WARN("server load array is empty", K(ret), K(server_cnt));
6554} else if (NULL == (max_load_server = server_load_ptrs_sorted.at(0))) {
6555ret = OB_ERR_UNEXPECTED;
6556LOG_WARN("load ptr is null", K(ret), KP(max_load_server));
6557} else if (NULL == (min_load_server = server_load_ptrs_sorted.at(server_cnt - 1))) {
6558ret = OB_ERR_UNEXPECTED;
6559LOG_WARN("load ptr is null", K(ret), KP(min_load_server));
6560} else if (max_load_server->intra_ttg_load_value_
6561< tolerance + min_load_server->intra_ttg_load_value_) {
6562break; // load balanced
6563} else if (max_load_server->unitgroup_loads_.count()
6564<= min_load_server->unitgroup_loads_.count()) {
6565if (OB_FAIL(try_exchange_ug_balance_ttg_load_foreach(
6566*max_load_server, *min_load_server, unitgroup_loads, do_operate))) {
6567LOG_WARN("fail to exchange ug", K(ret));
6568}
6569} else if (max_load_server->unitgroup_loads_.count()
6570> min_load_server->unitgroup_loads_.count() + 1) {
6571ret = OB_ERR_UNEXPECTED;
6572LOG_WARN("unitgroup load count unexpected", K(ret),
6573K(*max_load_server), K(*min_load_server));
6574} else {
6575if (OB_FAIL(try_move_ug_balance_ttg_load_foreach(
6576*max_load_server, *min_load_server, unitgroup_loads, do_operate))) {
6577LOG_WARN("fail to move ug", K(ret));
6578} else if (do_operate) {
6579// by pass
6580} else if (OB_FAIL(try_exchange_ug_balance_ttg_load_foreach(
6581*max_load_server, *min_load_server, unitgroup_loads, do_operate))) {
6582LOG_WARN("fail to exchange ug", K(ret));
6583}
6584}
6585if (OB_FAIL(ret)) {
6586} else if (!do_operate) {
6587// will leave the loop
6588} else {
6589times++;
6590IntraServerLoadCmp cmp;
6591std::sort(server_load_ptrs_sorted.begin(),
6592server_load_ptrs_sorted.end(),
6593cmp);
6594if (OB_FAIL(cmp.get_ret())) {
6595LOG_WARN("fail to sort", K(ret));
6596}
6597}
6598}
6599}
6600return ret;
6601}
6602
6603int ObServerBalancer::CountBalanceStrategy::try_move_ug_balance_ttg_load_foreach(
6604ServerLoad &max_server_load,
6605ServerLoad &min_server_load,
6606common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6607bool &do_move)
6608{
6609int ret = OB_SUCCESS;
6610do_move = false;
6611if (max_server_load.unitgroup_loads_.count() <= min_server_load.unitgroup_loads_.count()) {
6612// by pass
6613} else {
6614ObArray<common::ObAddr> excluded_dst_servers;
6615for (int64_t i = max_server_load.unitgroup_loads_.count() - 1;
6616!do_move && OB_SUCC(ret) && i >= 0;
6617--i) {
6618UnitGroupLoad &ug_load = *max_server_load.unitgroup_loads_.at(i);
6619bool can_move = false;
6620excluded_dst_servers.reset();
6621if (OB_FAIL(get_ug_balance_excluded_dst_servers(
6622ug_load, unitgroup_loads, excluded_dst_servers))) {
6623LOG_WARN("fail to get excluded server", K(ret));
6624} else if (has_exist_in_array(excluded_dst_servers, min_server_load.server_)) {
6625// in excluded servers, ignore
6626} else if (OB_FAIL(check_can_move_ug_balance_intra_ttg_load(
6627max_server_load, ug_load, min_server_load, can_move))) {
6628LOG_WARN("fail to check can move ug balance intra ttg load", K(ret));
6629} else if (!can_move) {
6630// ignore
6631} else if (OB_FAIL(move_ug_between_server_loads(
6632max_server_load, min_server_load, ug_load, i))) {
6633LOG_WARN("fail to move ug between server loads", K(ret));
6634} else {
6635do_move = true;
6636}
6637}
6638if (OB_SUCC(ret)) {
6639UnitGroupLoadCmp unitgroup_load_cmp(max_server_load);
6640std::sort(max_server_load.unitgroup_loads_.begin(),
6641max_server_load.unitgroup_loads_.end(),
6642unitgroup_load_cmp);
6643if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
6644LOG_WARN("fail to sort", K(ret));
6645}
6646}
6647if (OB_SUCC(ret)) {
6648UnitGroupLoadCmp unitgroup_load_cmp(min_server_load);
6649std::sort(min_server_load.unitgroup_loads_.begin(),
6650min_server_load.unitgroup_loads_.end(),
6651unitgroup_load_cmp);
6652if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
6653LOG_WARN("fail to sort", K(ret));
6654}
6655}
6656}
6657return ret;
6658}
6659
6660int ObServerBalancer::CountBalanceStrategy::try_exchange_ug_balance_ttg_load_foreach(
6661ServerLoad &max_server_load,
6662ServerLoad &min_server_load,
6663common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6664bool &do_exchange)
6665{
6666int ret = OB_SUCCESS;
6667do_exchange = false;
6668if (max_server_load.intra_ttg_load_value_ - min_server_load.intra_ttg_load_value_ < EPSILON) {
6669do_exchange = false;
6670} else if (max_server_load.unitgroup_loads_.count() <= 0
6671|| min_server_load.unitgroup_loads_.count() <= 0) {
6672do_exchange = false;
6673} else {
6674for (int64_t i = 0;
6675!do_exchange && OB_SUCC(ret) && i < max_server_load.unitgroup_loads_.count();
6676++i) {
6677common::ObArray<common::ObAddr> excluded_servers;
6678UnitGroupLoad *left_ug = max_server_load.unitgroup_loads_.at(i);
6679double left_load = 0.0;
6680if (OB_UNLIKELY(NULL == left_ug)) {
6681ret = OB_ERR_UNEXPECTED;
6682LOG_WARN("src ug ptr is null", K(ret), KP(left_ug));
6683} else if (OB_FAIL(get_ug_balance_excluded_dst_servers(
6684*left_ug, unitgroup_loads, excluded_servers))) {
6685LOG_WARN("fail to get excluded server", K(ret));
6686} else if (has_exist_in_array(excluded_servers, min_server_load.server_)) {
6687// ignore this
6688} else if (OB_FAIL(left_ug->get_intra_ttg_load_value(max_server_load, left_load))) {
6689LOG_WARN("fail to get intra ttg load value", K(ret));
6690} else {
6691for (int64_t j = min_server_load.unitgroup_loads_.count() - 1;
6692!do_exchange && OB_SUCC(ret) && j >= 0;
6693--j) {
6694UnitGroupLoad *right_ug = min_server_load.unitgroup_loads_.at(j);
6695// The calculation denominator of left load takes max_server_load,
6696// so the calculation denominator of right load also takes max_server_load,
6697// So that the comparison of the two values makes sense
6698double right_load = 0.0;
6699bool can_exchange = false;
6700if (NULL == right_ug) {
6701ret = OB_ERR_UNEXPECTED;
6702LOG_WARN("src or dst ug ptr is null", K(ret), KP(right_ug));
6703} else if (left_ug->column_tenant_id_ == right_ug->column_tenant_id_) {
6704// ignore this,
6705} else if (OB_FAIL(get_ug_balance_excluded_dst_servers(
6706*right_ug, unitgroup_loads, excluded_servers))) {
6707LOG_WARN("fail to get excluded servers", K(ret));
6708} else if (has_exist_in_array(excluded_servers, max_server_load.server_)) {
6709// ignore this
6710} else if (OB_FAIL(right_ug->get_intra_ttg_load_value(max_server_load, right_load))) {
6711LOG_WARN("fail to get intra ttg load value", K(ret));
6712} else if (left_load - right_load < EPSILON) {
6713// When the left is smaller than the right or a little bigger than the right (EPSILON), no swap
6714} else if (OB_FAIL(check_can_exchange_ug_balance_intra_ttg_load(
6715*left_ug, max_server_load, *right_ug, min_server_load, can_exchange))) {
6716LOG_WARN("fail to check can exchange ug balance ttg load", K(ret));
6717} else if (!can_exchange) {
6718// ignore this
6719} else if (OB_FAIL(exchange_ug_between_server_loads(
6720*left_ug, i, max_server_load, *right_ug, j, min_server_load))) {
6721LOG_WARN("fail to exchange ug between server loads", K(ret));
6722} else {
6723do_exchange = true;
6724}
6725}
6726}
6727}
6728if (OB_SUCC(ret)) {
6729UnitGroupLoadCmp unitgroup_load_cmp(max_server_load);
6730std::sort(max_server_load.unitgroup_loads_.begin(),
6731max_server_load.unitgroup_loads_.end(),
6732unitgroup_load_cmp);
6733if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
6734LOG_WARN("fail to sort", K(ret));
6735}
6736}
6737if (OB_SUCC(ret)) {
6738UnitGroupLoadCmp unitgroup_load_cmp(min_server_load);
6739std::sort(min_server_load.unitgroup_loads_.begin(),
6740min_server_load.unitgroup_loads_.end(),
6741unitgroup_load_cmp);
6742if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
6743LOG_WARN("fail to sort", K(ret));
6744}
6745}
6746}
6747return ret;
6748}
6749
6750// Keep moving the unitgroup from the server load with the largest cnt to the server load with the smallest cnt,
6751// until the difference between the largest server load and the smallest server load is less than or equal to 1 unitgroup
6752int ObServerBalancer::CountBalanceStrategy::make_count_balanced(
6753TenantGroupBalanceInfo &balance_info,
6754Matrix<UnitMigrateStat> &unit_migrate_stat_matrix,
6755common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6756common::ObIArray<ServerLoad> &server_loads)
6757{
6758int ret = OB_SUCCESS;
6759UNUSED(balance_info);
6760UNUSED(unit_migrate_stat_matrix);
6761if (OB_UNLIKELY(unitgroup_loads.count() <= 0 || server_loads.count() <= 0)) {
6762ret = OB_INVALID_ARGUMENT;
6763LOG_WARN("invalid argument", K(ret), K(server_loads), K(unitgroup_loads));
6764} else {
6765ObArray<ServerLoad *> server_cnt_ptrs_sorted;
6766for (int64_t i = 0; OB_SUCC(ret) && i < server_loads.count(); ++i) {
6767if (OB_FAIL(server_cnt_ptrs_sorted.push_back(&server_loads.at(i)))) {
6768LOG_WARN("fail to push back", K(ret));
6769}
6770}
6771if (OB_SUCC(ret)) {
6772// Sort by the number of unitgroups on the server in ascending order
6773ServerLoadUgCntCmp cmp;
6774std::sort(server_cnt_ptrs_sorted.begin(),
6775server_cnt_ptrs_sorted.end(),
6776cmp);
6777if (OB_FAIL(cmp.get_ret())) {
6778LOG_WARN("fail to sort", K(ret));
6779} else if (OB_FAIL(do_make_count_balanced(server_cnt_ptrs_sorted, unitgroup_loads))) {
6780LOG_WARN("fail to make count balanced", K(ret));
6781} else {} // no more to do
6782}
6783}
6784return ret;
6785}
6786
6787int ObServerBalancer::CountBalanceStrategy::do_make_count_balanced(
6788common::ObArray<ServerLoad *> &server_cnt_ptrs_sorted,
6789common::ObIArray<UnitGroupLoad> &unitgroup_loads)
6790{
6791int ret = OB_SUCCESS;
6792if (server_cnt_ptrs_sorted.count() <= 0 || unitgroup_loads.count() <= 0) {
6793ret = OB_INVALID_ARGUMENT;
6794LOG_WARN("invalid argument", K(ret), K(server_cnt_ptrs_sorted), K(unitgroup_loads));
6795} else {
6796int64_t times = 0;
6797while (OB_SUCC(ret) && times < unitgroup_loads.count()) {
6798ServerLoad *first = NULL;
6799ServerLoad *last = NULL;
6800const int64_t server_cnt = server_cnt_ptrs_sorted.count();
6801if (server_cnt <= 0) {
6802ret = OB_ERR_UNEXPECTED;
6803LOG_WARN("server load array is empty", K(ret));
6804} else if (NULL == (first = server_cnt_ptrs_sorted.at(0))) {
6805ret = OB_ERR_UNEXPECTED;
6806LOG_WARN("load ptr is null", K(ret), KP(first));
6807} else if (NULL == (last = server_cnt_ptrs_sorted.at(server_cnt - 1))) {
6808ret = OB_ERR_UNEXPECTED;
6809LOG_WARN("last ptr is null", K(ret), KP(last));
6810} else if (last->unitgroup_loads_.count() - first->unitgroup_loads_.count() <= 1) {
6811break;
6812} else if (OB_FAIL(do_make_count_balanced_foreach(*last, *first, unitgroup_loads))) {
6813LOG_WARN("fail to make count balanced foreach");
6814} else {
6815times++;
6816ServerLoadUgCntCmp cmp;
6817std::sort(server_cnt_ptrs_sorted.begin(),
6818server_cnt_ptrs_sorted.end(),
6819cmp);
6820if (OB_FAIL(cmp.get_ret())) {
6821LOG_WARN("fail to sort", K(ret));
6822}
6823}
6824}
6825}
6826return ret;
6827}
6828
6829int ObServerBalancer::CountBalanceStrategy::do_make_count_balanced_foreach(
6830ServerLoad &src_server_load,
6831ServerLoad &dst_server_load,
6832common::ObIArray<UnitGroupLoad> &unitgroup_loads)
6833{
6834int ret = OB_SUCCESS;
6835if (unitgroup_loads.count() <= 0) {
6836ret = OB_INVALID_ARGUMENT;
6837LOG_WARN("invalid argument", K(ret), K(unitgroup_loads));
6838} else {
6839for (int64_t i = src_server_load.unitgroup_loads_.count() - 1;
6840OB_SUCC(ret) && i >= 0;
6841--i) {
6842common::ObArray<common::ObAddr> excluded_servers;
6843UnitGroupLoad *ug_load = src_server_load.unitgroup_loads_.at(i);
6844if (src_server_load.unitgroup_loads_.count()
6845<= dst_server_load.unitgroup_loads_.count() + 1) {
6846break;
6847} else if (OB_UNLIKELY(NULL == ug_load)) {
6848ret = OB_ERR_UNEXPECTED;
6849LOG_WARN("ug_load ptr is null", K(ret), KP(ug_load));
6850} else if (OB_FAIL(get_ug_balance_excluded_dst_servers(
6851*ug_load, unitgroup_loads, excluded_servers))) {
6852LOG_WARN("fail to get excluded servers", K(ret));
6853} else if (has_exist_in_array(excluded_servers, dst_server_load.server_)) {
6854// ignore this ug load, since it cannot move to dst server
6855} else if (OB_FAIL(move_ug_between_server_loads(
6856src_server_load, dst_server_load, *ug_load, i))) {
6857LOG_WARN("fail to move ug", K(ret));
6858} else {} // no more to do
6859}
6860if (OB_SUCC(ret)) {
6861UnitGroupLoadCmp unitgroup_load_cmp(src_server_load);
6862std::sort(src_server_load.unitgroup_loads_.begin(),
6863src_server_load.unitgroup_loads_.end(),
6864unitgroup_load_cmp);
6865if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
6866LOG_WARN("fail to sort", K(ret));
6867}
6868}
6869if (OB_SUCC(ret)) {
6870UnitGroupLoadCmp unitgroup_load_cmp(dst_server_load);
6871std::sort(dst_server_load.unitgroup_loads_.begin(),
6872dst_server_load.unitgroup_loads_.end(),
6873unitgroup_load_cmp);
6874if (OB_FAIL(unitgroup_load_cmp.get_ret())) {
6875LOG_WARN("fail to sort", K(ret));
6876}
6877}
6878}
6879return ret;
6880}
6881
6882int ObServerBalancer::InnerTenantGroupBalanceStrategy::get_ug_balance_excluded_dst_servers(
6883const UnitGroupLoad &unitgroup_load,
6884const common::ObIArray<UnitGroupLoad> &unitgroup_loads,
6885common::ObIArray<common::ObAddr> &excluded_servers)
6886{
6887int ret = OB_SUCCESS;
6888excluded_servers.reset();
6889const uint64_t column_tenant_id = unitgroup_load.column_tenant_id_;
6890for (int64_t i = 0; OB_SUCC(ret) && i < unitgroup_loads.count(); ++i) {
6891const UnitGroupLoad &this_load = unitgroup_loads.at(i);
6892if (column_tenant_id != this_load.column_tenant_id_) {
6893// not from the same tenant column
6894} else if (!has_exist_in_array(excluded_servers, this_load.server_)) {
6895if (OB_FAIL(excluded_servers.push_back(this_load.server_))) {
6896LOG_WARN("fail to push back", K(ret));
6897}
6898}
6899}
6900return ret;
6901}
6902
6903int ObServerBalancer::InnerTenantGroupBalanceStrategy::move_ug_between_server_loads(
6904ServerLoad &src_server_load,
6905ServerLoad &dst_server_load,
6906UnitGroupLoad &ug_load,
6907const int64_t ug_idx)
6908{
6909int ret = OB_SUCCESS;
6910if (ug_idx < 0 || ug_idx >= src_server_load.unitgroup_loads_.count()) {
6911ret = OB_INVALID_ARGUMENT;
6912LOG_WARN("invalid argument", K(ug_idx), K(src_server_load));
6913} else if (&ug_load != src_server_load.unitgroup_loads_.at(ug_idx)) {
6914ret = OB_ERR_UNEXPECTED;
6915LOG_WARN("ug load ptr and idx not match", K(ret), K(src_server_load), K(ug_load), K(ug_idx));
6916} else {
6917if (OB_FAIL(src_server_load.unitgroup_loads_.remove(ug_idx))) {
6918LOG_WARN("remove failed", K(ret), K(ug_idx));
6919} else if (OB_FAIL(dst_server_load.unitgroup_loads_.push_back(&ug_load))) {
6920LOG_WARN("fail to push back", K(ret));
6921} else if (OB_FAIL(src_server_load.update_load_value())) {
6922LOG_WARN("fail to update load value", K(ret));
6923} else if (OB_FAIL(dst_server_load.update_load_value())) {
6924LOG_WARN("fail to update load value", K(ret));
6925} else {
6926ug_load.server_ = dst_server_load.server_;
6927ug_load.server_load_ = &dst_server_load;
6928}
6929}
6930return ret;
6931}
6932
6933int ObServerBalancer::InnerTenantGroupBalanceStrategy::exchange_ug_between_server_loads(
6934UnitGroupLoad &left_ug,
6935const int64_t left_idx,
6936ServerLoad &left_server,
6937UnitGroupLoad &right_ug,
6938const int64_t right_idx,
6939ServerLoad &right_server)
6940{
6941int ret = OB_SUCCESS;
6942if (left_idx < 0 || left_idx >= left_server.unitgroup_loads_.count()
6943|| right_idx < 0 || right_idx >= right_server.unitgroup_loads_.count()) {
6944ret = OB_INVALID_ARGUMENT;
6945LOG_WARN("invalid argument", K(ret),
6946K(left_idx),
6947"left_server_ug_cnt", left_server.unitgroup_loads_.count(),
6948K(right_idx),
6949"right_server_ug_cnt", right_server.unitgroup_loads_.count());
6950} else if (&left_ug != left_server.unitgroup_loads_.at(left_idx)
6951|| &right_ug != right_server.unitgroup_loads_.at(right_idx)) {
6952ret = OB_ERR_UNEXPECTED;
6953LOG_WARN("ug ptr and idx not match", K(ret), K(left_idx), K(right_idx));
6954} else {
6955if (OB_FAIL(left_server.unitgroup_loads_.remove(left_idx))) {
6956LOG_WARN("fail to remove", K(ret));
6957} else if (OB_FAIL(right_server.unitgroup_loads_.remove(right_idx))) {
6958LOG_WARN("fail to remove", K(ret));
6959} else if (OB_FAIL(left_server.unitgroup_loads_.push_back(&right_ug))) {
6960LOG_WARN("fail to push back", K(ret));
6961} else if (OB_FAIL(right_server.unitgroup_loads_.push_back(&left_ug))) {
6962LOG_WARN("fail to push back", K(ret));
6963} else if (OB_FAIL(left_server.update_load_value())) {
6964LOG_WARN("fail to update load value", K(ret));
6965} else if (OB_FAIL(right_server.update_load_value())) {
6966LOG_WARN("fail to update load value", K(ret));
6967} else {
6968left_ug.server_ = right_server.server_;
6969left_ug.server_load_ = &right_server;
6970right_ug.server_ = left_server.server_;
6971right_ug.server_load_ = &left_server;
6972}
6973}
6974return ret;
6975}
6976
6977int ObServerBalancer::CountBalanceStrategy::check_can_move_ug_balance_intra_ttg_load(
6978ServerLoad &left_server,
6979UnitGroupLoad &ug_load,
6980ServerLoad &right_server,
6981bool &can_move)
6982{
6983int ret = OB_SUCCESS;
6984can_move = false;
6985double left_before = left_server.intra_ttg_load_value_;
6986double right_before = right_server.intra_ttg_load_value_;
6987double ug_on_left_svr = 0.0; // ug's own load value of ug on the left server
6988double ug_on_right_svr = 0.0; // Load value of ug itself after ug is moved to the right server
6989double left_after = 0.0;
6990double right_after = 0.0;
6991if (OB_FAIL(ug_load.get_intra_ttg_load_value(left_server, ug_on_left_svr))) {
6992LOG_WARN("fail to get left intra ttg load value on left", K(ret));
6993} else if (OB_FAIL(ug_load.get_intra_ttg_load_value(right_server, ug_on_right_svr))) {
6994LOG_WARN("fail to get left intra ttg load value on right", K(ret));
6995} else {
6996left_after = left_before - ug_on_left_svr;
6997right_after = right_before + ug_on_right_svr;
6998if (left_after > right_after) {
6999can_move = (left_before - right_before > EPSILON)
7000&& ((left_before - right_before) - (left_after - right_after) > EPSILON);
7001} else {
7002can_move = (left_before - right_before > EPSILON)
7003&& ((left_before - right_before) - (right_after - left_after) > EPSILON);
7004}
7005}
7006return ret;
7007}
7008
7009int ObServerBalancer::CountBalanceStrategy::check_can_exchange_ug_balance_intra_ttg_load(
7010UnitGroupLoad &left_ug,
7011ServerLoad &left_server,
7012UnitGroupLoad &right_ug,
7013ServerLoad &right_server,
7014bool &can_exchange)
7015{
7016int ret = OB_SUCCESS;
7017can_exchange = false;
7018double left_before = left_server.intra_ttg_load_value_;
7019double right_before = right_server.intra_ttg_load_value_;
7020double left_ug_on_left_svr = 0.0; // Left ug's own load value of ug on the left server
7021double left_ug_on_right_svr = 0.0; // The load value of ug itself after the left ug is moved to the right server
7022double right_ug_on_right_svr = 0.0; // Right ug's own load value of ug on the right server
7023double right_ug_on_left_svr = 0.0; // The load value of ug itself after the right ug is moved to the left server
7024double left_after = 0.0;
7025double right_after = 0.0;
7026if (OB_FAIL(left_ug.get_intra_ttg_load_value(left_server, left_ug_on_left_svr))) {
7027LOG_WARN("fail to get left intra ttg load value on left", K(ret));
7028} else if (OB_FAIL(left_ug.get_intra_ttg_load_value(right_server, left_ug_on_right_svr))) {
7029LOG_WARN("fail to get left intra ttg load value on right", K(ret));
7030} else if (OB_FAIL(right_ug.get_intra_ttg_load_value(right_server, right_ug_on_right_svr))) {
7031LOG_WARN("fail to get right intra ttg load value on right", K(ret));
7032} else if (OB_FAIL(right_ug.get_intra_ttg_load_value(left_server, right_ug_on_left_svr))) {
7033LOG_WARN("fail to get right intra ttg load value on left", K(ret));
7034} else {
7035left_after = left_before - left_ug_on_left_svr + right_ug_on_left_svr;
7036right_after = right_before - right_ug_on_right_svr + left_ug_on_right_svr;
7037if (left_after > right_after) {
7038can_exchange = (left_before - right_before > EPSILON)
7039&& ((left_before - right_before) - (left_after - right_after) > EPSILON);
7040} else {
7041can_exchange = (left_before - right_before > EPSILON)
7042&& ((left_before - right_before) - (right_after - left_after) > EPSILON);
7043}
7044}
7045return ret;
7046}
7047
7048int ObServerBalancer::CountBalanceStrategy::check_can_move_ug_balance_inter_ttg_load(
7049ServerLoad &left_server,
7050UnitGroupLoad &ug_load,
7051ServerLoad &right_server,
7052bool &can_move)
7053{
7054int ret = OB_SUCCESS;
7055can_move = false;
7056double left_before = left_server.intra_ttg_load_value_;
7057double right_before = right_server.intra_ttg_load_value_;
7058double ug_on_left_svr = 0.0; // ug's own load value of ug on the left server
7059double ug_on_right_svr = 0.0; // Load value of ug itself after ug is moved to the right server
7060double left_after = 0.0;
7061double right_after = 0.0;
7062if (OB_FAIL(ug_load.get_intra_ttg_load_value(left_server, ug_on_left_svr))) {
7063LOG_WARN("fail to get left intra ttg load value on left", K(ret));
7064} else if (OB_FAIL(ug_load.get_intra_ttg_load_value(right_server, ug_on_right_svr))) {
7065LOG_WARN("fail to get left intra ttg load value on right", K(ret));
7066} else {
7067left_after = left_before - ug_on_left_svr;
7068right_after = right_before + ug_on_right_svr;
7069if (left_after > right_after) {
7070can_move = (left_before - right_before > EPSILON)
7071&& ((left_before - right_before) - (left_after - right_after) > -EPSILON);
7072} else {
7073can_move = (left_before - right_before > EPSILON)
7074&& ((left_before - right_before) - (right_after - left_after) > -EPSILON);
7075}
7076}
7077return ret;
7078}
7079
7080int ObServerBalancer::CountBalanceStrategy::check_can_exchange_ug_balance_inter_ttg_load(
7081UnitGroupLoad &left_ug,
7082ServerLoad &left_server,
7083UnitGroupLoad &right_ug,
7084ServerLoad &right_server,
7085bool &can_exchange)
7086{
7087int ret = OB_SUCCESS;
7088can_exchange = false;
7089double left_before = left_server.intra_ttg_load_value_;
7090double right_before = right_server.intra_ttg_load_value_;
7091double left_ug_on_left_svr = 0.0;
7092double left_ug_on_right_svr = 0.0;
7093double right_ug_on_right_svr = 0.0;
7094double right_ug_on_left_svr = 0.0;
7095double left_after = 0.0;
7096double right_after = 0.0;
7097if (OB_FAIL(left_ug.get_intra_ttg_load_value(left_server, left_ug_on_left_svr))) {
7098LOG_WARN("fail to get left intra ttg load value on left", K(ret));
7099} else if (OB_FAIL(left_ug.get_intra_ttg_load_value(right_server, left_ug_on_right_svr))) {
7100LOG_WARN("fail to get left intra ttg load value on right", K(ret));
7101} else if (OB_FAIL(right_ug.get_intra_ttg_load_value(right_server, right_ug_on_right_svr))) {
7102LOG_WARN("fail to get right intra ttg load value on right", K(ret));
7103} else if (OB_FAIL(right_ug.get_intra_ttg_load_value(left_server, right_ug_on_left_svr))) {
7104LOG_WARN("fail to get right intra ttg load value on left", K(ret));
7105} else {
7106left_after = left_before - left_ug_on_left_svr + right_ug_on_left_svr;
7107right_after = right_before - right_ug_on_right_svr + left_ug_on_right_svr;
7108if (left_after > right_after) {
7109can_exchange = (left_before - right_before > EPSILON)
7110&& ((left_before - right_before) - (left_after - right_after) > -EPSILON);
7111} else {
7112can_exchange = (left_before - right_before > EPSILON)
7113&& ((left_before - right_before) - (right_after - left_after) > -EPSILON);
7114}
7115}
7116return ret;
7117}
7118
7119bool ObServerBalancer::UnitGroupLoad::is_valid() const
7120{
7121bool bool_ret = OB_INVALID_ID != column_tenant_id_
7122&& start_column_idx_ >= 0
7123&& column_count_ > 0
7124&& unit_loads_.count() > 0
7125&& server_.is_valid()
7126&& load_sum_.is_valid();
7127for (int64_t i = 0; bool_ret && i < unit_loads_.count(); ++i) {
7128bool_ret = unit_loads_.at(i).is_valid();
7129}
7130return bool_ret;
7131}
7132
7133void ObServerBalancer::UnitGroupLoad::reset()
7134{
7135column_tenant_id_ = OB_INVALID_ID;
7136start_column_idx_ = -1;
7137column_count_ = 0;
7138server_.reset();
7139server_load_ = NULL;
7140unit_loads_.reset();
7141load_sum_.reset();
7142}
7143
7144int ObServerBalancer::UnitGroupLoad::sum_group_load()
7145{
7146int ret = OB_SUCCESS;
7147load_sum_.reset();
7148for (int64_t j = 0; OB_SUCC(ret) && j < unit_loads_.count(); ++j) {
7149const ObUnitConfig &unit_load = unit_loads_.at(j);
7150if (!unit_load.is_valid()) {
7151ret = OB_ERR_UNEXPECTED;
7152LOG_WARN("invalid unit load", K(ret), K(unit_load));
7153} else if (OB_FAIL(load_sum_.append_load(unit_load))) {
7154LOG_WARN("fail to append load", K(ret));
7155} else {} // no more to do
7156}
7157return ret;
7158}
7159
7160int ObServerBalancer::UnitGroupLoad::get_intra_ttg_load_value(
7161const ServerLoad &target_server_load,
7162double &intra_ttg_load_value) const
7163{
7164int ret = OB_SUCCESS;
7165intra_ttg_load_value = 0.0;
7166for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
7167ObResourceType res_type = static_cast<ObResourceType>(i);
7168if (target_server_load.get_intra_ttg_resource_capacity(res_type) <= 0
7169|| load_sum_.get_required(res_type) <= 0) {
7170// has no effect on load value
7171} else if (load_sum_.get_required(res_type) > target_server_load.get_intra_ttg_resource_capacity(res_type)) {
7172intra_ttg_load_value += target_server_load.intra_weights_[i] * 1.0;
7173} else {
7174double quotient
7175= load_sum_.get_required(res_type) / target_server_load.get_intra_ttg_resource_capacity(res_type);
7176intra_ttg_load_value += target_server_load.intra_weights_[i] * quotient;
7177}
7178}
7179return ret;
7180}
7181
7182int ObServerBalancer::UnitGroupLoad::get_inter_ttg_load_value(
7183const ServerLoad &target_server_load,
7184double &inter_ttg_load_value) const
7185{
7186int ret = OB_SUCCESS;
7187inter_ttg_load_value = 0.0;
7188for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
7189ObResourceType res_type = static_cast<ObResourceType>(i);
7190if (target_server_load.get_true_capacity(res_type) <= 0
7191|| load_sum_.get_required(res_type) <= 0) {
7192// has no effect on load value
7193} else if (load_sum_.get_required(res_type) > target_server_load.get_true_capacity(res_type)) {
7194inter_ttg_load_value += target_server_load.inter_weights_[i] * 1.0;
7195} else {
7196double quotient
7197= load_sum_.get_required(res_type) / target_server_load.get_true_capacity(res_type);
7198inter_ttg_load_value += target_server_load.inter_weights_[i] * quotient;
7199}
7200}
7201return ret;
7202}
7203
7204int ObServerBalancer::UnitGroupLoadCmp::get_ret() const
7205{
7206return ret_;
7207}
7208
7209bool ObServerBalancer::UnitGroupLoadCmp::operator()(
7210const UnitGroupLoad *left,
7211const UnitGroupLoad *right)
7212{
7213// Sort by load in ascending order
7214bool bool_ret = false;
7215double left_value = 0.0;
7216double right_value = 0.0;
7217int &ret = ret_;
7218if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7219// ignore
7220} else if (OB_UNLIKELY(NULL == left || NULL == right)) {
7221ret_ = OB_INVALID_ARGUMENT;
7222LOG_WARN("invalid argument", K(ret_), KP(left), K(right));
7223} else if (OB_SUCCESS != (ret_ = left->get_intra_ttg_load_value(server_load_, left_value))) {
7224LOG_WARN("fail to get left intra load value", K(ret_));
7225} else if (OB_SUCCESS != (ret_ = right->get_intra_ttg_load_value(server_load_, right_value))) {
7226LOG_WARN("fail to get right intra load value", K(ret_));
7227} else if (left_value < right_value) {
7228bool_ret = true;
7229} else {
7230bool_ret = false;
7231}
7232return bool_ret;
7233}
7234
7235bool ObServerBalancer::ServerLoad::is_valid() const
7236{
7237// unitgroup loads can be empty, indicating that there is no load on the server, but server_ must be valid
7238bool bool_ret = unitgroup_loads_.count() >= 0 && ServerResourceLoad::is_valid();
7239for (int64_t i = 0; bool_ret && i < unitgroup_loads_.count(); ++i) {
7240const UnitGroupLoad *ins = unitgroup_loads_.at(i);
7241bool_ret = (NULL != ins && ins->is_valid());
7242}
7243return bool_ret;
7244}
7245
7246double ObServerBalancer::ServerResourceLoad::get_true_capacity(const ObResourceType resource_type) const
7247{
7248double ret = -1;
7249switch (resource_type) {
7250case RES_CPU:
7251ret = resource_info_.cpu_;
7252break;
7253case RES_MEM:
7254ret = static_cast<double>(resource_info_.mem_total_);
7255break;
7256case RES_LOG_DISK:
7257ret = static_cast<double>(resource_info_.log_disk_total_);
7258break;
7259default:
7260ret = -1;
7261break;
7262}
7263return ret;
7264}
7265
7266double ObServerBalancer::ServerLoad::get_intra_ttg_resource_capacity(
7267const ObResourceType resource_type) const
7268{
7269double ret = -1;
7270switch (resource_type) {
7271case RES_CPU:
7272ret = intra_ttg_resource_info_.cpu_;
7273break;
7274case RES_MEM:
7275ret = static_cast<double>(intra_ttg_resource_info_.mem_total_);
7276break;
7277case RES_LOG_DISK:
7278ret = static_cast<double>(intra_ttg_resource_info_.log_disk_total_);
7279break;
7280default:
7281ret = -1;
7282break;
7283}
7284return ret;
7285}
7286
7287int ObServerBalancer::ServerLoad::update_load_value()
7288{
7289int ret = OB_SUCCESS;
7290intra_ttg_load_value_ = 0.0;
7291inter_ttg_load_value_ = 0.0;
7292LoadSum intra_load_sum;
7293LoadSum inter_load_sum;
7294for (int64_t i = 0; OB_SUCC(ret) && i < unitgroup_loads_.count(); ++i) {
7295const UnitGroupLoad *unitgroup_load = unitgroup_loads_.at(i);
7296if (NULL == unitgroup_load) {
7297ret = OB_ERR_UNEXPECTED;
7298LOG_WARN("unitgroup load null", K(ret), KP(unitgroup_load));
7299} else if (OB_FAIL(intra_load_sum.append_load(unitgroup_load->load_sum_))) {
7300LOG_WARN("fail to append intra load", K(ret));
7301} else if (OB_FAIL(inter_load_sum.append_load(unitgroup_load->load_sum_))) {
7302LOG_WARN("fail to append inter load", K(ret));
7303}
7304}
7305for (int64_t i = 0; OB_SUCC(ret) && i < alien_ug_loads_.count(); ++i) {
7306const UnitGroupLoad *unitgroup_load = alien_ug_loads_.at(i);
7307if (NULL == unitgroup_load) {
7308ret = OB_ERR_UNEXPECTED;
7309LOG_WARN("unitgroup load null", K(ret), KP(unitgroup_load));
7310} else if (OB_FAIL(inter_load_sum.append_load(unitgroup_load->load_sum_))) {
7311LOG_WARN("fail to append load", K(ret));
7312}
7313}
7314for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
7315ObResourceType resource_type = static_cast<ObResourceType>(i);
7316const double required = intra_load_sum.get_required(resource_type);
7317const double capacity = get_intra_ttg_resource_capacity(resource_type);
7318if (required <= 0 || capacity <= 0) {
7319// has on effect on load value
7320} else if (required > capacity) {
7321intra_ttg_load_value_ += intra_weights_[i] * 1.0;
7322} else {
7323intra_ttg_load_value_ += intra_weights_[i] * (required / capacity);
7324}
7325}
7326for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
7327ObResourceType resource_type = static_cast<ObResourceType>(i);
7328const double required = inter_load_sum.get_required(resource_type);
7329const double capacity = get_true_capacity(resource_type);
7330if (required <= 0 || capacity <= 0) {
7331// has on effect on load value
7332} else if (required > capacity) {
7333inter_ttg_load_value_ += inter_weights_[i] * 1.0;
7334} else {
7335inter_ttg_load_value_ += inter_weights_[i] * (required / capacity);
7336}
7337}
7338return ret;
7339}
7340
7341int ObServerBalancer::ServerTotalLoad::update_load_value()
7342{
7343int ret = OB_SUCCESS;
7344inter_ttg_load_value_ = 0.0;
7345for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
7346ObResourceType resource_type = static_cast<ObResourceType>(i);
7347const double required = load_sum_.get_required(resource_type);
7348const double capacity = get_true_capacity(resource_type);
7349if (required <= 0 || capacity <= 0) {
7350// has on effect on load value
7351} else if (required > capacity) {
7352inter_ttg_load_value_ += resource_weights_[i] * 1.0;
7353} else {
7354inter_ttg_load_value_ += resource_weights_[i] * (required / capacity);
7355}
7356}
7357return ret;
7358}
7359
7360bool ObServerBalancer::ServerTotalLoadCmp::operator()(
7361const ServerTotalLoad *left,
7362const ServerTotalLoad *right)
7363{
7364bool bool_ret = false;
7365if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7366// ignore
7367} else if (OB_UNLIKELY(NULL == left || NULL == right)) {
7368ret_ = OB_INVALID_ARGUMENT;
7369LOG_WARN_RET(ret_, "invalid argument", K(ret_), KP(left), KP(right));
7370} else if (left->wild_server_ && !left->wild_server_) {
7371bool_ret = true;
7372} else if (!left->wild_server_ && right->wild_server_) {
7373bool_ret = false;
7374} else {
7375if (left->inter_ttg_load_value_ > right->inter_ttg_load_value_) {
7376bool_ret = true;
7377} else {
7378bool_ret = false;
7379}
7380}
7381return bool_ret;
7382}
7383
7384int ObServerBalancer::ServerTotalLoadCmp::get_ret() const
7385{
7386return ret_;
7387}
7388
7389bool ObServerBalancer::ServerTotalLoadCmp::operator()(
7390const ServerTotalLoad &left,
7391const ServerTotalLoad &right)
7392{
7393bool bool_ret = false;
7394if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7395// ignore
7396} else if (left.wild_server_ && !right.wild_server_) {
7397bool_ret = true;
7398} else if (!left.wild_server_ && right.wild_server_) {
7399bool_ret = false;
7400} else {
7401if (left.inter_ttg_load_value_ > right.inter_ttg_load_value_) {
7402bool_ret = true;
7403} else {
7404bool_ret = false;
7405}
7406}
7407return bool_ret;
7408}
7409
7410bool ObServerBalancer::IntraServerLoadCmp::operator()(
7411const ServerLoad *left,
7412const ServerLoad *right)
7413{
7414bool bool_ret = false;
7415if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7416// ignore
7417} else if (OB_UNLIKELY(NULL == left || NULL == right)) {
7418ret_ = OB_INVALID_ARGUMENT;
7419LOG_WARN_RET(ret_, "invalid argument", K(ret_), KP(left), KP(right));
7420} else if (left->intra_ttg_load_value_ > right->intra_ttg_load_value_) {
7421bool_ret = true;
7422} else {
7423bool_ret = false;
7424}
7425return bool_ret;
7426}
7427
7428int ObServerBalancer::IntraServerLoadCmp::get_ret() const
7429{
7430return ret_;
7431}
7432
7433bool ObServerBalancer::IntraServerLoadCmp::operator()(
7434const ServerLoad &left,
7435const ServerLoad &right)
7436{
7437bool bool_ret = false;
7438if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7439// ignore
7440} else if (left.intra_ttg_load_value_ > right.intra_ttg_load_value_) {
7441bool_ret = true;
7442} else {
7443bool_ret = false;
7444}
7445return bool_ret;
7446}
7447
7448bool ObServerBalancer::InterServerLoadCmp::operator()(
7449const ServerLoad *left,
7450const ServerLoad *right)
7451{
7452bool bool_ret = false;
7453if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7454// ignore
7455} else if (OB_UNLIKELY(NULL == left || NULL == right)) {
7456ret_ = OB_INVALID_ARGUMENT;
7457LOG_WARN_RET(ret_, "invalid argument", K(ret_), KP(left), KP(right));
7458} else if (left->inter_ttg_load_value_ > right->inter_ttg_load_value_) {
7459bool_ret = true;
7460} else {
7461bool_ret = false;
7462}
7463return bool_ret;
7464}
7465
7466int ObServerBalancer::InterServerLoadCmp::get_ret() const
7467{
7468return ret_;
7469}
7470
7471bool ObServerBalancer::InterServerLoadCmp::operator()(
7472const ServerLoad &left,
7473const ServerLoad &right)
7474{
7475bool bool_ret = false;
7476if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7477// ignore
7478} else if (left.inter_ttg_load_value_ > right.inter_ttg_load_value_) {
7479bool_ret = true;
7480} else {
7481bool_ret = false;
7482}
7483return bool_ret;
7484}
7485
7486bool ObServerBalancer::ServerLoadUgCntCmp::operator()(
7487const ServerLoad *left,
7488const ServerLoad *right)
7489{
7490bool bool_ret = false;
7491if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
7492// ignore
7493} else if (OB_UNLIKELY(NULL == left || NULL == right)) {
7494ret_ = OB_INVALID_ARGUMENT;
7495LOG_WARN_RET(ret_, "invalid argument", K(ret_), KP(left), KP(right));
7496} else if (left->unitgroup_loads_.count() < right->unitgroup_loads_.count()) {
7497bool_ret = true;
7498} else {
7499bool_ret = false;
7500}
7501return bool_ret;
7502}
7503
7504int ObServerBalancer::ServerLoadUgCntCmp::get_ret() const
7505{
7506return ret_;
7507}
7508
7509bool ObServerBalancer::LoadSum::is_valid() const
7510{
7511return load_sum_.min_cpu() >= 0
7512&& load_sum_.max_cpu() >= load_sum_.min_cpu()
7513&& load_sum_.memory_size() >= 0
7514&& load_sum_.log_disk_size() >= 0;
7515}
7516
7517void ObServerBalancer::LoadSum::reset()
7518{
7519load_sum_.reset();
7520}
7521
7522double ObServerBalancer::LoadSum::get_required(const ObResourceType resource_type) const
7523{
7524double ret = -1;
7525switch (resource_type) {
7526case RES_CPU:
7527ret = load_sum_.min_cpu();
7528break;
7529case RES_MEM:
7530ret = static_cast<double>(load_sum_.memory_size());
7531break;
7532case RES_LOG_DISK:
7533ret = static_cast<double>(load_sum_.log_disk_size());
7534break;
7535default:
7536ret = -1;
7537break;
7538}
7539return ret;
7540}
7541
7542int ObServerBalancer::LoadSum::calc_load_value(
7543double *const resource_weights,
7544const int64_t weights_count,
7545const ServerResourceLoad &server_resource,
7546double &load_value)
7547{
7548int ret = OB_SUCCESS;
7549if (NULL == resource_weights || RES_MAX != weights_count) {
7550ret = OB_INVALID_ARGUMENT;
7551LOG_WARN("invalid argument", K(ret));
7552} else {
7553load_value = 0.0;
7554for (int32_t i = RES_CPU; i < RES_MAX; ++i) {
7555ObResourceType res_type = static_cast<ObResourceType>(i);
7556if (server_resource.get_true_capacity(res_type) <= 0
7557|| get_required(res_type) <= 0) {
7558// has no effect on load value
7559} else if (get_required(res_type) > server_resource.get_true_capacity(res_type)) {
7560load_value += resource_weights[i] * 1.0;
7561} else {
7562double quotient = get_required(res_type) / server_resource.get_true_capacity(res_type);
7563load_value += resource_weights[i] * quotient;
7564}
7565}
7566}
7567return ret;
7568}
7569
7570int ObServerBalancer::LoadSum::remove_load(
7571const ObUnitManager::ObUnitLoad &unit_load)
7572{
7573int ret = OB_SUCCESS;
7574if (OB_UNLIKELY(!unit_load.is_valid())) {
7575ret = OB_INVALID_ARGUMENT;
7576LOG_WARN("invalid argument", K(ret), K(unit_load));
7577} else {
7578load_sum_ -= *unit_load.unit_config_;
7579}
7580return ret;
7581}
7582
7583int ObServerBalancer::LoadSum::append_load(
7584const share::ObUnitConfig &load)
7585{
7586int ret = OB_SUCCESS;
7587load_sum_ += load;
7588return ret;
7589}
7590
7591int ObServerBalancer::LoadSum::append_load(
7592const ObUnitManager::ObUnitLoad &unit_load)
7593{
7594int ret = OB_SUCCESS;
7595if (OB_UNLIKELY(!unit_load.is_valid())) {
7596ret = OB_INVALID_ARGUMENT;
7597LOG_WARN("invalid argument", K(ret), K(unit_load));
7598} else {
7599load_sum_ += *unit_load.unit_config_;
7600}
7601return ret;
7602}
7603
7604int ObServerBalancer::LoadSum::append_load(
7605const common::ObIArray<ObUnitManager::ObUnitLoad> &unit_loads)
7606{
7607int ret = OB_SUCCESS;
7608for (int64_t i = 0; OB_SUCC(ret) && i < unit_loads.count(); ++i) {
7609const ObUnitManager::ObUnitLoad &unit_load = unit_loads.at(i);
7610if (OB_UNLIKELY(!unit_load.is_valid())) {
7611ret = OB_INVALID_ARGUMENT;
7612LOG_WARN("invalid argument", K(ret), K(unit_load));
7613} else {
7614load_sum_ += *unit_load.unit_config_;
7615}
7616}
7617return ret;
7618}
7619
7620int ObServerBalancer::LoadSum::append_load(
7621const ObServerBalancer::LoadSum &load)
7622{
7623int ret = OB_SUCCESS;
7624load_sum_ += load.load_sum_;
7625return ret;
7626}
7627
7628bool ObServerBalancer::ResourceSum::is_valid() const
7629{
7630return resource_sum_.cpu_ > 0
7631&& resource_sum_.mem_total_ > 0
7632&& resource_sum_.disk_total_ > 0;
7633}
7634
7635void ObServerBalancer::ResourceSum::reset()
7636{
7637resource_sum_.reset();
7638}
7639
7640double ObServerBalancer::ResourceSum::get_capacity(const ObResourceType resource_type) const
7641{
7642double ret = -1;
7643switch (resource_type) {
7644case RES_CPU:
7645ret = resource_sum_.cpu_;
7646break;
7647case RES_MEM:
7648ret = static_cast<double>(resource_sum_.mem_total_);
7649break;
7650case RES_LOG_DISK:
7651ret = static_cast<double>(resource_sum_.log_disk_total_);
7652break;
7653default:
7654ret = -1;
7655break;
7656}
7657return ret;
7658}
7659
7660int ObServerBalancer::ResourceSum::append_resource(
7661const share::ObServerResourceInfo &resource)
7662{
7663int ret = OB_SUCCESS;
7664resource_sum_.cpu_ += resource.cpu_;
7665resource_sum_.mem_total_ += resource.mem_total_;
7666resource_sum_.disk_total_ += resource.disk_total_;
7667resource_sum_.log_disk_total_ += resource.log_disk_total_;
7668return ret;
7669}
7670
7671int ObServerBalancer::ResourceSum::append_resource(
7672const ResourceSum &resource)
7673{
7674int ret = OB_SUCCESS;
7675resource_sum_.cpu_ += resource.resource_sum_.cpu_;
7676resource_sum_.mem_total_ += resource.resource_sum_.mem_total_;
7677resource_sum_.disk_total_ += resource.resource_sum_.disk_total_;
7678resource_sum_.log_disk_total_ += resource.resource_sum_.log_disk_total_;
7679return ret;
7680}
7681
7682int ObServerBalancer::TenantGroupBalanceInfo::get_trick_id(
7683uint64_t &trick_id)
7684{
7685int ret = OB_SUCCESS;
7686if (OB_UNLIKELY(NULL == tenant_id_matrix_)) {
7687ret = OB_ERR_UNEXPECTED;
7688LOG_WARN("tenant id matrix ptr is null", K(ret), KP(tenant_id_matrix_));
7689} else if (tenant_id_matrix_->get_row_count() <= 0
7690|| tenant_id_matrix_->get_row_count() >= INT32_MAX
7691|| tenant_id_matrix_->get_column_count() <= 0
7692|| tenant_id_matrix_->get_column_count() >= INT32_MAX) {
7693ret = OB_ERR_UNEXPECTED;
7694LOG_WARN("tenant id matrix size unexpected", K(ret),
7695"row_count", tenant_id_matrix_->get_row_count(),
7696"column_count", tenant_id_matrix_->get_column_count());
7697} else {
7698trick_id = UINT64_MAX;
7699for (int64_t row = 0;
7700OB_SUCC(ret) && row < tenant_id_matrix_->get_row_count();
7701++row) {
7702for (int64_t column = 0;
7703OB_SUCC(ret) && column < tenant_id_matrix_->get_column_count();
7704++column) {
7705uint64_t my_trick_id = UINT64_MAX;
7706if (OB_FAIL(tenant_id_matrix_->get(row, column, my_trick_id))) {
7707LOG_WARN("fail to get from tenant id matrix", K(ret), K(row), K(column));
7708} else if (my_trick_id < trick_id) {
7709trick_id = my_trick_id;
7710} else {} // next
7711}
7712}
7713}
7714return ret;
7715}
7716
7717ObServerBalancer::ServerLoad *ObServerBalancer::TenantGroupBalanceInfo::get_server_load(
7718const common::ObAddr &server)
7719{
7720ServerLoad *ret_ptr = NULL;
7721for (int64_t i = 0; NULL == ret_ptr && i < server_load_array_.count(); ++i) {
7722ServerLoad &server_load = server_load_array_.at(i);
7723if (server_load.server_ != server) {
7724// go on to check next
7725} else {
7726ret_ptr = &server_load;
7727}
7728}
7729return ret_ptr;
7730}
7731
7732int ObServerBalancer::TenantGroupBalanceInfo::get_all_unit_loads(
7733common::ObIArray<ObUnitManager::ObUnitLoad> &unit_loads)
7734{
7735int ret = OB_SUCCESS;
7736unit_loads.reset();
7737for (int64_t i = 0; OB_SUCC(ret) && i < unit_migrate_stat_matrix_.get_row_count(); ++i) {
7738for (int64_t j = 0; OB_SUCC(ret) && j < unit_migrate_stat_matrix_.get_column_count(); ++j) {
7739UnitMigrateStat *unit_stat = unit_migrate_stat_matrix_.get(i, j);
7740if (OB_UNLIKELY(NULL == unit_stat)) {
7741ret = OB_ERR_UNEXPECTED;
7742LOG_WARN("unit stat ptr is null", K(ret), KP(unit_stat));
7743} else if (OB_FAIL(unit_loads.push_back(unit_stat->unit_load_))) {
7744LOG_WARN("fail to push back", K(ret));
7745} else {} // go on next
7746}
7747}
7748return ret;
7749}
7750
7751bool ObServerBalancer::TenantGroupBalanceInfo::is_stable() const
7752{
7753bool stable = true;
7754for (int64_t i = 0; stable && i < unit_migrate_stat_matrix_.get_row_count(); ++i) {
7755for (int64_t j = 0; stable && j < unit_migrate_stat_matrix_.get_column_count(); ++j) {
7756const UnitMigrateStat *unit_stat = unit_migrate_stat_matrix_.get(i, j);
7757if (NULL == unit_stat) {
7758stable = false;
7759} else if (unit_stat->original_pos_ != unit_stat->arranged_pos_) {
7760stable = false;
7761} else {} // go on next
7762}
7763}
7764return stable;
7765}
7766
7767int ObServerBalancer::check_tenant_group_config_legality(
7768common::ObIArray<ObTenantGroupParser::TenantNameGroup> &tenant_groups,
7769bool &legal)
7770{
7771int ret = OB_SUCCESS;
7772SpinRLockGuard guard(unit_mgr_->get_lock()); // lock!
7773legal = true;
7774share::schema::ObSchemaGetterGuard schema_guard;
7775if (OB_UNLIKELY(!inited_)) {
7776ret = OB_NOT_INIT;
7777LOG_WARN("not init", K(ret));
7778} else if (OB_UNLIKELY(NULL == schema_service_)) {
7779ret = OB_ERR_UNEXPECTED;
7780LOG_WARN("schema service ptr is null", K(ret), KP(schema_service_));
7781} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
7782LOG_WARN("fail to get schema guard", K(ret));
7783} else {
7784for (int64_t i = 0; OB_SUCC(ret) && i < tenant_groups.count() && legal; ++i) {
7785const ObTenantGroupParser::TenantNameGroup &tenant_name_group = tenant_groups.at(i);
7786for (int64_t j = 0; OB_SUCC(ret) && j < tenant_name_group.tenants_.count(); ++j) {
7787const share::schema::ObTenantSchema *tenant_schema = NULL;
7788if (OB_FAIL(schema_guard.get_tenant_info(
7789tenant_name_group.tenants_.at(j), tenant_schema))) {
7790LOG_WARN("fail to get tenant info", K(ret));
7791} else if (OB_UNLIKELY(NULL == tenant_schema)) {
7792ret = OB_TENANT_NOT_EXIST;
7793LOG_WARN("tenant schema ptr is null", K(ret), KP(tenant_schema));
7794} else if (OB_UNLIKELY(OB_SYS_TENANT_ID == tenant_schema->get_tenant_id())) {
7795ret = OB_ERR_UNEXPECTED;
7796LOG_ERROR("sys tenant cannot be configured in tenant groups", K(ret));
7797} else {} // good and go on next
7798}
7799}
7800}
7801return ret;
7802}
7803
7804int ObServerBalancer::get_server_data_disk_usage_limit(
7805double &data_disk_usage_limit) const
7806{
7807int ret = OB_SUCCESS;
7808if (OB_UNLIKELY(!inited_)) {
7809ret = OB_NOT_INIT;
7810LOG_WARN("not init", K(ret));
7811} else {
7812int64_t value = GCONF.data_disk_usage_limit_percentage - 1;
7813value = (value <= 0 ? 0 : value);
7814data_disk_usage_limit = static_cast<double>(value) / 100;
7815}
7816return ret;
7817}
7818
7819int ObServerBalancer::get_server_balance_critical_disk_waterlevel(
7820double &server_balance_critical_disk_waterlevel) const
7821{
7822int ret = OB_SUCCESS;
7823if (OB_UNLIKELY(!inited_)) {
7824ret = OB_NOT_INIT;
7825LOG_WARN("not init", K(ret));
7826} else {
7827int64_t value = GCONF.server_balance_critical_disk_waterlevel;
7828server_balance_critical_disk_waterlevel = static_cast<double>(value) / 100;
7829}
7830return ret;
7831}
7832
7833ERRSIM_POINT_DEF(ERRSIM_SERVER_DISK_ASSIGN);
7834
7835int ObServerBalancer::generate_zone_server_disk_statistic(
7836const common::ObZone &zone)
7837{
7838int ret = OB_SUCCESS;
7839common::ObArray<common::ObAddr> server_list;
7840double disk_waterlevel = 0.0;
7841if (OB_UNLIKELY(!inited_)) {
7842ret = OB_NOT_INIT;
7843LOG_WARN("not init", K(ret));
7844} else if (OB_UNLIKELY(zone.is_empty())) {
7845ret = OB_INVALID_ARGUMENT;
7846LOG_WARN("invalid argument", K(ret), K(zone));
7847} else if (OB_ISNULL(server_mgr_)) {
7848ret = OB_ERR_UNEXPECTED;
7849LOG_WARN("server_mgr_ ptr is null", KR(ret), KP(server_mgr_));
7850} else if (OB_FAIL(SVR_TRACER.get_servers_of_zone(zone, server_list))) {
7851LOG_WARN("fail to get servers of zone", KR(ret), K(zone));
7852} else if (OB_FAIL(get_server_balance_critical_disk_waterlevel(disk_waterlevel))) {
7853LOG_WARN("fail to get server balance disk water level", K(ret));
7854} else {
7855zone_disk_statistic_.reset();
7856zone_disk_statistic_.zone_ = zone;
7857for (int64_t i = 0; OB_SUCC(ret) && i < server_list.count(); ++i) {
7858const common::ObAddr &server = server_list.at(i);
7859share::ObServerResourceInfo server_resource_info;
7860share::ObServerInfoInTable server_info;
7861ServerDiskStatistic disk_statistic;
7862if (OB_FAIL(SVR_TRACER.get_server_info(server, server_info))) {
7863LOG_WARN("fail to get server info", KR(ret), K(server));
7864} else if (server_info.is_temporary_offline() || server_info.is_stopped()) {
7865ret = OB_STATE_NOT_MATCH;
7866LOG_WARN("server is not stable, stop balance servers in this zone",
7867KR(ret), K(server), K(zone),
7868"is_temporary_offline", server_info.is_temporary_offline(),
7869"is_stopped", server_info.is_stopped());
7870} else if (OB_FAIL(server_mgr_->get_server_resource_info(server, server_resource_info))) {
7871LOG_WARN("fail to get server resource info", KR(ret), K(server));
7872} else if (server_info.is_active()) {
7873disk_statistic.server_ = server;
7874disk_statistic.wild_server_ = false;
7875if (OB_SUCC(ERRSIM_SERVER_DISK_ASSIGN)) {
7876disk_statistic.disk_in_use_ = server_resource_info.disk_in_use_;
7877} else {
7878// ONLY FOR TEST, errsim triggered, make disk_in_use equal to (1GB * unit_num)
7879ObArray<ObUnitManager::ObUnitLoad> *unit_loads_ptr;
7880if (OB_FAIL(unit_mgr_->get_loads_by_server(server, unit_loads_ptr))) {
7881if(OB_ENTRY_NOT_EXIST == ret) {
7882ret = OB_SUCCESS; // disk_in_use is 0
7883} else {
7884LOG_WARN("fail to get_loads_by_server", KR(ret), K(server));
7885}
7886} else {
7887disk_statistic.disk_in_use_ = unit_loads_ptr->count() * (1024 * 1024 * 1024);
7888}
7889LOG_ERROR("errsim triggered, assign server disk_in_use as unit count * 1GB", KR(ret), K(disk_statistic));
7890}
7891disk_statistic.disk_total_ = server_resource_info.disk_total_;
7892if (static_cast<double>(disk_statistic.disk_in_use_)
7893> disk_waterlevel * static_cast<double>(disk_statistic.disk_total_)) {
7894zone_disk_statistic_.over_disk_waterlevel_ = true;
7895}
7896} else if (server_info.is_deleting() || server_info.is_permanent_offline()) {
7897disk_statistic.server_ = server;
7898disk_statistic.wild_server_ = true;
7899disk_statistic.disk_in_use_ = server_resource_info.disk_in_use_;
7900disk_statistic.disk_total_ = server_resource_info.disk_total_;
7901} else {
7902ret = OB_ERR_UNEXPECTED;
7903LOG_WARN("unknow server_info", K(ret), K(server_info));
7904}
7905if (OB_FAIL(ret)) {
7906} else if (OB_FAIL(zone_disk_statistic_.append(disk_statistic))) {
7907LOG_WARN("fail to append server statistic", K(ret));
7908} else {} // no more to do
7909}
7910if (OB_SUCC(ret)) {
7911LOG_INFO("build zone disk statistic succeed", K(ret), K(zone_disk_statistic_));
7912}
7913}
7914return ret;
7915}
7916
7917bool ObServerBalancer::ServerDiskStatisticCmp::operator()(
7918const ServerDiskStatistic &left,
7919const ServerDiskStatistic &right)
7920{
7921bool bool_ret = false;
7922if (!left.wild_server_ && right.wild_server_) {
7923bool_ret = true;
7924} else if (left.wild_server_ && !right.wild_server_) {
7925bool_ret = false;
7926} else if (left.wild_server_ && right.wild_server_) {
7927// whatever, I don't care the sequence of two wild servers
7928} else {
7929int64_t left_available = left.disk_total_ - left.disk_in_use_;
7930int64_t right_available = right.disk_total_ - right.disk_in_use_;
7931if (left_available > right_available) {
7932bool_ret = true;
7933} else {
7934bool_ret = false;
7935}
7936}
7937return bool_ret;
7938}
7939
7940int ObServerBalancer::ZoneServerDiskStatistic::append(
7941ServerDiskStatistic &server_disk_statistic)
7942{
7943int ret = OB_SUCCESS;
7944if (OB_FAIL(server_disk_statistic_array_.push_back(server_disk_statistic))) {
7945LOG_WARN("fail to push back", K(ret));
7946} else {
7947ServerDiskStatisticCmp cmp;
7948std::sort(server_disk_statistic_array_.begin(),
7949server_disk_statistic_array_.end(),
7950cmp);
7951}
7952return ret;
7953}
7954
7955int ObServerBalancer::ZoneServerDiskStatistic::raise_server_disk_use(
7956const common::ObAddr &server,
7957const int64_t unit_required_size)
7958{
7959int ret = OB_SUCCESS;
7960if (OB_UNLIKELY(!server.is_valid())) {
7961ret = OB_INVALID_ARGUMENT;
7962LOG_WARN("invalid argument", K(ret));
7963} else {
7964bool find = false;
7965for (int64_t i = 0;
7966OB_SUCC(ret) && !find && i < server_disk_statistic_array_.count();
7967++i) {
7968if (server_disk_statistic_array_.at(i).server_ != server) {
7969// go on to check next
7970} else {
7971find = true;
7972ServerDiskStatistic &server_disk_statistic = server_disk_statistic_array_.at(i);
7973server_disk_statistic.disk_in_use_ += unit_required_size;
7974}
7975}
7976if (OB_FAIL(ret)) {
7977} else if (!find) {
7978ret = OB_ENTRY_NOT_EXIST;
7979LOG_WARN("server not exist", K(ret), K(server));
7980} else {
7981ServerDiskStatisticCmp cmp;
7982std::sort(server_disk_statistic_array_.begin(),
7983server_disk_statistic_array_.end(),
7984cmp);
7985}
7986}
7987return ret;
7988}
7989
7990int ObServerBalancer::ZoneServerDiskStatistic::reduce_server_disk_use(
7991const common::ObAddr &server,
7992const int64_t unit_required_size)
7993{
7994int ret = OB_SUCCESS;
7995if (OB_UNLIKELY(!server.is_valid())) {
7996ret = OB_INVALID_ARGUMENT;
7997LOG_WARN("invalid argument", K(ret));
7998} else {
7999bool find = false;
8000for (int64_t i = 0;
8001OB_SUCC(ret) && !find && i < server_disk_statistic_array_.count();
8002++i) {
8003if (server_disk_statistic_array_.at(i).server_ != server) {
8004// go on to check next
8005} else {
8006find = true;
8007ServerDiskStatistic &server_disk_statistic = server_disk_statistic_array_.at(i);
8008server_disk_statistic.disk_in_use_ -= unit_required_size;
8009}
8010}
8011if (OB_FAIL(ret)) {
8012} else if (!find) {
8013ret = OB_ENTRY_NOT_EXIST;
8014LOG_WARN("server not exist", K(ret), K(server));
8015} else {
8016ServerDiskStatisticCmp cmp;
8017std::sort(server_disk_statistic_array_.begin(),
8018server_disk_statistic_array_.end(),
8019cmp);
8020}
8021}
8022return ret;
8023}
8024
8025int ObServerBalancer::ZoneServerDiskStatistic::get_server_disk_statistic(
8026const common::ObAddr &server,
8027ServerDiskStatistic &server_disk_statistic)
8028{
8029int ret = OB_SUCCESS;
8030if (OB_UNLIKELY(!server.is_valid())) {
8031ret = OB_INVALID_ARGUMENT;
8032LOG_WARN("invalid argument", K(ret));
8033} else {
8034server_disk_statistic.reset();
8035bool find = false;
8036for (int64_t i = 0;
8037OB_SUCC(ret) && !find && i < server_disk_statistic_array_.count();
8038++i) {
8039if (server_disk_statistic_array_.at(i).server_ != server) {
8040// go on to check next
8041} else {
8042find = true;
8043server_disk_statistic = server_disk_statistic_array_.at(i);
8044}
8045}
8046if (OB_FAIL(ret)) {
8047} else if (!find) {
8048ret = OB_ENTRY_NOT_EXIST;
8049}
8050}
8051return ret;
8052}
8053
8054int ObServerBalancer::ZoneServerDiskStatistic::check_server_over_disk_waterlevel(
8055const common::ObAddr &server,
8056const double disk_waterlevel,
8057bool &disk_over_waterlevel)
8058{
8059int ret = OB_SUCCESS;
8060if (OB_UNLIKELY(!server.is_valid())) {
8061ret = OB_INVALID_ARGUMENT;
8062LOG_WARN("invalid argument", K(ret), K(server));
8063} else {
8064bool find = false;
8065for (int64_t i = 0; !find && i < server_disk_statistic_array_.count(); ++i) {
8066ServerDiskStatistic &disk_statistic = server_disk_statistic_array_.at(i);
8067if (server != disk_statistic.server_) {
8068// go on to check next
8069} else {
8070find = true;
8071disk_over_waterlevel
8072= (static_cast<double>(disk_statistic.disk_in_use_)
8073> disk_waterlevel * static_cast<double>(disk_statistic.disk_total_));
8074}
8075}
8076if (!find) {
8077ret = OB_ENTRY_NOT_EXIST;
8078LOG_WARN("server not exist", K(ret));
8079}
8080}
8081return ret;
8082}
8083
8084int ObServerBalancer::ZoneServerDiskStatistic::check_all_available_servers_over_disk_waterlevel(
8085const double disk_waterlevel,
8086bool &all_available_servers_over_disk_waterlevel)
8087{
8088int ret = OB_SUCCESS;
8089all_available_servers_over_disk_waterlevel = true;
8090for (int64_t i = 0;
8091all_available_servers_over_disk_waterlevel
8092&& OB_SUCC(ret)
8093&& i < server_disk_statistic_array_.count();
8094++i) {
8095ServerDiskStatistic &disk_statistic = server_disk_statistic_array_.at(i);
8096all_available_servers_over_disk_waterlevel
8097= (static_cast<double>(disk_statistic.disk_in_use_)
8098> disk_waterlevel * static_cast<double>(disk_statistic.disk_total_));
8099
8100LOG_INFO("check server over disk waterlevel",
8101K_(zone), K(disk_statistic),
8102"over_disk_waterlevel", all_available_servers_over_disk_waterlevel);
8103}
8104LOG_INFO("check all available servers over disk waterlevel",
8105K_(zone),
8106K(all_available_servers_over_disk_waterlevel),
8107"zone_server_over_disk_waterlevel", over_disk_waterlevel_,
8108K_(server_disk_statistic_array));
8109return ret;
8110}
8111
8112bool ObServerBalancer::ServerDiskPercentCmp::operator()(
8113const ServerDiskStatistic *left,
8114const ServerDiskStatistic *right)
8115{
8116// Sort by the percentage of disk usage from highest to bottom
8117bool bool_ret = false;
8118if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
8119// ignore
8120} else if (OB_UNLIKELY(NULL == left || NULL == right)) {
8121ret_ = OB_INVALID_ARGUMENT;
8122LOG_WARN_RET(ret_,"invalid argument", K(ret_), KP(left), KP(right));
8123} else {
8124double left_percent = left->get_disk_used_percent();
8125double right_percent = right->get_disk_used_percent();
8126if (left_percent > right_percent) {
8127bool_ret = true;
8128} else {
8129bool_ret = false;
8130}
8131}
8132return bool_ret;
8133}
8134
8135bool ObServerBalancer::UnitLoadDiskCmp::operator()(
8136const ObUnitManager::ObUnitLoad *left,
8137const ObUnitManager::ObUnitLoad *right)
8138{
8139bool bool_ret = false;
8140ObUnitStat left_stat;
8141ObUnitStat right_stat;
8142int &ret = ret_;
8143if (common::OB_SUCCESS != ret_) {
8144// bypass
8145} else if (NULL == left || NULL == right) {
8146ret_ = OB_ERR_UNEXPECTED;
8147LOG_WARN("unit load ptr is null", K(ret_), KP(left), KP(right));
8148} else if (!left->is_valid() || !right->is_valid()) {
8149ret_ = OB_ERR_UNEXPECTED;
8150LOG_WARN("unit load unexpected", K(ret_), K(*left), K(*right));
8151} else if (OB_SUCCESS != (ret_ = unit_stat_mgr_.get_unit_stat(
8152left->unit_->unit_id_, left->unit_->zone_, left_stat))) {
8153LOG_WARN("fail to get left unit stat", K(ret_));
8154} else if (OB_SUCCESS != (ret_ = unit_stat_mgr_.get_unit_stat(
8155right->unit_->unit_id_, right->unit_->zone_, right_stat))) {
8156LOG_WARN("fail to get right unit stat", K(ret_));
8157} else if (left_stat.get_required_size() > right_stat.get_required_size()) {
8158bool_ret = true;
8159} else {
8160bool_ret = false;
8161}
8162return bool_ret;
8163}
8164
8165