Patch to fix recent PITR bug, with proposals as discussed on -admin and
-hackers. Patch implements option #3, as proposed here:
This is a fairly important bug fix, backpatch required.
Jon, can you confirm this fixes for you?
I confirm this fix for CVS HEAD and REL8_2_STABLE.
Patch applies cleanly to CVS HEAD, and with some fuzz onto 8.2.
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.272
diff -c -r1.272 xlog.c
*** src/backend/access/transam/xlog.c 31 May 2007 15:13:01 -0000 1.272
--- src/backend/access/transam/xlog.c 8 Jun 2007 22:14:27 -0000
*** 1133,1138 ****
--- 1133,1148 ----
+ if (InRecovery)
+ struct stat stat_buf;
+ /* First check for .done --- this means archiver is already done with it */
+ StatusFilePath(archiveStatusPath, xlog, ".done");
+ if (stat(archiveStatusPath, &stat_buf) == 0)
/* insert an otherwise empty file called <XLOG>.ready */
StatusFilePath(archiveStatusPath, xlog, ".ready");
fd = AllocateFile(archiveStatusPath, "w");
*** 4472,4477 ****
--- 4482,4529 ----
XLogFileName(xlogpath, ThisTimeLineID, endLogId, endLogSeg);
+ * Write an archive status file to show that the last restored
+ * xlog file does not need to be re-archived. Normally
+ * archiver would do this, so the code is long hand here.
+ * This allows us to strictly enforce the rule that the
+ * archive_command should disallow duplicate inserts.
+ * The shutdown checkpoint at the end of recovery will force a
+ * switch to the next xlog segment. This would normally cause
+ * a .ready archive status file, but we prevent that by writing
+ * a .done message before the checkpoint occurs later in StartupXLog.
+ * We do this iff restoredFromArchive because there is a small
+ * chance that an xlog segment that wasn't restored from
+ * archive is so nearly full that a checkpoint record won't fit
+ * and that this could cause a switch also. In that case we *do*
+ * want to write an archive notification.
+ if (restoredFromArchive)
+ char archiveStatusPath[MAXPGPATH];
+ FILE *fd;
+ /* insert an otherwise empty file called <XLOG>.done */
+ StatusFilePath(archiveStatusPath, xlogpath, ".done");
+ fd = AllocateFile(archiveStatusPath, "w");
+ if (fd == NULL)
+ errmsg("could not create archive status file \"%s\": %m",
+ if (FreeFile(fd))
+ errmsg("could not write archive status file \"%s\": %m",
/* Get rid of any remaining recovered timeline-history file, too */
snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY");
unlink(recoveryPath); /* ignore any error */
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [EMAIL PROTECTED] so that your
message can get through to the mailing list cleanly