[FEAT MERGE] merge transfer

Co-authored-by: wxhwang <wxhwang@126.com>
Co-authored-by: godyangfight <godyangfight@gmail.com>
Co-authored-by: Tyshawn <tuyunshan@gmail.com>
This commit is contained in:
xuhuleon
2023-06-21 11:42:26 +00:00
committed by ob-robot
parent d06678002e
commit 9dae112952
1280 changed files with 149724 additions and 48813 deletions

View File

@ -18,7 +18,8 @@
#include "rootserver/ob_cluster_event.h" // CLUSTER_EVENT_ADD_CONTROL
#include "rootserver/ob_rs_event_history_table_operator.h" // ROOTSERVICE_EVENT_ADD
#include "rootserver/ob_tenant_role_transition_service.h" // ObTenantRoleTransitionService
#include "rootserver/ob_primary_ls_service.h"//ObTenantLSInfo
#include "rootserver/ob_ls_service_helper.h"//ObTenantLSInfo
#include "share/restore/ob_log_restore_source_mgr.h" // ObLogRestoreSourceMgr
#include "share/ls/ob_ls_recovery_stat_operator.h"// ObLSRecoveryStatOperator
#include "share/ls/ob_ls_life_manager.h" //ObLSLifeAgentManager
#include "share/ls/ob_ls_operator.h" //ObLSAttr
@ -86,9 +87,8 @@ int ObPrimaryStandbyService::switch_tenant(const obrpc::ObSwitchTenantArg &arg)
int ret = OB_SUCCESS;
int64_t begin_time = ObTimeUtility::current_time();
uint64_t switch_tenant_id = OB_INVALID_ID;
ObSchemaGetterGuard schema_guard;
const char *alter_cluster_event = arg.get_alter_type_str();
const ObSimpleTenantSchema *tenant_schema = nullptr;
ObTenantStatus tenant_status = TENANT_STATUS_MAX;
uint64_t compat_version = 0;
CLUSTER_EVENT_ADD_CONTROL_START(ret, alter_cluster_event, "stmt_str", arg.get_stmt_str());
if (OB_FAIL(check_inner_stat_())) {
@ -104,28 +104,23 @@ int ObPrimaryStandbyService::switch_tenant(const obrpc::ObSwitchTenantArg &arg)
ret = OB_NOT_SUPPORTED;
LOG_WARN("Tenant COMPATIBLE is below 4.1.0.0, switch tenant is not supported", KR(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Tenant COMPATIBLE is below 4.1.0.0, switch tenant is");
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
LOG_WARN("failed to get schema guard", KR(ret));
} else if (OB_FAIL(schema_guard.get_tenant_info(switch_tenant_id, tenant_schema))) {
LOG_WARN("failed to get tenant info", KR(ret), K(switch_tenant_id));
} else if (OB_ISNULL(tenant_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant_schema is null", KR(ret), K(switch_tenant_id), K(arg));
} else if (tenant_schema->is_normal()) {
} else if (OB_FAIL(get_tenant_status_(switch_tenant_id, tenant_status))) {
LOG_WARN("failed to get tenant status", KR(ret), K(switch_tenant_id));
} else if (is_tenant_normal(tenant_status)) {
switch (arg.get_op_type()) {
case ObSwitchTenantArg::SWITCH_TO_PRIMARY :
if (OB_FAIL(switch_to_primary(switch_tenant_id, arg.get_op_type()))) {
LOG_WARN("failed to switch_to_primary", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema));
LOG_WARN("failed to switch_to_primary", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status));
}
break;
case ObSwitchTenantArg::SWITCH_TO_STANDBY :
if (OB_FAIL(switch_to_standby(switch_tenant_id, arg.get_op_type()))) {
LOG_WARN("failed to switch_to_standby", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema));
LOG_WARN("failed to switch_to_standby", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status));
}
break;
case ObSwitchTenantArg::FAILOVER_TO_PRIMARY :
if (OB_FAIL(failover_to_primary(switch_tenant_id, arg.get_op_type()))) {
LOG_WARN("failed to failover_to_primary", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema));
LOG_WARN("failed to failover_to_primary", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status));
}
break;
default :
@ -134,7 +129,7 @@ int ObPrimaryStandbyService::switch_tenant(const obrpc::ObSwitchTenantArg &arg)
}
} else {
ret = OB_OP_NOT_ALLOW;
LOG_WARN("tenant status is not normal, switch tenant is not allowed", KR(ret), K(switch_tenant_id), K(arg), KPC(tenant_schema));
LOG_WARN("tenant status is not normal, switch tenant is not allowed", KR(ret), K(switch_tenant_id), K(arg), K(tenant_status));
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant status is not normal, switch tenant is");
}
@ -156,8 +151,7 @@ int ObPrimaryStandbyService::failover_to_primary(const uint64_t tenant_id,
{
int ret = OB_SUCCESS;
ObAllTenantInfo tenant_info;
ObSchemaGetterGuard schema_guard;
const ObSimpleTenantSchema *tenant_schema = nullptr;
ObTenantStatus tenant_status = TENANT_STATUS_MAX;
if (OB_FAIL(check_inner_stat_())) {
LOG_WARN("inner stat error", KR(ret), K_(inited));
} else if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(schema_service_)) {
@ -175,21 +169,16 @@ int ObPrimaryStandbyService::failover_to_primary(const uint64_t tenant_id,
LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id));
} else if (tenant_info.is_primary() && tenant_info.is_normal_status()) {
LOG_INFO("already is primary tenant, no need switch", K(tenant_info));
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
} else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) {
LOG_WARN("failed to get tenant info", KR(ret), K(tenant_id));
} else if (OB_ISNULL(tenant_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant_schema is null", KR(ret), K(tenant_id));
} else if (tenant_schema->is_normal()) {
} else if (OB_FAIL(get_tenant_status_(tenant_id, tenant_status))) {
LOG_WARN("failed to get tenant status", KR(ret), K(tenant_id));
} else if (is_tenant_normal(tenant_status)) {
ObTenantRoleTransitionService role_transition_service(tenant_id, sql_proxy_, GCTX.srv_rpc_proxy_, switch_optype);
if (OB_FAIL(role_transition_service.failover_to_primary())) {
LOG_WARN("failed to failover to primary", KR(ret), K(tenant_id));
}
} else {
ret = OB_OP_NOT_ALLOW;
LOG_WARN("tenant status is not normal, failover is not allowed", KR(ret), K(tenant_id), KPC(tenant_schema));
LOG_WARN("tenant status is not normal, failover is not allowed", KR(ret), K(tenant_id), K(tenant_status));
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant status is not normal, failover is");
}
@ -274,6 +263,60 @@ int ObPrimaryStandbyService::recover_tenant(const obrpc::ObRecoverTenantArg &arg
return ret;
}
int ObPrimaryStandbyService::get_tenant_status_(
const uint64_t tenant_id,
ObTenantStatus &status)
{
int ret = OB_SUCCESS;
status = TENANT_STATUS_MAX;
if (OB_FAIL(check_inner_stat_())) {
LOG_WARN("inner stat error", KR(ret), K_(inited));
} else if (!is_user_tenant(tenant_id)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("only support get user tenant status", KR(ret), K(tenant_id));
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "tenant id, only support operating user tenant");
} else if (OB_ISNULL(sql_proxy_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("pointer is null", KR(ret), KP(sql_proxy_));
} else {
ObSqlString sql;
SMART_VAR(ObISQLClient::ReadResult, result) {
if (OB_FAIL(sql.assign_fmt(
"SELECT status FROM %s WHERE tenant_id = %lu",
OB_ALL_TENANT_TNAME, tenant_id))) {
LOG_WARN("assign sql string failed", KR(ret), K(tenant_id));
} else if (OB_FAIL(sql_proxy_->read(result, OB_SYS_TENANT_ID, sql.ptr()))) {
LOG_WARN("execute sql failed", KR(ret), K(tenant_id), K(sql));
} else if (OB_ISNULL(result.get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get result failed", KR(ret), K(tenant_id), K(sql));
} else if (OB_FAIL(result.get_result()->next())) {
LOG_WARN("get next result failed", KR(ret), K(tenant_id), K(sql));
if (OB_ITER_END == ret) {
ret = OB_TENANT_NOT_EXIST;
}
} else if (OB_ISNULL(result.get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("result is null", KR(ret), K(tenant_id), K(sql));
} else {
ObString tenant_status_str("");
ObString default_tenant_status_str("NORMAL");
bool skip_null_error = false;
EXTRACT_VARCHAR_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result.get_result(), "status", tenant_status_str,
skip_null_error, ObSchemaService::g_ignore_column_retrieve_error_, default_tenant_status_str);
if (OB_FAIL(ret)) {
LOG_WARN("failed to get result", KR(ret), K(tenant_id), K(sql));
} else if (OB_FAIL(get_tenant_status(tenant_status_str, status))) {
LOG_WARN("fail to get tenant status", KR(ret), K(tenant_status_str), K(tenant_id), K(sql));
}
}
}
}
return ret;
}
int ObPrimaryStandbyService::do_recover_tenant(
const uint64_t tenant_id,
const share::ObTenantSwitchoverStatus &working_sw_status,
@ -282,31 +325,25 @@ int ObPrimaryStandbyService::do_recover_tenant(
{
int ret = OB_SUCCESS;
ObAllTenantInfo tenant_info;
ObSchemaGetterGuard schema_guard;
const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
common::ObMySQLTransaction trans;
const ObSimpleTenantSchema *tenant_schema = nullptr;
ObLSRecoveryStatOperator ls_recovery_operator;
ObLSRecoveryStat sys_ls_recovery;
ObTenantStatus tenant_status = TENANT_STATUS_MAX;
if (OB_FAIL(check_inner_stat_())) {
LOG_WARN("inner stat error", KR(ret), K_(inited));
} else if (!obrpc::ObRecoverTenantArg::is_valid(recover_type, recovery_until_scn)
|| !working_sw_status.is_valid()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arg", K(recover_type), K(recovery_until_scn), KR(ret));
} else if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(schema_service_) || OB_ISNULL(sql_proxy_)) {
} else if (OB_ISNULL(sql_proxy_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("pointer is null", KR(ret), KP(GCTX.srv_rpc_proxy_), KP(schema_service_), KP(sql_proxy_));
LOG_WARN("pointer is null", KR(ret), KP(sql_proxy_));
} else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", KR(ret), K(tenant_id));
} else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
LOG_WARN("failed to get schema guard", KR(ret), K(tenant_id));
} else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) {
LOG_WARN("failed to get tenant info", KR(ret), K(tenant_id));
} else if (OB_ISNULL(tenant_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant_schema is null", KR(ret), K(tenant_id), K(recover_type), K(recovery_until_scn));
} else if (OB_FAIL(get_tenant_status_(tenant_id, tenant_status))) {
LOG_WARN("failed to get tenant status", KR(ret), K(tenant_id));
} else if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) {
LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id), K(tenant_id));
} else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, &trans, true, tenant_info))) {
@ -328,7 +365,7 @@ int ObPrimaryStandbyService::do_recover_tenant(
LOG_WARN("recover before tenant sync_scn or SYS LS sync_scn is not allow", KR(ret), K(tenant_info),
K(tenant_id), K(recover_type), K(recovery_until_scn), K(sys_ls_recovery));
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "recover before tenant sync_scn or SYS LS sync_scn is");
} else if (tenant_schema->is_normal()) {
} else if (is_tenant_normal(tenant_status)) {
const SCN &recovery_until_scn_to_set = obrpc::ObRecoverTenantArg::RecoverType::UNTIL == recover_type ?
recovery_until_scn : SCN::max(tenant_info.get_sync_scn(), sys_ls_recovery.get_sync_scn());
if (tenant_info.get_recovery_until_scn() == recovery_until_scn_to_set) {
@ -342,7 +379,7 @@ int ObPrimaryStandbyService::do_recover_tenant(
} else {
ret = OB_OP_NOT_ALLOW;
LOG_WARN("tenant status is not normal, recover is not allowed", KR(ret), K(tenant_id),
K(recover_type), K(recovery_until_scn), KPC(tenant_schema));
K(recover_type), K(recovery_until_scn), K(tenant_status));
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant status is not normal, recover is");
}
@ -572,14 +609,14 @@ int ObPrimaryStandbyService::switch_to_standby_prepare_ls_status_(
ret = OB_TENANT_NOT_EXIST;
LOG_WARN("tenant not exist", KR(ret), K(tenant_id));
} else {
ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id,
GCTX.srv_rpc_proxy_, GCTX.lst_operator_);
ObTenantLSInfo tenant_stat(GCTX.sql_proxy_, tenant_schema, tenant_id);
/* lock SYS_LS to get accurate LS list, then fix ls status to make ls status consistency
between __all_ls&__all_ls_status.
Refer to ls operator, insert/update/delete of ls table are executed in the SYS_LS lock
and normal switchover status */
if (OB_FAIL(tenant_stat.process_ls_status_missmatch(true/* lock_sys_ls */,
share::PREP_SWITCHING_TO_STANDBY_SWITCHOVER_STATUS))) {
if (OB_FAIL(ObLSServiceHelper::process_status_to_steady(true/* lock_sys_ls */,
share::PREP_SWITCHING_TO_STANDBY_SWITCHOVER_STATUS,
tenant_stat))) {
LOG_WARN("failed to process_ls_status_missmatch", KR(ret));
} else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_role(
tenant_id, sql_proxy_, switchover_epoch,