[FEAT MERGE] log4100 branch
Co-authored-by: tino247 <tino247@126.com> Co-authored-by: BinChenn <binchenn.bc@gmail.com> Co-authored-by: HaHaJeff <jeffzhouhhh@gmail.com>
This commit is contained in:
		@ -18,9 +18,12 @@
 | 
			
		||||
#include "share/config/ob_server_config.h"//GCONF
 | 
			
		||||
#include "share/inner_table/ob_inner_table_schema.h"//ALL_TENANT_INFO_TNAME
 | 
			
		||||
#include "share/ls/ob_ls_i_life_manager.h"//TODO SCN VALUE
 | 
			
		||||
#include "share/ls/ob_ls_recovery_stat_operator.h"//ObLSRecoveryStatOperator
 | 
			
		||||
#include "lib/string/ob_sql_string.h"//ObSqlString
 | 
			
		||||
#include "lib/mysqlclient/ob_mysql_transaction.h"//ObMySQLTrans
 | 
			
		||||
#include "common/ob_timeout_ctx.h"//ObTimeoutCtx
 | 
			
		||||
#include "rootserver/ob_root_utils.h"//ObRootUtils
 | 
			
		||||
#include "rootserver/ob_rs_event_history_table_operator.h" // ROOTSERVICE_EVENT_ADD
 | 
			
		||||
 | 
			
		||||
using namespace oceanbase;
 | 
			
		||||
using namespace oceanbase::common;
 | 
			
		||||
