Hi,

Attached is the self-contained patch to skip checkpoint at pg_start_backup.
This is a part of Synch Rep patches, and was discussed in the following
thread.
http://archives.postgresql.org/message-id/3f0b79eb0812240710j7e613f3atfd6b6fc274035...@mail.gmail.com

In Synch Rep, we basically have to get a fresh backup, to make the failed
server catch up with the primary after failover. But getting an online-backup
is expensive operation because of pg_start_backup's checkpoint and data
copying. Especially since pg_start_backup is performed as one transaction,
its checkpoint might not only increase I/O traffic but also cause
long-transaction which prevents VACUUM and HOT. This patch makes
pg_start_backup skip a checkpoint if possible, and works out the above
problem.

Specifically, pg_start_backup uses the last checkpoint instead of doing a
new checkpoint if full_page_writes = on since the last checkpoint, which
guarantees that all the full-pages required for PITR are written.

There is one constraint: XLR_BKP_REMOVABLE flag cannot be marked
correctly, because we cannot judge whether the full-pages (generated
before pg_start_backup) are removal or not. AFAIK, this flag is only used
by pglesslog. Should we add a new option to specify whether checkpoint
is skippable, for the backward compatibility?

Regards,

-- 
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center
? GNUmakefile
? config.log
? config.status
? contrib/pgbench/pgbench
? src/Makefile.global
? src/backend/postgres
? src/backend/catalog/postgres.bki
? src/backend/catalog/postgres.description
? src/backend/catalog/postgres.shdescription
? src/backend/postmaster/walreceiver.c
? src/backend/postmaster/walsender.c
? src/backend/snowball/snowball_create.sql
? src/backend/utils/probes.h
? src/backend/utils/mb/conversion_procs/conversion_create.sql
? src/bin/initdb/initdb
? src/bin/pg_config/pg_config
? src/bin/pg_controldata/pg_controldata
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_dump/pg_restore
? src/bin/pg_resetxlog/pg_resetxlog
? src/bin/psql/psql
? src/bin/scripts/clusterdb
? src/bin/scripts/createdb
? src/bin/scripts/createlang
? src/bin/scripts/createuser
? src/bin/scripts/dropdb
? src/bin/scripts/droplang
? src/bin/scripts/dropuser
? src/bin/scripts/reindexdb
? src/bin/scripts/vacuumdb
? src/include/pg_config.h
? src/include/stamp-h
? src/include/postmaster/walreceiver.h
? src/include/postmaster/walsender.h
? src/interfaces/ecpg/compatlib/exports.list
? src/interfaces/ecpg/compatlib/libecpg_compat.so.3.1
? src/interfaces/ecpg/ecpglib/exports.list
? src/interfaces/ecpg/ecpglib/libecpg.so.6.1
? src/interfaces/ecpg/include/ecpg_config.h
? src/interfaces/ecpg/pgtypeslib/exports.list
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.3.1
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/libpq/exports.list
? src/interfaces/libpq/libpq.so.5.2
? src/port/pg_config_paths.h
? src/test/regress/log
? src/test/regress/pg_regress
? src/test/regress/results
? src/test/regress/testtablespace
? src/test/regress/tmp_check
? src/test/regress/expected/constraints.out
? src/test/regress/expected/copy.out
? src/test/regress/expected/create_function_1.out
? src/test/regress/expected/create_function_2.out
? src/test/regress/expected/largeobject.out
? src/test/regress/expected/largeobject_1.out
? src/test/regress/expected/misc.out
? src/test/regress/expected/tablespace.out
? src/test/regress/sql/constraints.sql
? src/test/regress/sql/copy.sql
? src/test/regress/sql/create_function_1.sql
? src/test/regress/sql/create_function_2.sql
? src/test/regress/sql/largeobject.sql
? src/test/regress/sql/misc.sql
? src/test/regress/sql/tablespace.sql
? src/timezone/zic
Index: doc/src/sgml/backup.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/backup.sgml,v
retrieving revision 2.121
diff -c -r2.121 backup.sgml
*** doc/src/sgml/backup.sgml	9 Nov 2008 17:51:15 -0000	2.121
--- doc/src/sgml/backup.sgml	27 Dec 2008 10:57:25 -0000
***************
*** 730,735 ****
--- 730,736 ----
      </para>
  
      <para>
