oceanbase
696 строк · 24.0 Кб
1/**
2* Copyright (c) 2021 OceanBase
3* OceanBase CE is licensed under Mulan PubL v2.
4* You can use this software according to the terms and conditions of the Mulan PubL v2.
5* You may obtain a copy of Mulan PubL v2 at:
6* http://license.coscl.org.cn/MulanPubL-2.0
7* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10* See the Mulan PubL v2 for more details.
11*/
12
13#define USING_LOG_PREFIX RS14
15#include "lib/trace/ob_trace_event.h"16#include "share/rc/ob_tenant_base.h" // MTL_ID17#include "share/scn.h"//SCN18#include "share/ob_all_server_tracer.h" // ObAllServerTracer19#include "observer/ob_server_struct.h" // GCTX20#include "rootserver/ob_tenant_info_loader.h"21#include "rootserver/ob_rs_async_rpc_proxy.h"22#include "logservice/ob_log_service.h" // ObLogService23#include "storage/tx/ob_ts_mgr.h" // OB_TS_MGR24
25namespace oceanbase26{
27using namespace share;28using namespace common;29namespace rootserver30{
31int ObTenantInfoLoader::mtl_init(ObTenantInfoLoader *&ka)32{
33int ret = OB_SUCCESS;34
35if (OB_ISNULL(ka)) {36ret = OB_ERR_UNEXPECTED;37LOG_WARN("ka is null", KR(ret));38} else if (OB_FAIL(ka->init())) {39LOG_WARN("failed to init", KR(ret), KP(ka));40}41
42return ret;43}
44
45int ObTenantInfoLoader::init()46{
47int ret = OB_SUCCESS;48lib::ThreadPool::set_run_wrapper(MTL_CTX());49const int64_t thread_cnt = 1;50
51if (IS_INIT) {52ret = OB_INIT_TWICE;53LOG_WARN("init twice", KR(ret));54} else {55sql_proxy_ = GCTX.sql_proxy_;56tenant_id_ = MTL_ID();57tenant_info_cache_.reset();58ATOMIC_STORE(&broadcast_times_, 0);59ATOMIC_STORE(&rpc_update_times_, 0);60ATOMIC_STORE(&sql_update_times_, 0);61ATOMIC_STORE(&last_rpc_update_time_us_, OB_INVALID_TIMESTAMP);62
63if (!is_user_tenant(tenant_id_)) {64} else if (OB_ISNULL(GCTX.sql_proxy_)) {65ret = OB_ERR_UNEXPECTED;66LOG_WARN("sql proxy is null", KR(ret));67} else if (OB_FAIL(create(thread_cnt, "TenantInf"))) {68LOG_WARN("failed to create tenant info loader thread", KR(ret), K(thread_cnt));69}70}71if (OB_SUCC(ret)) {72is_inited_ = true;73}74return ret;75}
76
77void ObTenantInfoLoader::destroy()78{
79LOG_INFO("tenant info loader destory", KPC(this));80stop();81wait();82is_inited_ = false;83tenant_id_ = OB_INVALID_TENANT_ID;84tenant_info_cache_.reset();85sql_proxy_ = NULL;86ATOMIC_STORE(&broadcast_times_, 0);87ATOMIC_STORE(&rpc_update_times_, 0);88ATOMIC_STORE(&sql_update_times_, 0);89ATOMIC_STORE(&last_rpc_update_time_us_, OB_INVALID_TIMESTAMP);90}
91
92int ObTenantInfoLoader::start()93{
94int ret = OB_SUCCESS;95if (IS_NOT_INIT) {96ret = OB_NOT_INIT;97LOG_WARN("not init", KR(ret));98} else if (!is_user_tenant(tenant_id_)) {99//meta and sys tenant is primary100MTL_SET_TENANT_ROLE_CACHE(ObTenantRole::PRIMARY_TENANT);101LOG_INFO("not user tenant no need load", K(tenant_id_));102} else if (OB_FAIL(logical_start())) {103LOG_WARN("failed to start", KR(ret));104} else {105LOG_INFO("tenant info loader start", KPC(this));106}107return ret;108}
109
110void ObTenantInfoLoader::stop()111{
112logical_stop();113}
114void ObTenantInfoLoader::wait()115{
116logical_wait();117}
118
119void ObTenantInfoLoader::wakeup()120{
121int ret = OB_SUCCESS;122if (IS_NOT_INIT) {123ret = OB_NOT_INIT;124LOG_TRACE("not init", KR(ret));125} else {126ObThreadCondGuard guard(get_cond());127get_cond().broadcast();128}129}
130
131void ObTenantInfoLoader::run2()132{
133int ret = OB_SUCCESS;134LOG_INFO("tenant info loader run", KPC(this));135if (IS_NOT_INIT) {136ret = OB_NOT_INIT;137LOG_WARN("not init", KR(ret));138} else {139ObThreadCondGuard guard(get_cond());140int64_t last_dump_time_us = ObTimeUtility::current_time();141
142while (!stop_) {143const int64_t start_time_us = ObTimeUtility::current_time();144share::ObAllTenantInfo tenant_info;145bool content_changed = false;146bool is_sys_ls_leader = is_sys_ls_leader_();147const int64_t refresh_time_interval_us = act_as_standby_() && is_sys_ls_leader ?148ObTenantRoleTransitionConstants::STS_TENANT_INFO_REFRESH_TIME_US :149ObTenantRoleTransitionConstants::DEFAULT_TENANT_INFO_REFRESH_TIME_US;150
151if (need_refresh(refresh_time_interval_us)152&& OB_FAIL(tenant_info_cache_.refresh_tenant_info(tenant_id_, sql_proxy_, content_changed))) {153LOG_WARN("failed to update tenant info", KR(ret), K_(tenant_id), KP(sql_proxy_));154}155
156const int64_t now_us = ObTimeUtility::current_time();157const int64_t sql_update_cost_time = now_us - start_time_us;158if (OB_FAIL(ret)) {159} else if (content_changed && is_sys_ls_leader) {160(void)ATOMIC_AAF(&sql_update_times_, 1);161(void)broadcast_tenant_info_content_();162}163const int64_t broadcast_cost_time = ObTimeUtility::current_time() - now_us;164
165const int64_t end_time_us = ObTimeUtility::current_time();166const int64_t cost_time_us = end_time_us - start_time_us;167if (content_changed) {168(void)dump_tenant_info_(sql_update_cost_time, is_sys_ls_leader, broadcast_cost_time, end_time_us, last_dump_time_us);169}170const int64_t idle_time = max(10 * 1000, refresh_time_interval_us - cost_time_us);171//At least sleep 10ms, allowing the thread to release the lock172if (!stop_) {173get_cond().wait_us(idle_time);174}175}//end while176}177}
178
179void ObTenantInfoLoader::dump_tenant_info_(180const int64_t sql_update_cost_time,181const bool is_sys_ls_leader,182const int64_t broadcast_cost_time,183const int64_t end_time_us,184int64_t &last_dump_time_us)185{
186int ret = OB_SUCCESS;187if (IS_NOT_INIT) {188ret = OB_NOT_INIT;189LOG_WARN("not init", KR(ret));190} else if (0 >= last_dump_time_us || end_time_us < last_dump_time_us) {191ret = OB_INVALID_ARGUMENT;192LOG_WARN("invalid argument", KR(ret), K(last_dump_time_us), K(end_time_us));193} else {194const int64_t dump_interval_s = (end_time_us - last_dump_time_us) / 1000000; // 1s unit;195if (dump_tenant_info_cache_update_action_interval_.reach() && 1 <= dump_interval_s) {196const uint64_t broadcast_times = ATOMIC_LOAD(&broadcast_times_);197const uint64_t rpc_update_times = ATOMIC_LOAD(&rpc_update_times_);198const uint64_t sql_update_times = ATOMIC_LOAD(&sql_update_times_);199const int64_t broadcast_per_sec = broadcast_times / dump_interval_s; // per second200const int64_t rpc_update_per_sec = rpc_update_times / dump_interval_s; // per second201const int64_t sql_update_per_sec = sql_update_times / dump_interval_s; // per second202if (OB_NOT_NULL(THE_TRACE)) {203THE_TRACE->reset();204}205NG_TRACE_EXT(ob_tenant_info_loader, OB_ID(tenant_id), tenant_id_,206OB_ID(is_sys_ls_leader), is_sys_ls_leader,207OB_ID(broadcast_cost_time), broadcast_cost_time,208OB_ID(broadcast_times), broadcast_times_,209OB_ID(broadcast_per_sec), broadcast_per_sec,210OB_ID(rpc_update_times), rpc_update_times,211OB_ID(rpc_update_per_sec), rpc_update_per_sec,212OB_ID(last_rpc_update_time_us), last_rpc_update_time_us_,213OB_ID(sql_update_cost_time), sql_update_cost_time,214OB_ID(sql_update_times), sql_update_times,215OB_ID(tenant_info_cache), tenant_info_cache_, OB_ID(is_inited), is_inited_);216FORCE_PRINT_TRACE(THE_TRACE, "[dump tenant_info_loader]");217ATOMIC_STORE(&broadcast_times_, 0);218ATOMIC_STORE(&rpc_update_times_, 0);219ATOMIC_STORE(&sql_update_times_, 0);220last_dump_time_us = ObTimeUtility::current_time();221}222}223}
224
225bool ObTenantInfoLoader::need_refresh(const int64_t refresh_time_interval_us)226{
227int ret = OB_SUCCESS;228ObAllTenantInfo tenant_info;229bool need_refresh = true;230const int64_t now = ObTimeUtility::current_time();231int64_t last_sql_update_time = OB_INVALID_TIMESTAMP;232int64_t ora_rowscn = 0;233
234if (ObTenantRoleTransitionConstants::DEFAULT_TENANT_INFO_REFRESH_TIME_US < refresh_time_interval_us) {235LOG_WARN("unexpected refresh_time_interval_us");236need_refresh = true;237} else if (OB_FAIL(tenant_info_cache_.get_tenant_info(tenant_info, last_sql_update_time, ora_rowscn))) {238LOG_WARN("failed to get tenant info", KR(ret));239} else if (now - last_sql_update_time < refresh_time_interval_us) {240need_refresh = false;241}242
243return need_refresh;244}
245
246bool ObTenantInfoLoader::is_sys_ls_leader_()247{
248int ret = OB_SUCCESS;249bool is_sys_ls_leader = false;250logservice::ObLogService *log_svr = MTL(logservice::ObLogService*);251int64_t proposal_id = 0;252common::ObRole role;253
254if (IS_NOT_INIT) {255ret = OB_NOT_INIT;256LOG_WARN("not init", KR(ret));257} else if (OB_ISNULL(log_svr)) {258ret = OB_ERR_UNEXPECTED;259LOG_WARN("mtl pointer is null", KR(ret), KP(log_svr));260} else if (OB_FAIL(log_svr->get_palf_role(share::SYS_LS, role, proposal_id))) {261LOG_WARN("failed to get palf role", KR(ret));262} else if (is_strong_leader(role)) {263is_sys_ls_leader = true;264}265
266return is_sys_ls_leader;267}
268
269int ObTenantInfoLoader::get_max_ls_id(uint64_t &tenant_id, ObLSID &max_ls_id)270{
271int ret = OB_SUCCESS;272ObAllTenantInfo tenant_info;273const uint64_t mtl_tenant_id = MTL_ID();274tenant_id = OB_INVALID_TENANT_ID;275max_ls_id.reset();276if (OB_SYS_TENANT_ID == mtl_tenant_id || is_meta_tenant(mtl_tenant_id)) {277tenant_id = mtl_tenant_id;278max_ls_id = ObLSID::SYS_LS_ID;279} else if (OB_FAIL(get_tenant_info(tenant_info))) {280LOG_WARN("get_tenant_info failed", KR(ret));281} else {282tenant_id = tenant_info.get_tenant_id();283max_ls_id = tenant_info.get_max_ls_id();284}285return ret;286}
287
288bool ObTenantInfoLoader::act_as_standby_()289{
290int ret = OB_SUCCESS;291bool act_as_standby = true;292ObAllTenantInfo tenant_info;293
294if (IS_NOT_INIT) {295ret = OB_NOT_INIT;296LOG_WARN("not init", KR(ret));297} else if (OB_FAIL(get_tenant_info(tenant_info))) {298LOG_WARN("failed to get tenant_info", KR(ret));299} else if (tenant_info.is_primary() && tenant_info.is_normal_status()) {300act_as_standby = false;301}302
303return act_as_standby;304}
305
306void ObTenantInfoLoader::broadcast_tenant_info_content_()307{
308int ret = OB_SUCCESS;309const int64_t DEFAULT_TIMEOUT_US = 200 * 1000; // 200ms310const int64_t begin_time = ObTimeUtility::current_time();311ObArray<int> return_code_array;312share::ObAllTenantInfo tenant_info;313int64_t last_sql_update_time = OB_INVALID_TIMESTAMP;314int64_t ora_rowscn = 0;315
316if (IS_NOT_INIT) {317ret = OB_NOT_INIT;318LOG_WARN("not init", KR(ret));319} else if (OB_ISNULL(GCTX.srv_rpc_proxy_)) {320ret = OB_ERR_UNEXPECTED;321LOG_WARN("pointer is null", KR(ret), KP(GCTX.srv_rpc_proxy_));322} else {323ObUpdateTenantInfoCacheProxy proxy(324*GCTX.srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::update_tenant_info_cache);325int64_t rpc_count = 0;326
327if (OB_FAIL(tenant_info_cache_.get_tenant_info(tenant_info, last_sql_update_time, ora_rowscn))) {328LOG_WARN("failed to get tenant info", KR(ret));329} else if (OB_FAIL(share::ObAllServerTracer::get_instance().for_each_server_info(330[&rpc_count, &tenant_info, &proxy, ora_rowscn](const share::ObServerInfoInTable &server_info) -> int {331int ret = OB_SUCCESS;332obrpc::ObUpdateTenantInfoCacheArg arg;333if (!server_info.is_valid()) {334LOG_WARN("skip invalid server_info", KR(ret), K(server_info));335} else if (!server_info.is_alive()) {336//not send to alive337} else if (OB_FAIL(arg.init(tenant_info.get_tenant_id(), tenant_info, ora_rowscn))) {338LOG_WARN("failed to init arg", KR(ret), K(tenant_info), K(ora_rowscn));339// use meta rpc process thread340} else if (OB_FAIL(proxy.call(server_info.get_server(), DEFAULT_TIMEOUT_US, gen_meta_tenant_id(tenant_info.get_tenant_id()), arg))) {341LOG_WARN("failed to send rpc", KR(ret), K(server_info), K(tenant_info), K(arg));342} else {343rpc_count++;344}345
346return ret;347}))) {348LOG_WARN("for each server_info failed", KR(ret));349}350
351int tmp_ret = OB_SUCCESS;352if (OB_TMP_FAIL(proxy.wait_all(return_code_array))) {353LOG_WARN("wait all batch result failed", KR(ret), KR(tmp_ret));354ret = OB_SUCCESS == ret ? tmp_ret : ret;355} else if (OB_FAIL(ret)) {356} else if (OB_FAIL(proxy.check_return_cnt(return_code_array.count()))) {357LOG_WARN("fail to check return cnt", KR(ret), "return_cnt", return_code_array.count());358} else {359(void)ATOMIC_AAF(&broadcast_times_, 1);360ObUpdateTenantInfoCacheRes res;361for (int64_t i = 0; OB_SUCC(ret) && i < return_code_array.count(); ++i) {362ret = return_code_array.at(i);363const ObAddr &dest = proxy.get_dests().at(i);364if (OB_FAIL(ret)) {365LOG_WARN("send rpc is failed", KR(ret), K(i), K(dest));366} else {367LOG_INFO("refresh tenant info content success", KR(ret), K(i), K(dest));368}369}370}371}372const int64_t cost_time_us = ObTimeUtility::current_time() - begin_time;373const int64_t PRINT_INTERVAL = 3 * 1000 * 1000L;374if (REACH_TIME_INTERVAL(PRINT_INTERVAL)) {375LOG_INFO("broadcast_tenant_info_content_ finished", KR(ret), K_(tenant_id), K(cost_time_us),376K(return_code_array), K_(broadcast_times));377}378return ;379}
380
381int ObTenantInfoLoader::get_valid_sts_after(const int64_t specified_time_us, share::SCN &standby_scn)382{
383int ret = OB_SUCCESS;384standby_scn.set_min();385share::ObAllTenantInfo tenant_info;386int64_t last_sql_update_time = OB_INVALID_TIMESTAMP;387int64_t ora_rowscn = 0;388
389if (IS_NOT_INIT) {390ret = OB_NOT_INIT;391LOG_WARN("not init", KR(ret));392} else if (OB_INVALID_TIMESTAMP == specified_time_us) {393ret = OB_INVALID_ARGUMENT;394LOG_WARN("invalid argument", KR(ret), K(specified_time_us));395} else if (OB_FAIL(tenant_info_cache_.get_tenant_info(tenant_info, last_sql_update_time, ora_rowscn))) {396if (OB_NEED_WAIT == ret) {397LOG_TRACE("tenant info cache is not refreshed, need wait", KR(ret));398} else {399LOG_WARN("failed to get tenant info", KR(ret));400}401} else if (last_sql_update_time <= specified_time_us) {402ret = OB_NEED_WAIT;403LOG_TRACE("tenant info cache is old, need wait", KR(ret), K(last_sql_update_time), K(specified_time_us), K(tenant_info));404wakeup();405} else if (!tenant_info.is_sts_ready()) {406ret = OB_NEED_WAIT;407LOG_TRACE("sts can not work for current tenant status", KR(ret), K(tenant_info));408} else {409standby_scn = tenant_info.get_standby_scn();410}411
412const int64_t PRINT_INTERVAL = 3 * 1000 * 1000L;413if (REACH_TIME_INTERVAL(PRINT_INTERVAL)) {414LOG_INFO("get_valid_sts_after", KR(ret), K(specified_time_us), K(last_sql_update_time), K(tenant_info));415}416
417return ret;418}
419
420int ObTenantInfoLoader::get_readable_scn(share::SCN &readable_scn)421{
422int ret = OB_SUCCESS;423readable_scn.set_min();424
425if (OB_FAIL(OB_TS_MGR.get_gts(MTL_ID(), nullptr, readable_scn))) {426LOG_WARN("failed to get gts as readable_scn", KR(ret));427}428
429return ret;430}
431
432int ObTenantInfoLoader::check_is_standby_normal_status(bool &is_standby_normal_status)433{
434int ret = OB_SUCCESS;435is_standby_normal_status = false;436
437if (OB_SYS_TENANT_ID == MTL_ID() || is_meta_tenant(MTL_ID())) {438is_standby_normal_status = false;439} else {440// user tenant441share::ObAllTenantInfo tenant_info;442if (OB_FAIL(tenant_info_cache_.get_tenant_info(tenant_info))) {443LOG_WARN("failed to get tenant info", KR(ret));444} else {445is_standby_normal_status = tenant_info.is_standby() && tenant_info.is_normal_status();446}447}448return ret;449}
450
451int ObTenantInfoLoader::check_is_primary_normal_status(bool &is_primary_normal_status)452{
453int ret = OB_SUCCESS;454is_primary_normal_status = false;455
456if (OB_SYS_TENANT_ID == MTL_ID() || is_meta_tenant(MTL_ID())) {457is_primary_normal_status = true;458} else {459// user tenant460share::ObAllTenantInfo tenant_info;461if (OB_FAIL(tenant_info_cache_.get_tenant_info(tenant_info))) {462LOG_WARN("failed to get tenant info", KR(ret));463} else {464is_primary_normal_status = tenant_info.is_primary() && tenant_info.is_normal_status();465}466}467return ret;468}
469
470int ObTenantInfoLoader::get_replayable_scn(share::SCN &replayable_scn)471{
472int ret = OB_SUCCESS;473replayable_scn.set_min();474
475if (OB_SYS_TENANT_ID == MTL_ID() || is_meta_tenant(MTL_ID())) {476// there isn't replayable_scn for SYS/META tenant477ret = OB_ERR_UNEXPECTED;478LOG_ERROR("there isn't replayable_scn for SYS/META tenant", KR(ret));479} else {480// user tenant481share::ObAllTenantInfo tenant_info;482if (OB_FAIL(tenant_info_cache_.get_tenant_info(tenant_info))) {483LOG_WARN("failed to get tenant info", KR(ret));484} else {485replayable_scn = tenant_info.get_replayable_scn();486}487}488return ret;489}
490
491int ObTenantInfoLoader::get_sync_scn(share::SCN &sync_scn)492{
493int ret = OB_SUCCESS;494share::ObAllTenantInfo tenant_info;495sync_scn.set_invalid();496if (OB_FAIL(get_tenant_info(tenant_info))) {497LOG_WARN("failed to get tenant info", KR(ret));498} else {499sync_scn = tenant_info.get_sync_scn();500}501return ret;502}
503
504int ObTenantInfoLoader::get_recovery_until_scn(share::SCN &recovery_until_scn)505{
506int ret = OB_SUCCESS;507share::ObAllTenantInfo tenant_info;508recovery_until_scn.set_invalid();509if (OB_FAIL(get_tenant_info(tenant_info))) {510LOG_WARN("failed to get tenant info", KR(ret));511} else {512recovery_until_scn = tenant_info.get_recovery_until_scn();513}514return ret;515}
516
517int ObTenantInfoLoader::get_tenant_info(share::ObAllTenantInfo &tenant_info)518{
519int ret = OB_SUCCESS;520tenant_info.reset();521
522if (OB_SYS_TENANT_ID == MTL_ID() || is_meta_tenant(MTL_ID())) {523// there isn't tenant info for SYS/META tenant524ret = OB_ERR_UNEXPECTED;525LOG_ERROR("there isn't tenant info for SYS/META tenant", KR(ret));526} else {527// user tenant528if (OB_FAIL(tenant_info_cache_.get_tenant_info(tenant_info))) {529LOG_WARN("failed to get tenant info", KR(ret));530}531}532
533return ret;534}
535
536int ObTenantInfoLoader::refresh_tenant_info()537{
538int ret = OB_SUCCESS;539bool content_changed = false;540if (IS_NOT_INIT) {541ret = OB_NOT_INIT;542LOG_WARN("not init", KR(ret));543} else if (OB_FAIL(tenant_info_cache_.refresh_tenant_info(tenant_id_, sql_proxy_, content_changed))) {544LOG_WARN("failed to refresh_tenant_info", KR(ret), K_(tenant_id), KP(sql_proxy_));545}546return ret;547}
548
549int ObTenantInfoLoader::update_tenant_info_cache(const int64_t new_ora_rowscn, const ObAllTenantInfo &new_tenant_info)550{
551int ret = OB_SUCCESS;552bool refreshed = false;553if (IS_NOT_INIT) {554ret = OB_NOT_INIT;555LOG_WARN("not init", KR(ret));556} else if (OB_FAIL(tenant_info_cache_.update_tenant_info_cache(new_ora_rowscn, new_tenant_info, refreshed))) {557LOG_WARN("failed to update_tenant_info_cache", KR(ret), K(new_ora_rowscn), K(new_tenant_info));558} else if (refreshed) {559(void)ATOMIC_AAF(&rpc_update_times_, 1);560(void)ATOMIC_STORE(&last_rpc_update_time_us_, ObTimeUtility::current_time());561}562return ret;563}
564
565DEFINE_TO_YSON_KV(ObAllTenantInfoCache,566OB_ID(tenant_info), tenant_info_,567OB_ID(last_sql_update_time), last_sql_update_time_,568OB_ID(ora_rowscn), ora_rowscn_);569
570void ObAllTenantInfoCache::reset()571{
572SpinWLockGuard guard(lock_);573tenant_info_.reset();574last_sql_update_time_ = OB_INVALID_TIMESTAMP;575ora_rowscn_ = 0;576}
577
578int ObAllTenantInfoCache::refresh_tenant_info(const uint64_t tenant_id,579common::ObMySQLProxy *sql_proxy,580bool &content_changed)581{
582int ret = OB_SUCCESS;583ObAllTenantInfo new_tenant_info;584int64_t ora_rowscn = 0;585const int64_t new_refresh_time_us = ObClockGenerator::getClock();586content_changed = false;587if (OB_ISNULL(sql_proxy) || !is_user_tenant(tenant_id)) {588ret = OB_INVALID_ARGUMENT;589LOG_WARN("invalid argument", KR(ret), K(tenant_id), KP(sql_proxy));590} else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id,591sql_proxy, false /* for_update */, ora_rowscn, new_tenant_info))) {592LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id));593} else if (INT64_MAX == ora_rowscn || 0 == ora_rowscn) {594ret = OB_ERR_UNEXPECTED;595LOG_ERROR("invalid ora_rowscn", KR(ret), K(ora_rowscn), K(tenant_id), K(new_tenant_info), K(lbt()));596} else {597/**598* Only need to refer to tenant role, no need to refer to switchover status.
599* tenant_role is primary in <primary, normal switchoverstatus> or <primary, prep switching_to_standby switchover_status>.
600* When switch to standby starts, it will change to <standby, switch to standby>.
601* During the switch to standby process, some LS may be in RO state. GTS & STS may not work.
602* This also ensures the consistency of tenant_role cache and the tenant role field in all_tenant_info
603*/
604SpinWLockGuard guard(lock_);605if (ora_rowscn >= ora_rowscn_) {606if (ora_rowscn > ora_rowscn_) {607MTL_SET_TENANT_ROLE_CACHE(new_tenant_info.get_tenant_role().value());608(void)tenant_info_.assign(new_tenant_info);609ora_rowscn_ = ora_rowscn;610content_changed = true;611}612// In order to provide sts an accurate time of tenant info refresh time, it is necessary to613// update last_sql_update_time_ after sql refresh614last_sql_update_time_ = new_refresh_time_us;615} else {616ret = OB_EAGAIN;617LOG_WARN("refresh tenant info conflict", KR(ret), K(new_tenant_info), K(new_refresh_time_us),618K(tenant_id), K(tenant_info_), K(last_sql_update_time_), K(ora_rowscn_), K(ora_rowscn));619}620}621
622if (dump_tenant_info_interval_.reach()) {623LOG_INFO("refresh tenant info", KR(ret), K(new_tenant_info), K(new_refresh_time_us),624K(tenant_id), K(tenant_info_), K(last_sql_update_time_), K(ora_rowscn_));625}626
627return ret;628}
629
630int ObAllTenantInfoCache::update_tenant_info_cache(631const int64_t new_ora_rowscn,632const ObAllTenantInfo &new_tenant_info,633bool &refreshed)634{
635int ret = OB_SUCCESS;636refreshed = false;637if (!new_tenant_info.is_valid() || 0 == new_ora_rowscn || INT64_MAX == new_ora_rowscn) {638ret = OB_INVALID_ARGUMENT;639LOG_WARN("invalid argument", KR(ret), K(new_tenant_info), K(new_ora_rowscn));640} else {641SpinWLockGuard guard(lock_);642if (!tenant_info_.is_valid() || 0 == ora_rowscn_) {643ret = OB_EAGAIN;644LOG_WARN("my tenant_info is invalid, don't refresh", KR(ret), K_(tenant_info), K_(ora_rowscn));645} else if (new_ora_rowscn > ora_rowscn_) {646MTL_SET_TENANT_ROLE_CACHE(new_tenant_info.get_tenant_role().value());647(void)tenant_info_.assign(new_tenant_info);648ora_rowscn_ = new_ora_rowscn;649refreshed = true;650LOG_TRACE("refresh_tenant_info_content", K(new_tenant_info), K(new_ora_rowscn), K(tenant_info_), K(ora_rowscn_));651}652}653
654return ret;655}
656
657int ObAllTenantInfoCache::get_tenant_info(658share::ObAllTenantInfo &tenant_info,659int64_t &last_sql_update_time,660int64_t &ora_rowscn)661{
662int ret = OB_SUCCESS;663tenant_info.reset();664last_sql_update_time = OB_INVALID_TIMESTAMP;665ora_rowscn = 0;666SpinRLockGuard guard(lock_);667
668if (!tenant_info_.is_valid() || OB_INVALID_TIMESTAMP == last_sql_update_time_ || 0 == ora_rowscn_) {669ret = OB_NEED_WAIT;670const int64_t PRINT_INTERVAL = 1 * 1000 * 1000L;671if (REACH_TIME_INTERVAL(PRINT_INTERVAL)) {672LOG_WARN("tenant info is invalid, need wait", KR(ret), K(last_sql_update_time_), K(tenant_info_), K(ora_rowscn_));673}674} else {675(void)tenant_info.assign(tenant_info_);676last_sql_update_time = last_sql_update_time_;677ora_rowscn = ora_rowscn_;678}679return ret;680}
681
682int ObAllTenantInfoCache::get_tenant_info(share::ObAllTenantInfo &tenant_info)683{
684int ret = OB_SUCCESS;685tenant_info.reset();686int64_t last_sql_update_time = OB_INVALID_TIMESTAMP;687int64_t ora_rowscn = 0;688
689if (OB_FAIL(get_tenant_info(tenant_info, last_sql_update_time, ora_rowscn))) {690LOG_WARN("failed to get tenant info", KR(ret));691}692return ret;693}
694
695}
696}
697