@ -28,66 +31,72 @@ namespace oceanbase
 | 
			
		||||
{
 | 
			
		||||
namespace share
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
bool is_valid_tenant_scn(
 | 
			
		||||
  const SCN &sync_scn,
 | 
			
		||||
  const SCN &replayable_scn,
 | 
			
		||||
  const SCN &standby_scn,
 | 
			
		||||
  const SCN &recovery_until_scn)
 | 
			
		||||
{
 | 
			
		||||
  return standby_scn <= replayable_scn && replayable_scn <= sync_scn && sync_scn <= recovery_until_scn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SCN gen_new_sync_scn(const SCN &cur_sync_scn, const SCN &desired_sync_scn, const SCN &cur_recovery_until_scn)
 | 
			
		||||
{
 | 
			
		||||
  return MIN(MAX(cur_sync_scn, desired_sync_scn), cur_recovery_until_scn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SCN gen_new_replayable_scn(const SCN &cur_replayable_scn, const SCN &desired_replayable_scn, const SCN &new_sync_scn)
 | 
			
		||||
{
 | 
			
		||||
  return MIN(MAX(cur_replayable_scn, desired_replayable_scn), new_sync_scn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SCN gen_new_standby_scn(const SCN &cur_standby_scn, const SCN &desired_standby_scn, const SCN &new_replayable_scn)
 | 
			
		||||
{
 | 
			
		||||
  return MIN(MAX(cur_standby_scn, desired_standby_scn), new_replayable_scn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////ObAllTenantInfo
 | 
			
		||||
bool ObAllTenantInfo::is_valid() const
 | 
			
		||||
{
 | 
			
		||||
  return OB_INVALID_TENANT_ID != tenant_id_
 | 
			
		||||
         && sync_scn_.is_valid()
 | 
			
		||||
         && (sync_scn_ != SCN::min_scn())
 | 
			
		||||
         && replayable_scn_.is_valid()
 | 
			
		||||
         && (replayable_scn_ != SCN::min_scn())
 | 
			
		||||
         && standby_scn_.is_valid()
 | 
			
		||||
         && (standby_scn_ != SCN::min_scn())
 | 
			
		||||
         && recovery_until_scn_.is_valid()
 | 
			
		||||
         && (recovery_until_scn_ != SCN::min_scn())
 | 
			
		||||
         && tenant_role_.is_valid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const SCN ObAllTenantInfo::get_ref_scn() const
 | 
			
		||||
{
 | 
			
		||||
  SCN ref_scn;
 | 
			
		||||
  if (!sync_scn_.is_valid()) {
 | 
			
		||||
    LOG_WARN("sync scn is invalid", K(sync_scn_));
 | 
			
		||||
  } else {
 | 
			
		||||
    ref_scn = sync_scn_;
 | 
			
		||||
  }
 | 
			
		||||
  return ref_scn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int ObAllTenantInfo::init(const uint64_t tenant_id, const ObTenantRole tenant_role)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  reset();
 | 
			
		||||
  if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id
 | 
			
		||||
                  || !tenant_role.is_valid())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_role));
 | 
			
		||||
  } else {
 | 
			
		||||
    tenant_id_ = tenant_id;
 | 
			
		||||
    tenant_role_ = tenant_role;
 | 
			
		||||
    switchover_status_ = ObTenantSwitchoverStatus::NORMAL_STATUS;
 | 
			
		||||
    switchover_epoch_ = 0;
 | 
			
		||||
    sync_scn_.set_base();
 | 
			
		||||
    replayable_scn_.set_base();
 | 
			
		||||
    standby_scn_.set_base();
 | 
			
		||||
    recovery_until_scn_.set_max();
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
         && 0 <= switchover_epoch_
 | 
			
		||||
         && sync_scn_.is_valid_and_not_min()
 | 
			
		||||
         && replayable_scn_.is_valid_and_not_min()
 | 
			
		||||
         && standby_scn_.is_valid_and_not_min()
 | 
			
		||||
         && recovery_until_scn_.is_valid_and_not_min()
 | 
			
		||||
         && tenant_role_.is_valid()
 | 
			
		||||
         && switchover_status_.is_valid()
 | 
			
		||||
         && log_mode_.is_valid()
 | 
			
		||||
         && is_valid_tenant_scn(sync_scn_, replayable_scn_, standby_scn_, recovery_until_scn_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObAllTenantInfo::init(
 | 
			
		||||
    const uint64_t tenant_id, const ObTenantRole &tenant_role, const ObTenantSwitchoverStatus &switchover_status,
 | 
			
		||||
    int64_t switchover_epoch, const SCN &sync_scn, const SCN &replayable_scn,
 | 
			
		||||
    const SCN &standby_scn, const SCN &recovery_until_scn)
 | 
			
		||||
    const uint64_t tenant_id,
 | 
			
		||||
    const ObTenantRole &tenant_role,
 | 
			
		||||
    const ObTenantSwitchoverStatus &switchover_status,
 | 
			
		||||
    int64_t switchover_epoch,
 | 
			
		||||
    const SCN &sync_scn,
 | 
			
		||||
    const SCN &replayable_scn,
 | 
			
		||||
    const SCN &standby_scn,
 | 
			
		||||
    const SCN &recovery_until_scn,
 | 
			
		||||
    const ObArchiveMode &log_mode)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  reset();
 | 
			
		||||
  if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id
 | 
			
		||||
                  || !tenant_role.is_valid()
 | 
			
		||||
                  || !switchover_status.is_valid())) {
 | 
			
		||||
                  || !switchover_status.is_valid()
 | 
			
		||||
                  || 0 > switchover_epoch
 | 
			
		||||
                  || !sync_scn.is_valid_and_not_min()
 | 
			
		||||
                  || !replayable_scn.is_valid_and_not_min()
 | 
			
		||||
                  || !standby_scn.is_valid_and_not_min()
 | 
			
		||||
                  || !recovery_until_scn.is_valid_and_not_min()
 | 
			
		||||
                  || !log_mode.is_valid()
 | 
			
		||||
                  || !is_valid_tenant_scn(sync_scn, replayable_scn, standby_scn, recovery_until_scn))) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_role), K(switchover_status));
 | 
			
		||||
    LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_role), K(switchover_status),
 | 
			
		||||
             K(switchover_epoch), K(sync_scn), K(replayable_scn), K(standby_scn), K(recovery_until_scn),
 | 
			
		||||
             K(log_mode));
 | 
			
		||||
  } else {
 | 
			
		||||
    tenant_id_ = tenant_id;
 | 
			
		||||
    tenant_role_ = tenant_role;
 | 
			
		||||
@ -97,11 +106,11 @@ int ObAllTenantInfo::init(
 | 
			
		||||
    replayable_scn_ = replayable_scn;
 | 
			
		||||
    standby_scn_ = standby_scn;
 | 
			
		||||
    recovery_until_scn_ = recovery_until_scn;
 | 
			
		||||
  
 | 
			
		||||
    log_mode_ = log_mode;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
int ObAllTenantInfo::assign(const ObAllTenantInfo &other)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
@ -115,6 +124,7 @@ int ObAllTenantInfo::assign(const ObAllTenantInfo &other)
 | 
			
		||||
    replayable_scn_ = other.replayable_scn_;
 | 
			
		||||
    standby_scn_ = other.standby_scn_;
 | 
			
		||||
    recovery_until_scn_ = other.recovery_until_scn_;
 | 
			
		||||
    log_mode_ = other.log_mode_;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
@ -129,10 +139,11 @@ void ObAllTenantInfo::reset()
 | 
			
		||||
  replayable_scn_.set_min();
 | 
			
		||||
  standby_scn_.set_min() ;
 | 
			
		||||
  recovery_until_scn_.set_min();
 | 
			
		||||
  log_mode_.reset();
 | 
			
		||||
}
 | 
			
		||||
OB_SERIALIZE_MEMBER(ObAllTenantInfo, tenant_id_, tenant_role_,
 | 
			
		||||
                    switchover_status_, switchover_epoch_, sync_scn_,
 | 
			
		||||
                    replayable_scn_, standby_scn_, recovery_until_scn_);
 | 
			
		||||
                    replayable_scn_, standby_scn_, recovery_until_scn_, log_mode_);
 | 
			
		||||
 | 
			
		||||
