diff --git a/src/logservice/restoreservice/ob_log_restore_archive_driver.cpp b/src/logservice/restoreservice/ob_log_restore_archive_driver.cpp index 032867b47e..878d14bdb7 100644 --- a/src/logservice/restoreservice/ob_log_restore_archive_driver.cpp +++ b/src/logservice/restoreservice/ob_log_restore_archive_driver.cpp @@ -203,6 +203,21 @@ int ObLogRestoreArchiveDriver::get_palf_base_lsn_scn_(ObLS &ls, LSN &lsn, SCN &s } else if (OB_UNLIKELY(!scn.is_valid() || !lsn.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("get_palf_base_lsn_scn_, return invalid scn or lsn", K(id), K(scn), K(lsn)); + } else if (!ls.get_clog_checkpoint_scn().is_valid()) { + // checkpoint_scn not valid, just skip it + LOG_ERROR("ls checkpoint_scn not valid", K(ls)); + } else { + // The start scn for palf to restore is the min scn of a block, + // so if the min scn exists in two or more archive rounds and the the rounds are not continuous, + // the location of the scn will hit the first round, which results to restore failure. + // + // Use the ls checkpoint_scn to help the first location. + // + // For example, the round 1 range: [100, 200], the checkpoint_scn of the matched backup fall in the range [100, 200], + // the round 2 range: [300, 500], the checkpoint_scn of the matched backup in [300, 500]. + // But the start_scn for restore maybe only 50, so it will locate failed. + // The checkpoint_scn is precise, it will help to locate the correct round. + scn = std::max(scn, ls.get_clog_checkpoint_scn()); } return ret; }