+      If <varname>full_page_writes</> is <literal>off</>,
       <function>pg_start_backup</> can take a long time to finish.
       This is because it performs a checkpoint, and the I/O
       required for a checkpoint will be spread out over a significant
***************
*** 743,748 ****
--- 744,752 ----
       immediately execute <function>pg_start_backup</>.  Then there
       will be very little for <function>pg_start_backup</>'s checkpoint
       to do, and it won't take long.
+      On the other hand, if <varname>full_page_writes</> is <literal>on</>
+      at least from the last checkpoint to <function>pg_start_backup</>,
+      it doesn't perform a checkpoint and take time.
      </para>
     </listitem>
     <listitem>
***************
*** 845,853 ****
      For example, if the starting WAL file is
      <literal>0000000100001234000055CD</> the backup history file will be
      named something like
!     <literal>0000000100001234000055CD.007C9330.backup</>. (The second
      part of the file name stands for an exact position within the WAL
!     file, and can ordinarily be ignored.) Once you have safely archived
      the file system backup and the WAL segment files used during the
      backup (as specified in the backup history file), all archived WAL
      segments with names numerically less are no longer needed to recover
--- 849,859 ----
      For example, if the starting WAL file is
      <literal>0000000100001234000055CD</> the backup history file will be
      named something like
!     <literal>0000000100001234000055CD.007C9330.01.backup</>. (The second
      part of the file name stands for an exact position within the WAL
!     file. The third part is ID number to identify each backup operation
!     which has the same WAL position. These can ordinarily be ignored.) 
!     Once you have safely archived
      the file system backup and the WAL segment files used during the
      backup (as specified in the backup history file), all archived WAL
      segments with names numerically less are no longer needed to recover
***************
*** 859,865 ****
     <para>
      The backup history file is just a small text file. It contains the
      label string you gave to <function>pg_start_backup</>, as well as
!     the starting and ending times and WAL segments of the backup.
      If you used the label to identify where the associated dump file is kept,
      then the archived history file is enough to tell you which dump file to
      restore, should you need to do so.
--- 865,871 ----
     <para>
      The backup history file is just a small text file. It contains the
      label string you gave to <function>pg_start_backup</>, as well as
!     the starting and ending times, WAL segments of the backup and the backup ID.
      If you used the label to identify where the associated dump file is kept,
      then the archived history file is enough to tell you which dump file to
      restore, should you need to do so.
***************
*** 882,889 ****
      This file will of course be archived as a part of your backup dump file.
      The backup label file includes the label string you gave to
      <function>pg_start_backup</>, as well as the time at which
!     <function>pg_start_backup</> was run, and the name of the starting WAL
!     file.  In case of confusion it will
      therefore be possible to look inside a backup dump file and determine
      exactly which backup session the dump file came from.
     </para>
--- 888,895 ----
      This file will of course be archived as a part of your backup dump file.
      The backup label file includes the label string you gave to
      <function>pg_start_backup</>, as well as the time at which
!     <function>pg_start_backup</> was run, the name of the starting WAL file
!     and the backup ID.  In case of confusion it will
      therefore be possible to look inside a backup dump file and determine
      exactly which backup session the dump file came from.
     </para>
Index: doc/src/sgml/config.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/config.sgml,v
retrieving revision 1.200
diff -c -r1.200 config.sgml
*** doc/src/sgml/config.sgml	13 Dec 2008 19:13:43 -0000	1.200
--- doc/src/sgml/config.sgml	27 Dec 2008 10:57:25 -0000
***************
*** 1433,1438 ****
--- 1433,1443 ----
         </para>
  
         <para>
