diff --git a/src/logservice/ob_garbage_collector.cpp b/src/logservice/ob_garbage_collector.cpp index 1db3c67a64..4b0954a37a 100644 --- a/src/logservice/ob_garbage_collector.cpp +++ b/src/logservice/ob_garbage_collector.cpp @@ -355,7 +355,7 @@ void ObGCHandler::execute_pre_gc_process(ObGarbageCollector::LSStatus &ls_status } } -int ObGCHandler::check_ls_can_offline() +int ObGCHandler::check_ls_can_offline(const share::ObLSStatus &ls_status) { int ret = OB_SUCCESS; if (IS_NOT_INIT) { @@ -370,9 +370,35 @@ int ObGCHandler::check_ls_can_offline() } else if (!is_valid_ls_gc_state(gc_state)) { ret = OB_STATE_NOT_MATCH; CLOG_LOG(WARN, "ls check gc state invalid", K(ls_id), K(gc_state)); - } else if (is_wait_offline_finished_(gc_state)) { + } else if (is_ls_offline_finished_(gc_state)) { CLOG_LOG(INFO, "ls check_ls_can_offline success", K(ls_id), K(gc_state)); + } else if (is_ls_blocked_state_(gc_state)) { + share::ObLSStatus current_ls_status = ls_status; + ObGarbageCollector::LSStatus ls_gc_status = ObGarbageCollector::LSStatus::LS_INVALID_STATUS; + if (ls_is_empty_status(ls_status)) { + // rpc from old version, need get real ls status from table + ObGarbageCollector *gc_service = MTL(logservice::ObGarbageCollector *); + const ObLSID &id = ls_->get_ls_id(); + if (NULL == gc_service) { + CLOG_LOG(WARN, "gc_service is null", K(ret)); + } else if (OB_FAIL(gc_service->get_ls_status_from_table(id, current_ls_status))) { + CLOG_LOG(WARN, "failed to get ls status from table", K(ret), K(id)); + } + } + if (ls_is_dropping_status(current_ls_status)) { + ls_gc_status = ObGarbageCollector::LSStatus::LS_DROPPING; + } else if (ls_is_tenant_dropping_status(current_ls_status)) { + ls_gc_status = ObGarbageCollector::LSStatus::LS_TENANT_DROPPING; + } + // invalid ls_gc_status will return false, ret will be rewritten as OB_EAGAIN + if (is_tablet_clear_(ls_gc_status)) { + CLOG_LOG(INFO, "ls check_ls_can_offline success", K(ls_id), K(gc_state)); + } else { + ret = OB_EAGAIN; + CLOG_LOG(WARN, "ls check_ls_can_offline need retry", K(ls_id), K(gc_state)); + } } else { + // block log not flushed ret = OB_EAGAIN; CLOG_LOG(WARN, "ls check_ls_can_offline need retry", K(ls_id), K(gc_state)); } @@ -495,11 +521,6 @@ bool ObGCHandler::is_ls_wait_gc_state_(const LSGCState &state) return LSGCState::WAIT_GC == state; } -bool ObGCHandler::is_wait_offline_finished_(const LSGCState &state) -{ - return LSGCState::WAIT_OFFLINE <= state; -} - bool ObGCHandler::is_ls_blocked_finished_(const LSGCState &state) { return LSGCState::LS_BLOCKED <= state; @@ -536,9 +557,10 @@ int ObGCHandler::get_gts_(const int64_t timeout_us, SCN >s_scn) return ret; } -void ObGCHandler::try_check_and_set_tablet_clear_(const ObGarbageCollector::LSStatus &ls_status) +bool ObGCHandler::is_tablet_clear_(const ObGarbageCollector::LSStatus &ls_status) { int ret = OB_SUCCESS; + bool bool_ret = false; ObLSID ls_id = ls_->get_ls_id(); if (ObGarbageCollector::is_ls_dropping_ls_status(ls_status)) { //TODO: transfer完成前先统一检查事务结束 @@ -551,12 +573,12 @@ void ObGCHandler::try_check_and_set_tablet_clear_(const ObGarbageCollector::LSSt } else { CLOG_LOG(WARN, "check_all_tx_clean_up failed", K(ls_id), K(ret)); } - } else if (OB_FAIL(ls_->set_gc_state(LSGCState::WAIT_OFFLINE))) { - CLOG_LOG(WARN, "set_gc_state failed", K(ls_id), K(ret)); } else { - CLOG_LOG(INFO, "try_check_and_set_tablet_clear_ success", K(ls_id), K(ls_status)); + bool_ret = true; + CLOG_LOG(INFO, "tablet is clear", K(ls_id), K(ls_status), K(bool_ret)); } } else if (ObGarbageCollector::is_tenant_dropping_ls_status(ls_status)) { + // tenant dropping only check transaction clean if (OB_FAIL(ls_->check_all_tx_clean_up())) { if (OB_EAGAIN == ret) { CLOG_LOG(INFO, "check_all_tx_clean_up need retry", K(ls_id), K(ret)); @@ -566,14 +588,14 @@ void ObGCHandler::try_check_and_set_tablet_clear_(const ObGarbageCollector::LSSt } else { CLOG_LOG(WARN, "check_all_tx_clean_up failed", K(ls_id), K(ret)); } - } else if (OB_FAIL(ls_->set_gc_state(LSGCState::WAIT_OFFLINE))) { - CLOG_LOG(WARN, "set_gc_state failed", K(ls_id), K(ret)); } else { - CLOG_LOG(INFO, "try_check_and_set_tablet_clear_ success", K(ls_id), K(ls_status)); + bool_ret = true; + CLOG_LOG(INFO, "tablet is clear", K(ls_id), K(ls_status)); } } else { - CLOG_LOG(INFO, "try_check_and_set_tablet_clear_ invalid ls status", K(ls_id), K(ls_status)); + CLOG_LOG(WARN, "invalid ls status", K(ls_id), K(ls_status)); } + return bool_ret; } void ObGCHandler::try_check_and_set_wait_gc_(ObGarbageCollector::LSStatus &ls_status) @@ -800,15 +822,16 @@ void ObGCHandler::handle_gc_ls_dropping_(const ObGarbageCollector::LSStatus &ls_ CLOG_LOG(WARN, "get_gc_state failed", K(ls_id), K(gc_state)); } else if (!is_valid_ls_gc_state(gc_state)) { CLOG_LOG(WARN, "ls check gc state invalid", K(ls_id), K(gc_state)); - } else if (is_wait_offline_finished_(gc_state)) { + } else if (is_ls_offline_finished_(gc_state)) { CLOG_LOG(INFO, "handle_gc_ls_dropping already finished", K(ls_id), K(gc_state)); } else if (is_ls_blocked_state_(gc_state)) { - (void)try_check_and_set_tablet_clear_(ls_status); + // trigger kill all tx + (void)is_tablet_clear_(ls_status); } else { (void)submit_log_(ObGCLSLOGType::BLOCK_TABLET_TRANSFER_IN); - (void)try_check_and_set_tablet_clear_(ls_status); + (void)is_tablet_clear_(ls_status); } - CLOG_LOG(INFO, "ls handle_gc_ls_dropping_ finished", K(ls_id), K(role)); + CLOG_LOG(INFO, "ls handle_gc_ls_dropping_ finished", K(ls_id), K(role), K(gc_state)); } } @@ -831,8 +854,8 @@ void ObGCHandler::handle_gc_ls_offline_(ObGarbageCollector::LSStatus &ls_status) } else if (!is_valid_ls_gc_state(gc_state)) { ret = OB_STATE_NOT_MATCH; CLOG_LOG(WARN, "ls check gc state invalid", K(ls_id), K(gc_state)); - } else if (!is_wait_offline_finished_(gc_state)) { - CLOG_LOG(INFO, "ls not ready for offline", K(ls_id), K(gc_state)); + } else if (!is_ls_blocked_finished_(gc_state)) { + CLOG_LOG(WARN, "ls not ready for offline", K(ls_id), K(gc_state)); } else if (is_ls_wait_gc_state_(gc_state)) { ls_status = ObGarbageCollector::LSStatus::LS_NEED_DELETE_ENTRY; CLOG_LOG(INFO, "handle_gc_ls_offline need delete entry", K(ls_id), K(gc_state)); @@ -842,7 +865,7 @@ void ObGCHandler::handle_gc_ls_offline_(ObGarbageCollector::LSStatus &ls_status) (void)submit_log_(ObGCLSLOGType::OFFLINE_LS); (void)try_check_and_set_wait_gc_(ls_status); } - CLOG_LOG(INFO, "ls handle_gc_ls_offline finished", K(ls_id), K(role)); + CLOG_LOG(INFO, "ls handle_gc_ls_offline finished", K(ls_id), K(role), K(gc_state)); } } @@ -985,6 +1008,24 @@ void ObGarbageCollector::run1() } } +int ObGarbageCollector::get_ls_status_from_table(const ObLSID &ls_id, + share::ObLSStatus &ls_status) +{ + int ret = OB_SUCCESS; + const int64_t tenant_id = MTL_ID(); + ObLSStatusOperator ls_op; + ObLSStatusInfo status_info; + // sys tenant should always return LS_NORMAL + if (OB_SYS_TENANT_ID == tenant_id) { + ls_status = OB_LS_NORMAL; + } else if (OB_FAIL(ls_op.get_ls_status_info(tenant_id, ls_id, status_info, *sql_proxy_))) { + CLOG_LOG(INFO, "failed to get ls status info from table", K(ret), K(tenant_id), K(ls_id)); + } else { + ls_status = status_info.status_; + } + return ret; +} + bool ObGarbageCollector::is_ls_dropping_ls_status(const LSStatus &status) { return LSStatus::LS_DROPPING == status; @@ -1180,15 +1221,12 @@ int ObGarbageCollector::gc_check_ls_status_(const ObLSID &id, ObString status_str; const int64_t tenant_id = MTL_ID(); ObLSStatusOperator ls_op; - ObLSStatusInfo status_info; + share::ObLSStatus ls_status = OB_LS_NORMAL; GCCandidate candidate; candidate.ls_id_ = id; candidate.ls_status_ = LSStatus::LS_NORMAL; candidate.gc_reason_ = GCReason::INVALID_GC_REASON; - // sys tenant should always return LS_NORMAL - if (OB_SYS_TENANT_ID == tenant_id) { - // do nothing - } else if (OB_FAIL(ls_op.get_ls_status_info(tenant_id, id, status_info, *sql_proxy_))) { + if (OB_FAIL(get_ls_status_from_table(id, ls_status))) { // 对应行被删除则说明可以gc if (OB_ENTRY_NOT_EXIST == ret) { candidate.ls_status_ = LSStatus::LS_NEED_GC; @@ -1209,7 +1247,7 @@ int ObGarbageCollector::gc_check_ls_status_(const ObLSID &id, } } } else { - candidate.set_ls_status(status_info.status_); + candidate.set_ls_status(ls_status); candidate.gc_reason_ = GCReason::INVALID_GC_REASON; } if (OB_SUCCESS == ret) { diff --git a/src/logservice/ob_garbage_collector.h b/src/logservice/ob_garbage_collector.h index 8204845d86..656123e773 100644 --- a/src/logservice/ob_garbage_collector.h +++ b/src/logservice/ob_garbage_collector.h @@ -63,7 +63,7 @@ enum LSGCState INVALID_LS_GC_STATE = 0, NORMAL = 1, LS_BLOCKED = 2, - WAIT_OFFLINE = 3, + WAIT_OFFLINE = 3, //deprecated after version 4.0.0 LS_OFFLINE = 4, WAIT_GC = 5, MAX_LS_GC_STATE = 6, @@ -82,6 +82,7 @@ int gc_state_to_string(const LSGCState gc_state, } else if (gc_state == LS_BLOCKED) { strncpy(str ,"LS_BLOCKED", str_len); } else if (gc_state == WAIT_OFFLINE) { + // only for version 4.0.0 strncpy(str ,"WAIT_OFFLINE", str_len); } else if (gc_state == LS_OFFLINE) { strncpy(str ,"LS_OFFLINE", str_len); @@ -176,6 +177,8 @@ public: public: static bool is_ls_dropping_ls_status(const LSStatus &status); static bool is_tenant_dropping_ls_status(const LSStatus &status); + int get_ls_status_from_table(const share::ObLSID &ls_id, + share::ObLSStatus &ls_status); private: bool is_valid_ls_status_(const LSStatus &status); bool is_need_gc_ls_status_(const LSStatus &status); @@ -222,7 +225,7 @@ public: int init(storage::ObLS *ls); void reset(); void execute_pre_gc_process(ObGarbageCollector::LSStatus &ls_status); - int check_ls_can_offline(); + int check_ls_can_offline(const share::ObLSStatus &ls_status); int gc_check_invalid_member_seq(const int64_t gc_seq, bool &need_gc); static bool is_valid_ls_gc_state(const LSGCState &state); int diagnose(GCDiagnoseInfo &diagnose_info) const; @@ -286,10 +289,9 @@ private: bool is_ls_blocked_state_(const LSGCState &state); bool is_ls_offline_state_(const LSGCState &state); bool is_ls_wait_gc_state_(const LSGCState &state); - bool is_wait_offline_finished_(const LSGCState &state); bool is_ls_blocked_finished_(const LSGCState &state); bool is_ls_offline_finished_(const LSGCState &state); - void try_check_and_set_tablet_clear_(const ObGarbageCollector::LSStatus &ls_status); + bool is_tablet_clear_(const ObGarbageCollector::LSStatus &ls_status); void try_check_and_set_wait_gc_(ObGarbageCollector::LSStatus &ls_status); int get_tenant_readable_scn_(share::SCN &readable_scn); int check_if_tenant_in_archive_(bool &in_archive); diff --git a/src/observer/ob_rpc_processor_simple.cpp b/src/observer/ob_rpc_processor_simple.cpp index bcb7ad6cb0..c0bee93534 100644 --- a/src/observer/ob_rpc_processor_simple.cpp +++ b/src/observer/ob_rpc_processor_simple.cpp @@ -1325,7 +1325,7 @@ int ObRpcCheckLSCanOfflineP::process() } else if (OB_ISNULL(gc_handler = ls->get_gc_handler())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("gc_handler is null", K(ls_id)); - } else if (OB_FAIL(gc_handler->check_ls_can_offline())) { + } else if (OB_FAIL(gc_handler->check_ls_can_offline(arg_.get_ls_status()))) { LOG_WARN("check_ls_can_offline failed", K(ls_id), K(ret)); } else { LOG_INFO("check_ls_can_offline success", K(ls_id)); diff --git a/src/rootserver/ob_primary_ls_service.cpp b/src/rootserver/ob_primary_ls_service.cpp index a11144870d..4f4629494d 100755 --- a/src/rootserver/ob_primary_ls_service.cpp +++ b/src/rootserver/ob_primary_ls_service.cpp @@ -1411,7 +1411,7 @@ int ObTenantLSInfo::do_tenant_drop_ls_(const share::ObLSStatusInfo &status_info, LOG_WARN("failed to update ls status", KR(ret), K(status_info)); } } - if (FAILEDx(check_ls_can_offline_by_rpc_(status_info, can_offline))) { + if (FAILEDx(check_ls_can_offline_by_rpc_(status_info, share::OB_LS_TENANT_DROPPING, can_offline))) { // send rpc to observer LOG_WARN("failed to check ls can offline", KR(ret), K(status_info)); } else if (can_offline) { @@ -1471,7 +1471,7 @@ int ObTenantLSInfo::do_drop_ls_(const share::ObLSStatusInfo &status_info, if (OB_SUCC(ret) && tablet_empty) { // send rpc to observer bool can_offline = false; - if (OB_FAIL(check_ls_can_offline_by_rpc_(status_info, can_offline))) { + if (OB_FAIL(check_ls_can_offline_by_rpc_(status_info, share::OB_LS_DROPPING, can_offline))) { LOG_WARN("failed to check ls can offline", KR(ret), K(status_info)); } else if (can_offline) { ObLSLifeAgentManager ls_life_agent(*sql_proxy_); @@ -1605,14 +1605,16 @@ int ObTenantLSInfo::check_ls_empty_(const share::ObLSStatusInfo &info, bool &emp return ret; } -int ObTenantLSInfo::check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &info, bool &can_offline) +int ObTenantLSInfo::check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &info, + const share::ObLSStatus ¤t_ls_status, bool &can_offline) { int ret = OB_SUCCESS; share::ObLSInfo ls_info; const share::ObLSReplica *replica = NULL; - if (OB_UNLIKELY(!info.is_valid())) { + if (OB_UNLIKELY(!info.is_valid() + || !ls_is_tenant_dropping_status(current_ls_status) && ! ls_is_dropping_status(current_ls_status))) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("info not valid", KR(ret), K(info)); + LOG_WARN("info not valid", KR(ret), K(info), K(current_ls_status)); } else if (OB_ISNULL(lst_operator_) || OB_ISNULL(rpc_proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("lst operator or proxy is null", KR(ret), KP(lst_operator_), @@ -1628,8 +1630,8 @@ int ObTenantLSInfo::check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &in } else { const int64_t timeout = GCONF.rpc_timeout; obrpc::ObCheckLSCanOfflineArg arg; - if (OB_FAIL(arg.init(info.tenant_id_, info.ls_id_))) { - LOG_WARN("failed to init arg", KR(ret), K(arg)); + if (OB_FAIL(arg.init(info.tenant_id_, info.ls_id_, current_ls_status))) { + LOG_WARN("failed to init arg", KR(ret), K(info), K(current_ls_status)); } else if (OB_FAIL(rpc_proxy_->to(replica->get_server()) .by(info.tenant_id_) .timeout(timeout) diff --git a/src/rootserver/ob_primary_ls_service.h b/src/rootserver/ob_primary_ls_service.h index 167ac4330a..36752d8683 100644 --- a/src/rootserver/ob_primary_ls_service.h +++ b/src/rootserver/ob_primary_ls_service.h @@ -235,6 +235,7 @@ private: int check_sys_ls_can_offline_(bool &can_offline); int check_ls_empty_(const share::ObLSStatusInfo &info, bool &empty); int check_ls_can_offline_by_rpc_(const share::ObLSStatusInfo &info, + const share::ObLSStatus ¤t_ls_status, bool &can_offline); int process_ls_status_after_created_(const share::ObLSStatusInfo &info, const share::ObTenantSwitchoverStatus &working_sw_status); diff --git a/src/share/ob_rpc_struct.cpp b/src/share/ob_rpc_struct.cpp index b339f3f74f..10e556fac8 100644 --- a/src/share/ob_rpc_struct.cpp +++ b/src/share/ob_rpc_struct.cpp @@ -20,6 +20,7 @@ #include "common/ob_store_format.h" #include "observer/ob_server_struct.h" #include "storage/tx/ob_trans_service.h" +#include "share/ls/ob_ls_status_operator.h" namespace oceanbase { @@ -6357,7 +6358,7 @@ OB_SERIALIZE_MEMBER(ObLogReqUnloadProxyResponse, err_); OB_SERIALIZE_MEMBER(ObLogReqLoadProxyProgressRequest, agency_addr_seq_, principal_addr_seq_); OB_SERIALIZE_MEMBER(ObLogReqLoadProxyProgressResponse, err_, progress_); -OB_SERIALIZE_MEMBER(ObDDLBuildSingleReplicaRequestArg, tenant_id_, ls_id_, source_tablet_id_, dest_tablet_id_, +OB_SERIALIZE_MEMBER(ObDDLBuildSingleReplicaRequestArg, tenant_id_, ls_id_, source_tablet_id_, dest_tablet_id_, source_table_id_, dest_schema_id_, schema_version_, snapshot_version_, ddl_type_, task_id_, execution_id_, parallelism_, tablet_task_id_, cluster_version_); @@ -7404,13 +7405,17 @@ OB_SERIALIZE_MEMBER(ObRpcRemoteWriteDDLCommitLogArg, tenant_id_, ls_id_, table_k bool ObCheckLSCanOfflineArg::is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ - && id_.is_valid(); + && id_.is_valid() + && (ls_is_tenant_dropping_status(current_ls_status_) + || ls_is_dropping_status(current_ls_status_) + || ls_is_empty_status(current_ls_status_)); //rpc from old version } void ObCheckLSCanOfflineArg::reset() { tenant_id_ = OB_INVALID_TENANT_ID; id_.reset(); + current_ls_status_ = share::ObLSStatus::OB_LS_EMPTY; } int ObCheckLSCanOfflineArg::assign(const ObCheckLSCanOfflineArg &arg) @@ -7421,16 +7426,19 @@ int ObCheckLSCanOfflineArg::assign(const ObCheckLSCanOfflineArg &arg) return ret; } int ObCheckLSCanOfflineArg::init(const uint64_t tenant_id, - const share::ObLSID &id) + const share::ObLSID &id, + const share::ObLSStatus &ls_status) { int ret = OB_SUCCESS; if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id - || !id.is_valid())) { + || !id.is_valid() + || (!ls_is_tenant_dropping_status(ls_status) && ! ls_is_dropping_status(ls_status)))) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(id)); + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(id), K(ls_status)); } else { tenant_id_ = tenant_id; id_ = id; + current_ls_status_ = ls_status; } return ret; } @@ -7438,11 +7446,11 @@ int ObCheckLSCanOfflineArg::init(const uint64_t tenant_id, DEF_TO_STRING(ObCheckLSCanOfflineArg) { int64_t pos = 0; - J_KV(K_(tenant_id), K_(id)); + J_KV(K_(tenant_id), K_(id), K_(current_ls_status)); return pos; } -OB_SERIALIZE_MEMBER(ObCheckLSCanOfflineArg, tenant_id_, id_); +OB_SERIALIZE_MEMBER(ObCheckLSCanOfflineArg, tenant_id_, id_, current_ls_status_); bool ObRegisterTxDataArg::is_valid() const { diff --git a/src/share/ob_rpc_struct.h b/src/share/ob_rpc_struct.h index 215a89be1a..b3e5bb0bf4 100644 --- a/src/share/ob_rpc_struct.h +++ b/src/share/ob_rpc_struct.h @@ -52,6 +52,7 @@ #include "storage/ob_i_table.h" #include "share/ob_ls_id.h" #include "share/ls/ob_ls_info.h" +#include "share/ls/ob_ls_i_life_manager.h"//ObLSStatus #include "share/ob_tablet_autoincrement_param.h" #include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo #include "share/ob_alive_server_tracer.h"//ServerAddr @@ -8125,13 +8126,14 @@ struct ObCheckLSCanOfflineArg { OB_UNIS_VERSION(1); public: - ObCheckLSCanOfflineArg() : tenant_id_(OB_INVALID_TENANT_ID), id_() {} + ObCheckLSCanOfflineArg() : tenant_id_(OB_INVALID_TENANT_ID), id_(), current_ls_status_(share::ObLSStatus::OB_LS_EMPTY) {} ~ObCheckLSCanOfflineArg() {} bool is_valid() const; void reset(); int assign(const ObCheckLSCanOfflineArg &arg); int init(const uint64_t tenant_id, - const share::ObLSID &id); + const share::ObLSID &id, + const share::ObLSStatus &ls_status); DECLARE_TO_STRING; uint64_t get_tenant_id() const @@ -8142,9 +8144,14 @@ public: { return id_; } + share::ObLSStatus get_ls_status() const + { + return current_ls_status_; + } private: uint64_t tenant_id_; share::ObLSID id_; + share::ObLSStatus current_ls_status_; private: DISALLOW_COPY_AND_ASSIGN(ObCheckLSCanOfflineArg); }; diff --git a/src/storage/ls/ob_ls_meta.cpp b/src/storage/ls/ob_ls_meta.cpp index d206d9e23a..75156984b5 100644 --- a/src/storage/ls/ob_ls_meta.cpp +++ b/src/storage/ls/ob_ls_meta.cpp @@ -429,6 +429,7 @@ int ObLSMeta::update_ls_meta( if (update_restore_status) { tmp.restore_status_ = ls_restore_status; } + tmp.gc_state_ = src_ls_meta.gc_state_; guard.click(); tmp.all_id_meta_.update_all_id_meta(src_ls_meta.all_id_meta_); if (tmp.clog_checkpoint_scn_ < clog_checkpoint_scn_) { @@ -445,6 +446,7 @@ int ObLSMeta::update_ls_meta( tablet_change_checkpoint_scn_ = src_ls_meta.tablet_change_checkpoint_scn_; all_id_meta_.update_all_id_meta(src_ls_meta.all_id_meta_); rebuild_seq_ = tmp.rebuild_seq_; + gc_state_ = tmp.gc_state_; if (update_restore_status) { restore_status_ = ls_restore_status; }