diff --git a/src/logservice/restoreservice/ob_log_restore_handler.cpp b/src/logservice/restoreservice/ob_log_restore_handler.cpp index 6651aa644b..fc6c4be78a 100644 --- a/src/logservice/restoreservice/ob_log_restore_handler.cpp +++ b/src/logservice/restoreservice/ob_log_restore_handler.cpp @@ -546,15 +546,16 @@ int ObLogRestoreHandler::check_restore_done(const SCN &recovery_end_scn, bool &d return ret; } -bool ObLogRestoreHandler::check_restore_to_newest() +int ObLogRestoreHandler::check_restore_to_newest(share::SCN &end_scn, share::SCN &archive_scn) { int ret = OB_SUCCESS; - bool bret = false; ObRemoteSourceGuard guard; ObRemoteLogParent *source = NULL; ObLogArchivePieceContext *piece_context = NULL; share::ObBackupDest *dest = NULL; - SCN end_scn; + end_scn = SCN::min_scn(); + archive_scn = SCN::min_scn(); + SCN restore_scn = SCN::min_scn(); { if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -572,33 +573,21 @@ bool ObLogRestoreHandler::check_restore_to_newest() CLOG_LOG(WARN, "source is invalid", K(ret), KPC(this), KPC(source)); } else { ObRemoteLocationParent *location_source = dynamic_cast(source); - location_source->get(dest, piece_context, end_scn); + location_source->get(dest, piece_context, restore_scn); } } if (OB_SUCC(ret) && NULL != piece_context) { palf::LSN archive_lsn; - SCN archive_scn; - SCN scn; - if (OB_FAIL(palf_handle_.get_end_scn(scn))) { + if (OB_FAIL(palf_handle_.get_end_scn(end_scn))) { CLOG_LOG(WARN, "get end scn failed", K(ret), K(id_)); } else if (OB_FAIL(piece_context->get_max_archive_log(archive_lsn, archive_scn))) { CLOG_LOG(WARN, "get max archive log failed", K(ret), K(id_)); } else { - if (archive_scn == scn) { - bret = true; - CLOG_LOG(INFO, "check_restore_to_newest succ", K(id_), K(bret), K(archive_scn), K(scn)); - } else if (archive_scn < scn) { - bret = true; - CLOG_LOG(INFO, "archive_scn smaller than palf end_scn, check_restore_to_newest succ", - K(id_), K(bret), K(archive_scn), K(scn)); - } else { - CLOG_LOG(INFO, "archive_scn bigger than palf end_scn, restore log not finish", - K(id_), K(bret), K(archive_scn), K(scn)); - } + CLOG_LOG(INFO, "check_restore_to_newest succ", K(id_), K(archive_scn), K(end_scn)); } } - return bret; + return ret; } int ObLogRestoreHandler::submit_sorted_task(ObFetchLogTask &task) diff --git a/src/logservice/restoreservice/ob_log_restore_handler.h b/src/logservice/restoreservice/ob_log_restore_handler.h index fdbdc29cfb..135d0d288c 100644 --- a/src/logservice/restoreservice/ob_log_restore_handler.h +++ b/src/logservice/restoreservice/ob_log_restore_handler.h @@ -135,7 +135,9 @@ public: // @brief Before the standby tenant switchover to primary, check if all primary logs are restored in the standby // 1. for standby based on archive, check the max archived log is restored in the standby // 2. for standby based on net service, check the max log in primary is restored in the standby - bool check_restore_to_newest(); + // @param[out] end_scn, the end_scn of palf + // @param[out] archive_scn, the max scn in archive logs + int check_restore_to_newest(share::SCN &end_scn, share::SCN &archive_scn); // @brief Remote Fetch Log Workers fetch log from remote source in parallel, but raw write to palf in series // This interface to to sort and cache logs // @ret_code OB_NOT_MASTER the restore_handler is not master diff --git a/src/observer/ob_service.cpp b/src/observer/ob_service.cpp index d3183b8909..eebab49a35 100644 --- a/src/observer/ob_service.cpp +++ b/src/observer/ob_service.cpp @@ -2439,6 +2439,7 @@ int ObService::get_ls_sync_scn( MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); ObLSService *ls_svr = nullptr; SCN cur_sync_scn = SCN::min_scn(); + SCN cur_restore_source_max_scn = SCN::min_scn(); bool restore_to_newest = false; LOG_INFO("start get_ls_sync_scn", K(arg)); @@ -2482,13 +2483,15 @@ int ObService::get_ls_sync_scn( } else if (OB_ISNULL(restore_handler = ls->get_log_restore_handler())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get restore_handler failed", KR(ret), K(ls_id), KP(ls)); - } else if (FALSE_IT(restore_to_newest = - arg.check_sync_to_latest() ? restore_handler->check_restore_to_newest() : false)) { + // scn get order, sync_scn from leader before archive_scn } else if (OB_FAIL(log_handler->get_end_scn(cur_sync_scn))) { LOG_WARN("failed to get ls cur_sync_scn", KR(ret), K(ls_id), KPC(ls)); - } else if (OB_FAIL(result.init(arg.get_tenant_id(), ls_id, cur_sync_scn, restore_to_newest))) { + } else if (arg.check_sync_to_latest() + && OB_FAIL(restore_handler->check_restore_to_newest(cur_sync_scn, cur_restore_source_max_scn))) { + LOG_WARN("failed to check_restore_to_newest", KR(ret), K(arg), KPC(ls)); + } else if (OB_FAIL(result.init(arg.get_tenant_id(), ls_id, cur_sync_scn, cur_restore_source_max_scn))) { LOG_WARN("failed to init res", KR(ret), K(arg.get_tenant_id()), K(ls_id), K(cur_sync_scn), - K(restore_to_newest)); + K(cur_restore_source_max_scn)); } else if (OB_FAIL(log_ls_svr->get_palf_role(ls_id, role, second_leader_epoch))) { COMMON_LOG(WARN, "failed to get palf role", KR(ret), K(ls_id)); } else if (first_leader_epoch != second_leader_epoch || !is_strong_leader(role)) { @@ -2497,7 +2500,7 @@ int ObService::get_ls_sync_scn( K(second_leader_epoch), K(role)); } } - LOG_INFO("finish get_ls_sync_scn", KR(ret), K(cur_sync_scn), K(arg), K(result)); + LOG_INFO("finish get_ls_sync_scn", KR(ret), K(cur_sync_scn), K(cur_restore_source_max_scn), K(arg), K(result)); return ret; } diff --git a/src/rootserver/ob_tenant_role_transition_service.cpp b/src/rootserver/ob_tenant_role_transition_service.cpp index d68e5976f2..3e2740a4fb 100644 --- a/src/rootserver/ob_tenant_role_transition_service.cpp +++ b/src/rootserver/ob_tenant_role_transition_service.cpp @@ -234,6 +234,8 @@ int ObTenantRoleTransitionService::do_prepare_flashback_for_switch_to_primary_( ObLogRestoreSourceMgr restore_source_mgr; ObLogRestoreSourceItem item; + DEBUG_SYNC(PREPARE_FLASHBACK_FOR_SWITCH_TO_PRIMARY); + if (OB_FAIL(check_inner_stat())) { LOG_WARN("error unexpected", KR(ret), K(tenant_id_), KP(sql_proxy_), KP(rpc_proxy_)); } else if (OB_UNLIKELY(!tenant_info.is_prepare_flashback_for_switch_to_primary_status())) { @@ -380,7 +382,7 @@ int ObTenantRoleTransitionService::do_flashback_(const share::ObAllTenantInfo &t } int ObTenantRoleTransitionService::do_switch_access_mode_to_append( - share::ObAllTenantInfo &tenant_info, + const share::ObAllTenantInfo &tenant_info, const share::ObTenantRole &target_tenant_role) { int ret = OB_SUCCESS; @@ -399,21 +401,28 @@ int ObTenantRoleTransitionService::do_switch_access_mode_to_append( LOG_WARN("failed to get access mode", KR(ret), K(access_mode), K(ref_scn), K(tenant_info)); } else { common::ObMySQLTransaction trans; + share::ObAllTenantInfo cur_tenant_info; const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id_); 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))) { + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id_, &trans, true, cur_tenant_info))) { LOG_WARN("failed to load all tenant info", KR(ret), K(tenant_id_)); + } else if (OB_UNLIKELY(tenant_info.get_switchover_status() != cur_tenant_info.get_switchover_status() + || tenant_info.get_switchover_epoch() != cur_tenant_info.get_switchover_epoch())) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("Tenant status changed by concurrent operation, switch to primary not allowed", + KR(ret), K(tenant_info), K(cur_tenant_info)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "Tenant status changed by concurrent operation, switch to primary"); } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_role( tenant_id_, &trans, tenant_info.get_switchover_epoch(), share::PRIMARY_TENANT_ROLE, tenant_info.get_switchover_status(), share::NORMAL_SWITCHOVER_STATUS, switchover_epoch_))) { - LOG_WARN("failed to update tenant switchover status", KR(ret), K(tenant_id_), K(tenant_info)); - } else if (tenant_info.get_recovery_until_scn().is_max()) { - LOG_INFO("recovery_until_scn already is max_scn", KR(ret), K_(tenant_id), K(tenant_info)); + LOG_WARN("failed to update tenant switchover status", KR(ret), K(tenant_id_), K(tenant_info), K(cur_tenant_info)); + } else if (cur_tenant_info.get_recovery_until_scn().is_max()) { + LOG_INFO("recovery_until_scn already is max_scn", KR(ret), K_(tenant_id), K(cur_tenant_info)); } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_recovery_until_scn( tenant_id_, trans, switchover_epoch_, SCN::max_scn()))) { - LOG_WARN("failed to update_tenant_recovery_until_scn", KR(ret), K_(tenant_id), K(tenant_info)); + LOG_WARN("failed to update_tenant_recovery_until_scn", KR(ret), K_(tenant_id), K(tenant_info), K(cur_tenant_info)); } if (trans.is_started()) { int tmp_ret = OB_SUCCESS; @@ -971,7 +980,7 @@ int ObTenantRoleTransitionService::check_sync_to_latest_(const uint64_t tenant_i has_sync_to_latest = true; for (int64_t i = 0; i < switchover_checkpoints.count() && OB_SUCC(ret) && has_sync_to_latest; i++) { const auto &checkpoint = switchover_checkpoints.at(i); - if (checkpoint.is_sync_to_latest() && checkpoint.get_cur_sync_scn().is_valid_and_not_min()) { + if (checkpoint.is_sync_to_latest()) { // LS is sync } else { has_sync_to_latest = false; @@ -1064,7 +1073,7 @@ int ObTenantRoleTransitionService::get_checkpoints_by_rpc_(const uint64_t tenant ret = OB_ERR_UNEXPECTED; LOG_WARN("result is null", KR(ret), K(i)); } else { - ObCheckpoint checkpoint(result->get_ls_id(), result->get_cur_sync_scn(), result->is_sync_to_latest()); + ObCheckpoint checkpoint(result->get_ls_id(), result->get_cur_sync_scn(), result->get_cur_restore_source_max_scn()); if (OB_FAIL(checkpoints.push_back(checkpoint))) { LOG_WARN("failed to push back checkpoint", KR(ret), K(checkpoint)); } diff --git a/src/rootserver/ob_tenant_role_transition_service.h b/src/rootserver/ob_tenant_role_transition_service.h index 2e7bd9b3d3..d887d660ae 100644 --- a/src/rootserver/ob_tenant_role_transition_service.h +++ b/src/rootserver/ob_tenant_role_transition_service.h @@ -98,7 +98,7 @@ public: virtual ~ObTenantRoleTransitionService() {} int failover_to_primary(); int check_inner_stat(); - int do_switch_access_mode_to_append(share::ObAllTenantInfo &tenant_info, + int do_switch_access_mode_to_append(const share::ObAllTenantInfo &tenant_info, const share::ObTenantRole &target_tenant_role); int do_switch_access_mode_to_raw_rw(const share::ObAllTenantInfo &tenant_info, const share::ObTenantRole &target_tenant_role); diff --git a/src/share/ob_debug_sync_point.h b/src/share/ob_debug_sync_point.h index fdba5e78fe..702db15535 100644 --- a/src/share/ob_debug_sync_point.h +++ b/src/share/ob_debug_sync_point.h @@ -394,6 +394,8 @@ class ObString; ACT(BEFORE_RESTORE_TABLETS_META,)\ ACT(BEFORE_RESTORE_MINOR,)\ ACT(BEFORE_DO_FLASHBACK,)\ + ACT(PREPARE_FLASHBACK_FOR_SWITCH_TO_PRIMARY,)\ + ACT(SWITCHING_TO_STANDBY,)\ ACT(BEFORE_LS_RESTORE_SYS_TABLETS,)\ ACT(BEFORE_WAIT_RESTORE_SYS_TABLETS,)\ ACT(BEFORE_WAIT_RESTORE_TABLETS_META,)\ diff --git a/src/share/ob_primary_standby_service.cpp b/src/share/ob_primary_standby_service.cpp index 6b6c78ba6d..0e7f19267c 100644 --- a/src/share/ob_primary_standby_service.cpp +++ b/src/share/ob_primary_standby_service.cpp @@ -263,6 +263,8 @@ int ObPrimaryStandbyService::do_recover_tenant(const obrpc::ObRecoverTenantArg & 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; if (OB_FAIL(check_inner_stat_())) { LOG_WARN("inner stat error", KR(ret), K_(inited)); } else if (!arg.is_valid()) { @@ -293,15 +295,20 @@ int ObPrimaryStandbyService::do_recover_tenant(const obrpc::ObRecoverTenantArg & ret = OB_OP_NOT_ALLOW; LOG_WARN("tenant switchover_status is not NORMAL", K(tenant_info)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant switchover_status is not NORMAL, recover is"); + } else if (OB_FAIL(ls_recovery_operator.get_ls_recovery_stat(tenant_id, share::SYS_LS, + true /*for_update*/, sys_ls_recovery, trans))) { + LOG_WARN("failed to get ls recovery stat", KR(ret), K(tenant_id)); } else if (obrpc::ObRecoverTenantArg::RecoverType::UNTIL == arg.get_type() - && (arg.get_recovery_until_scn() < tenant_info.get_sync_scn())) { + && (arg.get_recovery_until_scn() < tenant_info.get_sync_scn() + || arg.get_recovery_until_scn() < sys_ls_recovery.get_sync_scn())) { ret = OB_OP_NOT_ALLOW; - LOG_WARN("recover before sync_scn is not allow", KR(ret), K(tenant_info), K(tenant_id), K(arg)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "recover before sync_scn is"); + LOG_WARN("recover before tenant sync_scn or SYS LS sync_scn is not allow", KR(ret), K(tenant_info), + K(tenant_id), K(arg), 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()) { ObLogRestoreSourceMgr restore_source_mgr; const SCN &recovery_until_scn = obrpc::ObRecoverTenantArg::RecoverType::UNTIL == arg.get_type() ? - arg.get_recovery_until_scn() : tenant_info.get_sync_scn(); + arg.get_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) { LOG_WARN("recovery_until_scn is same with original", KR(ret), K(tenant_info), K(tenant_id), K(arg)); } else if (OB_FAIL(restore_source_mgr.init(tenant_id, &trans))) { @@ -560,6 +567,8 @@ int ObPrimaryStandbyService::switch_to_standby_prepare_ls_status_( ret = OB_NEED_RETRY; LOG_WARN("switchover is concurrency", KR(ret), K(switchover_epoch), K(new_tenant_info)); } + + DEBUG_SYNC(SWITCHING_TO_STANDBY); } return ret; diff --git a/src/share/ob_rpc_struct.cpp b/src/share/ob_rpc_struct.cpp index 9a2a93a53f..e35fef61fe 100644 --- a/src/share/ob_rpc_struct.cpp +++ b/src/share/ob_rpc_struct.cpp @@ -5235,15 +5235,15 @@ DEF_TO_STRING(ObSplitPartitionBatchArg) bool ObCheckpoint::is_valid() const { - return (ls_id_.is_valid() && cur_sync_scn_.is_valid_and_not_min()); + return (ls_id_.is_valid() && cur_sync_scn_.is_valid_and_not_min() && cur_restore_source_max_scn_.is_valid_and_not_min()); } bool ObCheckpoint::operator==(const obrpc::ObCheckpoint &r) const { - return ls_id_ == r.ls_id_ && cur_sync_scn_ == r.cur_sync_scn_ && is_sync_to_latest_ == r.is_sync_to_latest_; + return ls_id_ == r.ls_id_ && cur_sync_scn_ == r.cur_sync_scn_ && cur_restore_source_max_scn_ == r.cur_restore_source_max_scn_; } -OB_SERIALIZE_MEMBER(ObCheckpoint, ls_id_, cur_sync_scn_, is_sync_to_latest_); +OB_SERIALIZE_MEMBER(ObCheckpoint, ls_id_, cur_sync_scn_, cur_restore_source_max_scn_); OB_SERIALIZE_MEMBER(ObGetWRSArg, tenant_id_, scope_, need_filter_); OB_SERIALIZE_MEMBER(ObGetWRSResult, self_addr_, err_code_); @@ -5391,31 +5391,32 @@ int ObGetLSSyncScnArg::assign(const ObGetLSSyncScnArg &other) return ret; } -OB_SERIALIZE_MEMBER(ObGetLSSyncScnRes, tenant_id_, ls_id_, cur_sync_scn_, is_sync_to_latest_); +OB_SERIALIZE_MEMBER(ObGetLSSyncScnRes, tenant_id_, ls_id_, cur_sync_scn_, cur_restore_source_max_scn_); bool ObGetLSSyncScnRes::is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ && ls_id_.is_valid() - && cur_sync_scn_.is_valid_and_not_min(); + && cur_sync_scn_.is_valid_and_not_min() + && cur_restore_source_max_scn_.is_valid_and_not_min(); } int ObGetLSSyncScnRes::init( const uint64_t tenant_id, const share::ObLSID &ls_id, const share::SCN &cur_sync_scn, - const bool is_sync_to_latest) + const share::SCN &cur_restore_source_max_scn) { int ret = OB_SUCCESS; if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !ls_id.is_valid() || !cur_sync_scn.is_valid_and_not_min())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id), K(cur_sync_scn), K(is_sync_to_latest)); + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id), K(cur_sync_scn), K(cur_restore_source_max_scn)); } else { tenant_id_ = tenant_id; ls_id_ = ls_id; cur_sync_scn_ = cur_sync_scn; - is_sync_to_latest_ = is_sync_to_latest; + cur_restore_source_max_scn_ = cur_restore_source_max_scn; } return ret; } @@ -5427,7 +5428,7 @@ int ObGetLSSyncScnRes::assign(const ObGetLSSyncScnRes &other) tenant_id_ = other.tenant_id_; ls_id_ = other.ls_id_; cur_sync_scn_ = other.cur_sync_scn_; - is_sync_to_latest_ = other.is_sync_to_latest_; + cur_restore_source_max_scn_ = other.cur_restore_source_max_scn_; } return ret; } diff --git a/src/share/ob_rpc_struct.h b/src/share/ob_rpc_struct.h index 11b88fa025..8ff941c3ca 100644 --- a/src/share/ob_rpc_struct.h +++ b/src/share/ob_rpc_struct.h @@ -6150,12 +6150,12 @@ public: ObGetLSSyncScnRes(): tenant_id_(OB_INVALID_TENANT_ID), ls_id_(), cur_sync_scn_(share::SCN::min_scn()), - is_sync_to_latest_(false) {} + cur_restore_source_max_scn_(share::SCN::min_scn()) {} ~ObGetLSSyncScnRes() {} bool is_valid() const; - int init(const uint64_t tenant_id, const share::ObLSID &ls_id, const share::SCN &cur_sync_scn, const bool is_sync_to_latest); + int init(const uint64_t tenant_id, const share::ObLSID &ls_id, const share::SCN &cur_sync_scn, const share::SCN &cur_restore_source_max_scn); int assign(const ObGetLSSyncScnRes &other); - TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(cur_sync_scn), K_(is_sync_to_latest)); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(cur_sync_scn), K_(cur_restore_source_max_scn)); uint64_t get_tenant_id() const { return tenant_id_; @@ -6168,9 +6168,9 @@ public: { return cur_sync_scn_; } - bool is_sync_to_latest() const + share::SCN get_cur_restore_source_max_scn() const { - return is_sync_to_latest_; + return cur_restore_source_max_scn_; } private: DISALLOW_COPY_AND_ASSIGN(ObGetLSSyncScnRes); @@ -6178,7 +6178,7 @@ private: uint64_t tenant_id_; share::ObLSID ls_id_; share::SCN cur_sync_scn_; - bool is_sync_to_latest_; + share::SCN cur_restore_source_max_scn_; }; struct ObRefreshTenantInfoArg @@ -6229,16 +6229,16 @@ public: ObCheckpoint(): ls_id_(), cur_sync_scn_(share::SCN::min_scn()), - is_sync_to_latest_(false) {} - explicit ObCheckpoint(const int64_t id, const share::SCN &cur_sync_scn, const bool is_sync_to_latest): + cur_restore_source_max_scn_(share::SCN::min_scn()) {} + explicit ObCheckpoint(const int64_t id, const share::SCN &cur_sync_scn, const share::SCN &cur_restore_source_max_scn): ls_id_(id), cur_sync_scn_(cur_sync_scn), - is_sync_to_latest_(is_sync_to_latest) {} + cur_restore_source_max_scn_(cur_restore_source_max_scn) {} - explicit ObCheckpoint(const share::ObLSID id, const share::SCN &cur_sync_scn, const bool is_sync_to_latest): + explicit ObCheckpoint(const share::ObLSID id, const share::SCN &cur_sync_scn, const share::SCN &cur_restore_source_max_scn): ls_id_(id), cur_sync_scn_(cur_sync_scn), - is_sync_to_latest_(is_sync_to_latest) {} + cur_restore_source_max_scn_(cur_restore_source_max_scn) {} bool is_valid() const; bool operator==(const obrpc::ObCheckpoint &r) const; @@ -6250,16 +6250,22 @@ public: { return cur_sync_scn_; } - bool is_sync_to_latest() const + share::SCN get_cur_restore_source_max_scn() const { - return is_sync_to_latest_; + return cur_restore_source_max_scn_; } - TO_STRING_KV(K_(ls_id), K_(cur_sync_scn), K_(is_sync_to_latest)); + bool is_sync_to_latest() const + { + return (cur_sync_scn_ >= cur_restore_source_max_scn_ + && cur_sync_scn_.is_valid_and_not_min() && cur_restore_source_max_scn_.is_valid_and_not_min()); + } + + TO_STRING_KV(K_(ls_id), K_(cur_sync_scn), K_(cur_restore_source_max_scn)); share::ObLSID ls_id_; share::SCN cur_sync_scn_; - bool is_sync_to_latest_; + share::SCN cur_restore_source_max_scn_; }; struct ObSwitchTenantArg diff --git a/src/sql/engine/cmd/ob_alter_system_executor.cpp b/src/sql/engine/cmd/ob_alter_system_executor.cpp index c50fb51289..90dadcbb29 100644 --- a/src/sql/engine/cmd/ob_alter_system_executor.cpp +++ b/src/sql/engine/cmd/ob_alter_system_executor.cpp @@ -1822,11 +1822,24 @@ int ObSwitchTenantExecutor::execute(ObExecContext &ctx, ObSwitchTenantStmt &stmt ObSwitchTenantArg &arg = stmt.get_arg(); arg.set_stmt_str(first_stmt); + //left 200ms to return result + const int64_t remain_timeout_interval_us = THIS_WORKER.get_timeout_remain(); + const int64_t execute_timeout_interval_us = remain_timeout_interval_us - 200 * 1000; // left 200ms to return result + const int64_t original_timeout_abs_us = THIS_WORKER.get_timeout_ts(); + if (0 < execute_timeout_interval_us) { + THIS_WORKER.set_timeout_ts(ObTimeUtility::current_time() + execute_timeout_interval_us); + } + // TODO support specify ALL if (OB_FAIL(ret)) { } else if (OB_FAIL(OB_PRIMARY_STANDBY_SERVICE.switch_tenant(arg))) { LOG_WARN("failed to switch_tenant", KR(ret), K(arg)); } + + //set timeout back + if (0 < execute_timeout_interval_us) { + THIS_WORKER.set_timeout_ts(original_timeout_abs_us); + } } return ret; }