+        When this parameter is off, <function>pg_start_backup</> forces
+        a checkpoint and might take a long time to finish.
+        </para>
+ 
+        <para>
          This parameter can only be set in the <filename>postgresql.conf</>
          file or on the server command line.
          The default is <literal>on</>.
Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.463
diff -c -r1.463 func.sgml
*** doc/src/sgml/func.sgml	19 Dec 2008 16:25:16 -0000	1.463
--- doc/src/sgml/func.sgml	27 Dec 2008 10:57:26 -0000
***************
*** 12560,12566 ****
      <function>pg_start_backup</>, and instead creates a backup history file in
      the transaction log archive area.  The history file includes the label given to
      <function>pg_start_backup</>, the starting and ending transaction log locations for
!     the backup, and the starting and ending times of the backup.  The return
      value is the backup's ending transaction log location (which again might be of little
      interest).  After noting the ending location, the current transaction log insertion
      point is automatically advanced to the next transaction log file, so that the
--- 12560,12566 ----
      <function>pg_start_backup</>, and instead creates a backup history file in
      the transaction log archive area.  The history file includes the label given to
      <function>pg_start_backup</>, the starting and ending transaction log locations for
!     the backup, the backup ID, and the starting and ending times of the backup.  The return
      value is the backup's ending transaction log location (which again might be of little
      interest).  After noting the ending location, the current transaction log insertion
      point is automatically advanced to the next transaction log file, so that the
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.325
diff -c -r1.325 xlog.c
*** src/backend/access/transam/xlog.c	24 Dec 2008 20:41:29 -0000	1.325
--- src/backend/access/transam/xlog.c	27 Dec 2008 10:57:32 -0000
***************
*** 295,300 ****
--- 295,302 ----
  	/* Protected by info_lck: */
  	XLogwrtRqst LogwrtRqst;
  	XLogwrtResult LogwrtResult;
+ 	uint8		bkpCount;		/* ID of bkp using the same ckpt */
+ 	bool		bkpForceCkpt;	/* reset full_page_writes since last ckpt? */
  	uint32		ckptXidEpoch;	/* nextXID & epoch of latest checkpoint */
  	TransactionId ckptXid;
  	XLogRecPtr	asyncCommitLSN; /* LSN of newest async commit */
