diff --git a/src/bin/pg_rewind/pg_rewind.cpp b/src/bin/pg_rewind/pg_rewind.cpp index 4075b0c9c7eefbddd7ccd33ab9494c8f83b26e97..cdc173e588bf547bbdbb05e20eedef2175fab36b 100755 --- a/src/bin/pg_rewind/pg_rewind.cpp +++ b/src/bin/pg_rewind/pg_rewind.cpp @@ -90,6 +90,7 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char* errno_t errorno = EOK; GaussState state; BuildErrorCode rv = BUILD_SUCCESS; + bool needCrashRecovery = false; datadir_target = pg_strdup(pgdata); /* here we set basedir for last xlog requests purpose. the value is the datadir */ @@ -252,12 +253,20 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char* } } - /* Checkpoint redo should exist. Otherwise, fatal and change to full build. */ - (void)readOneRecord(datadir_target, chkptredo, chkpttli); - pg_log(PG_PROGRESS, - "read checkpoint redo (%X/%X) success before rewinding.\n", - (uint32)(chkptredo >> 32), - (uint32)chkptredo); + /* + * If chkptrec < startrec, we don't need to restore the pages modified by + * XLog between [chkptredo, chkptrec] because they have already been fsync'd + * to the disk, and therefore there is no need to determine whether the XLog + * at chkptredo exists either. + */ + needCrashRecovery = chkptrec >= startrec; + if (needCrashRecovery) { + (void)readOneRecord(datadir_target, chkptredo, chkpttli); + pg_log(PG_PROGRESS, + "read checkpoint redo (%X/%X) success before rewinding.\n", + (uint32)(chkptredo >> 32), + (uint32)chkptredo); + } pg_log(PG_PROGRESS, "rewinding from checkpoint redo point at %X/%X on timeline %u\n", @@ -297,7 +306,7 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char* * we would need to replay until the end of WAL here. */ pg_log(PG_PROGRESS, "reading WAL in target\n"); - extractPageMap(datadir_target, chkptredo, lastcommontli); + extractPageMap(datadir_target, needCrashRecovery ? chkptredo : chkptrec, lastcommontli); PG_CHECKBUILD_AND_RETURN(); filemap_finalize(); calculate_totals(); @@ -333,7 +342,7 @@ BuildErrorCode gs_increment_build(const char* pgdata, const char* connstr, char* PG_CHECKBUILD_AND_RETURN(); } pg_log(PG_WARNING, _("starting background WAL receiver\n")); - nRet = snprintf_s(xlog_start, MAXFNAMELEN, MAXFNAMELEN - 1, "%X/%X", (uint32)(chkptredo >> 32), (uint32)chkptredo); + nRet = snprintf_s(xlog_start, MAXFNAMELEN, MAXFNAMELEN - 1, "%X/%X", (uint32)(chkptrec >> 32), (uint32)chkptrec); securec_check_ss_c(nRet, "", ""); get_xlog_location(xlog_location); pg_log(PG_PROGRESS, "Starting copy xlog, start point: %s\n", xlog_start);