=== Applying patches on top of PostgreSQL commit ID c68cba09dd7fb2cca1fdddfcf8e0fe206e97a8a4 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Tue Sep 15 06:14:28 UTC 2026 On branch cf/7221 nothing to commit, working tree clean === using 'git am' to apply patch ./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch === Applying: Fix pg_rewind file sync bypass and findLastCheckpoint boundary crash .git/rebase-apply/patch:18: trailing whitespace. XLogRecPtr *lastchkptredo, const char *restoreCommand, .git/rebase-apply/patch:19: indent with spaces. XLogRecPtr cntrlfilechkptrec) .git/rebase-apply/patch:37: trailing whitespace. /* .git/rebase-apply/patch:38: trailing whitespace, indent with spaces. * Attempt the standard backward scan first. .git/rebase-apply/patch:39: indent with spaces. */ warning: squelched 12 whitespace errors warning: 17 lines add whitespace errors. Using index info to reconstruct a base tree... M src/bin/pg_rewind/parsexlog.c M src/bin/pg_rewind/pg_rewind.c M src/bin/pg_rewind/pg_rewind.h Falling back to patching base and 3-way merge... Auto-merging src/bin/pg_rewind/pg_rewind.h CONFLICT (content): Merge conflict in src/bin/pg_rewind/pg_rewind.h Auto-merging src/bin/pg_rewind/pg_rewind.c CONFLICT (content): Merge conflict in src/bin/pg_rewind/pg_rewind.c Auto-merging src/bin/pg_rewind/parsexlog.c CONFLICT (content): Merge conflict in src/bin/pg_rewind/parsexlog.c error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Fix pg_rewind file sync bypass and findLastCheckpoint boundary crash When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". === using patch(1) to apply patch ./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch === patching file src/bin/pg_rewind/parsexlog.c Hunk #1 FAILED at 167. Hunk #2 succeeded at 178 (offset 1 line). Hunk #3 FAILED at 201. 2 out of 3 hunks FAILED -- saving rejects to file src/bin/pg_rewind/parsexlog.c.rej patching file src/bin/pg_rewind/pg_rewind.c Hunk #1 succeeded at 441 (offset 2 lines). Hunk #2 FAILED at 467. 1 out of 2 hunks FAILED -- saving rejects to file src/bin/pg_rewind/pg_rewind.c.rej patching file src/bin/pg_rewind/pg_rewind.h Hunk #1 FAILED at 39. 1 out of 1 hunk FAILED -- saving rejects to file src/bin/pg_rewind/pg_rewind.h.rej patching file src/bin/pg_rewind/t/012_equal_lsn_sync.pl Unstaged changes after reset: M src/bin/pg_rewind/parsexlog.c M src/bin/pg_rewind/pg_rewind.c Removing src/bin/pg_rewind/parsexlog.c.rej Removing src/bin/pg_rewind/pg_rewind.c.rej Removing src/bin/pg_rewind/pg_rewind.h.rej Removing src/bin/pg_rewind/t/012_equal_lsn_sync.pl === using 'git apply' to apply patch ./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch === /work/patches/./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch:52: trailing whitespace. XLogRecPtr *lastchkptredo, const char *restoreCommand, /work/patches/./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch:53: indent with spaces. XLogRecPtr cntrlfilechkptrec) /work/patches/./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch:71: trailing whitespace. /* /work/patches/./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch:72: trailing whitespace, indent with spaces. * Attempt the standard backward scan first. /work/patches/./v1-0001-Fix-pg_rewind-file-sync-bypass-and-findLastCheckpoin.patch:73: indent with spaces. */ Applied patch to 'src/bin/pg_rewind/parsexlog.c' with conflicts. Applied patch to 'src/bin/pg_rewind/pg_rewind.c' with conflicts. Applied patch to 'src/bin/pg_rewind/pg_rewind.h' with conflicts. Falling back to direct application... U src/bin/pg_rewind/parsexlog.c U src/bin/pg_rewind/pg_rewind.c U src/bin/pg_rewind/pg_rewind.h warning: squelched 12 whitespace errors warning: 17 lines add whitespace errors. diff --cc src/bin/pg_rewind/parsexlog.c index 6e87b00f8c2,cb578d2a44b..00000000000 --- a/src/bin/pg_rewind/parsexlog.c +++ b/src/bin/pg_rewind/parsexlog.c @@@ -167,10 -167,9 +167,14 @@@ readOneRecord(const char *datadir, XLog void findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex, XLogRecPtr *lastchkptrec, TimeLineID *lastchkpttli, ++<<<<<<< ours + XLogRecPtr *lastchkptredo, uint32 *lastchkptdatachecksums, + const char *restoreCommand) ++======= + XLogRecPtr *lastchkptredo, const char *restoreCommand, + XLogRecPtr cntrlfilechkptrec) ++>>>>>>> theirs { - /* Walk backwards, starting from the given record */ XLogRecord *record; XLogRecPtr searchptr; XLogReaderState *xlogreader; @@@ -201,67 -201,137 +206,147 @@@ if (xlogreader == NULL) pg_fatal("out of memory while allocating a WAL reading processor"); + /* + * Attempt the standard backward scan first. + */ searchptr = forkptr; - for (;;) - { - uint8 info; - - XLogBeginRead(xlogreader, searchptr); - record = XLogReadRecord(xlogreader, &errormsg); + XLogBeginRead(xlogreader, searchptr); + record = XLogReadRecord(xlogreader, &errormsg); - if (record == NULL) - { - if (errormsg) - pg_fatal("could not find previous WAL record at %X/%08X: %s", - LSN_FORMAT_ARGS(searchptr), - errormsg); - else - pg_fatal("could not find previous WAL record at %X/%08X", - LSN_FORMAT_ARGS(searchptr)); - } + if (record == NULL) + { + /* + * If we fail to read exactly at the forkptr, we assume the target crashed + * exactly at a record boundary and the WAL is padded with zeroes. + * Instead of crashing pg_rewind, we fallback to a forward scan. + */ + fallback_to_forward = true; + } - /* Detect if a new WAL file has been opened */ - if (xlogreader->seg.ws_tli != current_tli || - xlogreader->seg.ws_segno != current_segno) + if (!fallback_to_forward) + { + /* We successfully read the first record; proceed with backward scan */ + for (;;) { - char xlogfname[MAXFNAMELEN]; - - snprintf(xlogfname, MAXFNAMELEN, XLOGDIR "/"); - - /* update current values */ - current_tli = xlogreader->seg.ws_tli; - current_segno = xlogreader->seg.ws_segno; - - XLogFileName(xlogfname + sizeof(XLOGDIR), - current_tli, current_segno, WalSegSz); - - /* Track this filename as one to not remove */ - keepwal_add_entry(xlogfname); + uint8 info; + + if (record == NULL) + { + /* A failure mid-scan means real corruption, so we error out */ + if (errormsg) + pg_fatal("could not find previous WAL record at %X/%08X: %s", + LSN_FORMAT_ARGS(searchptr), errormsg); + else + pg_fatal("could not find previous WAL record at %X/%08X", + LSN_FORMAT_ARGS(searchptr)); + } + + /* Detect if a new WAL file has been opened */ + if (xlogreader->seg.ws_tli != current_tli || + xlogreader->seg.ws_segno != current_segno) + { + char xlogfname[MAXFNAMELEN]; + + snprintf(xlogfname, MAXFNAMELEN, XLOGDIR "/"); + current_tli = xlogreader->seg.ws_tli; + current_segno = xlogreader->seg.ws_segno; + XLogFileName(xlogfname + sizeof(XLOGDIR), + current_tli, current_segno, WalSegSz); + keepwal_add_entry(xlogfname); + } + + /* Check if it is a valid checkpoint record. */ + info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK; + if (searchptr < forkptr && + XLogRecGetRmid(xlogreader) == RM_XLOG_ID && + (info == XLOG_CHECKPOINT_SHUTDOWN || + info == XLOG_CHECKPOINT_ONLINE)) + { + CheckPoint checkPoint; + + memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint)); + *lastchkptrec = searchptr; + *lastchkpttli = checkPoint.ThisTimeLineID; + *lastchkptredo = checkPoint.redo; + break; + } + + /* Walk backwards to previous record. */ + searchptr = record->xl_prev; + XLogBeginRead(xlogreader, searchptr); + record = XLogReadRecord(xlogreader, &errormsg); } + } + else + { + /* + * Fallback. Scan forward from the control file's last checkpoint. + */ + searchptr = cntrlfilechkptrec; + XLogBeginRead(xlogreader, searchptr); - /* - * Check if it is a checkpoint record. This checkpoint record needs to - * be the latest checkpoint before WAL forked and not the checkpoint - * where the primary has been stopped to be rewound. - */ - info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK; - if (searchptr < forkptr && - XLogRecGetRmid(xlogreader) == RM_XLOG_ID && - (info == XLOG_CHECKPOINT_SHUTDOWN || - info == XLOG_CHECKPOINT_ONLINE)) + for (;;) { - CheckPoint checkPoint; + uint8 info; ++<<<<<<< ours + memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint)); + *lastchkptrec = searchptr; + *lastchkpttli = checkPoint.ThisTimeLineID; + *lastchkptredo = checkPoint.redo; + *lastchkptdatachecksums = checkPoint.dataChecksumState; + break; + } - - /* Walk backwards to previous record. */ - searchptr = record->xl_prev; ++======= + record = XLogReadRecord(xlogreader, &errormsg); + + if (record == NULL) + { + if (errormsg) + pg_fatal("could not read WAL record during forward scan at %X/%08X: %s", + LSN_FORMAT_ARGS(searchptr), errormsg); + else + pg_fatal("could not read WAL record during forward scan at %X/%08X", + LSN_FORMAT_ARGS(searchptr)); + } + + /* Update searchptr to the start of the record we just read */ + searchptr = xlogreader->ReadRecPtr; + + /* Detect if a new WAL file has been opened */ + if (xlogreader->seg.ws_tli != current_tli || + xlogreader->seg.ws_segno != current_segno) + { + char xlogfname[MAXFNAMELEN]; + + snprintf(xlogfname, MAXFNAMELEN, XLOGDIR "/"); + current_tli = xlogreader->seg.ws_tli; + current_segno = xlogreader->seg.ws_segno; + XLogFileName(xlogfname + sizeof(XLOGDIR), + current_tli, current_segno, WalSegSz); + keepwal_add_entry(xlogfname); + } ++>>>>>>> theirs + + /* Check if it is a checkpoint record. Update pointers iteratively. */ + info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK; + if (searchptr < forkptr && + XLogRecGetRmid(xlogreader) == RM_XLOG_ID && + (info == XLOG_CHECKPOINT_SHUTDOWN || + info == XLOG_CHECKPOINT_ONLINE)) + { + CheckPoint checkPoint; + + memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint)); + *lastchkptrec = searchptr; + *lastchkpttli = checkPoint.ThisTimeLineID; + *lastchkptredo = checkPoint.redo; + } + + /* If we've reached or passed the divergence point, we are done */ + if (xlogreader->EndRecPtr >= forkptr) + break; + } } XLogReaderFree(xlogreader); diff --cc src/bin/pg_rewind/pg_rewind.c index d2521dab333,fdeced703cb..00000000000 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@@ -473,8 -467,7 +469,12 @@@ main(int argc, char **argv keepwal_init(); findLastCheckpoint(datadir_target, divergerec, lastcommontliIndex, ++<<<<<<< ours + &chkptrec, &chkpttli, &chkptredo, &chkptdatachecksums, + restore_command); ++======= + &chkptrec, &chkpttli, &chkptredo, restore_command, ControlFile_target.checkPoint); ++>>>>>>> theirs pg_log_info("rewinding from last common checkpoint at %X/%08X on timeline %u", LSN_FORMAT_ARGS(chkptrec), chkpttli); diff --cc src/bin/pg_rewind/pg_rewind.h index 9187c3bf72f,bc3f700a76e..00000000000 --- a/src/bin/pg_rewind/pg_rewind.h +++ b/src/bin/pg_rewind/pg_rewind.h @@@ -39,8 -39,7 +39,12 @@@ extern void findLastCheckpoint(const ch int tliIndex, XLogRecPtr *lastchkptrec, TimeLineID *lastchkpttli, XLogRecPtr *lastchkptredo, ++<<<<<<< ours + uint32 *lastchkptdatachecksums, + const char *restoreCommand); ++======= + const char *restoreCommand, XLogRecPtr cntrlfilechkptrec); ++>>>>>>> theirs extern XLogRecPtr readOneRecord(const char *datadir, XLogRecPtr ptr, int tliIndex, const char *restoreCommand);