From c1c674e458354b1a3e104186201eaacbe6c7e722 Mon Sep 17 00:00:00 2001 From: godyangfight Date: Thu, 8 Aug 2024 13:27:27 +0000 Subject: [PATCH] rebuild tablet master placehold persist value. --- src/objit/include/objit/common/ob_item_type.h | 3 + src/share/CMakeLists.txt | 1 + .../ob_rebuild_tablet_location.cpp | 215 ++++++++++++++++++ .../ob_rebuild_tablet_location.h | 67 ++++++ .../ob_storage_ha_struct.cpp | 126 +++++++++- .../high_availability/ob_storage_ha_struct.h | 49 +++- 6 files changed, 457 insertions(+), 4 deletions(-) create mode 100644 src/share/rebuild_tablet/ob_rebuild_tablet_location.cpp create mode 100644 src/share/rebuild_tablet/ob_rebuild_tablet_location.h diff --git a/src/objit/include/objit/common/ob_item_type.h b/src/objit/include/objit/common/ob_item_type.h index 3612940a3c..266f35c6a3 100755 --- a/src/objit/include/objit/common/ob_item_type.h +++ b/src/objit/include/objit/common/ob_item_type.h @@ -2572,6 +2572,9 @@ typedef enum ObItemType T_QUOTA = 4724, T_TABLE = 4725, T_EXTERNAL_TABLE_PARTITION = 4726, + + //Rebuild Tablet + T_REBUILD_TABLET = 4727, T_MAX //Attention: add a new type before T_MAX } ObItemType; diff --git a/src/share/CMakeLists.txt b/src/share/CMakeLists.txt index 3969bedd75..8687880dd3 100644 --- a/src/share/CMakeLists.txt +++ b/src/share/CMakeLists.txt @@ -300,6 +300,7 @@ ob_set_subtarget(ob_share common_mixed throttle/ob_share_throttle_define.cpp throttle/ob_throttle_common.cpp restore/ob_restore_data_mode.cpp + rebuild_tablet/ob_rebuild_tablet_location.cpp ) ob_set_subtarget(ob_share tablet diff --git a/src/share/rebuild_tablet/ob_rebuild_tablet_location.cpp b/src/share/rebuild_tablet/ob_rebuild_tablet_location.cpp new file mode 100644 index 0000000000..21b5d5a832 --- /dev/null +++ b/src/share/rebuild_tablet/ob_rebuild_tablet_location.cpp @@ -0,0 +1,215 @@ +/** + * 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 SHARE +#include "share/rebuild_tablet/ob_rebuild_tablet_location.h" + +using namespace oceanbase; +using namespace share; + +static const char *location_type_strs[] = { + "", + "server_addr", + "region", + "server_id", +}; + +const char *ObRebuildTabletLocationType::get_str(const TYPE &type) +{ + const char *str = nullptr; + + if (type < 0 || type >= MAX) { + str = "UNKNOWN"; + } else { + str = location_type_strs[type]; + } + return str; +} + +ObRebuildTabletLocationType::TYPE ObRebuildTabletLocationType::get_type(const char *type_str) +{ + ObRebuildTabletLocationType::TYPE type = ObRebuildTabletLocationType::MAX; + + const int64_t count = ARRAYSIZEOF(location_type_strs); + STATIC_ASSERT(static_cast(ObRebuildTabletLocationType::MAX) == count, "status count mismatch"); + for (int64_t i = 0; i < count; ++i) { + if (0 == strcmp(type_str, location_type_strs[i])) { + type = static_cast(i); + break; + } + } + return type; +} + +ObRebuildTabletLocation::ObRebuildTabletLocation() + : type_(ObRebuildTabletLocationType::NONE) +{ + MEMSET(location_, '\0', sizeof(location_)); +} + +void ObRebuildTabletLocation::reset() +{ + type_ = ObRebuildTabletLocationType::NONE; + MEMSET(location_, '\0', sizeof(location_)); +} + +bool ObRebuildTabletLocation::is_valid() const +{ + bool b_ret = false; + int ret = OB_SUCCESS; + if (!ObRebuildTabletLocationType::is_valid(type_)) { + b_ret = false; + } else { + switch (type_) { + case ObRebuildTabletLocationType::NONE: { + b_ret = true; + break; + } + case ObRebuildTabletLocationType::SERVER_ADDR : { + ObAddr addr; + if (OB_FAIL(addr.parse_from_cstring(location_))) { + LOG_WARN("failed to parse from cstring", K(ret), K(location_)); + } else if (addr.is_valid()) { + b_ret = true; + } + break; + } + case ObRebuildTabletLocationType::REGION : + case ObRebuildTabletLocationType::SERVER_ID : { + b_ret = false; + ret = OB_NOT_SUPPORTED; + LOG_ERROR("rebuild tablet location type do not support", K(ret), K(type_)); + break; + } + default: { + b_ret = false; + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid type", K(ret), K(type_)); + } + } + } + return b_ret; +} + +int ObRebuildTabletLocation::get_location_addr( + common::ObAddr &addr) const +{ + int ret = OB_SUCCESS; + addr.reset(); + if (!is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rebuild tablet src is invalid", K(ret), KPC(this)); + } else { + switch (type_) { + case ObRebuildTabletLocationType::NONE: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get src addr type is unexpected", K(ret), K(type_)); + break; + } + case ObRebuildTabletLocationType::SERVER_ADDR : { + if (OB_FAIL(addr.parse_from_cstring(location_))) { + LOG_WARN("failed to parse from cstring", K(ret)); + } + break; + } + case ObRebuildTabletLocationType::REGION : + case ObRebuildTabletLocationType::SERVER_ID : { + ret = OB_NOT_SUPPORTED; + LOG_ERROR("rebuild tablet src type do not support", K(ret), K(type_)); + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid type", K(ret), K(type_)); + } + } + } + return ret; +} + +int ObRebuildTabletLocation::resolve_location(const ObString &location) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator; + int64_t pos = 0; + ObString location_str_without_blank; + int64_t src_type_length = 0; + + if (location.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("resolve src get invalid argument", K(ret), K(location)); + } else if (OB_FAIL(ob_strip_space(allocator, location, location_str_without_blank))) { + LOG_WARN("strip location space failed", K(location), K(ret)); + } else { + for (int64_t i = 0; i < location_str_without_blank.length(); ++i) { + if (':' == location_str_without_blank[i]) { + pos = i + 1; //skip ':' + src_type_length = i; + break; + } + } + const int64_t left_size = location_str_without_blank.length() - pos; + if (left_size >= MAX_REGION_LENGTH || left_size <= 0 || src_type_length <= 0 || src_type_length >= MAX_REGION_LENGTH) { + ret = OB_INVALID_ERROR; + LOG_ERROR("src string is too long or is empty, cannot work", K(ret), K(left_size), K(location_str_without_blank), + K(pos), K(src_type_length)); + } else { + ObString src_type_str(src_type_length, location_str_without_blank.ptr()); + if (OB_FAIL(get_type_from_src_(src_type_str))) { + LOG_WARN("failed to get type from location", K(ret), K(location_str_without_blank)); + } else { + MEMCPY(location_, location_str_without_blank.ptr() + pos, left_size); + location_[left_size] ='\0'; + if (!is_valid()) { + ret = OB_INVALID_ERROR; + LOG_WARN("rebuild src is invalid", K(ret), K(location_str_without_blank)); + } + } + } + } + return ret; +} + +int ObRebuildTabletLocation::get_type_from_src_(const ObString &src) +{ + int ret = OB_SUCCESS; + type_ = ObRebuildTabletLocationType::MAX; + const int64_t count = ARRAYSIZEOF(location_type_strs); + bool found = false; + + for (int64_t i = 1; OB_SUCC(ret) && i < count && !found; ++i) { + if (0 == src.compare(location_type_strs[i])) { + type_ = ObRebuildTabletLocationType::get_type(location_type_strs[i]); + found = true; + } + } + + if (OB_SUCC(ret) && !found) { + ret = OB_INVALID_ERROR; + LOG_WARN("invalid src type", K(ret), K(src)); + } + return ret; +} + +int64_t ObRebuildTabletLocation::to_string(char *buffer, const int64_t size) const +{ + int64_t pos = 0; + pos = snprintf(buffer, size, "[type = %d], [address = %s]", type_, location_); + if (pos < 0) { + pos = 0; + } + return pos; +} + +OB_SERIALIZE_MEMBER(ObRebuildTabletLocation, + type_, + location_); diff --git a/src/share/rebuild_tablet/ob_rebuild_tablet_location.h b/src/share/rebuild_tablet/ob_rebuild_tablet_location.h new file mode 100644 index 0000000000..c22fb3349e --- /dev/null +++ b/src/share/rebuild_tablet/ob_rebuild_tablet_location.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2022 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OCENABASE_SHARE_OB_REBUILD_TABLET_LOCATION_TYPE_H +#define OCENABASE_SHARE_OB_REBUILD_TABLET_LOCATION_TYPE_H + +#include +#include "lib/utility/ob_print_utils.h" +#include "lib/string/ob_sql_string.h" // ObSqlString +#include "lib/utility/ob_unify_serialize.h" +#include "share/ob_ls_id.h" // ObLSID +#include "share/ob_define.h" +#include "common/ob_tablet_id.h" // ObTabletID +#include "share/scn.h" // SCN + +namespace oceanbase +{ +namespace share +{ + +struct ObRebuildTabletLocationType final +{ + enum TYPE + { + NONE = 0, + SERVER_ADDR = 1, + REGION = 2, + SERVER_ID = 3, + MAX + }; + + static const char *get_str(const TYPE &type); + static TYPE get_type(const char *type_str); + static OB_INLINE bool is_valid(const TYPE &type) { return type >= 0 && type < MAX; } +}; + +struct ObRebuildTabletLocation final +{ + OB_UNIS_VERSION(1); +public: + ObRebuildTabletLocation(); + ~ObRebuildTabletLocation() = default; + void reset(); + bool is_valid() const; + int get_location_addr(common::ObAddr &addr) const; + int resolve_location(const ObString &src); + int64_t to_string(char *buffer, const int64_t size) const; +private: + int get_type_from_src_(const ObString &src); + +private: + ObRebuildTabletLocationType::TYPE type_; + char location_[MAX_REGION_LENGTH]; +}; + +} // end namespace share +} // end namespace oceanbase +#endif diff --git a/src/storage/high_availability/ob_storage_ha_struct.cpp b/src/storage/high_availability/ob_storage_ha_struct.cpp index ec8a44fef7..b62f0a375b 100644 --- a/src/storage/high_availability/ob_storage_ha_struct.cpp +++ b/src/storage/high_availability/ob_storage_ha_struct.cpp @@ -1397,10 +1397,114 @@ int ObLSRebuildType::set_type(int32_t type) OB_SERIALIZE_MEMBER(ObLSRebuildType, type_); +/******************ObRebuildTabletIDArray*********************/ +ObRebuildTabletIDArray::ObRebuildTabletIDArray() + : count_(0) +{ +} + +ObRebuildTabletIDArray::~ObRebuildTabletIDArray() +{ +} + +OB_DEF_SERIALIZE(ObRebuildTabletIDArray) +{ + int ret = OB_SUCCESS; + OB_UNIS_ENCODE_ARRAY(id_array_, count_); + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObRebuildTabletIDArray) +{ + int64_t len = 0; + OB_UNIS_ADD_LEN_ARRAY(id_array_, count_); + return len; +} + +OB_DEF_DESERIALIZE(ObRebuildTabletIDArray) +{ + int ret = OB_SUCCESS; + int64_t count = 0; + + OB_UNIS_DECODE(count); + if (OB_SUCC(ret)) { + count_ = count; + } + OB_UNIS_DECODE_ARRAY(id_array_, count_); + return ret; +} + +int ObRebuildTabletIDArray::push_back(const common::ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + if (!tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet id is invalid", K(ret), K(tablet_id)); + } else if (count_ >= MAX_TABLET_COUNT) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("rebuild tablet id array is size overflow", K(ret), K(count_)); + } else { + id_array_[count_] = tablet_id; + count_++; + } + return ret; +} + +int ObRebuildTabletIDArray::assign(const common::ObIArray &tablet_id_array) +{ + int ret = OB_SUCCESS; + if (tablet_id_array.count() > MAX_TABLET_COUNT) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("cannot assign tablet id array", K(ret), K(tablet_id_array)); + } else { + count_ = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) { + const common::ObTabletID &tablet_id = tablet_id_array.at(i); + if (OB_FAIL(push_back(tablet_id))) { + LOG_WARN("failed to push tablet id into array", K(ret)); + } + } + } + return ret; +} + +int ObRebuildTabletIDArray::assign(const ObRebuildTabletIDArray &tablet_id_array) +{ + int ret = OB_SUCCESS; + if (tablet_id_array.count() > MAX_TABLET_COUNT) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("cannot assign tablet id array", K(ret), K(tablet_id_array)); + } else { + count_ = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) { + const common::ObTabletID &tablet_id = tablet_id_array.at(i); + if (OB_FAIL(push_back(tablet_id))) { + LOG_WARN("failed to push tablet id into array", K(ret)); + } + } + } + return ret; +} + +int ObRebuildTabletIDArray::get_tablet_id_array( + common::ObIArray &tablet_id_array) +{ + int ret = OB_SUCCESS; + tablet_id_array.reset(); + for (int64_t i = 0; OB_SUCC(ret) && i < count_; ++i) { + if (OB_FAIL(tablet_id_array.push_back(id_array_[i]))) { + LOG_WARN("failed to push tablet id into array", K(ret), K(count_), K(i)); + } + } + return ret; +} + /******************ObLSRebuildInfo*********************/ ObLSRebuildInfo::ObLSRebuildInfo() : status_(), - type_() + type_(), + tablet_id_array_(), + src_() { } @@ -1408,6 +1512,8 @@ void ObLSRebuildInfo::reset() { status_.reset(); type_.reset(); + tablet_id_array_.reset(); + src_.reset(); } bool ObLSRebuildInfo::is_valid() const @@ -1429,7 +1535,23 @@ bool ObLSRebuildInfo::operator ==(const ObLSRebuildInfo &other) const && type_ == other.type_; } -OB_SERIALIZE_MEMBER(ObLSRebuildInfo, status_, type_); +int ObLSRebuildInfo::assign(const ObLSRebuildInfo &info) +{ + int ret = OB_SUCCESS; + if (!info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("assign ls rebuild info get invalid argument", K(ret), K(info)); + } else if (OB_FAIL(tablet_id_array_.assign(info.tablet_id_array_))) { + LOG_WARN("failed to assign tablet id array", K(ret), K(info)); + } else { + status_ = info.status_; + type_ = info.type_; + src_ = info.src_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObLSRebuildInfo, status_, type_, tablet_id_array_, src_); ObTabletBackfillInfo::ObTabletBackfillInfo() : tablet_id_(), diff --git a/src/storage/high_availability/ob_storage_ha_struct.h b/src/storage/high_availability/ob_storage_ha_struct.h index 119c806b08..680b143407 100644 --- a/src/storage/high_availability/ob_storage_ha_struct.h +++ b/src/storage/high_availability/ob_storage_ha_struct.h @@ -24,7 +24,7 @@ #include "storage/blocksstable/ob_logic_macro_id.h" #include "share/ls/ob_ls_i_life_manager.h" #include "share/scheduler/ob_dag_scheduler_config.h" - +#include "share/rebuild_tablet/ob_rebuild_tablet_location.h" namespace oceanbase { @@ -379,6 +379,7 @@ public: NONE = 0, CLOG = 1, TRANSFER = 2, + TABLET = 3, MAX }; @@ -401,6 +402,47 @@ private: TYPE type_; }; +struct ObRebuildTabletIDArray final +{ + OB_UNIS_VERSION(1); +public: + ObRebuildTabletIDArray(); + ~ObRebuildTabletIDArray(); + int assign(const common::ObIArray &tablet_id_array); + int assign(const ObRebuildTabletIDArray&tablet_id_array); + int push_back(const common::ObTabletID &tablet_id); + int get_tablet_id_array(common::ObIArray &tablet_id_array); + + inline const common::ObTabletID &at(int64_t idx) const + { + OB_ASSERT(idx >= 0 && idx < count_); + return id_array_[idx]; + } + inline common::ObTabletID &at(int64_t idx) + { + OB_ASSERT(idx >= 0 && idx < count_); + return id_array_[idx]; + } + inline int64_t count() const { return count_; } + inline bool empty() const { return 0 == count(); } + void reset() { count_ = 0; } + + int64_t to_string(char* buf, const int64_t buf_len) const + { + int64_t pos = 0; + J_OBJ_START(); + J_NAME("id_array"); + J_COLON(); + (void)databuff_print_obj_array(buf, buf_len, pos, id_array_, count_); + J_OBJ_END(); + return pos; + } +private: + static const int64_t MAX_TABLET_COUNT = 64; + int64_t count_; + common::ObTabletID id_array_[MAX_TABLET_COUNT]; +}; + struct ObLSRebuildInfo final { OB_UNIS_VERSION(1); @@ -411,10 +453,13 @@ public: bool is_valid() const; bool is_in_rebuild() const; bool operator ==(const ObLSRebuildInfo &other) const; + int assign(const ObLSRebuildInfo &info); - TO_STRING_KV(K_(status), K_(type)); + TO_STRING_KV(K_(status), K_(type), K_(tablet_id_array), K_(src)); ObLSRebuildStatus status_; ObLSRebuildType type_; + ObRebuildTabletIDArray tablet_id_array_; + share::ObRebuildTabletLocation src_; }; struct ObTabletBackfillInfo final