***************
*** 5862,5867 ****
--- 5864,5884 ----
  	}
  
  	/*
+ 	 * Reset shared-memory copy of backup flag/count. We track whether
+ 	 * full_page_writes is reset after calculating a REDO pointer until
+ 	 * pg_start_backup is called.
+ 	 */
+ 	{
+ 		/* use volatile pointer to prevent code rearrangement */
+ 		volatile XLogCtlData *xlogctl = XLogCtl;
+ 
+ 		SpinLockAcquire(&xlogctl->info_lck);
+ 		xlogctl->bkpCount = 0;
+ 		xlogctl->bkpForceCkpt = true;
+ 		SpinLockRelease(&xlogctl->info_lck);
+ 	}
+ 
+ 	/*
  	 * Compute new REDO record ptr = location of next XLOG record.
  	 *
  	 * NB: this is NOT necessarily where the checkpoint record itself will be,
***************
*** 6502,6507 ****
--- 6519,6546 ----
  	}
  }
  
+ bool
+ assign_full_page_writes(bool newval, bool doit, GucSource source)
+ {
+ 	/*
+ 	 * If full_page_writes is reset, since all indispensable full pages
+ 	 * might not be written since last checkpoint, we force a checkpoint
+ 	 * at pg_start_backup. Only postmaster reset a shared-memory flag
+ 	 * because it's only necessary that one process do this.
+ 	 */
+ 	if (doit && MyProcPid == PostmasterPid && fullPageWrites != newval)
+ 	{
+ 		/* use volatile pointer to prevent code rearrangement */
+ 		volatile XLogCtlData *xlogctl = XLogCtl;
+ 
+ 		SpinLockAcquire(&xlogctl->info_lck);
+ 		xlogctl->bkpForceCkpt = false;
+ 		SpinLockRelease(&xlogctl->info_lck);
+ 	}
+ 	
+ 	return true;
+ }
+ 
  
  /*
   * pg_start_backup: set up for taking an on-line backup dump
***************
*** 6519,6524 ****
--- 6558,6565 ----
  	char	   *backupidstr;
  	XLogRecPtr	checkpointloc;
  	XLogRecPtr	startpoint;
+ 	uint8		bkpCount;
+ 	bool		bkpForceCkpt;
  	pg_time_t	stamp_time;
  	char		strfbuf[128];
  	char		xlogfilename[MAXFNAMELEN];
***************
*** 6554,6565 ****
  	 * written) copy of a database page if it reads the page concurrently with
  	 * our write to the same page.	This can be fixed as long as the first
  	 * write to the page in the WAL sequence is a full-page write. Hence, we
! 	 * turn on forcePageWrites and then force a CHECKPOINT, to ensure there
! 	 * are no dirty pages in shared memory that might get dumped while the
! 	 * backup is in progress without having a corresponding WAL record.  (Once
! 	 * the backup is complete, we need not force full-page writes anymore,
! 	 * since we expect that any pages not modified during the backup interval
! 	 * must have been correctly captured by the backup.)
  	 *
  	 * We must hold WALInsertLock to change the value of forcePageWrites, to
  	 * ensure adequate interlocking against XLogInsert().
--- 6595,6606 ----
  	 * written) copy of a database page if it reads the page concurrently with
  	 * our write to the same page.	This can be fixed as long as the first
  	 * write to the page in the WAL sequence is a full-page write. Hence, we
! 	 * turn on forcePageWrites, then force a CHECKPOINT or use the last one,
! 	 * to ensure there are no dirty pages in shared memory that might get
! 	 * dumped while the backup is in progress without having a corresponding
! 	 * WAL record.  (Once the backup is complete, we need not force full-page
! 	 * writes anymore, since we expect that any pages not modified during the
! 	 * backup interval must have been correctly captured by the backup.)
  	 *
  	 * We must hold WALInsertLock to change the value of forcePageWrites, to
  	 * ensure adequate interlocking against XLogInsert().
***************
*** 6580,6593 ****
  	PG_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) 0);
  	{
  		/*
! 		 * Force a CHECKPOINT.	Aside from being necessary to prevent torn
! 		 * page problems, this guarantees that two successive backup runs will
! 		 * have different checkpoint positions and hence different history
! 		 * file names, even if nothing happened in between.
  		 *
! 		 * We don't use CHECKPOINT_IMMEDIATE, hence this can take awhile.
  		 */
! 		RequestCheckpoint(CHECKPOINT_FORCE | CHECKPOINT_WAIT);
  
  		/*
  		 * Now we need to fetch the checkpoint record location, and also its
--- 6621,6664 ----
  	PG_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) 0);
  	{
  		/*
! 		 * Check whether this online-backup needs a new checkpoint.If all
! 		 * indispensable full-page writes might not be written (because of
! 		 * resetting full_page_writes) since the last checkpoint, we force
! 		 * a CHECKPOINT (We don't use CHECKPOINT_IMMEDIATE, hence this can
! 		 * take awhile). Otherwise, we don't do a new checkpoint and use
! 		 * the last one.
  		 *
! 		 * In the latter situation, the successive backup runs will have
! 		 * same checkpoint positions and hence same history file names,
! 		 * if no checkpoint happens in between. We identify each backup
! 		 * run using the counter in shared memory, to prevent the
! 		 * overwriting of a backup history file. If the counter wraparound
! 		 * occurs, we force a CHECKPONT and ensure that each has different
! 		 * history file name.
  		 */
