Co-authored-by: Charles0429 <xiezhenjiang@gmail.com> Co-authored-by: tino247 <tino247@126.com> Co-authored-by: chaser-ch <chaser.ch@antgroup.com>
1240 lines
39 KiB
C++
1240 lines
39 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX RS
|
|
|
|
#include "ob_zone_manager.h"
|
|
|
|
#include "lib/time/ob_time_utility.h"
|
|
#include "lib/string/ob_sql_string.h"
|
|
#include "lib/mysqlclient/ob_mysql_transaction.h"
|
|
#include "share/ob_zone_table_operation.h"
|
|
#include "share/ob_global_stat_proxy.h"
|
|
#include "share/ob_zone_info.h"
|
|
#include "share/config/ob_server_config.h"
|
|
#include "ob_rs_event_history_table_operator.h"
|
|
#include "observer/ob_server_struct.h"
|
|
#include "rootserver/ob_root_service.h"
|
|
#include "rootserver/ob_cluster_event.h"
|
|
#include "storage/ob_file_system_router.h"
|
|
|
|
namespace oceanbase
|
|
{
|
|
using namespace common;
|
|
using namespace storage;
|
|
using namespace share;
|
|
using namespace share::schema;
|
|
using namespace observer;
|
|
|
|
namespace rootserver
|
|
{
|
|
|
|
ObZoneManagerBase::ObZoneManagerBase()
|
|
: lock_(ObLatchIds::ZONE_INFO_RW_LOCK), inited_(false), loaded_(false),
|
|
zone_infos_(), zone_count_(0),
|
|
global_info_(), proxy_(NULL)
|
|
{
|
|
}
|
|
|
|
ObZoneManagerBase::~ObZoneManagerBase()
|
|
{
|
|
}
|
|
|
|
void ObZoneManagerBase::reset()
|
|
{
|
|
zone_count_ = 0;
|
|
global_info_.reset();
|
|
}
|
|
|
|
int ObZoneManagerBase::init(ObMySQLProxy &proxy)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (inited_) {
|
|
ret = OB_INIT_TWICE;
|
|
LOG_WARN("init twice", K(ret));
|
|
} else {
|
|
proxy_ = &proxy;
|
|
inited_ = true;
|
|
loaded_ = false;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::check_inner_stat() const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (!inited_ || !loaded_) {
|
|
ret = OB_INNER_STAT_ERROR;
|
|
LOG_WARN("inner_stat_error", K_(inited), K_(loaded), K(ret));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone_count(int64_t &zone_count) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
zone_count = 0;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
zone_count = zone_count_;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone(const int64_t idx, ObZoneInfo &info) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
info.reset();
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (idx < 0) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid idx", K(idx), K(ret));
|
|
} else {
|
|
ret = OB_ENTRY_NOT_EXIST;
|
|
if (idx >= 0 && idx < zone_count_) {
|
|
info = zone_infos_[idx];
|
|
ret = OB_SUCCESS;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone(ObZoneInfo &info) const
|
|
{
|
|
return get_zone(info.zone_, info);
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone(const common::ObZone &zone, ObZoneInfo &info) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("zone is empty", K(zone), K(ret));
|
|
} else {
|
|
ret = OB_ENTRY_NOT_EXIST;
|
|
for (int64_t i = 0; OB_ENTRY_NOT_EXIST == ret && i < zone_count_; ++i) {
|
|
if (zone_infos_[i].zone_ == zone) {
|
|
ret = OB_SUCCESS;
|
|
info = zone_infos_[i];
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_all_region(common::ObIArray<common::ObRegion> ®ion_list) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("fail to check inner stat", K(ret));
|
|
} else {
|
|
region_list.reset();
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < zone_count_; ++i) {
|
|
common::ObRegion region;
|
|
if (OB_FAIL(zone_infos_[i].get_region(region))) {
|
|
LOG_WARN("fail to get region", K(ret));
|
|
} else if (has_exist_in_array(region_list, region)) {
|
|
// bypass
|
|
} else if (OB_FAIL(region_list.push_back(region))) {
|
|
LOG_WARN("fail to push back", K(ret));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_region(const common::ObZone &zone, ObRegion ®ion) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("zone is empty", K(zone), K(ret));
|
|
} else {
|
|
ret = OB_ENTRY_NOT_EXIST;
|
|
for (int64_t i = 0; OB_ENTRY_NOT_EXIST == ret && i < zone_count_; ++i) {
|
|
if (zone_infos_[i].zone_ == zone) {
|
|
if (OB_FAIL(zone_infos_[i].get_region(region))) {
|
|
LOG_WARN("fail get region", K(ret));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone_count(const ObRegion ®ion, int64_t &count) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
count = 0;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (region.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("zone is empty", K(region), K(ret));
|
|
} else {
|
|
for (int64_t i = 0; i < zone_count_; ++i) {
|
|
ObRegion zone_region(zone_infos_[i].region_.info_.ptr());
|
|
if (zone_region == region) {
|
|
count ++;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone(const ObRegion ®ion, ObIArray<ObZone> &zone_list) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
zone_list.reset();
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (region.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("zone is empty", K(region), K(ret));
|
|
} else {
|
|
for (int64_t i = 0; i < zone_count_ && OB_SUCC(ret); ++i) {
|
|
ObRegion zone_region(zone_infos_[i].region_.info_.ptr());
|
|
if (zone_region == region) {
|
|
if (OB_FAIL(zone_list.push_back(zone_infos_[i].zone_))) {
|
|
LOG_WARN("fail to push back", K(ret));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone(const share::ObZoneStatus::Status &status,
|
|
common::ObIArray<ObZone> &zone_list) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
zone_list.reset();
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (status < ObZoneStatus::INACTIVE || status >= ObZoneStatus::UNKNOWN) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid status", K(status), K(ret));
|
|
} else {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < zone_count_; ++i) {
|
|
if (zone_infos_[i].status_ == status) {
|
|
if (OB_FAIL(zone_list.push_back(zone_infos_[i].zone_))) {
|
|
LOG_WARN("failed to add zone list", K(ret));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone(ObIArray<ObZoneInfo> &infos) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
infos.reset();
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < zone_count_; ++i) {
|
|
if (OB_FAIL(infos.push_back(zone_infos_[i]))) {
|
|
LOG_WARN("failed to add zone info list", K(ret));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_zone(ObIArray<ObZone> &zone_list) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
zone_list.reset();
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < zone_count_; ++i) {
|
|
if (OB_FAIL(zone_list.push_back(zone_infos_[i].zone_))) {
|
|
LOG_WARN("push back zone failed", K(ret));
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_active_zone(ObZoneInfo &info) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObMalloc alloc(ObModIds::OB_TEMP_VARIABLES);
|
|
ObPtrGuard<ObZoneInfo> tmp_info_guard(alloc);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (!info.is_valid()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid info", K(ret), K(info));
|
|
} else if (OB_FAIL(tmp_info_guard.init())) {
|
|
LOG_WARN("init temporary variable failed", K(ret));
|
|
} else {
|
|
ObZoneInfo &tmp_info = *tmp_info_guard.ptr();
|
|
tmp_info.zone_ = info.zone_;
|
|
ret = get_zone(tmp_info);
|
|
if (OB_FAIL(get_zone(tmp_info))) {
|
|
LOG_WARN("get_zone failed", "zone", tmp_info.zone_, K(ret));
|
|
} else {
|
|
if (ObZoneStatus::ACTIVE == tmp_info.status_) {
|
|
info = tmp_info;
|
|
} else {
|
|
ret = OB_ENTRY_NOT_EXIST;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::check_zone_exist(const common::ObZone &zone, bool &zone_exist) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
zone_exist = false;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
for (int64_t i = 0; i < zone_count_; ++i) {
|
|
if (zone == zone_infos_[i].zone_) {
|
|
zone_exist = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::check_zone_active(const common::ObZone &zone, bool &zone_active) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
zone_active = false;
|
|
bool find_zone = false;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
for (int64_t i = 0; i < zone_count_; ++i) {
|
|
if (zone == zone_infos_[i].zone_) {
|
|
find_zone = true;
|
|
if (ObZoneStatus::ACTIVE == zone_infos_[i].status_) {
|
|
zone_active = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret) && !find_zone) {
|
|
ret = OB_ENTRY_NOT_EXIST;
|
|
LOG_WARN("fail to find zone", KR(ret), K(zone));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::add_zone(
|
|
const ObZone &zone,
|
|
const ObRegion ®ion,
|
|
const ObIDC &idc,
|
|
const ObZoneType &zone_type)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t index = OB_INVALID_INDEX;
|
|
ObRegion my_region = region;
|
|
ObIDC my_idc = idc;
|
|
ObZoneType my_zone_type = zone_type;
|
|
ObZoneInfo::StorageType storage_type = ObZoneInfo::STORAGE_TYPE_LOCAL;
|
|
if (my_region.is_empty()) {
|
|
my_region.assign(DEFAULT_REGION_NAME); // compatible with ob1.2
|
|
}
|
|
if (my_idc.is_empty()) {
|
|
my_idc.assign("");
|
|
}
|
|
if (my_zone_type < ObZoneType::ZONE_TYPE_READWRITE
|
|
|| my_zone_type >= ObZoneType::ZONE_TYPE_INVALID) {
|
|
my_zone_type = ObZoneType::ZONE_TYPE_READWRITE;
|
|
}
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(zone), K(ret));
|
|
} else if (ObZoneType::ZONE_TYPE_READONLY == my_zone_type) {
|
|
ret = OB_NOT_SUPPORTED;
|
|
LOG_WARN("cant't set readonly zone since ver2.2", K(ret));
|
|
} else if (my_region.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(my_region), K(ret));
|
|
} else if (zone_count_ >= common::MAX_ZONE_NUM) {
|
|
ret = OB_OVER_ZONE_NUM_LIMIT;
|
|
LOG_ERROR("only support MAX_ZONE_NUM zone", K(MAX_ZONE_NUM), K(ret));
|
|
} else if (OB_SUCCESS == (ret = find_zone(zone, index))) {
|
|
ret = OB_ENTRY_EXIST;
|
|
LOG_ERROR("zone is already exist, cannot add", K(zone), K(ret));
|
|
} else if (OB_ENTRY_NOT_EXIST != ret) {
|
|
LOG_WARN("find_zone failed", K(zone), K(ret));
|
|
} else {
|
|
ret = OB_SUCCESS;
|
|
zone_infos_[zone_count_].reset();
|
|
zone_infos_[zone_count_].zone_ = zone;
|
|
zone_infos_[zone_count_].zone_type_.value_ = my_zone_type;
|
|
zone_infos_[zone_count_].storage_type_.value_ = storage_type;
|
|
ObMySQLTransaction trans;
|
|
if (OB_FAIL(zone_infos_[zone_count_].region_.info_.assign(
|
|
ObString(my_region.size(), my_region.ptr())))) {
|
|
LOG_WARN("fail assign region info", K(ret), K(my_region));
|
|
} else if (OB_FAIL(zone_infos_[zone_count_].idc_.info_.assign(
|
|
ObString(my_idc.size(), my_idc.ptr())))) {
|
|
LOG_WARN("fail to assign idc info", K(ret), K(my_idc));
|
|
} else if (OB_FAIL(zone_infos_[zone_count_].zone_type_.info_.assign(
|
|
ObString(zone_type_to_str(my_zone_type))))) {
|
|
LOG_WARN("fail to assign zone_type info", K(ret), K(my_zone_type));
|
|
} else if (OB_FAIL(zone_infos_[zone_count_].storage_type_.info_.assign(
|
|
ObString(ObZoneInfo::get_storage_type_str(storage_type))))) {
|
|
LOG_WARN("fail to assign zone_type info", K(ret), K(my_zone_type));
|
|
} else if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) {
|
|
LOG_WARN("start transaction failed", K(ret));
|
|
} else {
|
|
if (OB_FAIL(ObZoneTableOperation::insert_zone_info(
|
|
trans, zone_infos_[zone_count_]))) {
|
|
LOG_WARN("insert transaction failed", "zone_info", zone_infos_[zone_count_], K(ret));
|
|
}
|
|
int tmp_ret = trans.end(OB_SUCC(ret));
|
|
if (OB_SUCCESS != tmp_ret) {
|
|
LOG_WARN("end transaction failed", K(ret), K(tmp_ret));
|
|
ret = OB_SUCCESS == ret ? tmp_ret : ret;
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
LOG_INFO("succeed to add new zone", "zone_info", zone_infos_[zone_count_]);
|
|
++zone_count_;
|
|
ROOTSERVICE_EVENT_ADD("zone", "add_zone", K(zone));
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::delete_zone(const ObZone &zone)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t idx = OB_INVALID_INDEX;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(zone), K(ret));
|
|
} else if (OB_FAIL(find_zone(zone, idx))) {
|
|
LOG_WARN("find_zone failed", K(zone), K(ret));
|
|
} else if (OB_INVALID_INDEX == idx) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unexpected idx", K(idx), K(ret));
|
|
} else if (ObZoneStatus::INACTIVE != zone_infos_[idx].status_) {
|
|
ret = OB_ZONE_STATUS_NOT_MATCH;
|
|
LOG_WARN("zone is not inactive, can't delete it", K(ret));
|
|
} else if (OB_FAIL(ObZoneTableOperation::remove_zone_info(*proxy_, zone))) {
|
|
LOG_WARN("remove_zone_info failed", K(zone), K(ret));
|
|
} else {
|
|
for (int64_t i = idx; i < zone_count_ - 1; ++i) {
|
|
zone_infos_[i] = zone_infos_[i + 1];
|
|
}
|
|
--zone_count_;
|
|
LOG_INFO("succeed to delete zone", K(zone));
|
|
ROOTSERVICE_EVENT_ADD("zone", "delete_zone", K(zone));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::start_zone(const ObZone &zone)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t idx = OB_INVALID_INDEX;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(zone), K(ret));
|
|
} else if (OB_FAIL(find_zone(zone, idx))) {
|
|
LOG_WARN("find_zone failed", K(zone), K(ret));
|
|
} else if (OB_INVALID_INDEX == idx) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unexpected idx", K(idx), K(ret));
|
|
} else if (ObZoneStatus::ACTIVE == zone_infos_[idx].status_) {
|
|
ret = OB_ZONE_STATUS_NOT_MATCH;
|
|
LOG_WARN("zone is already active, no need to start it again", K(zone), K(ret));
|
|
} else if (ObZoneStatus::UNKNOWN == zone_infos_[idx].status_) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unknown status", K(ret));
|
|
} else if (OB_FAIL(zone_infos_[idx].status_.update(*proxy_, zone,
|
|
ObZoneStatus::ACTIVE, ObZoneStatus::get_status_str(ObZoneStatus::ACTIVE)))) {
|
|
LOG_WARN("failed to update zone status", K(zone), "status", ObZoneStatus::ACTIVE, K(ret));
|
|
} else {
|
|
//leader_coordinator_->signal();
|
|
LOG_INFO("succeed to start zone", K(zone));
|
|
ROOTSERVICE_EVENT_ADD("zone", "start_zone", K(zone));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::stop_zone(const ObZone &zone)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t idx = OB_INVALID_INDEX;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(zone), K(ret));
|
|
} else if (OB_FAIL(find_zone(zone, idx))) {
|
|
LOG_WARN("find_zone failed", K(zone), K(ret));
|
|
} else if (OB_INVALID_INDEX == idx) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unexpected idx", K(idx), K(ret));
|
|
} else if (ObZoneStatus::INACTIVE == zone_infos_[idx].status_) {
|
|
// make sure we can retry alter system stop zone until succ
|
|
// so, ret is not OB_ZONE_STATUS_NOT_MATCH, but OB_SUCCESS
|
|
ret = OB_SUCCESS;
|
|
LOG_WARN("zone is inactive, no need to update its status", K(zone), K(ret));
|
|
} else if (ObZoneStatus::UNKNOWN == zone_infos_[idx].status_) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("unknown status", K(ret));
|
|
} else {
|
|
int64_t active_zone_cnt = 0;
|
|
for (int64_t i = 0; i < zone_count_; ++i) {
|
|
if (zone_infos_[i].status_ == ObZoneStatus::ACTIVE) {
|
|
active_zone_cnt ++;
|
|
}
|
|
}
|
|
if (active_zone_cnt <= 1) {
|
|
ret = OB_OP_NOT_ALLOW;
|
|
LOG_WARN("try to stop the last active zone not allowed", K(ret), K(zone));
|
|
} else if (OB_FAIL(zone_infos_[idx].status_.update(*proxy_, zone,
|
|
ObZoneStatus::INACTIVE, ObZoneStatus::get_status_str(ObZoneStatus::INACTIVE)))) {
|
|
LOG_WARN("failed to update zone status", K(zone), "status", ObZoneStatus::INACTIVE, K(ret));
|
|
} else {
|
|
//leader_coordinator_->signal();
|
|
LOG_INFO("succeed to stop zone", K(zone));
|
|
ROOTSERVICE_EVENT_ADD("zone", "stop_zone", K(zone));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::alter_zone(
|
|
const obrpc::ObAdminZoneArg &arg)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
int64_t index = OB_INVALID_INDEX;
|
|
ObZone zone = arg.zone_;
|
|
ObRegion my_region = arg.region_;
|
|
ObIDC my_idc = arg.idc_;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(zone), K(ret));
|
|
} else if (my_region.is_empty() && OB_FAIL(my_region.assign(DEFAULT_REGION_NAME))) {
|
|
LOG_WARN("fail to assign default region name", KR(ret));
|
|
} else if (my_idc.is_empty() && OB_FAIL(my_idc.assign(""))) {
|
|
LOG_WARN("fail to assign empty string to idc", KR(ret));
|
|
} else if (my_region.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(my_region), K(ret));
|
|
} else {
|
|
HEAP_VAR(ObZoneInfoItem::Info, item_info) {
|
|
if (OB_FAIL(find_zone(zone, index))) {
|
|
LOG_WARN("find_zone failed", K(zone), K(ret));
|
|
} else if (index < 0){
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_ERROR("invalid index", K(ret), K(index));
|
|
} else {
|
|
ObZoneItemTransUpdater updater;
|
|
if (OB_FAIL(updater.start(*proxy_))) {
|
|
LOG_WARN("start transaction failed", K(ret));
|
|
} else {
|
|
if (arg.alter_zone_options_.has_member(obrpc::ObAdminZoneArg::ALTER_ZONE_REGION)) {
|
|
item_info.reset();
|
|
if (OB_FAIL(item_info.assign(ObString(my_region.size(), my_region.ptr())))) {
|
|
LOG_WARN("fail assign region info", K(ret), K(my_region));
|
|
} else if (OB_FAIL(zone_infos_[index].region_.update(updater, zone, 0, item_info))) {
|
|
LOG_WARN("failed to update region", K(ret), K(zone));
|
|
} else {} // no more to do
|
|
}
|
|
if (OB_SUCC(ret)
|
|
&& arg.alter_zone_options_.has_member(obrpc::ObAdminZoneArg::ALTER_ZONE_IDC)) {
|
|
item_info.reset();
|
|
if (OB_FAIL(item_info.assign(ObString(my_idc.size(), my_idc.ptr())))) {
|
|
LOG_WARN("fail to assign idc info", K(ret), K(my_idc));
|
|
} else if (OB_FAIL(zone_infos_[index].idc_.update(updater, zone, 0, item_info))) {
|
|
LOG_WARN("fail to update idc", K(ret), K(zone));
|
|
} else {} // no more to do
|
|
}
|
|
if (OB_SUCC(ret)
|
|
&& arg.alter_zone_options_.has_member(obrpc::ObAdminZoneArg::ALTER_ZONE_TYPE)) {
|
|
// after encryption zone is introduced, operations of modifing zone type are not supported
|
|
ret = OB_NOT_SUPPORTED;
|
|
LOG_WARN("alter zone type is not supported", K(ret), K(zone));
|
|
LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter zone type");
|
|
}
|
|
int tmp_ret = updater.end(OB_SUCC(ret));
|
|
if (OB_SUCCESS != tmp_ret) {
|
|
LOG_WARN("end transaction failed", K(tmp_ret), K(ret));
|
|
ret = OB_SUCCESS == ret ? tmp_ret : ret;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
//leader_coordinator_->signal();
|
|
LOG_INFO("succeed to alter zone", "zone_info", zone_infos_[index]);
|
|
ROOTSERVICE_EVENT_ADD("zone", "alter_zone",
|
|
"zone", arg.zone_,
|
|
"region", arg.region_,
|
|
"idc", arg.idc_,
|
|
"zone_type", arg.zone_type_);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::reload()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObArray<ObZone> zone_list;
|
|
HEAP_VAR(ObGlobalInfo, global_info) {
|
|
ObMalloc alloc(ObModIds::OB_TEMP_VARIABLES);
|
|
ObPtrGuard<ObZoneInfo, common::MAX_ZONE_NUM> tmp_zone_infos(alloc);
|
|
// use last value default
|
|
|
|
if (!inited_) {
|
|
ret = OB_NOT_INIT;
|
|
LOG_WARN("not init", K(ret));
|
|
} else if (OB_FAIL(tmp_zone_infos.init())) {
|
|
LOG_WARN("failed to alloc temp zone infos", K(ret));
|
|
} else if (OB_FAIL(ObZoneTableOperation::load_global_info(*proxy_, global_info))) {
|
|
LOG_WARN("failed to get global info", K(ret));
|
|
} else if (OB_FAIL(ObZoneTableOperation::get_zone_list(*proxy_, zone_list))) {
|
|
LOG_WARN("failed to get zone list", K(ret));
|
|
} else if (zone_list.count() > common::MAX_ZONE_NUM) {
|
|
ret = OB_ERR_SYS;
|
|
LOG_ERROR("the count of zone on __all_zone table is more than limit, cannot reload",
|
|
"zone count", zone_list.count(),
|
|
"zone count limit", common::MAX_ZONE_NUM, K(ret));
|
|
} else {
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < zone_list.count(); ++i) {
|
|
ObZoneInfo &info = tmp_zone_infos.ptr()[i];
|
|
info.zone_ = zone_list[i];
|
|
if (OB_FAIL(ObZoneTableOperation::load_zone_info(*proxy_, info))) {
|
|
LOG_WARN("failed reload zone", "zone", zone_list[i], K(ret));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
reset();
|
|
global_info_ = global_info;
|
|
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < zone_list.count(); ++i) {
|
|
zone_infos_[zone_count_] = tmp_zone_infos.ptr()[i];
|
|
++zone_count_;
|
|
}
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
loaded_ = true;
|
|
LOG_INFO("succeed to reload zone manager", "zone_manager_info", this);
|
|
} else {
|
|
LOG_WARN("failed to reload zone manager", KR(ret));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::update_privilege_version(const int64_t privilege_version)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (privilege_version <= 0) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid privilege_version", K(privilege_version), K(ret));
|
|
} else if (OB_FAIL(update_value_with_lease(global_info_.zone_,
|
|
global_info_.privilege_version_, privilege_version))) {
|
|
LOG_WARN("update privilege version failed", K(ret), K(privilege_version));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::update_config_version(const int64_t config_version)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (config_version <= 0) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid config_version", K(config_version), K(ret));
|
|
} else if (OB_FAIL(update_value_with_lease(global_info_.zone_,
|
|
global_info_.config_version_, config_version))) {
|
|
LOG_WARN("update config version failed", K(ret), K(config_version));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::update_recovery_status(
|
|
const common::ObZone &zone,
|
|
const share::ObZoneInfo::RecoveryStatus status)
|
|
{
|
|
return OB_OP_NOT_ALLOW; // discarded.
|
|
}
|
|
|
|
int ObZoneManagerBase::set_cluster_name(const ObString &cluster_name)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObZoneItemTransUpdater updater;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", KR(ret));
|
|
} else if (OB_ISNULL(proxy_)) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("sql proxy is null", KR(ret));
|
|
} else if (cluster_name.empty() || cluster_name.length() > common::OB_MAX_CLUSTER_NAME_LENGTH) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("cluster_name invalid", KR(ret), K(cluster_name));
|
|
} else if (OB_FAIL(updater.start(*proxy_))) {
|
|
LOG_WARN("start transaction failed", KR(ret));
|
|
} else {
|
|
const ObZone &zone = global_info_.zone_;
|
|
|
|
if (OB_FAIL(global_info_.cluster_.info_.assign(cluster_name))) {
|
|
LOG_WARN("fail assign cluster name", KR(ret), K(cluster_name), K(global_info_.cluster_));
|
|
} else if (OB_FAIL(global_info_.cluster_.update(updater, zone, 0, global_info_.cluster_.info_))) {
|
|
LOG_WARN("update cluster_name failed", KR(ret), K(zone), K(cluster_name), K(global_info_.cluster_));
|
|
}
|
|
|
|
int tmp_ret = updater.end(OB_SUCC(ret));
|
|
if (OB_SUCCESS != tmp_ret) {
|
|
LOG_WARN("end transaction failed", KR(tmp_ret), KR(ret));
|
|
ret = OB_SUCCESS == ret ? tmp_ret : ret;
|
|
}
|
|
}
|
|
|
|
DEBUG_SYNC(AFTER_SET_ALL_ZONE_CLUSTER_NAME);
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_cluster(ObFixedLengthString<MAX_ZONE_INFO_LENGTH> &cluster) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
cluster = global_info_.cluster_.info_;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_config_version(int64_t &config_version) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
config_version = global_info_.config_version_;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_time_zone_info_version(int64_t &time_zone_info_version) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
time_zone_info_version = global_info_.time_zone_info_version_;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_lease_info_version(int64_t &lease_info_version) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
lease_info_version = global_info_.lease_info_version_;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
ObClusterRole ObZoneManagerBase::get_cluster_role()
|
|
{
|
|
ObClusterRole cluster_role = PRIMARY_CLUSTER;
|
|
return cluster_role;
|
|
}
|
|
|
|
int ObZoneManagerBase::check_encryption_zone(const common::ObZone &zone, bool &encryption)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (zone.is_empty()) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("zone is empty", K(zone), KR(ret));
|
|
} else {
|
|
bool found = false;
|
|
for (int64_t i = 0; !found && i < zone_count_ && OB_SUCC(ret); ++i) {
|
|
if (zone_infos_[i].zone_ == zone) {
|
|
found = true;
|
|
encryption = zone_infos_[i].is_encryption();
|
|
} else {
|
|
// go on check
|
|
}
|
|
}
|
|
if (!found) {
|
|
ret = OB_ENTRY_NOT_EXIST;
|
|
LOG_WARN("zone not exist", KR(ret), K(zone));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::update_value_with_lease(
|
|
const common::ObZone &zone, share::ObZoneInfoItem &item,
|
|
int64_t value, const char *info /* = NULL */)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const int64_t cur_time = ObTimeUtility::current_time();
|
|
const int64_t lease_info_version = std::max(global_info_.lease_info_version_ + 1, cur_time);
|
|
ObZoneItemTransUpdater updater;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (!item.is_valid() || value < 0) {
|
|
// empty zone means all zone, info can be null
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(item), K(value), K(ret));
|
|
} else if (OB_FAIL(updater.start(*proxy_))) {
|
|
LOG_WARN("start transaction failed", K(ret));
|
|
} else {
|
|
if (OB_FAIL(item.update(updater, zone, value, info))) {
|
|
LOG_WARN("update item failed", K(ret), K(zone), K(value), K(info));
|
|
} else if (OB_FAIL(global_info_.lease_info_version_.update(
|
|
updater, global_info_.zone_, lease_info_version))) {
|
|
LOG_WARN("update lease info version failed", K(ret), K(lease_info_version));
|
|
}
|
|
|
|
int tmp_ret = updater.end(OB_SUCC(ret));
|
|
if (OB_SUCCESS != tmp_ret) {
|
|
LOG_WARN("end transaction failed", K(tmp_ret), K(ret));
|
|
ret = OB_SUCCESS == ret ? tmp_ret : ret;
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
(void)ATOMIC_SET(&global_info_.lease_info_version_.value_, lease_info_version);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::find_zone(const common::ObZone &zone, int64_t &idx) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
idx = OB_INVALID_INDEX;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
ret = OB_ENTRY_NOT_EXIST;
|
|
for (int64_t i = 0; i < zone_count_; ++i) {
|
|
if (zone == zone_infos_[i].zone_) {
|
|
idx = i;
|
|
ret = OB_SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
DEF_TO_STRING(ObZoneManagerBase)
|
|
{
|
|
SpinRLockGuard guard(lock_);
|
|
int64_t pos = 0;
|
|
J_KV(K_(global_info),
|
|
K_(zone_count));
|
|
J_ARRAY_START();
|
|
for(int64_t i = 0; i < zone_count_; ++i) {
|
|
if (0 != i) {
|
|
J_COMMA();
|
|
}
|
|
BUF_PRINTO(zone_infos_[i]);
|
|
}
|
|
J_ARRAY_END();
|
|
return pos;
|
|
}
|
|
|
|
// only used for copying data to/from shadow_
|
|
int ObZoneManagerBase::copy_infos(ObZoneManagerBase &dest, const ObZoneManagerBase &src)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const int64_t count = src.zone_count_;
|
|
if (0 > count || common::MAX_ZONE_NUM < count) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid zone count", K(count), K(ret));
|
|
} else {
|
|
for (int64_t idx = 0; idx < count; ++idx) {
|
|
dest.zone_infos_[idx] = src.zone_infos_[idx];
|
|
}
|
|
dest.global_info_ = src.global_info_;
|
|
dest.zone_count_ = count;
|
|
dest.inited_ = src.inited_;
|
|
dest.loaded_ = src.loaded_;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
///////////////////////////
|
|
///////////////////////////
|
|
ObZoneManager::ObZoneManager()
|
|
: write_lock_(ObLatchIds::ZONE_MANAGER_LOCK), shadow_(), random_(71)
|
|
{
|
|
}
|
|
|
|
ObZoneManager::~ObZoneManager()
|
|
{
|
|
}
|
|
|
|
ObZoneManager::ObZoneManagerShadowGuard::ObZoneManagerShadowGuard(const common::SpinRWLock &lock,
|
|
ObZoneManagerBase &zone_mgr,
|
|
ObZoneManagerBase &shadow,
|
|
int &ret)
|
|
: lock_(const_cast<SpinRWLock &>(lock)),
|
|
zone_mgr_(zone_mgr), shadow_(shadow), ret_(ret)
|
|
{
|
|
SpinRLockGuard copy_guard(lock_);
|
|
if (OB_UNLIKELY(OB_SUCCESS !=
|
|
(ret_ = ObZoneManager::copy_infos(shadow_, zone_mgr_)))) {
|
|
LOG_WARN("copy to shadow_ failed", K(ret_));
|
|
}
|
|
}
|
|
|
|
ObZoneManager::ObZoneManagerShadowGuard::~ObZoneManagerShadowGuard()
|
|
{
|
|
SpinWLockGuard copy_guard(lock_);
|
|
if (OB_UNLIKELY(OB_SUCCESS != ret_)) {
|
|
} else if (OB_UNLIKELY(OB_SUCCESS !=
|
|
(ret_ = ObZoneManager::copy_infos(zone_mgr_, shadow_)))) {
|
|
LOG_WARN_RET(ret_, "copy from shadow_ failed", K(ret_));
|
|
}
|
|
}
|
|
|
|
int ObZoneManager::init(ObMySQLProxy &proxy)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (is_inited()) {
|
|
ret = OB_INIT_TWICE;
|
|
LOG_WARN("init twice", K(ret));
|
|
} else {
|
|
// uninit proxy is used to prevent somebody from
|
|
// trying to directly use the set-interfaces in ObZoneManagerBase
|
|
// actually, all update operations are performed in shadow_
|
|
if (OB_FAIL(ObZoneManagerBase::init(uninit_proxy_))) {
|
|
LOG_WARN("init zone manager failed", K(ret));
|
|
} else if (OB_FAIL(shadow_.init(proxy))) {
|
|
LOG_WARN("init shadow_ failed", K(ret));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::reload()
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.reload();
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::add_zone(
|
|
const common::ObZone &zone,
|
|
const common::ObRegion ®ion,
|
|
const common::ObIDC &idc,
|
|
const common::ObZoneType &zone_type)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.add_zone(zone, region, idc, zone_type);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::delete_zone(const common::ObZone &zone)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.delete_zone(zone);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::start_zone(const common::ObZone &zone)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.start_zone(zone);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::stop_zone(const common::ObZone &zone)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.stop_zone(zone);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::alter_zone(
|
|
const obrpc::ObAdminZoneArg &arg)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.alter_zone(arg);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::update_privilege_version(const int64_t privilege_version)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.update_privilege_version(privilege_version);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::update_config_version(const int64_t config_version)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.update_config_version(config_version);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::update_recovery_status(
|
|
const common::ObZone &zone,
|
|
const share::ObZoneInfo::RecoveryStatus status)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.update_recovery_status(zone, status);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManager::set_cluster_name(const ObString &cluster_name)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.set_cluster_name(cluster_name);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
int ObZoneManager::set_storage_format_version(const int64_t version)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinWLockGuard guard(write_lock_);
|
|
// destruct shadow_copy_guard before return
|
|
// otherwise the ret_ in shadow_copy_guard will never be returned
|
|
{
|
|
ObZoneManagerShadowGuard shadow_copy_guard(lock_,
|
|
*(static_cast<ObZoneManagerBase *> (this)), shadow_, ret);
|
|
if (OB_SUCC(ret)) {
|
|
ret = shadow_.set_storage_format_version(version);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::construct_zone_region_list(
|
|
common::ObIArray<ObZoneRegion> &zone_region_list,
|
|
const common::ObIArray<common::ObZone> &zone_list)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
zone_region_list.reset();
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
ret = OB_INNER_STAT_ERROR;
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
common::ObArray<share::ObZoneInfo> zone_infos;
|
|
if (OB_FAIL(get_zone(zone_infos))) {
|
|
LOG_WARN("fail to get zone", K(ret));
|
|
} else {
|
|
ObZoneRegion zone_region;
|
|
for (int64_t i = 0; i < zone_infos.count() && OB_SUCC(ret); ++i) {
|
|
zone_region.reset();
|
|
share::ObZoneInfo &zone_info = zone_infos.at(i);
|
|
if (OB_FAIL(zone_region.zone_.assign(zone_info.zone_.ptr()))) {
|
|
LOG_WARN("fail to assign zone", K(ret));
|
|
} else if (OB_FAIL(zone_region.region_.assign(zone_info.region_.info_.ptr()))) {
|
|
LOG_WARN("fail to assign region", K(ret));
|
|
} else if (OB_FAIL(zone_region.set_check_zone_type(zone_info.zone_type_.value_))) {
|
|
LOG_WARN("fail to set check zone type", KR(ret));
|
|
} else if (!has_exist_in_array(zone_list, zone_region.zone_)) {
|
|
// this zone do not exist in my zone list, ignore it
|
|
} else if (OB_FAIL(zone_region_list.push_back(zone_region))) {
|
|
LOG_WARN("fail to push back", K(ret));
|
|
} else {} // no more to do
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::get_storage_format_version(int64_t &version) const
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
SpinRLockGuard guard(lock_);
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else {
|
|
version = global_info_.storage_format_version_;
|
|
if (version < OB_STORAGE_FORMAT_VERSION_V3) {
|
|
ret = OB_ERR_UNEXPECTED;
|
|
LOG_WARN("storage format version should greater than or equal to 3", K(ret), K(version));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObZoneManagerBase::set_storage_format_version(const int64_t version)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObZoneItemTransUpdater updater;
|
|
const int64_t old_version = global_info_.storage_format_version_;
|
|
if (OB_FAIL(check_inner_stat())) {
|
|
LOG_WARN("check_inner_stat failed", K(ret));
|
|
} else if (version <= OB_STORAGE_FORMAT_VERSION_INVALID
|
|
|| version >= OB_STORAGE_FORMAT_VERSION_MAX
|
|
|| old_version < OB_STORAGE_FORMAT_VERSION_V3
|
|
|| version != old_version + 1 ) {
|
|
ret = OB_INVALID_ARGUMENT;
|
|
LOG_WARN("invalid argument", K(version), K(old_version), K(ret));
|
|
} else if (OB_FAIL(updater.start(*proxy_))) {
|
|
LOG_WARN("start transaction failed", K(ret));
|
|
} else {
|
|
if (OB_FAIL(global_info_.storage_format_version_.update(updater, global_info_.zone_, version))) {
|
|
LOG_WARN("set storage format version failed", K(ret), "zone", global_info_.zone_, K(version));
|
|
}
|
|
int tmp_ret = updater.end(OB_SUCC(ret));
|
|
if (OB_SUCCESS != tmp_ret) {
|
|
LOG_WARN("end transaction failed", K(tmp_ret), K(ret));
|
|
ret = OB_SUCCESS == ret ? tmp_ret : ret;
|
|
}
|
|
if (OB_SUCC(ret)) {
|
|
LOG_INFO("set format version succeed", K(ret), K(version), K(global_info_.storage_format_version_));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
} // rootserver
|
|
} // oceanbase
|