[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:
244
src/rootserver/ob_common_ls_service.cpp
Executable file
244
src/rootserver/ob_common_ls_service.cpp
Executable file
@ -0,0 +1,244 @@
|
||||
/**
|
||||
* 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_common_ls_service.h"
|
||||
#include "ob_ls_service_helper.h"
|
||||
#include "ob_balance_ls_primary_zone.h"
|
||||
#include "lib/profile/ob_trace_id.h"
|
||||
#include "share/ob_errno.h"
|
||||
#include "share/ob_max_id_fetcher.h"
|
||||
#include "share/schema/ob_schema_struct.h"//ObTenantInfo
|
||||
#include "share/ls/ob_ls_creator.h" //ObLSCreator
|
||||
#include "share/ls/ob_ls_life_manager.h"//ObLSLifeAgentManager
|
||||
#include "share/ob_primary_zone_util.h"//ObPrimaryZoneUtil
|
||||
#include "share/ob_share_util.h"//ObShareUtil
|
||||
#include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo
|
||||
#include "share/ob_common_rpc_proxy.h"//common_rpc_proxy
|
||||
#include "observer/ob_server_struct.h"//GCTX
|
||||
#include "logservice/palf/palf_base_info.h"//PalfBaseInfo
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
using namespace share;
|
||||
using namespace transaction;
|
||||
using namespace palf;
|
||||
namespace rootserver
|
||||
{
|
||||
//////////////ObCommonLSService
|
||||
int ObCommonLSService::init()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(inited_)) {
|
||||
ret = OB_INIT_TWICE;
|
||||
LOG_WARN("has inited", KR(ret));
|
||||
} else if (OB_FAIL(ObTenantThreadHelper::create("COMMONLSSe",
|
||||
lib::TGDefIDs::SimpleLSService, *this))) {
|
||||
LOG_WARN("failed to create thread", KR(ret));
|
||||
} else if (OB_FAIL(ObTenantThreadHelper::start())) {
|
||||
LOG_WARN("fail to start", KR(ret));
|
||||
} else {
|
||||
tenant_id_ = MTL_ID();
|
||||
inited_ = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObCommonLSService::destroy()
|
||||
{
|
||||
ObTenantThreadHelper::destroy();
|
||||
tenant_id_ = OB_INVALID_TENANT_ID;
|
||||
inited_ = false;
|
||||
}
|
||||
|
||||
void ObCommonLSService::do_work()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", K(ret));
|
||||
} else if (is_user_tenant(tenant_id_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("is user tenant", KR(ret), K(tenant_id_));
|
||||
} else if (OB_FAIL(wait_tenant_schema_and_version_ready_(tenant_id_, DATA_VERSION_4_1_0_0))) {
|
||||
LOG_WARN("failed to wait tenant schema version ready", KR(ret), K(tenant_id_), K(DATA_CURRENT_VERSION));
|
||||
} else {
|
||||
int64_t idle_time_us = 1000 * 1000L;//1s
|
||||
share::schema::ObTenantSchema user_tenant_schema;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
while (!has_set_stop()) {
|
||||
ret = OB_SUCCESS;
|
||||
ObCurTraceId::init(GCONF.self_addr_);
|
||||
if (is_meta_tenant(tenant_id_)) {
|
||||
const uint64_t user_tenant_id = gen_user_tenant_id(tenant_id_);
|
||||
if (OB_FAIL(check_can_do_recovery_(user_tenant_id))) {
|
||||
LOG_WARN("can not do recovery now", KR(ret), K(user_tenant_id));
|
||||
} else if (OB_FAIL(get_tenant_schema(user_tenant_id, user_tenant_schema))) {
|
||||
LOG_WARN("failed to get user tenant schema", KR(ret), K(user_tenant_id));
|
||||
} else if (user_tenant_schema.is_dropping()) {
|
||||
if (OB_TMP_FAIL(try_force_drop_tenant_(user_tenant_schema))) {
|
||||
LOG_WARN("failed to force drop tenant", KR(ret), KR(tmp_ret), K(user_tenant_id));
|
||||
}
|
||||
} else if (OB_TMP_FAIL(try_create_ls_(user_tenant_schema))) {
|
||||
LOG_WARN("failed to create ls", KR(ret), KR(tmp_ret), K(user_tenant_schema));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_TMP_FAIL(ObBalanceLSPrimaryZone::try_update_sys_ls_primary_zone(tenant_id_))) {
|
||||
LOG_WARN("failed to update sys ls primary zone", KR(ret), KR(tmp_ret), K(tenant_id_));
|
||||
}
|
||||
|
||||
user_tenant_schema.reset();
|
||||
LOG_INFO("[COMMON_LS_SERVICE] finish one round", KR(ret), KR(tmp_ret), K(idle_time_us));
|
||||
idle(idle_time_us);
|
||||
} // end while
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ObCommonLSService::try_create_ls_(const share::schema::ObTenantSchema &tenant_schema)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const uint64_t tenant_id = tenant_schema.get_tenant_id();
|
||||
if (OB_ISNULL(GCTX.sql_proxy_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("sql proxy is null", KR(ret), KP(GCTX.sql_proxy_));
|
||||
} else if (!is_user_tenant(tenant_id) || !tenant_schema.is_valid()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tenant is invalid", KR(ret), K(tenant_id), K(tenant_schema));
|
||||
} else {
|
||||
share::ObLSStatusInfoArray status_info_array;
|
||||
share::ObLSStatusOperator ls_op;
|
||||
ObLSRecoveryStat recovery_stat;
|
||||
ObLSRecoveryStatOperator ls_recovery_operator;
|
||||
palf::PalfBaseInfo palf_base_info;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ls_op.get_all_ls_status_by_order(
|
||||
tenant_id, status_info_array, *GCTX.sql_proxy_))) {
|
||||
LOG_WARN("failed to get all ls status", KR(ret), K(tenant_id));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < status_info_array.count(); ++i) {
|
||||
const ObLSStatusInfo &status_info = status_info_array.at(i);
|
||||
if (status_info.ls_is_creating()) {
|
||||
recovery_stat.reset();
|
||||
if (OB_FAIL(ls_recovery_operator.get_ls_recovery_stat(
|
||||
tenant_id, status_info.ls_id_, false /*for_update*/,
|
||||
recovery_stat, *GCTX.sql_proxy_))) {
|
||||
LOG_WARN("failed to get ls recovery stat", KR(ret), K(tenant_id),
|
||||
K(status_info));
|
||||
} else if (OB_FAIL(do_create_user_ls(tenant_schema, status_info,
|
||||
recovery_stat.get_create_scn(),
|
||||
false, palf_base_info))) {
|
||||
LOG_WARN("failed to create new ls", KR(ret), K(status_info),
|
||||
K(recovery_stat));
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObCommonLSService::do_create_user_ls(
|
||||
const share::schema::ObTenantSchema &tenant_schema,
|
||||
const share::ObLSStatusInfo &info, const SCN &create_scn,
|
||||
bool create_with_palf, const palf::PalfBaseInfo &palf_base_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LOG_INFO("[COMMON_LS_SERVICE] start to create ls", K(info), K(create_scn));
|
||||
const int64_t start_time = ObTimeUtility::fast_current_time();
|
||||
if (OB_UNLIKELY(!info.is_valid() || !info.ls_is_creating())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("info not valid", KR(ret), K(info));
|
||||
} else {
|
||||
CK(OB_NOT_NULL(GCTX.sql_proxy_), OB_NOT_NULL(GCTX.srv_rpc_proxy_))
|
||||
common::ObArray<share::ObZoneReplicaAttrSet> locality_array;
|
||||
int64_t paxos_replica_num = 0;
|
||||
ObSchemaGetterGuard guard;//nothing
|
||||
if (FAILEDx(tenant_schema.get_zone_replica_attr_array(
|
||||
locality_array))) {
|
||||
LOG_WARN("failed to get zone locality array", KR(ret));
|
||||
} else if (OB_FAIL(tenant_schema.get_paxos_replica_num(
|
||||
guard, paxos_replica_num))) {
|
||||
LOG_WARN("failed to get paxos replica num", KR(ret));
|
||||
} else {
|
||||
ObLSCreator creator(*GCTX.srv_rpc_proxy_, info.tenant_id_,
|
||||
info.ls_id_, GCTX.sql_proxy_);
|
||||
if (OB_FAIL(creator.create_user_ls(info, paxos_replica_num,
|
||||
locality_array, create_scn,
|
||||
tenant_schema.get_compatibility_mode(),
|
||||
create_with_palf,
|
||||
palf_base_info))) {
|
||||
LOG_WARN("failed to create user ls", KR(ret), K(info), K(locality_array), K(create_scn),
|
||||
K(palf_base_info), K(create_with_palf));
|
||||
}
|
||||
}
|
||||
}
|
||||
const int64_t cost = ObTimeUtility::fast_current_time() - start_time;
|
||||
LOG_INFO("[COMMON_LS_SERVICE] end to create ls", KR(ret), K(info), K(cost));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCommonLSService::try_force_drop_tenant_(
|
||||
const share::schema::ObTenantSchema &tenant_schema)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTimeoutCtx ctx;
|
||||
const uint64_t tenant_id = tenant_schema.get_tenant_id();
|
||||
|
||||
if (OB_UNLIKELY(!inited_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("not init", KR(ret));
|
||||
} else if (OB_ISNULL(GCTX.sql_proxy_)
|
||||
|| OB_ISNULL(GCTX.rs_rpc_proxy_)
|
||||
|| OB_ISNULL(GCTX.schema_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("ptr is null", KR(ret), KP(GCTX.sql_proxy_), KP(GCTX.rs_rpc_proxy_),
|
||||
KP(GCTX.schema_service_));
|
||||
} else if (!is_user_tenant(tenant_id) || !tenant_schema.is_valid()
|
||||
|| !tenant_schema.is_dropping()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tenant is invalid", KR(ret), K(tenant_id), K(tenant_schema));
|
||||
} else {
|
||||
ObLSStatusOperator op;
|
||||
share::ObLSStatusInfoArray ls_array;
|
||||
const int64_t start_time = ObTimeUtility::fast_current_time();
|
||||
if (OB_FAIL(ObShareUtil::set_default_timeout_ctx(ctx, GCONF.internal_sql_execute_timeout))) {
|
||||
LOG_WARN("fail to set timeout ctx", KR(ret), K(tenant_id));
|
||||
} else if (OB_FAIL(op.get_all_ls_status_by_order(tenant_id, ls_array, *GCTX.sql_proxy_))) {
|
||||
LOG_WARN("fail to get all ls status", KR(ret), K(tenant_id));
|
||||
} else if (ls_array.count() <= 0) {
|
||||
obrpc::ObDropTenantArg arg;
|
||||
arg.exec_tenant_id_ = OB_SYS_TENANT_ID;
|
||||
arg.tenant_name_ = tenant_schema.get_tenant_name();
|
||||
arg.tenant_id_ = tenant_schema.get_tenant_id();
|
||||
arg.if_exist_ = true;
|
||||
arg.delay_to_drop_ = false;
|
||||
ObSqlString sql;
|
||||
const int64_t timeout_ts = ctx.get_timeout();
|
||||
if (OB_FAIL(sql.append_fmt("DROP TENANT IF EXISTS %s FORCE", arg.tenant_name_.ptr()))) {
|
||||
LOG_WARN("fail to generate sql", KR(ret), K(arg));
|
||||
} else if (FALSE_IT(arg.ddl_stmt_str_ = sql.string())) {
|
||||
} else if (OB_FAIL(GCTX.rs_rpc_proxy_->timeout(timeout_ts).drop_tenant(arg))) {
|
||||
LOG_WARN("fail to drop tenant", KR(ret), K(arg), K(timeout_ts));
|
||||
}
|
||||
} else {
|
||||
// tenant's logstream is still dropping, check next round
|
||||
}
|
||||
const int64_t cost = ObTimeUtility::fast_current_time() - start_time;
|
||||
LOG_INFO("finish try drop tenant", KR(ret), K(tenant_id), K(ls_array),
|
||||
"timeout", ctx.get_timeout(), K(cost));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}//end of rootserver
|
||||
}
|
||||
Reference in New Issue
Block a user