diff --git a/src/logservice/ob_garbage_collector.cpp b/src/logservice/ob_garbage_collector.cpp index 780b91a308..a25018e3c6 100644 --- a/src/logservice/ob_garbage_collector.cpp +++ b/src/logservice/ob_garbage_collector.cpp @@ -237,14 +237,24 @@ int ObGarbageCollector::QueryLSIsValidMemberFunctor::handle_rpc_response_(const if (OB_SUCCESS != (tmp_ret = gc_handler->gc_check_invalid_member_seq(gc_seq_, need_gc))) { CLOG_LOG(WARN, "gc_check_invalid_member_seq failed", K(tmp_ret), K(id), K(leader), K(gc_seq_), K(need_gc)); } else if (need_gc) { - GCCandidate candidate; - candidate.ls_id_ = id; - candidate.ls_status_ = LSStatus::LS_NEED_GC; - candidate.gc_reason_ = NOT_IN_LEADER_MEMBER_LIST; - if (OB_FAIL(gc_candidates_.push_back(candidate))) { - CLOG_LOG(WARN, "gc_candidates push_back failed", K(ret), K(id), K(leader)); + bool allow_gc = false; + ObMigrationStatus migration_status; + if (OB_FAIL(ls->get_migration_status(migration_status))) { + CLOG_LOG(WARN, "get_migration_status failed", K(ret), K(id)); + } else if (OB_FAIL(ObMigrationStatusHelper::check_ls_allow_gc(id, migration_status, true/*not_in_member_list_scene*/, allow_gc))) { + CLOG_LOG(WARN, "failed to check allow gc", K(ret), K(id), K(leader)); + } else if (!allow_gc) { + CLOG_LOG(INFO, "The ls is dependent and is not allowed to be GC", K(id), K(leader)); } else { - CLOG_LOG(INFO, "gc_candidates push_back success", K(ret), K(candidate), K(leader)); + GCCandidate candidate; + candidate.ls_id_ = id; + candidate.ls_status_ = LSStatus::LS_NEED_GC; + candidate.gc_reason_ = NOT_IN_LEADER_MEMBER_LIST; + if (OB_FAIL(gc_candidates_.push_back(candidate))) { + CLOG_LOG(WARN, "gc_candidates push_back failed", K(ret), K(id), K(leader)); + } else { + CLOG_LOG(INFO, "gc_candidates push_back success", K(ret), K(candidate), K(leader)); + } } } else { CLOG_LOG(INFO, "gc_check_invalid_member_seq set seq", K(tmp_ret), K(id), K(leader), K(gc_seq_), K(need_gc)); @@ -1293,7 +1303,6 @@ int ObGarbageCollector::construct_server_ls_map_for_member_list_(ServerLSMap &se int tmp_ret = OB_SUCCESS; while (OB_SUCC(ret)) { common::ObAddr leader; - bool allow_gc = false; if (OB_FAIL(iter->get_next(ls))) { if (OB_ITER_END != ret) { CLOG_LOG(WARN, "get next log stream failed", K(ret)); @@ -1320,10 +1329,8 @@ int ObGarbageCollector::construct_server_ls_map_for_member_list_(ServerLSMap &se CLOG_LOG(WARN, "get invalid leader from location service", K(tmp_ret), K(ls->get_ls_id())); } else if (OB_SUCCESS != (tmp_ret = ls->get_migration_status(migration_status))) { CLOG_LOG(WARN, "get_migration_status failed", K(tmp_ret), K(ls->get_ls_id())); - } else if (OB_SUCCESS != (tmp_ret = ObMigrationStatusHelper::check_allow_gc(ls->get_ls_id(), migration_status, allow_gc))) { - CLOG_LOG(WARN, "failed to check ls allowed to gc", K(tmp_ret), K(migration_status), "ls_id", ls->get_ls_id()); - } else if (!allow_gc) { - CLOG_LOG(INFO, "The ls is dependent and is not allowed to be GC", "ls_id", ls->get_ls_id(), K(migration_status)); + } else if (ObMigrationStatusHelper::check_is_running_migration(migration_status)) { + CLOG_LOG(INFO, "The log stream is in the process of being migrated", "ls_id", ls->get_ls_id(), K(migration_status)); } else if (OB_SUCCESS != (tmp_ret = construct_server_ls_map_(server_ls_map, leader, ls->get_ls_id()))) { CLOG_LOG(WARN, "construct_server_ls_map_ failed", K(tmp_ret), K(ls->get_ls_id()), K(leader)); } @@ -1448,7 +1455,8 @@ int ObGarbageCollector::gc_check_ls_status_(storage::ObLS &ls, } else if (OB_ENTRY_NOT_EXIST == ret) { if (OB_SUCCESS != (tmp_ret = ls.get_migration_status(migration_status))) { CLOG_LOG(WARN, "get_migration_status failed", K(tmp_ret), K(ls_id)); - } else if (OB_SUCCESS != (tmp_ret = ObMigrationStatusHelper::check_allow_gc(ls.get_ls_id(), migration_status, allow_gc))) { + } else if (OB_SUCCESS != (tmp_ret = ObMigrationStatusHelper::check_ls_allow_gc( + ls.get_ls_id(), migration_status, false/*not_in_member_list_scene*/, allow_gc))) { CLOG_LOG(WARN, "failed to check ls allowed to gc", K(tmp_ret), K(migration_status), K(ls_id)); } else if (!allow_gc) { CLOG_LOG(INFO, "The ls is dependent and is not allowed to be GC", K(ls_id), K(migration_status)); diff --git a/src/storage/high_availability/ob_ls_prepare_migration.cpp b/src/storage/high_availability/ob_ls_prepare_migration.cpp index 0e202bbdd1..76023ce70c 100755 --- a/src/storage/high_availability/ob_ls_prepare_migration.cpp +++ b/src/storage/high_availability/ob_ls_prepare_migration.cpp @@ -1223,7 +1223,7 @@ int ObStartPrepareMigrationTask::wait_transfer_tablets_ready_() //do nothing } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { //do nothing - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet, user_data))) { LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_) { @@ -1263,7 +1263,7 @@ int ObStartPrepareMigrationTask::wait_transfer_out_tablet_ready_( } else if (OB_ISNULL(tablet) || OB_ISNULL(ls)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("wait transfer out tablet ready get invalid argument", K(ret), KP(tablet), KP(ls)); - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet, user_data))) { LOG_WARN("failed to get tablet status", K(ret), KPC(tablet)); } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_) { @@ -1333,7 +1333,7 @@ int ObStartPrepareMigrationTask::wait_transfer_out_tablet_ready_( || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_WAIT == status || ObMigrationStatus::OB_MIGRATION_STATUS_ADD_WAIT == status) && dest_tablet->get_tablet_meta().has_transfer_table()) { - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, dest_tablet, dest_user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, dest_tablet, dest_user_data))) { LOG_WARN("failed to get tablet status", K(ret), KPC(dest_tablet)); } else if (ObTabletStatus::TRANSFER_IN != dest_user_data.tablet_status_ || dest_tablet->get_tablet_meta().transfer_info_.transfer_seq_ != tablet->get_tablet_meta().transfer_info_.transfer_seq_ + 1 diff --git a/src/storage/high_availability/ob_storage_ha_struct.cpp b/src/storage/high_availability/ob_storage_ha_struct.cpp index 607328d9a9..5caf39ab15 100644 --- a/src/storage/high_availability/ob_storage_ha_struct.cpp +++ b/src/storage/high_availability/ob_storage_ha_struct.cpp @@ -259,6 +259,10 @@ int ObMigrationStatusHelper::trans_reboot_status(const ObMigrationStatus &cur_st reboot_status = OB_MIGRATION_STATUS_REBUILD_FAIL; break; } + case OB_MIGRATION_STATUS_GC: { + reboot_status = OB_MIGRATION_STATUS_GC; + break; + } default: { ret = OB_INVALID_ARGUMENT; LOG_ERROR("invalid cur status for fail", K(ret), K(cur_status)); @@ -288,14 +292,52 @@ bool ObMigrationStatusHelper::check_can_restore(const ObMigrationStatus &cur_sta return OB_MIGRATION_STATUS_NONE == cur_status; } -int ObMigrationStatusHelper::check_transfer_dest_ls_status_( +// If dest_tablet does not exist, the log stream allows GC. +// If dest_tablet exists, has_transfer_table=false, the log stream allows GC. +// src_ls GC process: offline log_handler ---> set OB_MIGRATION_STATUS_GC ---> get dest_tablet +// dest_ls replay clog process: create transfer in tablet(on_redo) ----> check the migration_status of src_ls in dest_ls replay clog(on_prepare) +// if the replay of the next start transfer in log depends on this log stream, the replay of the on_prepare log will be stuck, and the newly created transfer in tablet will be unreadable +// If dest_tablet exists, has_transfer_table=true, the log stream does not allow GC, because the data of the log stream also needs to be relied on +int ObMigrationStatusHelper::check_transfer_dest_tablet_for_ls_gc(ObLS *ls, const ObTabletID &tablet_id, bool &allow_gc) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + if (OB_ISNULL(ls) || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(ls), K(tablet_id)); + } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { + if (OB_TABLET_NOT_EXIST == ret) { + LOG_WARN("dest tablet not exist", K(ret), "ls_id", ls->get_ls_id(), K(tablet_id)); + allow_gc = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret), "ls_id", ls->get_ls_id(), K(tablet_id)); + } + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet should not be NULL", K(ret), "ls_id", ls->get_ls_id(), K(tablet_id)); + } else if (tablet->get_tablet_meta().has_transfer_table()) { + allow_gc = false; + LOG_INFO("dest tablet has transfer table", "ls_id", ls->get_ls_id(), K(tablet_id)); + } else { + allow_gc = true; + LOG_INFO("dest tablet has no transfer table", "ls_id", ls->get_ls_id(), K(tablet_id)); + } + return ret; +} + +int ObMigrationStatusHelper::check_transfer_dest_ls_status_for_ls_gc( const ObLSID &transfer_ls_id, + const ObTabletID &tablet_id, + const bool not_in_member_list_scene, bool &allow_gc) { int ret = OB_SUCCESS; ObLSService *ls_service = nullptr; ObLS *dest_ls = nullptr; ObLSHandle ls_handle; + allow_gc = false; ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; if (!transfer_ls_id.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -316,18 +358,48 @@ int ObMigrationStatusHelper::check_transfer_dest_ls_status_( LOG_WARN("ls should not be NULL", K(ret), KP(dest_ls), K(transfer_ls_id)); } else if (OB_FAIL(dest_ls->get_migration_status(migration_status))) { LOG_WARN("failed to get migration status", K(ret), KPC(dest_ls)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == migration_status - || ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_WAIT == migration_status - || ObMigrationStatus::OB_MIGRATION_STATUS_ADD_WAIT == migration_status - || ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_WAIT == migration_status) { - allow_gc = false; - } else { + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status + && ObMigrationStatus::OB_MIGRATION_STATUS_MIGRATE_WAIT != migration_status + && ObMigrationStatus::OB_MIGRATION_STATUS_ADD_WAIT != migration_status + && ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD_WAIT != migration_status) { allow_gc = true; + LOG_INFO("transfer dest ls check transfer status passed", K(ret), K(transfer_ls_id), K(migration_status)); + } else if (not_in_member_list_scene) { + if (OB_FAIL(check_transfer_dest_tablet_for_ls_gc(dest_ls, tablet_id, allow_gc))) { + LOG_WARN("failed to check transfer dest tablet", K(ret), KPC(dest_ls), K(tablet_id)); + } + } else { + allow_gc = false; + } + + return ret; +} + +// The status of the log stream is OB_MIGRATION_STATUS_GC, which will block the replay of the start transfer in log corresponding to transfer dest_ls +// Log stream that is not in the member_list will not be added to the member_list. +// If the log stream status modification fails, there is no need to online log_handler. +int ObMigrationStatusHelper::set_ls_migrate_gc_status_( + ObLS &ls, + const ObMigrationStatus &migration_status, + const bool not_in_member_list_scene) +{ + int ret = OB_SUCCESS; + const ObMigrationStatus migrate_GC_status = ObMigrationStatus::OB_MIGRATION_STATUS_GC; + if (!not_in_member_list_scene || ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + // do nothing + } else if (OB_FAIL(ls.get_log_handler()->offline())) { + LOG_WARN("failed to disable replay", K(ret)); + } else if (OB_FAIL(ls.set_migration_status(migrate_GC_status, ls.get_ls_meta().get_rebuild_seq()))) { + LOG_WARN("failed to set migration status", K(ret)); } return ret; } -int ObMigrationStatusHelper::check_ls_transfer_tablet_(const share::ObLSID &ls_id, bool &allow_gc) +int ObMigrationStatusHelper::check_ls_transfer_tablet_( + const share::ObLSID &ls_id, + const ObMigrationStatus &migration_status, + const bool not_in_member_list_scene, + bool &allow_gc) { int ret = OB_SUCCESS; allow_gc = false; @@ -350,8 +422,10 @@ int ObMigrationStatusHelper::check_ls_transfer_tablet_(const share::ObLSID &ls_i } else if (FALSE_IT(create_status = ls->get_ls_meta().get_ls_create_status())) { } else if (ObInnerLSStatus::COMMITTED != create_status) { allow_gc = true; + } else if (OB_FAIL(set_ls_migrate_gc_status_(*ls, migration_status, not_in_member_list_scene))) { + LOG_WARN("failed to set ls gc status", KR(ret)); } else if (OB_FAIL(ls->get_tablet_svr()->build_tablet_iter(tablet_iter))) { - LOG_WARN( "failed to build ls tablet iter", KR(ret)); + LOG_WARN("failed to build ls tablet iter", KR(ret)); } else { ObTabletHandle tablet_handle; ObTablet *tablet = NULL; @@ -384,7 +458,8 @@ int ObMigrationStatusHelper::check_ls_transfer_tablet_(const share::ObLSID &ls_i } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_) { // do nothing - } else if (OB_FAIL(check_transfer_dest_ls_status_(user_data.transfer_ls_id_, allow_gc))) { + } else if (OB_FAIL(check_transfer_dest_ls_status_for_ls_gc( + user_data.transfer_ls_id_, tablet->get_tablet_meta().tablet_id_, not_in_member_list_scene, allow_gc))) { LOG_WARN("failed to check ls transfer tablet", K(ret), K(ls), K(user_data)); } else if (!allow_gc) { LOG_INFO("The ls is not allowed to be GC because it is also dependent on other ls", K(user_data), @@ -396,32 +471,60 @@ int ObMigrationStatusHelper::check_ls_transfer_tablet_(const share::ObLSID &ls_i return ret; } -int ObMigrationStatusHelper::check_allow_gc(const share::ObLSID &ls_id, const ObMigrationStatus &cur_status, bool &allow_gc) +int ObMigrationStatusHelper::check_ls_allow_gc( + const share::ObLSID &ls_id, + const ObMigrationStatus &cur_status, + const bool not_in_member_list_scene, + bool &allow_gc) { int ret = OB_SUCCESS; allow_gc = false; - if (check_allow_gc_abandoned_ls(cur_status)) { + if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_id is invalid", K(ret), K(ls_id)); + } else if (check_migration_status_is_fail_(cur_status)) { allow_gc = true; - } else if (OB_MIGRATION_STATUS_NONE != cur_status) { - allow_gc = false; - } else if (OB_FAIL(check_ls_transfer_tablet_(ls_id, allow_gc))) { + } else if (OB_FAIL(check_ls_transfer_tablet_(ls_id, cur_status, not_in_member_list_scene, allow_gc))) { LOG_WARN("failed to check ls transfer tablet", K(ret), K(ls_id)); - } else { } return ret; } +bool ObMigrationStatusHelper::check_migration_status_is_fail_(const ObMigrationStatus &cur_status) +{ + bool is_fail = false; + if (OB_MIGRATION_STATUS_ADD_FAIL == cur_status + || OB_MIGRATION_STATUS_MIGRATE_FAIL == cur_status + || OB_MIGRATION_STATUS_REBUILD_FAIL == cur_status) { + is_fail = true; + } + return is_fail; +} + bool ObMigrationStatusHelper::check_allow_gc_abandoned_ls(const ObMigrationStatus &cur_status) { bool allow_gc = false; - if (OB_MIGRATION_STATUS_ADD_FAIL == cur_status - || OB_MIGRATION_STATUS_MIGRATE_FAIL == cur_status - || OB_MIGRATION_STATUS_REBUILD_FAIL == cur_status) { + if (check_migration_status_is_fail_(cur_status)) { + allow_gc = true; + } else if (OB_MIGRATION_STATUS_GC == cur_status) { allow_gc = true; } return allow_gc; } +bool ObMigrationStatusHelper::check_is_running_migration(const ObMigrationStatus &cur_status) +{ + bool is_running = true; + if (check_allow_gc_abandoned_ls(cur_status)) { + is_running = false; + } else if (OB_MIGRATION_STATUS_NONE == cur_status) { + is_running = false; + } else { + is_running = true; + } + return is_running; +} + bool ObMigrationStatusHelper::check_can_migrate_out(const ObMigrationStatus &cur_status) { bool can_migrate_out = true; @@ -449,7 +552,8 @@ int ObMigrationStatusHelper::check_can_change_status( || OB_MIGRATION_STATUS_MIGRATE == change_status || OB_MIGRATION_STATUS_CHANGE == change_status || OB_MIGRATION_STATUS_REBUILD == change_status - || OB_MIGRATION_STATUS_RESTORE_STANDBY == change_status) { + || OB_MIGRATION_STATUS_RESTORE_STANDBY == change_status + || OB_MIGRATION_STATUS_GC == change_status) { can_change = true; } break; @@ -541,6 +645,12 @@ int ObMigrationStatusHelper::check_can_change_status( } break; } + case OB_MIGRATION_STATUS_GC: { + if (OB_MIGRATION_STATUS_GC == change_status) { + can_change = true; + } + break; + } default: { ret = OB_INVALID_ARGUMENT; LOG_ERROR("invalid cur status for fail", K(ret), K(cur_status)); diff --git a/src/storage/high_availability/ob_storage_ha_struct.h b/src/storage/high_availability/ob_storage_ha_struct.h index 95d54da3e0..3cb0d72911 100644 --- a/src/storage/high_availability/ob_storage_ha_struct.h +++ b/src/storage/high_availability/ob_storage_ha_struct.h @@ -45,6 +45,7 @@ enum ObMigrationStatus OB_MIGRATION_STATUS_MIGRATE_WAIT = 10, OB_MIGRATION_STATUS_ADD_WAIT = 11, OB_MIGRATION_STATUS_REBUILD_WAIT = 12, + OB_MIGRATION_STATUS_GC = 13, // ls wait allow gc OB_MIGRATION_STATUS_MAX, }; @@ -75,7 +76,11 @@ public: static int trans_reboot_status(const ObMigrationStatus &cur_status, ObMigrationStatus &reboot_status); static bool check_can_election(const ObMigrationStatus &cur_status); static bool check_can_restore(const ObMigrationStatus &cur_status); - static int check_allow_gc(const share::ObLSID &ls_id, const ObMigrationStatus &cur_status, bool &allow_gc); + static int check_ls_allow_gc( + const share::ObLSID &ls_id, + const ObMigrationStatus &cur_status, + const bool not_in_member_list_scene, + bool &allow_gc); // Check the migration status. The LS in the XXX_FAIL state is considered to be an abandoned LS, which can be judged to be directly GC when restarting static bool check_allow_gc_abandoned_ls(const ObMigrationStatus &cur_status); static bool check_can_migrate_out(const ObMigrationStatus &cur_status); @@ -86,15 +91,30 @@ public: static bool is_valid(const ObMigrationStatus &status); static int trans_rebuild_fail_status( const ObMigrationStatus &cur_status, - const bool is_in_member_list, + const bool not_in_member_list_scene, const bool is_ls_deleted, ObMigrationStatus &fail_status); static int check_migration_in_final_state( const ObMigrationStatus &status, bool &in_final_state); + static bool check_is_running_migration(const ObMigrationStatus &cur_status); private: - static int check_ls_transfer_tablet_(const share::ObLSID &ls_id, bool &allow_gc); - static int check_transfer_dest_ls_status_(const share::ObLSID &transfer_ls_id, bool &allow_gc); + static int check_ls_transfer_tablet_( + const share::ObLSID &ls_id, + const ObMigrationStatus &migration_status, + const bool not_in_member_list_scene, + bool &allow_gc); + static int check_transfer_dest_ls_status_for_ls_gc( + const share::ObLSID &transfer_ls_id, + const ObTabletID &tablet_id, + const bool not_in_member_list_scene, + bool &allow_gc); + static int check_transfer_dest_tablet_for_ls_gc(ObLS *ls, const ObTabletID &tablet_id, bool &allow_gc); + static bool check_migration_status_is_fail_(const ObMigrationStatus &cur_status); + static int set_ls_migrate_gc_status_( + ObLS &ls, + const ObMigrationStatus &migration_status, + const bool not_in_member_list_scene); }; enum ObMigrationOpPriority diff --git a/src/storage/high_availability/ob_transfer_backfill_tx.cpp b/src/storage/high_availability/ob_transfer_backfill_tx.cpp index e6e1871950..4df647d0cf 100644 --- a/src/storage/high_availability/ob_transfer_backfill_tx.cpp +++ b/src/storage/high_availability/ob_transfer_backfill_tx.cpp @@ -119,7 +119,7 @@ int ObTransferWorkerMgr::get_need_backfill_tx_tablets_(ObTransferBackfillTXParam LOG_WARN("tablet should not be NULL", K(ret), KP(tablet)); } else if (tablet->get_tablet_meta().tablet_id_.is_ls_inner_tablet()) { //do nothing - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet, user_data))) { if (OB_EMPTY_RESULT == ret || OB_ERR_SHARED_LOCK_CONFLICT == ret) { // needs to delete this judgment after ObLSTabletIterator optimization LOG_INFO("committed tablet_status does not exist", K(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_); ret = OB_SUCCESS; @@ -226,7 +226,7 @@ int ObTransferWorkerMgr::check_source_tablet_ready_( SCN max_decided_scn; ObTabletCreateDeleteMdsUserData user_data; ObMigrationStatus migration_status = ObMigrationStatus::OB_MIGRATION_STATUS_MAX; - + bool need_check_tablet = false; is_ready = false; if (!ls_id.is_valid() || !tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -246,12 +246,25 @@ int ObTransferWorkerMgr::check_source_tablet_ready_( LOG_WARN("ls should not be NULL", K(ret), KP(ls), K(ls_id)); } else if (OB_FAIL(ls->get_migration_status(migration_status))) { LOG_WARN("failed to get migration status", K(ret), KPC(ls)); - } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status) { + } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status + && ObMigrationStatus::OB_MIGRATION_STATUS_GC != migration_status) { LOG_INFO("[TRANSFER_BACKFILL]source ls is not in migration none", K(ls_id), K(migration_status)); } else if (OB_FAIL(ls->get_max_decided_scn(max_decided_scn))) { - LOG_WARN("failed to get source ls max decided scn", K(ret), KPC(ls)); + if (OB_STATE_NOT_MATCH == ret && ObMigrationStatus::OB_MIGRATION_STATUS_GC == migration_status) { + LOG_INFO("the migration status of the log stream is OB_MIGRATION_STATUS_GC", K(ret), KPC(ls)); + need_check_tablet = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get source ls max decided scn", K(ret), KPC(ls)); + } } else if (max_decided_scn < transfer_info.transfer_start_scn_) { - LOG_INFO("[TRANSFER_BACKFILL]src ls max decided scn is smaller than transfer start scn, need wait", K(ls_id), K(tablet_id), K(max_decided_scn), K(transfer_info)); + LOG_INFO("[TRANSFER_BACKFILL]src ls max decided scn is smaller than transfer start scn, need wait", + K(ls_id), K(tablet_id), K(max_decided_scn), K(transfer_info)); + } else { + need_check_tablet = true; + } + + if (OB_FAIL(ret) || !need_check_tablet) { } else if (OB_FAIL(ls->ha_get_tablet(tablet_id, tablet_handle))) { if (OB_TABLET_NOT_EXIST == ret) { LOG_INFO("[TRANSFER_BACKFILL]source tablet not exist", K(ls_id), K(tablet_id)); @@ -264,7 +277,7 @@ int ObTransferWorkerMgr::check_source_tablet_ready_( LOG_WARN("tablet should not be NULL", K(ret), K(ls_id), K(tablet_id)); } else if (tablet->is_empty_shell()) { LOG_INFO("[TRANSFER_BACKFILL]source tablet is empty shell", K(ls_id), K(tablet_id)); - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet, user_data))) { LOG_WARN("failed to get tablet status", K(ret), K(ls_id), KPC(tablet)); } else if (ObTabletStatus::TRANSFER_OUT != user_data.tablet_status_ && ObTabletStatus::TRANSFER_OUT_DELETED != user_data.tablet_status_ ) { @@ -1448,9 +1461,9 @@ int ObTransferReplaceTableTask::get_source_tablet_tables_( } else if (tablet->is_empty_shell()) { ret = OB_EAGAIN; LOG_WARN("transfer src tablet should not be empty shell, task need to retry", K(ret), KPC(tablet), "ls_id", ctx_->src_ls_id_); - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet_handle, src_user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet_handle, src_user_data))) { LOG_WARN("failed to get src user data", K(ret), K(tablet_handle), KPC(tablet)); - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, dest_tablet, dest_user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, dest_tablet, dest_user_data))) { LOG_WARN("failed to get src user data", K(ret), K(tablet_handle), KPC(tablet)); } else if (FALSE_IT(src_transfer_seq = tablet->get_tablet_meta().transfer_info_.transfer_seq_)) { } else if (FALSE_IT(dest_transfer_seq = dest_tablet->get_tablet_meta().transfer_info_.transfer_seq_)) { @@ -1576,7 +1589,7 @@ int ObTransferReplaceTableTask::transfer_replace_tables_( LOG_WARN("ls should not be nullptr", K(ret)); } else if (OB_FAIL(ls->get_migration_status(migration_status))) { LOG_WARN("failed to get migration status", K(ret), KPC(ls)); - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet, user_data))) { LOG_WARN("failed to get tablet status", K(ret), KPC(ls)); } else if (OB_FAIL(tablet->fetch_table_store(dest_wrapper))) { LOG_WARN("failed to fetch table store", K(ret), KPC(tablet)); @@ -1658,7 +1671,7 @@ int ObTransferReplaceTableTask::do_replace_logical_tables_(ObLS *ls) } else if (tablet_id.is_ls_inner_tablet()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("inner tablet cannot transfer", KR(ret), K(tablet_id), KPC(this)); - } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(true/*get_commit*/, tablet, user_data))) { + } else if (OB_FAIL(ObTXTransferUtils::get_tablet_status(false/*get_commit*/, tablet, user_data))) { LOG_WARN("failed to get tablet status", K(ret), K(tablet_handle)); } else if (ObTabletStatus::TRANSFER_IN != user_data.tablet_status_ && !in_migration) { ret = OB_UNEXPECTED_TABLET_STATUS;