Files
oceanbase/src/share/restore/ob_physical_restore_info.cpp

446 lines
16 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 SHARE
#include "share/restore/ob_physical_restore_info.h"
#include "share/backup/ob_backup_struct.h"
#include <algorithm>
#include "share/ob_rpc_struct.h"
using namespace oceanbase;
using namespace common;
using namespace share;
ObPhysicalRestoreWhiteList::ObPhysicalRestoreWhiteList()
: allocator_("PhyReWhiteList"),
table_items_(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator(allocator_))
{
}
ObPhysicalRestoreWhiteList::~ObPhysicalRestoreWhiteList()
{
}
void ObPhysicalRestoreWhiteList::reset()
{
table_items_.reset();
allocator_.reset();
}
int ObPhysicalRestoreWhiteList::assign(const ObPhysicalRestoreWhiteList &other)
{
int ret = OB_SUCCESS;
if (this != &other) {
reset();
if (OB_FAIL(table_items_.reserve(other.table_items_.count()))) {
LOG_WARN("fail to reserve", KR(ret), K(other));
}
for (int64_t i = 0; OB_SUCC(ret) && i < other.table_items_.count(); i++) {
const obrpc::ObTableItem &item = other.table_items_.at(i);
if (OB_FAIL(add_table_item(item))) {
LOG_WARN("fail to add table item", KR(ret), K(item));
}
}
}
return ret;
}
int ObPhysicalRestoreWhiteList::add_table_item(const obrpc::ObTableItem &other)
{
int ret = OB_SUCCESS;
obrpc::ObTableItem item;
if (OB_FAIL(ob_write_string(allocator_, other.table_name_, item.table_name_))) {
LOG_WARN("fail to assign table_name", KR(ret), K(other));
} else if (OB_FAIL(ob_write_string(allocator_, other.database_name_, item.database_name_))) {
LOG_WARN("fail to assign database_name", KR(ret), K(other));
} else if (OB_FAIL(table_items_.push_back(item))) {
LOG_WARN("fail to push back table_item", KR(ret), K(item));
}
return ret;
}
// str without '\0'
int64_t ObPhysicalRestoreWhiteList::get_format_str_length() const
{
int64_t length = 0;
for (int64_t i = 0; i < table_items_.count(); i++) {
const obrpc::ObTableItem &item = table_items_.at(i);
length += (item.database_name_.length()
+ item.table_name_.length()
+ 5 // '`' & '.'
+ (0 == i ? 0 : 1)); // ','
}
return length;
}
// str without '\0'
int ObPhysicalRestoreWhiteList::get_format_str(
common::ObIAllocator &allocator,
common::ObString &str) const
{
int ret = OB_SUCCESS;
char *format_str_buf = NULL;
int64_t format_str_length = get_format_str_length() + 1;
if (format_str_length > OB_MAX_LONGTEXT_LENGTH + 1) {
ret = OB_SIZE_OVERFLOW;
LOG_WARN("format str is too long", KR(ret), K(format_str_length));
} else if (OB_ISNULL(format_str_buf = static_cast<char *>(allocator.alloc(format_str_length)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc buf", KR(ret), K(format_str_length));
} else if (table_items_.count() <= 0) {
MEMSET(format_str_buf, '\0', format_str_length);
} else {
int64_t pos = 0;
for (int64_t i = 0; OB_SUCC(ret) && i < table_items_.count(); i++) {
const obrpc::ObTableItem &item = table_items_.at(i);
if (OB_FAIL(databuff_printf(format_str_buf, format_str_length, pos, "%s`%.*s`.`%.*s`",
0 == i ? "" : ",",
item.database_name_.length(), item.database_name_.ptr(),
item.table_name_.length(), item.table_name_.ptr()))) {
LOG_WARN("fail to append str", KR(ret), K(item), K(pos), K(format_str_length));
}
}
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(format_str_buf) || format_str_length <= 0) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected format str", KR(ret), K(format_str_buf), K(format_str_length));
} else {
str.assign_ptr(format_str_buf, static_cast<int32_t>(format_str_length - 1));
LOG_DEBUG("get format white_list str", KR(ret), K(str));
}
return ret;
}
// str without '\0'
int ObPhysicalRestoreWhiteList::get_hex_str(
common::ObIAllocator &allocator,
common::ObString &str) const
{
int ret = OB_SUCCESS;
char *serialize_buf = NULL;
int64_t serialize_size = table_items_.get_serialize_size();
int64_t serialize_pos = 0;
char *hex_buf = NULL;
int64_t hex_size = 2 * serialize_size;
int64_t hex_pos = 0;
if (serialize_size > OB_MAX_LONGTEXT_LENGTH / 2) {
ret = OB_SIZE_OVERFLOW;
LOG_WARN("serialize_size is too long", KR(ret), K(serialize_size));
} else if (OB_ISNULL(serialize_buf = static_cast<char*>(allocator.alloc(serialize_size)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory", KR(ret));
} else if (OB_FAIL(table_items_.serialize(serialize_buf, serialize_size, serialize_pos))) {
LOG_WARN("fail to serialize table_items", KR(ret), K_(table_items));
} else if (serialize_pos > serialize_size) {
ret = OB_SIZE_OVERFLOW;
LOG_WARN("serialize error", KR(ret), K(serialize_pos), K(serialize_size));
} else if (OB_ISNULL(hex_buf = static_cast<char*>(allocator.alloc(hex_size)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory", KR(ret), K(hex_size));
} else if (OB_FAIL(hex_print(serialize_buf, serialize_pos, hex_buf, hex_size, hex_pos))) {
LOG_WARN("fail to print hex", KR(ret), K(serialize_pos), K(hex_size));
} else if (hex_pos > hex_size) {
ret = OB_SIZE_OVERFLOW;
LOG_WARN("encode error", KR(ret), K(hex_pos), K(hex_size));
} else {
str.assign_ptr(hex_buf, static_cast<int32_t>(hex_size));
LOG_DEBUG("get hex white_list str", KR(ret), K(str));
}
return ret;
}
// str without '\0'
int ObPhysicalRestoreWhiteList::assign_with_hex_str(
const common::ObString &str)
{
int ret = OB_SUCCESS;
reset();
int64_t str_size = str.length();
char *deserialize_buf = NULL;
int64_t deserialize_size = str.length() / 2 + 1;
int64_t deserialize_pos = 0;
if (str_size <= 0) {
// skip
} else if (OB_ISNULL(deserialize_buf = static_cast<char*>(allocator_.alloc(deserialize_size)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory", KR(ret), K(deserialize_size));
} else if (OB_FAIL(hex_to_cstr(str.ptr(), str_size, deserialize_buf, deserialize_size))) {
LOG_WARN("fail to get cstr from hex", KR(ret), K(str_size), K(deserialize_size), K(str));
} else if (OB_FAIL(table_items_.deserialize(deserialize_buf, deserialize_size, deserialize_pos))) {
LOG_WARN("fail to deserialize table_items", KR(ret), K(str),
"deserialize_buf", ObString(deserialize_size, deserialize_buf));
} else if (deserialize_pos > deserialize_size) {
ret = OB_SIZE_OVERFLOW;
LOG_WARN("deserialize error", KR(ret), K(deserialize_pos), K(deserialize_size));
} else {
LOG_DEBUG("assign with hex str", KR(ret), K(str), K_(table_items));
}
return ret;
}
DEF_TO_STRING(ObPhysicalRestoreWhiteList)
{
int64_t pos = 0;
J_OBJ_START();
J_KV(K_(table_items));
J_OBJ_END();
return pos;
}
void ObRestoreProgressInfo::reset()
{
total_pg_cnt_ = 0;
finish_pg_cnt_ = 0;
total_partition_cnt_ = 0;
finish_partition_cnt_ = 0;
}
ObPhysicalRestoreJob::ObPhysicalRestoreJob()
: allocator_("PhyRestoreJob")
{
reset();
}
int ObPhysicalRestoreJob::init_restore_key(const uint64_t tenant_id, const int64_t job_id)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || job_id < 0)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid_argument", KR(ret), K(tenant_id), K(job_id));
} else {
restore_key_.tenant_id_ = tenant_id;
restore_key_.job_id_ = job_id;
}
return ret;
}
bool ObPhysicalRestoreJob::is_valid() const
{
return restore_key_.is_pkey_valid()
&& PhysicalRestoreStatus::PHYSICAL_RESTORE_MAX_STATUS != status_;
}
DEF_TO_STRING(ObPhysicalRestoreJob)
{
int64_t pos = 0;
J_OBJ_START();
J_KV(
K_(restore_key),
K_(initiator_job_id),
K_(initiator_tenant_id),
K_(tenant_id),
K_(backup_tenant_id),
K_(restore_type),
K_(status),
K_(comment),
K_(restore_start_ts),
K_(restore_scn),
K_(consistent_scn),
K_(post_data_version),
K_(source_cluster_version),
K_(source_data_version),
K_(restore_option),
K_(backup_dest),
K_(description),
K_(tenant_name),
K_(pool_list),
K_(locality),
K_(primary_zone),
K_(compat_mode),
K_(compatible),
K_(kms_info),
K_(kms_encrypt),
K_(concurrency),
K_(passwd_array),
K_(multi_restore_path_list),
K_(white_list),
K_(recover_table)
);
J_OBJ_END();
return pos;
}
int ObPhysicalRestoreJob::assign(const ObPhysicalRestoreJob &other)
{
int ret = OB_SUCCESS;
if (this != &other) {
reset();
restore_key_ = other.restore_key_;
initiator_job_id_ = other.initiator_job_id_;
initiator_tenant_id_ = other.initiator_tenant_id_;
tenant_id_ = other.tenant_id_;
backup_tenant_id_ = other.backup_tenant_id_;
restore_type_ = other.restore_type_;
status_ = other.status_;
restore_start_ts_ = other.restore_start_ts_;
restore_scn_ = other.restore_scn_;
consistent_scn_ = other.consistent_scn_;
post_data_version_ = other.post_data_version_;
source_cluster_version_ = other.source_cluster_version_;
source_data_version_ = other.source_data_version_;
compat_mode_ = other.compat_mode_;
compatible_ = other.compatible_;
kms_encrypt_ = other.kms_encrypt_;
concurrency_ = other.concurrency_;
recover_table_ = other.recover_table_;
if (FAILEDx(deep_copy_ob_string(allocator_, other.comment_, comment_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.restore_option_, restore_option_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.backup_dest_, backup_dest_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.description_, description_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.tenant_name_, tenant_name_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.pool_list_, pool_list_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.locality_, locality_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.primary_zone_, primary_zone_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.kms_info_, kms_info_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.encrypt_key_, encrypt_key_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.kms_dest_, kms_dest_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.kms_encrypt_key_, kms_encrypt_key_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.passwd_array_, passwd_array_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.backup_tenant_name_, backup_tenant_name_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, other.backup_cluster_name_, backup_cluster_name_))) {
LOG_WARN("failed to copy string", KR(ret), K(other));
} else if (OB_FAIL(multi_restore_path_list_.assign(other.multi_restore_path_list_))) {
LOG_WARN("failed to assign path list", KR(ret), K(other));
} else if (OB_FAIL(white_list_.assign(other.white_list_))) {
LOG_WARN("failed to assign white list", KR(ret), K(other));
}
}
return ret;
}
void ObPhysicalRestoreJob::reset()
{
/* rs */
restore_key_.reset();
initiator_job_id_ = OB_INVALID_ID;
initiator_tenant_id_ = OB_INVALID_TENANT_ID;
tenant_id_ = OB_INVALID_TENANT_ID;
backup_tenant_id_ = OB_INVALID_TENANT_ID;
restore_type_ = ObRestoreType::RESTORE_TYPE_MAX;
status_ = PhysicalRestoreStatus::PHYSICAL_RESTORE_MAX_STATUS;
comment_.reset();
restore_start_ts_ = 0;
restore_scn_ = SCN::min_scn();
consistent_scn_ = SCN::min_scn();
post_data_version_ = 0;
source_cluster_version_ = 0;
source_data_version_ = 0;
restore_option_.reset();
backup_dest_.reset();
description_.reset();
tenant_name_.reset();
pool_list_.reset();
locality_.reset();
primary_zone_.reset();
compat_mode_ = lib::Worker::CompatMode::INVALID;
compatible_ = 0;
kms_info_.reset();
kms_encrypt_ = false;
encrypt_key_.reset();
kms_dest_.reset();
kms_encrypt_key_.reset();
concurrency_ = 0;
recover_table_ = false;
passwd_array_.reset();
multi_restore_path_list_.reset();
white_list_.reset();
allocator_.reset();
}
int ObPhysicalRestoreJob::copy_to(ObSimplePhysicalRestoreJob &simple_job_info) const
{
int ret = OB_SUCCESS;
int64_t pos = 0;
const int64_t len = OB_MAX_BACKUP_DEST_LENGTH;
if (OB_FAIL(databuff_printf(simple_job_info.restore_info_.backup_dest_, len, pos, "%.*s",
backup_dest_.length(), backup_dest_.ptr()))) {
LOG_WARN("failed to copy to restore job", KR(ret), K(backup_dest_));
} else if (OB_UNLIKELY(pos >= len)) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("buf not enough", KR(ret), K(pos), K(len), K(backup_dest_));
} else if (OB_FAIL(simple_job_info.restore_info_.multi_restore_path_list_.assign(multi_restore_path_list_))) {
LOG_WARN("failed to assign multi path", KR(ret), K(multi_restore_path_list_));
} else {
simple_job_info.job_id_ = restore_key_.job_id_;
simple_job_info.restore_info_.backup_dest_[share::OB_MAX_BACKUP_DEST_LENGTH - 1] = '\0';
simple_job_info.restore_info_.tenant_id_ = backup_tenant_id_;
simple_job_info.restore_info_.restore_snapshot_version_ = restore_scn_.get_val_for_inner_table_field();
simple_job_info.restore_info_.restore_start_ts_ = restore_start_ts_;
simple_job_info.restore_info_.compatible_ = compatible_;
simple_job_info.restore_info_.cluster_version_ = source_cluster_version_;
}
return ret;
}
ObSimplePhysicalRestoreJob::ObSimplePhysicalRestoreJob()
: restore_info_(),
restore_data_version_(0),
snapshot_version_(0),
schema_version_(0),
job_id_(0)
{
}
bool ObSimplePhysicalRestoreJob::is_valid() const
{
return restore_info_.is_valid()
&& restore_data_version_ > 0
&& snapshot_version_ > 0
&& schema_version_ > 0
&& job_id_ > 0;
}
int ObSimplePhysicalRestoreJob::assign(const ObSimplePhysicalRestoreJob &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(restore_info_.assign(other.restore_info_))) {
LOG_WARN("failed to assign restore info", K(ret), K(other));
} else {
restore_data_version_ = other.restore_data_version_;
snapshot_version_ = other.snapshot_version_;
schema_version_ = other.schema_version_;
job_id_ = other.job_id_;
}
return ret;
}
int ObSimplePhysicalRestoreJob::copy_to(ObPhysicalRestoreInfo &resotre_info) const
{
int ret = OB_SUCCESS;
if (!is_valid()) {
ret = OB_NOT_INIT;
LOG_WARN("simple physical restore job do not init", K(ret), K(*this));
} else if (OB_FAIL(resotre_info.assign(restore_info_))) {
LOG_WARN("failed to assign restore info", K(ret), K(*this));
}
return ret;
}