! 		{
! 			/* use volatile pointer to prevent code rearrangement */
! 			volatile XLogCtlData *xlogctl = XLogCtl;
! 			
! 			SpinLockAcquire(&xlogctl->info_lck);
! 			bkpCount		= ++xlogctl->bkpCount;
! 			bkpForceCkpt	= xlogctl->bkpForceCkpt;
! 			SpinLockRelease(&xlogctl->info_lck);
! 		}
! 
! 		if (!fullPageWrites || !bkpForceCkpt || bkpCount == 0)
! 		{
! 			RequestCheckpoint(CHECKPOINT_FORCE | CHECKPOINT_WAIT);
! 
! 			{
! 				/* use volatile pointer to prevent code rearrangement */
! 				volatile XLogCtlData *xlogctl = XLogCtl;
! 				
! 				SpinLockAcquire(&xlogctl->info_lck);
! 				bkpCount		= ++xlogctl->bkpCount;
! 				SpinLockRelease(&xlogctl->info_lck);
! 			}
! 		}
  
  		/*
  		 * Now we need to fetch the checkpoint record location, and also its
***************
*** 6637,6644 ****
  					(errcode_for_file_access(),
  					 errmsg("could not create file \"%s\": %m",
  							BACKUP_LABEL_FILE)));
! 		fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
! 				startpoint.xlogid, startpoint.xrecoff, xlogfilename);
  		fprintf(fp, "CHECKPOINT LOCATION: %X/%X\n",
  				checkpointloc.xlogid, checkpointloc.xrecoff);
  		fprintf(fp, "START TIME: %s\n", strfbuf);
--- 6708,6715 ----
  					(errcode_for_file_access(),
  					 errmsg("could not create file \"%s\": %m",
  							BACKUP_LABEL_FILE)));
! 		fprintf(fp, "START WAL LOCATION: %X/%X (file %s id %02X)\n",
! 				startpoint.xlogid, startpoint.xrecoff, xlogfilename, bkpCount);
  		fprintf(fp, "CHECKPOINT LOCATION: %X/%X\n",
  				checkpointloc.xlogid, checkpointloc.xrecoff);
  		fprintf(fp, "START TIME: %s\n", strfbuf);
***************
*** 6683,6688 ****
--- 6754,6760 ----
  {
  	XLogRecPtr	startpoint;
  	XLogRecPtr	stoppoint;
+ 	uint8		bkpCount;
  	pg_time_t	stamp_time;
  	char		strfbuf[128];
  	char		histfilepath[MAXPGPATH];
***************
*** 6753,6761 ****
  	 * Read and parse the START WAL LOCATION line (this code is pretty crude,
  	 * but we are not expecting any variability in the file format).
  	 */
! 	if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %24s)%c",
  			   &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename,
! 			   &ch) != 4 || ch != '\n')
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
--- 6825,6833 ----
  	 * Read and parse the START WAL LOCATION line (this code is pretty crude,
  	 * but we are not expecting any variability in the file format).
  	 */
! 	if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %24s id %02X)%c",
  			   &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename,
! 			   &bkpCount, &ch) != 5 || ch != '\n')
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
***************
*** 6765,6779 ****
  	 */
  	XLByteToSeg(startpoint, _logId, _logSeg);
  	BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logId, _logSeg,
! 						  startpoint.xrecoff % XLogSegSize);
  	fp = AllocateFile(histfilepath, "w");
  	if (!fp)
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not create file \"%s\": %m",
  						histfilepath)));
! 	fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
! 			startpoint.xlogid, startpoint.xrecoff, startxlogfilename);
  	fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
  			stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename);
  	/* transfer remaining lines from label to history file */
--- 6837,6851 ----
  	 */
  	XLByteToSeg(startpoint, _logId, _logSeg);
  	BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logId, _logSeg,
! 						  startpoint.xrecoff % XLogSegSize, bkpCount);
  	fp = AllocateFile(histfilepath, "w");
  	if (!fp)
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not create file \"%s\": %m",
  						histfilepath)));