ObAllTenantInfo& ObAllTenantInfo::operator= (const ObAllTenantInfo &other)
 | 
			
		||||
{
 | 
			
		||||
@ -150,10 +161,12 @@ int ObAllTenantInfoProxy::init_tenant_info(
 | 
			
		||||
    const ObAllTenantInfo &tenant_info,
 | 
			
		||||
    ObISQLClient *proxy)
 | 
			
		||||
{
 | 
			
		||||
  int64_t begin_time = ObTimeUtility::current_time();
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_info.get_tenant_id());
 | 
			
		||||
  ObSqlString sql;
 | 
			
		||||
  int64_t affected_rows = 0;
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
  if (OB_UNLIKELY(!tenant_info.is_valid())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("tenant_info is invalid", KR(ret), K(tenant_info));
 | 
			
		||||
@ -163,18 +176,22 @@ int ObAllTenantInfoProxy::init_tenant_info(
 | 
			
		||||
  } else if (!is_user_tenant(tenant_info.get_tenant_id())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("meta tenant no need init tenant info", KR(ret), K(tenant_info));
 | 
			
		||||
  } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
    LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
  } else if (OB_FAIL(sql.assign_fmt(
 | 
			
		||||
                 "insert into %s (tenant_id, tenant_role, "
 | 
			
		||||
                 "switchover_status, switchover_epoch, "
 | 
			
		||||
                 "sync_scn, replayable_scn, readable_scn) "
 | 
			
		||||
                 "values(%lu, '%s', '%s', %ld, %lu, %lu, %lu)",
 | 
			
		||||
                 "sync_scn, replayable_scn, readable_scn, recovery_until_scn, log_mode) "
 | 
			
		||||
                 "values(%lu, '%s', '%s', %ld, %lu, %lu, %lu, %lu, '%s')",
 | 
			
		||||
                 OB_ALL_TENANT_INFO_TNAME, tenant_info.get_tenant_id(),
 | 
			
		||||
                 tenant_info.get_tenant_role().to_str(),
 | 
			
		||||
                 tenant_info.get_switchover_status().to_str(),
 | 
			
		||||
                 tenant_info.get_switchover_epoch(),
 | 
			
		||||
                 tenant_info.get_sync_scn().get_val_for_inner_table_field(),
 | 
			
		||||
                 tenant_info.get_replayable_scn().get_val_for_inner_table_field(),
 | 
			
		||||
                 tenant_info.get_standby_scn().get_val_for_inner_table_field()))) {
 | 
			
		||||
                 tenant_info.get_standby_scn().get_val_for_inner_table_field(),
 | 
			
		||||
                 tenant_info.get_recovery_until_scn().get_val_for_inner_table_field(),
 | 
			
		||||
                 tenant_info.get_log_mode().to_str()))) {
 | 
			
		||||
    LOG_WARN("failed to assign sql", KR(ret), K(tenant_info), K(sql));
 | 
			
		||||
  } else if (OB_FAIL(proxy->write(exec_tenant_id, sql.ptr(), affected_rows))) {
 | 
			
		||||
    LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql));
 | 
			
		||||
