Fix the problem that log streams not in member_list cannot be GC
This commit is contained in:
		@ -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));
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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));
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user