! 	fprintf(fp, "START WAL LOCATION: %X/%X (file %s id %02X)\n",
! 			startpoint.xlogid, startpoint.xrecoff, startxlogfilename, bkpCount);
  	fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
  			stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename);
  	/* transfer remaining lines from label to history file */
***************
*** 6822,6828 ****
  
  	XLByteToSeg(startpoint, _logId, _logSeg);
  	BackupHistoryFileName(histfilename, ThisTimeLineID, _logId, _logSeg,
! 						  startpoint.xrecoff % XLogSegSize);
  
  	seconds_before_warning = 60;
  	waits = 0;
--- 6894,6900 ----
  
  	XLByteToSeg(startpoint, _logId, _logSeg);
  	BackupHistoryFileName(histfilename, ThisTimeLineID, _logId, _logSeg,
! 						  startpoint.xrecoff % XLogSegSize, bkpCount);
  
  	seconds_before_warning = 60;
  	waits = 0;
***************
*** 7060,7065 ****
--- 7132,7138 ----
  {
  	XLogRecPtr	startpoint;
  	XLogRecPtr	stoppoint;
+ 	uint8		bkpCount;
  	char		histfilename[MAXFNAMELEN];
  	char		histfilepath[MAXPGPATH];
  	char		startxlogfilename[MAXFNAMELEN];
***************
*** 7094,7102 ****
  	 * is pretty crude, but we are not expecting any variability in the file
  	 * format).
  	 */
! 	if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %08X%16s)%c",
  			   &startpoint.xlogid, &startpoint.xrecoff, &tli,
! 			   startxlogfilename, &ch) != 5 || ch != '\n')
  		ereport(FATAL,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
--- 7167,7175 ----
  	 * is pretty crude, but we are not expecting any variability in the file
  	 * format).
  	 */
! 	if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %08X%16s id %02X)%c",
  			   &startpoint.xlogid, &startpoint.xrecoff, &tli,
! 			   startxlogfilename, &bkpCount, &ch) != 6 || ch != '\n')
  		ereport(FATAL,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
***************
*** 7117,7129 ****
  	 */
  	XLByteToSeg(startpoint, _logId, _logSeg);
  	BackupHistoryFileName(histfilename, tli, _logId, _logSeg,
! 						  startpoint.xrecoff % XLogSegSize);
  
  	if (InArchiveRecovery)
  		RestoreArchivedFile(histfilepath, histfilename, "RECOVERYHISTORY", 0);
  	else
  		BackupHistoryFilePath(histfilepath, tli, _logId, _logSeg,
! 							  startpoint.xrecoff % XLogSegSize);
  
  	fp = AllocateFile(histfilepath, "r");
  	if (fp)
--- 7190,7202 ----
  	 */
  	XLByteToSeg(startpoint, _logId, _logSeg);
  	BackupHistoryFileName(histfilename, tli, _logId, _logSeg,
! 						  startpoint.xrecoff % XLogSegSize, bkpCount);
  
  	if (InArchiveRecovery)
  		RestoreArchivedFile(histfilepath, histfilename, "RECOVERYHISTORY", 0);
  	else
  		BackupHistoryFilePath(histfilepath, tli, _logId, _logSeg,
! 							  startpoint.xrecoff % XLogSegSize, bkpCount);
  
  	fp = AllocateFile(histfilepath, "r");
  	if (fp)
***************
*** 7131,7139 ****
  		/*
  		 * Parse history file to identify stop point.
  		 */
! 		if (fscanf(fp, "START WAL LOCATION: %X/%X (file %24s)%c",
  				   &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename,
! 				   &ch) != 4 || ch != '\n')
  			ereport(FATAL,
  					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  					 errmsg("invalid data in file \"%s\"", histfilename)));
--- 7204,7212 ----
  		/*
  		 * Parse history file to identify stop point.
  		 */