@ -182,6 +199,11 @@ int ObAllTenantInfoProxy::init_tenant_info(
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int64_t cost = ObTimeUtility::current_time() - begin_time;
 | 
			
		||||
  ROOTSERVICE_EVENT_ADD("tenant_info", "init_tenant_info", K(ret),
 | 
			
		||||
                        K(tenant_info), K(affected_rows), K(cost));
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -258,6 +280,7 @@ int ObAllTenantInfoProxy::load_tenant_info(const uint64_t tenant_id,
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  tenant_info.reset();
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
  if (OB_ISNULL(proxy)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("proxy is null", KR(ret), KP(proxy));
 | 
			
		||||
@ -272,7 +295,9 @@ int ObAllTenantInfoProxy::load_tenant_info(const uint64_t tenant_id,
 | 
			
		||||
  } else {
 | 
			
		||||
    ObSqlString sql;
 | 
			
		||||
    uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
 | 
			
		||||
    if (OB_FAIL(sql.assign_fmt("select * from %s where tenant_id = %lu ",
 | 
			
		||||
    if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
      LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
    } else if (OB_FAIL(sql.assign_fmt("select * from %s where tenant_id = %lu ",
 | 
			
		||||
                   OB_ALL_TENANT_INFO_TNAME, tenant_id))) {
 | 
			
		||||
      LOG_WARN("failed to assign sql", KR(ret), K(sql));
 | 
			
		||||
    } else if(for_update && OB_FAIL(sql.append(" for update"))) {
 | 
			
		||||
@ -307,6 +332,7 @@ int ObAllTenantInfoProxy::update_tenant_recovery_status(
 | 
			
		||||
  int64_t affected_rows = 0;
 | 
			
		||||
  common::ObMySQLTransaction trans;
 | 
			
		||||
  ObAllTenantInfo old_tenant_info;
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
  if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id ||
 | 
			
		||||
                  !status.is_valid())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
@ -322,25 +348,24 @@ int ObAllTenantInfoProxy::update_tenant_recovery_status(
 | 
			
		||||
  } else if (OB_FAIL(load_tenant_info(tenant_id, &trans, true, old_tenant_info))) {
 | 
			
		||||
    LOG_WARN("failed to load all tenant info", KR(ret), K(tenant_id));
 | 
			
		||||
  } else {
 | 
			
		||||
    const SCN new_sync_scn = old_tenant_info.get_sync_scn() > sync_scn ? old_tenant_info.get_sync_scn() : sync_scn;
 | 
			
		||||
 | 
			
		||||
    SCN new_replay_scn_tmp = old_tenant_info.get_replayable_scn() > replay_scn ? old_tenant_info.get_replayable_scn() : replay_scn;
 | 
			
		||||
    SCN new_replay_scn = new_replay_scn_tmp < new_sync_scn ? new_replay_scn_tmp : new_sync_scn;
 | 
			
		||||
 | 
			
		||||
    SCN new_sts_tmp = old_tenant_info.get_standby_scn() > readable_scn ? old_tenant_info.get_standby_scn() : readable_scn;
 | 
			
		||||
    SCN new_sts = new_sts_tmp < new_replay_scn ? new_sts_tmp : new_replay_scn;
 | 
			
		||||
    SCN new_sync_scn = gen_new_sync_scn(old_tenant_info.get_sync_scn(), sync_scn, old_tenant_info.get_recovery_until_scn());
 | 
			
		||||
    SCN new_replay_scn = gen_new_replayable_scn(old_tenant_info.get_replayable_scn(), replay_scn, new_sync_scn);
 | 
			
		||||
    SCN new_scn = gen_new_standby_scn(old_tenant_info.get_standby_scn(), readable_scn, new_replay_scn);
 | 
			
		||||
 | 
			
		||||
    if (old_tenant_info.get_sync_scn() == new_sync_scn
 | 
			
		||||
        && old_tenant_info.get_replayable_scn() == new_replay_scn
 | 
			
		||||
        && old_tenant_info.get_standby_scn() == new_sts) {
 | 
			
		||||
      LOG_DEBUG("no need update", K(old_tenant_info), K(new_sync_scn), K(new_replay_scn), K(new_sts));
 | 
			
		||||
        && old_tenant_info.get_standby_scn() == new_scn) {
 | 
			
		||||
      LOG_DEBUG("no need update", K(old_tenant_info), K(new_sync_scn), K(new_replay_scn), K(new_scn));
 | 
			
		||||
    } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
      LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
    } else if (OB_FAIL(sql.assign_fmt(
 | 
			
		||||
                 "update %s set sync_scn = %lu, replayable_scn = %lu, "
 | 
			
		||||
                 "readable_scn = %lu where tenant_id = %lu "
 | 
			
		||||
                 "and switchover_status = '%s'", OB_ALL_TENANT_INFO_TNAME,
 | 
			
		||||
                 "update %s set sync_scn = %ld, replayable_scn = %ld, "
 | 
			
		||||
                 "readable_scn = %ld where tenant_id = %lu "
 | 
			
		||||
                 "and switchover_status = '%s' and readable_scn <= replayable_scn and "
 | 
			
		||||
                 "replayable_scn <= sync_scn and sync_scn <= recovery_until_scn", OB_ALL_TENANT_INFO_TNAME,
 | 
			
		||||
                 new_sync_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                 new_replay_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                 new_sts.get_val_for_inner_table_field(),
 | 
			
		||||
                 new_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                 tenant_id, status.to_str()))) {
 | 
			
		||||
      LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(status),
 | 
			
		||||
               K(sql));
 | 
			
		||||
@ -373,38 +398,47 @@ int ObAllTenantInfoProxy::fill_cell(common::sqlclient::ObMySQLResult *result, Ob
 | 
			
		||||
    ObString status_str;
 | 
			
		||||
    uint64_t tenant_id = OB_INVALID_TENANT_ID;
 | 
			
		||||
    int64_t switchover_epoch = OB_INVALID_TIMESTAMP;
 | 
			
		||||
    int64_t sync_ts = OB_INVALID_SCN_VAL;
 | 
			
		||||
    int64_t replay_ts = OB_INVALID_SCN_VAL;
 | 
			
		||||
    int64_t sts = OB_INVALID_SCN_VAL;
 | 
			
		||||
    uint64_t sync_scn_val = OB_INVALID_SCN_VAL;
 | 
			
		||||
    uint64_t replay_scn_val = OB_INVALID_SCN_VAL;
 | 
			
		||||
    uint64_t sts_scn_val = OB_INVALID_SCN_VAL;
 | 
			
		||||
    uint64_t recovery_until_scn_val = OB_INVALID_SCN_VAL;
 | 
			
		||||
    ObString log_mode_str;
 | 
			
		||||
    ObString log_mode_default_value("NOARCHIVELOG");
 | 
			
		||||
    SCN sync_scn;
 | 
			
		||||
    SCN replay_scn;
 | 
			
		||||
    SCN sts_scn;
 | 
			
		||||
    SCN recovery_scn;
 | 
			
		||||
    recovery_scn.set_base();
 | 
			
		||||
    SCN recovery_until_scn;
 | 
			
		||||
    EXTRACT_VARCHAR_FIELD_MYSQL(*result, "tenant_role", tenant_role_str);
 | 
			
		||||
    EXTRACT_VARCHAR_FIELD_MYSQL(*result, "switchover_status", status_str);
 | 
			
		||||
    EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tenant_id, uint64_t);
 | 
			
		||||
    EXTRACT_INT_FIELD_MYSQL(*result, "switchover_epoch", switchover_epoch, int64_t);
 | 
			
		||||
    EXTRACT_UINT_FIELD_MYSQL(*result, "sync_scn", sync_ts, int64_t);
 | 
			
		||||
    EXTRACT_UINT_FIELD_MYSQL(*result, "replayable_scn", replay_ts, int64_t);
 | 
			
		||||
    EXTRACT_UINT_FIELD_MYSQL(*result, "readable_scn", sts, int64_t);
 | 
			
		||||
    EXTRACT_UINT_FIELD_MYSQL(*result, "sync_scn", sync_scn_val, uint64_t);
 | 
			
		||||
    EXTRACT_UINT_FIELD_MYSQL(*result, "replayable_scn", replay_scn_val, uint64_t);
 | 
			
		||||
    EXTRACT_UINT_FIELD_MYSQL(*result, "readable_scn", sts_scn_val, uint64_t);
 | 
			
		||||
    EXTRACT_UINT_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "recovery_until_scn", recovery_until_scn_val, uint64_t, false /* skip_null_error */, true /* skip_column_error */, OB_MAX_SCN_TS_NS);
 | 
			
		||||
    EXTRACT_VARCHAR_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "log_mode", log_mode_str,
 | 
			
		||||
                false /* skip_null_error */, true /* skip_column_error */, log_mode_default_value);
 | 
			
		||||
    ObTenantRole tmp_tenant_role(tenant_role_str);
 | 
			
		||||
    ObTenantSwitchoverStatus tmp_tenant_sw_status(status_str);
 | 
			
		||||
    ObArchiveMode tmp_log_mode(log_mode_str);
 | 
			
		||||
    if (OB_FAIL(ret)) {
 | 
			
		||||
      LOG_WARN("failed to get result", KR(ret));
 | 
			
		||||
      //tenant_id in inner table can be used directly
 | 
			
		||||
    } else if (OB_FAIL(sync_scn.convert_for_inner_table_field(sync_ts))) {
 | 
			
		||||
      LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(sync_ts));
 | 
			
		||||
    } else if (OB_FAIL(replay_scn.convert_for_inner_table_field(replay_ts))) {
 | 
			
		||||
      LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(replay_ts));
 | 
			
		||||
    } else if (OB_FAIL(sts_scn.convert_for_inner_table_field(sts))) {
 | 
			
		||||
      LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(sts));
 | 
			
		||||
    } else if (OB_FAIL(sync_scn.convert_for_inner_table_field(sync_scn_val))) {
 | 
			
		||||
      LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(sync_scn_val));
 | 
			
		||||
    } else if (OB_FAIL(replay_scn.convert_for_inner_table_field(replay_scn_val))) {
 | 
			
		||||
      LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(replay_scn_val));
 | 
			
		||||
    } else if (OB_FAIL(sts_scn.convert_for_inner_table_field(sts_scn_val))) {
 | 
			
		||||
      LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(sts_scn_val));
 | 
			
		||||
    } else if (OB_FAIL(recovery_until_scn.convert_for_inner_table_field(recovery_until_scn_val))) {
 | 
			
		||||
      LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(recovery_until_scn_val));
 | 
			
		||||
    } else if (OB_FAIL(tenant_info.init(
 | 
			
		||||
            tenant_id, tmp_tenant_role,
 | 
			
		||||
            tmp_tenant_sw_status, switchover_epoch,
 | 
			
		||||
            sync_scn, replay_scn, sts_scn, recovery_scn))) {
 | 
			
		||||
            sync_scn, replay_scn, sts_scn, recovery_until_scn, tmp_log_mode))) {
 | 
			
		||||
      LOG_WARN("failed to init tenant info", KR(ret), K(tenant_id), K(tmp_tenant_role), K(tenant_role_str),
 | 
			
		||||
          K(tmp_tenant_sw_status), K(status_str), K(switchover_epoch), K(sync_ts));
 | 
			
		||||
          K(tmp_tenant_sw_status), K(status_str), K(switchover_epoch), K(sync_scn), K(recovery_until_scn),
 | 
			
		||||
          K(log_mode_str), K(tmp_log_mode));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
