Patch to fix recent PITR bug, with proposals as discussed on -admin and
-hackers. Patch implements option #3, as proposed here:
http://archives.postgresql.org/pgsql-hackers/2007-06/msg00234.php
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.

-- 
  Simon Riggs             
  EnterpriseDB   http://www.enterprisedb.com

Index: src/backend/access/transam/xlog.c
===================================================================
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 ----
  	char		archiveStatusPath[MAXPGPATH];
  	FILE	   *fd;
  
+ 	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)
+ 			return;
+ 	}
+ 
  	/* 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);
  	XLogArchiveCleanup(xlogpath);
  
+ 	/*
+ 	 * 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)
+ 		{
+ 			ereport(ERROR,
+ 					(errcode_for_file_access(),
+ 					 errmsg("could not create archive status file \"%s\": %m",
+ 							archiveStatusPath)));
+ 		}
+ 		if (FreeFile(fd))
+ 		{
+ 			ereport(ERROR,
+ 					(errcode_for_file_access(),
+ 					 errmsg("could not write archive status file \"%s\": %m",
+ 							archiveStatusPath)));
+ 		}
+ 	}
+ 
  	/* 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

Reply via email to