! 		if (fscanf(fp, "START WAL LOCATION: %X/%X (file %24s id %02X)%c",
  				   &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename,
! 				   &bkpCount, &ch) != 5 || ch != '\n')
  			ereport(FATAL,
  					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  					 errmsg("invalid data in file \"%s\"", histfilename)));
Index: src/backend/postmaster/pgarch.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/postmaster/pgarch.c,v
retrieving revision 1.38
diff -c -r1.38 pgarch.c
*** src/backend/postmaster/pgarch.c	11 Jan 2008 00:54:08 -0000	1.38
--- src/backend/postmaster/pgarch.c	27 Dec 2008 10:57:43 -0000
***************
*** 66,72 ****
   * ----------
   */
  #define MIN_XFN_CHARS	16
! #define MAX_XFN_CHARS	40
  #define VALID_XFN_CHARS "0123456789ABCDEF.history.backup"
  
  #define NUM_ARCHIVE_RETRIES 3
--- 66,72 ----
   * ----------
   */
  #define MIN_XFN_CHARS	16
! #define MAX_XFN_CHARS	43
  #define VALID_XFN_CHARS "0123456789ABCDEF.history.backup"
  
  #define NUM_ARCHIVE_RETRIES 3
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.483
diff -c -r1.483 guc.c
*** src/backend/utils/misc/guc.c	13 Dec 2008 19:13:44 -0000	1.483
--- src/backend/utils/misc/guc.c	27 Dec 2008 10:57:58 -0000
***************
*** 57,62 ****
--- 57,63 ----
  #include "regex/regex.h"
  #include "storage/bufmgr.h"
  #include "storage/fd.h"
+ #include "storage/spin.h"
  #include "tcop/tcopprot.h"
  #include "tsearch/ts_cache.h"
  #include "utils/builtins.h"
***************
*** 713,719 ****
  						 "is possible.")
  		},
  		&fullPageWrites,
! 		true, NULL, NULL
  	},
  	{
  		{"silent_mode", PGC_POSTMASTER, LOGGING_WHEN,
--- 714,720 ----
  						 "is possible.")
  		},
  		&fullPageWrites,
! 		true, assign_full_page_writes, NULL
  	},
  	{
  		{"silent_mode", PGC_POSTMASTER, LOGGING_WHEN,
Index: src/include/access/xlog_internal.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/xlog_internal.h,v
retrieving revision 1.24
diff -c -r1.24 xlog_internal.h
*** src/include/access/xlog_internal.h	11 Aug 2008 11:05:11 -0000	1.24
--- src/include/access/xlog_internal.h	27 Dec 2008 10:58:03 -0000
***************
*** 215,225 ****
  #define StatusFilePath(path, xlog, suffix)	\
  	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix)
  
! #define BackupHistoryFileName(fname, tli, log, seg, offset) \
! 	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, log, seg, offset)
  
! #define BackupHistoryFilePath(path, tli, log, seg, offset)	\
! 	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, log, seg, offset)
  
  
  /*
--- 215,225 ----
  #define StatusFilePath(path, xlog, suffix)	\
  	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix)
  
! #define BackupHistoryFileName(fname, tli, log, seg, offset, count)			\
! 	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.%02X.backup", tli, log, seg, offset, count)
  
! #define BackupHistoryFilePath(path, tli, log, seg, offset, count)				\
! 	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.%02X.backup", tli, log, seg, offset, count)
  
  
  /*
Index: src/include/utils/guc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.99
diff -c -r1.99 guc.h
*** src/include/utils/guc.h	19 Nov 2008 01:10:23 -0000	1.99
--- src/include/utils/guc.h	27 Dec 2008 10:58:04 -0000
***************
*** 308,312 ****
--- 308,314 ----
  /* in access/transam/xlog.c */
  extern bool assign_xlog_sync_method(int newval,
  				bool doit, GucSource source);
+ extern bool assign_full_page_writes(bool newval,
+ 				bool doit, GucSource source);
  
  #endif   /* GUC_H */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to