@ -414,40 +448,60 @@ int ObAllTenantInfoProxy::update_tenant_role(
 | 
			
		||||
    const uint64_t tenant_id,
 | 
			
		||||
    ObISQLClient *proxy,
 | 
			
		||||
    int64_t old_switchover_epoch,
 | 
			
		||||
    const ObTenantRole &new_role, const ObTenantSwitchoverStatus &status,
 | 
			
		||||
    const ObTenantRole &new_role,
 | 
			
		||||
    const ObTenantSwitchoverStatus &old_status,
 | 
			
		||||
    const ObTenantSwitchoverStatus &new_status,
 | 
			
		||||
    int64_t &new_switchover_ts)
 | 
			
		||||
{
 | 
			
		||||
  int64_t begin_time = ObTimeUtility::current_time();
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
 | 
			
		||||
  ObSqlString sql;
 | 
			
		||||
  int64_t affected_rows = 0;
 | 
			
		||||
  //update switchover epoch while role change
 | 
			
		||||
  new_switchover_ts = max(old_switchover_epoch + 1, ObTimeUtility::current_time());
 | 
			
		||||
  if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id
 | 
			
		||||
    || OB_INVALID_VERSION == new_switchover_ts
 | 
			
		||||
    || !new_role.is_valid())) {
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
 | 
			
		||||
  if (OB_UNLIKELY(!is_user_tenant(tenant_id)
 | 
			
		||||
    || OB_INVALID_VERSION == old_switchover_epoch
 | 
			
		||||
    || !new_role.is_valid()
 | 
			
		||||
    || !old_status.is_valid()
 | 
			
		||||
    || !new_status.is_valid())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("tenant_info is invalid", KR(ret), K(tenant_id), K(old_switchover_epoch), K(new_role));
 | 
			
		||||
    LOG_WARN("tenant_info is invalid", KR(ret), K(tenant_id), K(old_switchover_epoch), K(old_status),
 | 
			
		||||
                                       K(new_role), K(new_status));
 | 
			
		||||
  } else if (OB_ISNULL(proxy)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("proxy is null", KR(ret), KP(proxy));
 | 
			
		||||
  } else if (OB_FAIL(get_new_switchover_epoch_(old_switchover_epoch, old_status, new_status,
 | 
			
		||||
                                               new_switchover_ts))) {
 | 
			
		||||
    LOG_WARN("fail to get_new_switchover_epoch_", KR(ret), K(old_switchover_epoch), K(old_status),
 | 
			
		||||
                                                  K(new_status));
 | 
			
		||||
  } else if (OB_UNLIKELY(OB_INVALID_VERSION == new_switchover_ts)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("new_switchover_ts is invalid", KR(ret), K(new_switchover_ts),
 | 
			
		||||
             K(old_switchover_epoch), K(old_status), K(new_status));
 | 
			
		||||
  } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
    LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
  } else if (OB_FAIL(sql.assign_fmt(
 | 
			
		||||
          "update %s set tenant_role = '%s', switchover_status = '%s', switchover_epoch = %ld "
 | 
			
		||||
          "where tenant_id = %lu and switchover_epoch = %ld",
 | 
			
		||||
          "where tenant_id = %lu and switchover_epoch = %ld and switchover_status = '%s'",
 | 
			
		||||
          OB_ALL_TENANT_INFO_TNAME,
 | 
			
		||||
          new_role.to_str(), status.to_str(),
 | 
			
		||||
          new_switchover_ts, tenant_id, old_switchover_epoch))) {
 | 
			
		||||
          new_role.to_str(), new_status.to_str(),
 | 
			
		||||
          new_switchover_ts, tenant_id, old_switchover_epoch, old_status.to_str()))) {
 | 
			
		||||
    LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(old_switchover_epoch),
 | 
			
		||||
             K(new_role), K(sql));
 | 
			
		||||
             K(new_role), K(old_status), K(sql));
 | 
			
		||||
  } else if (OB_FAIL(proxy->write(exec_tenant_id, sql.ptr(), affected_rows))) {
 | 
			
		||||
    LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql));
 | 
			
		||||
  } else if (0 == affected_rows) {
 | 
			
		||||
    ret = OB_NEED_RETRY;
 | 
			
		||||
    LOG_WARN("switchover may concurrency, need retry", KR(ret), K(old_switchover_epoch));
 | 
			
		||||
    LOG_WARN("switchover may concurrency, need retry", KR(ret), K(old_switchover_epoch), K(sql));
 | 
			
		||||
  } else if (!is_single_row(affected_rows)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql));
 | 
			
		||||
  }
 | 
			
		||||
  int64_t cost = ObTimeUtility::current_time() - begin_time;
 | 
			
		||||
  ROOTSERVICE_EVENT_ADD("tenant_info", "update_tenant_role", K(ret), K(tenant_id),
 | 
			
		||||
                        K(new_status), K(new_switchover_ts), K(old_status), K(cost));
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -457,10 +511,13 @@ int ObAllTenantInfoProxy::update_tenant_switchover_status(
 | 
			
		||||
    int64_t switchover_epoch,
 | 
			
		||||
    const ObTenantSwitchoverStatus &old_status, const ObTenantSwitchoverStatus &status)
 | 
			
		||||
{
 | 
			
		||||
  int64_t begin_time = ObTimeUtility::current_time();
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
 | 
			
		||||
  ObSqlString sql;
 | 
			
		||||
  int64_t affected_rows = 0;
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
 | 
			
		||||
  //update switchover epoch while role change
 | 
			
		||||
  if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id
 | 
			
		||||
    || OB_INVALID_VERSION == switchover_epoch
 | 
			
		||||
@ -471,6 +528,8 @@ int ObAllTenantInfoProxy::update_tenant_switchover_status(
 | 
			
		||||
  } else if (OB_ISNULL(proxy)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("proxy is null", KR(ret), KP(proxy));
 | 
			
		||||
  } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
    LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
  } else if (OB_FAIL(sql.assign_fmt(
 | 
			
		||||
          "update %s set switchover_status = '%s'"
 | 
			
		||||
          "where tenant_id = %lu and switchover_epoch = %ld and switchover_status = '%s'",
 | 
			
		||||
@ -488,6 +547,225 @@ int ObAllTenantInfoProxy::update_tenant_switchover_status(
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int64_t cost = ObTimeUtility::current_time() - begin_time;
 | 
			
		||||
  ROOTSERVICE_EVENT_ADD("tenant_info", "update_tenant_switchover_status", K(ret), K(tenant_id),
 | 
			
		||||
                        K(status), K(switchover_epoch), K(old_status), K(cost));
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObAllTenantInfoProxy::update_tenant_recovery_until_scn(
 | 
			
		||||
    const uint64_t tenant_id,
 | 
			
		||||
    common::ObMySQLTransaction &trans,
 | 
			
		||||
    const int64_t switchover_epoch,
 | 
			
		||||
    const SCN &recovery_until_scn)
 | 
			
		||||
{
 | 
			
		||||
  DEBUG_SYNC(BEFORE_UPDATE_RECOVERY_UNTIL_SCN);
 | 
			
		||||
 | 
			
		||||
  int64_t begin_time = ObTimeUtility::current_time();
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
 | 
			
		||||
  ObSqlString sql;
 | 
			
		||||
  int64_t affected_rows = 0;
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
  ObLSRecoveryStatOperator ls_recovery_operator;
 | 
			
		||||
  ObLSRecoveryStat sys_ls_recovery;
 | 
			
		||||
 | 
			
		||||
  if (!is_user_tenant(tenant_id) || OB_INVALID_VERSION == switchover_epoch) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(switchover_epoch));
 | 
			
		||||
  } else if (OB_UNLIKELY(!recovery_until_scn.is_valid_and_not_min())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("recovery_until_scn invalid", KR(ret), K(recovery_until_scn));
 | 
			
		||||
  } 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 (recovery_until_scn < sys_ls_recovery.get_sync_scn()) {
 | 
			
		||||
    ret = OB_OP_NOT_ALLOW;
 | 
			
		||||
    LOG_WARN("recover before SYS LS sync_scn is not allowed", KR(ret), K(tenant_id), K(recovery_until_scn), K(sys_ls_recovery));
 | 
			
		||||
    LOG_USER_ERROR(OB_OP_NOT_ALLOW, "recover before SYS LS sync_scn is");
 | 
			
		||||
  } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
    LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
  } else if (OB_FAIL(sql.assign_fmt(
 | 
			
		||||
      "update %s set recovery_until_scn = %lu where tenant_id = %lu and sync_scn <= %lu and switchover_epoch = %ld",
 | 
			
		||||
      OB_ALL_TENANT_INFO_TNAME, recovery_until_scn.get_val_for_inner_table_field(), tenant_id,
 | 
			
		||||
      recovery_until_scn.get_val_for_inner_table_field(), switchover_epoch))) {
 | 
			
		||||
    LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(recovery_until_scn), K(sql));
 | 
			
		||||
  } else if (OB_FAIL(trans.write(exec_tenant_id, sql.ptr(), affected_rows))) {
 | 
			
		||||
    LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql));
 | 
			
		||||
  } else if (0 == affected_rows) {
 | 
			
		||||
    ret = OB_OP_NOT_ALLOW;
 | 
			
		||||
    LOG_WARN("state changed, check sync_scn and switchover status", KR(ret), K(tenant_id),
 | 
			
		||||
             K(switchover_epoch), K(recovery_until_scn), K(sql));
 | 
			
		||||
    LOG_USER_ERROR(OB_OP_NOT_ALLOW, "state changed, check sync_scn and switchover status, recover is");
 | 
			
		||||
  } else if (!is_single_row(affected_rows)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int64_t cost = ObTimeUtility::current_time() - begin_time;
 | 
			
		||||
  LOG_INFO("update_recovery_until_scn finish", KR(ret), K(tenant_id), K(sys_ls_recovery),
 | 
			
		||||
                      K(recovery_until_scn), K(affected_rows), K(switchover_epoch), K(sql), K(cost));
 | 
			
		||||
  ROOTSERVICE_EVENT_ADD("tenant_info", "update_recovery_until_scn", K(ret), K(tenant_id),
 | 
			
		||||
                        K(recovery_until_scn), K(affected_rows), K(switchover_epoch), K(sys_ls_recovery));
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObAllTenantInfoProxy::update_tenant_status(
 | 
			
		||||
    const uint64_t tenant_id,
 | 
			
		||||
    ObISQLClient *proxy,
 | 
			
		||||
    const ObTenantRole new_role,
 | 
			
		||||
    const ObTenantSwitchoverStatus &old_status,
 | 
			
		||||
    const ObTenantSwitchoverStatus &new_status,
 | 
			
		||||
    const share::SCN &sync_scn,
 | 
			
		||||
    const share::SCN &replayable_scn,
 | 
			
		||||
    const share::SCN &readable_scn,
 | 
			
		||||
    const share::SCN &recovery_until_scn,
 | 
			
		||||
    const int64_t old_switchover_epoch)
 | 
			
		||||
{
 | 
			
		||||
  int64_t begin_time = ObTimeUtility::current_time();
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
 | 
			
		||||
  ObSqlString sql;
 | 
			
		||||
  int64_t affected_rows = 0;
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
  int64_t new_switchover_epoch = OB_INVALID_VERSION;
 | 
			
		||||
 | 
			
		||||
  if (OB_UNLIKELY(OB_ISNULL(proxy)
 | 
			
		||||
    || !is_user_tenant(tenant_id)
 | 
			
		||||
    || !new_role.is_valid()
 | 
			
		||||
    || !old_status.is_valid()
 | 
			
		||||
    || !new_status.is_valid()
 | 
			
		||||
    || old_status == new_status
 | 
			
		||||
    || !sync_scn.is_valid_and_not_min()
 | 
			
		||||
    || !replayable_scn.is_valid_and_not_min()
 | 
			
		||||
    || !readable_scn.is_valid_and_not_min()
 | 
			
		||||
    || !recovery_until_scn.is_valid_and_not_min()
 | 
			
		||||
    || OB_INVALID_VERSION == old_switchover_epoch)) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("tenant_info is invalid", KR(ret), KP(proxy), K(tenant_id), K(new_role), K(old_status),
 | 
			
		||||
                K(new_status), K(sync_scn), K(replayable_scn), K(readable_scn), K(recovery_until_scn),
 | 
			
		||||
                K(old_switchover_epoch));
 | 
			
		||||
  } else if (OB_FAIL(get_new_switchover_epoch_(old_switchover_epoch, old_status, new_status,
 | 
			
		||||
                                               new_switchover_epoch))) {
 | 
			
		||||
    LOG_WARN("fail to get_new_switchover_epoch_", KR(ret), K(old_switchover_epoch), K(old_status),
 | 
			
		||||
                                                  K(new_status));
 | 
			
		||||
  } else if (OB_UNLIKELY(OB_INVALID_VERSION == new_switchover_epoch)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("new_switchover_ts is invalid", KR(ret), K(new_switchover_epoch),
 | 
			
		||||
             K(old_switchover_epoch), K(old_status), K(new_status));
 | 
			
		||||
  } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
    LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
  } else if (OB_FAIL(sql.assign_fmt(
 | 
			
		||||
                "update %s set tenant_role = '%s', switchover_status = '%s', "
 | 
			
		||||
                "switchover_epoch = %ld, sync_scn = %lu, replayable_scn = %lu, "
 | 
			
		||||
                "readable_scn = %lu, recovery_until_scn = %lu where tenant_id = %lu "
 | 
			
		||||
                "and switchover_status = '%s' and switchover_epoch = %ld "
 | 
			
		||||
                "and readable_scn <= replayable_scn and replayable_scn <= sync_scn and sync_scn <= recovery_until_scn "
 | 
			
		||||
                "and sync_scn <= %lu and replayable_scn <= %lu and readable_scn <= %lu ",
 | 
			
		||||
                OB_ALL_TENANT_INFO_TNAME, new_role.to_str(), new_status.to_str(),
 | 
			
		||||
                new_switchover_epoch,
 | 
			
		||||
                sync_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                replayable_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                readable_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                recovery_until_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                tenant_id, old_status.to_str(), old_switchover_epoch,
 | 
			
		||||
                sync_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                replayable_scn.get_val_for_inner_table_field(),
 | 
			
		||||
                readable_scn.get_val_for_inner_table_field()))) {
 | 
			
		||||
    LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(sql));
 | 
			
		||||
  } else if (OB_FAIL(proxy->write(exec_tenant_id, sql.ptr(), affected_rows))) {
 | 
			
		||||
    LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql));
 | 
			
		||||
  } else if (0 == affected_rows) {
 | 
			
		||||
    ret = OB_NEED_RETRY;
 | 
			
		||||
    LOG_WARN("switchover may concurrency, need retry", KR(ret), K(old_switchover_epoch), K(sql));
 | 
			
		||||
  } else if (!is_single_row(affected_rows)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ObAllTenantInfo tenant_info;
 | 
			
		||||
  int tmp_ret = OB_SUCCESS;
 | 
			
		||||
  if (OB_SUCCESS != (tmp_ret = tenant_info.init(tenant_id,
 | 
			
		||||
                                                new_role,
 | 
			
		||||
                                                new_status,
 | 
			
		||||
                                                new_switchover_epoch,
 | 
			
		||||
                                                sync_scn,
 | 
			
		||||
                                                replayable_scn,
 | 
			
		||||
                                                readable_scn,
 | 
			
		||||
                                                recovery_until_scn))) {
 | 
			
		||||
    LOG_WARN("failed to init tenant_info", KR(ret), KR(tmp_ret), K(tenant_id), K(new_role),
 | 
			
		||||
                                           K(new_status), K(new_switchover_epoch), K(sync_scn),
 | 
			
		||||
                                           K(replayable_scn), K(readable_scn), K(recovery_until_scn));
 | 
			
		||||
    ret = OB_SUCC(ret) ? tmp_ret : ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int64_t cost = ObTimeUtility::current_time() - begin_time;
 | 
			
		||||
  ROOTSERVICE_EVENT_ADD("tenant_info", "update_tenant_role", K(ret), K(tenant_id),
 | 
			
		||||
                        K(tenant_info), K(old_status), K(old_switchover_epoch), K(cost));
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObAllTenantInfoProxy::get_new_switchover_epoch_(
 | 
			
		||||
    const int64_t old_switchover_epoch,
 | 
			
		||||
    const ObTenantSwitchoverStatus &old_status,
 | 
			
		||||
    const ObTenantSwitchoverStatus &new_status,
 | 
			
		||||
    int64_t &new_switchover_epoch)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  new_switchover_epoch = OB_INVALID_VERSION;
 | 
			
		||||
 | 
			
		||||
  //update switchover epoch when entering and leaving normal switchover status
 | 
			
		||||
  if (OB_UNLIKELY(OB_INVALID_VERSION == old_switchover_epoch
 | 
			
		||||
    || !old_status.is_valid()
 | 
			
		||||
    || !new_status.is_valid())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("invalid argument", KR(ret), K(old_switchover_epoch), K(old_status), K(new_status));
 | 
			
		||||
  } else if ((share::NORMAL_SWITCHOVER_STATUS == new_status
 | 
			
		||||
             || share::NORMAL_SWITCHOVER_STATUS == old_status) && (old_status != new_status)) {
 | 
			
		||||
    new_switchover_epoch = max(old_switchover_epoch + 1, ObTimeUtility::current_time());
 | 
			
		||||
  } else {
 | 
			
		||||
    new_switchover_epoch = old_switchover_epoch;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObAllTenantInfoProxy::update_tenant_log_mode(
 | 
			
		||||
    const uint64_t tenant_id,
 | 
			
		||||
    ObISQLClient *proxy,
 | 
			
		||||
    const ObArchiveMode &old_log_mode,
 | 
			
		||||
    const ObArchiveMode &new_log_mode)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id);
 | 
			
		||||
  ObSqlString sql;
 | 
			
		||||
  int64_t affected_rows = 0;
 | 
			
		||||
  ObTimeoutCtx ctx;
 | 
			
		||||
 | 
			
		||||
  if (OB_UNLIKELY(!is_user_tenant(tenant_id)
 | 
			
		||||
                  || !old_log_mode.is_valid()
 | 
			
		||||
                  || !new_log_mode.is_valid())) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(old_log_mode), K(new_log_mode));
 | 
			
		||||
  } else if (OB_FAIL(rootserver::ObRootUtils::get_rs_default_timeout_ctx(ctx))) {
 | 
			
		||||
    LOG_WARN("fail to get timeout ctx", KR(ret), K(ctx));
 | 
			
		||||
  } else if (OB_FAIL(sql.assign_fmt(
 | 
			
		||||
             "update %s set log_mode = '%s' where tenant_id = %lu and switchover_status = '%s' "
 | 
			
		||||
             "and log_mode = '%s' ",
 | 
			
		||||
             OB_ALL_TENANT_INFO_TNAME, new_log_mode.to_str(), tenant_id,
 | 
			
		||||
             NORMAL_SWITCHOVER_STATUS.to_str(), old_log_mode.to_str()))) {
 | 
			
		||||
    LOG_WARN("failed to assign sql", KR(ret), K(tenant_id), K(old_log_mode), K(new_log_mode), K(sql));
 | 
			
		||||
  } else if (OB_FAIL(proxy->write(exec_tenant_id, sql.ptr(), affected_rows))) {
 | 
			
		||||
    LOG_WARN("failed to execute sql", KR(ret), K(exec_tenant_id), K(sql));
 | 
			
		||||
  } else if (0 == affected_rows) {
 | 
			
		||||
    ret = OB_NEED_RETRY;
 | 
			
		||||
    LOG_WARN("may concurrency with switchover, need retry", KR(ret), K(tenant_id), K(sql));
 | 
			
		||||
  } else if (!is_single_row(affected_rows)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("expect updating one row", KR(ret), K(affected_rows), K(sql));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user