On Wed, 2006-08-16 at 10:09 +0100, Simon Riggs wrote:
> On Thu, 2006-08-03 at 19:03 +0100, Simon Riggs wrote:
> > On Thu, 2006-08-03 at 13:38 -0400, Tom Lane wrote:
> > > Simon Riggs <[EMAIL PROTECTED]> writes:
> > > > WIP archive_timeout.
> > > > All we need to do is add LWLock support to archiver.
> > > > Thoughts/ideas/hints welcome.
> > > 
> > > Hint: this isn't the archiver's problem, and so you don't need to get
> > > the archiver involved in the solution.  I'd suggest bgwriter as a
> > > reasonably appropriate place instead.
> 
> Revised patch enclosed, now believed to be production ready. This
> implements regular log switching using the archive_timeout GUC.

Further patch enclosed implementing these changes plus the record type
version of pg_xlogfile_name_offset()

-- 
  Simon Riggs             
  EnterpriseDB   http://www.enterprisedb.com
Index: doc/src/sgml/backup.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/backup.sgml,v
retrieving revision 2.82
diff -c -r2.82 backup.sgml
*** doc/src/sgml/backup.sgml	6 Aug 2006 03:53:43 -0000	2.82
--- doc/src/sgml/backup.sgml	16 Aug 2006 22:05:10 -0000
***************
*** 573,600 ****
      the <filename>pg_xlog/</> directory will contain large numbers of
      not-yet-archived segment files, which could eventually exceed available
      disk space. You are advised to monitor the archiving process to ensure that
!     it is working as you intend.
     </para>
  
     <para>
!     If you are concerned about being able to recover right up to the
!     current instant, you may want to take additional steps to ensure that
!     the current, partially-filled WAL segment is also copied someplace.
!     This is particularly important if your server generates only little WAL
!     traffic (or has slack periods where it does so), since it could take a
!     long time before a WAL segment file is completely filled and ready to
!     archive.  One possible way to handle this is to set up a
!     <application>cron</> job that periodically (once a minute, perhaps)
!     identifies the current WAL segment file and saves it someplace safe.
!     Then the combination of the archived WAL segments and the saved current
!     segment will be enough to ensure you can always restore to within a
!     minute of current time.  This behavior is not presently built into
!     <productname>PostgreSQL</> because we did not want to complicate the
!     definition of the <xref linkend="guc-archive-command"> by requiring it
!     to keep track of successively archived, but different, copies of the
!     same WAL file.  The <xref linkend="guc-archive-command"> is only
!     invoked on completed WAL segments. Except in the case of retrying a
!     failure, it will be called only once for any given file name.
     </para>
  
     <para>
--- 573,593 ----
      the <filename>pg_xlog/</> directory will contain large numbers of
      not-yet-archived segment files, which could eventually exceed available
      disk space. You are advised to monitor the archiving process to ensure that
!     it is working as you intend. 
     </para>
  
     <para>
!     The <xref linkend="guc-archive-command"> is only invoked on completed 
!     WAL segments. This could lead to delays in producing the next archive
!     if your server generates only little WAL traffic (or has slack periods 
!     where it does so). To ensure regular archives are produced you can 
!     specify an <xref linkend="guc-archive-timeout"> which will automatically
!     switch to a new WAL segment file during quieter periods. Archived files
!     produced in this way are still the same length as completely full files,
!     though entries made after the final processing instruction can be ignored.
!     Switching to a new WAL segment file can be performed manually using
!     <function>pg_switch_xlog</>. A variety of other utility functions are
!     also available, listed in <xref linkend="functions-admin-backup-table">
     </para>
  
     <para>
Index: doc/src/sgml/config.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/config.sgml,v
retrieving revision 1.74
diff -c -r1.74 config.sgml
*** doc/src/sgml/config.sgml	15 Aug 2006 18:26:58 -0000	1.74
--- doc/src/sgml/config.sgml	16 Aug 2006 22:05:17 -0000
***************
*** 1584,1589 ****
--- 1584,1612 ----
        </listitem>
       </varlistentry>
       
+      <varlistentry id="guc-archive-timeout" xreflabel="archive_timeout">
+       <term><varname>archive_timeout</varname> (<type>string</type>)</term>
+       <indexterm>
+        <primary><varname>archive_timeout</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        <para>
+         The <xref linkend="guc-archive-command"> is only invoked on completed 
+         WAL segments. This could lead to delays in producing the next archive
+         if your server generates only little WAL traffic (or has slack periods 
+         where it does so). This parameter provides regular archiving by
+         making sure that no more than <xref linkend="guc-archive-command">
+         go by before a new WAL segment file is produced for archiving, even
+         if that means we archive a partially filled file. Zero disables this
+         feature, which is the default Valid values are from 1 to 60 seconds.
+         This parameter can only be set in the <filename>postgresql.conf</>
+         file or on the server command line. Be careful to set 
+         <varname>checkpoint_segments</> sufficiently high that you do not
+         inadvertently increase the rate at which checkpoints occur.
+        </para>
+       </listitem>
+      </varlistentry>
+      
       </variablelist>
      </sect2>
     </sect1>
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.247
diff -c -r1.247 xlog.c
*** src/backend/access/transam/xlog.c	7 Aug 2006 16:57:56 -0000	1.247
--- src/backend/access/transam/xlog.c	16 Aug 2006 22:05:21 -0000
***************
*** 23,28 ****
--- 23,29 ----
  #include <sys/time.h>
  
  #include "access/clog.h"
+ #include "access/heapam.h"
  #include "access/multixact.h"
  #include "access/subtrans.h"
  #include "access/transam.h"
***************
*** 32,37 ****
--- 33,40 ----
  #include "access/xlogutils.h"
  #include "catalog/catversion.h"
  #include "catalog/pg_control.h"
+ #include "catalog/pg_type.h"
+ #include "funcapi.h"
  #include "miscadmin.h"
  #include "pgstat.h"
  #include "postmaster/bgwriter.h"
***************
*** 128,133 ****
--- 131,137 ----
  /* User-settable parameters */
  int			CheckPointSegments = 3;
  int			XLOGbuffers = 8;
+ int         XLogArchiveTimeout = 0;
  char	   *XLogArchiveCommand = NULL;
  char	   *XLOG_sync_method = NULL;
  const char	XLOG_sync_method_default[] = DEFAULT_SYNC_METHOD_STR;
***************
*** 5308,5313 ****
--- 5312,5333 ----
  }
  
  /*
+  * Get the current WAL Insert pointer ... shared lock is sufficient
+  */
+ XLogRecPtr
+ GetWALInsertPtr(void)
+ {
+ 	XLogCtlInsert *Insert = &XLogCtl->Insert;
+     XLogRecPtr InsertRecPtr;
+ 
+ 	LWLockAcquire(WALInsertLock, LW_SHARED);
+ 	INSERT_RECPTR(InsertRecPtr, Insert, Insert->curridx);
+ 	LWLockRelease(WALInsertLock);
+ 
+ 	return InsertRecPtr;
+ }
+ 
+ /*
   * GetRecentNextXid - get the nextXid value saved by the most recent checkpoint
   *
   * This is currently used only by the autovacuum daemon.  To check for
***************
*** 5728,5734 ****
   * or the end+1 address of the prior segment if we did not need to
   * write a switch record because we are already at segment start.
   */
! static XLogRecPtr
  RequestXLogSwitch(void)
  {
  	XLogRecPtr	RecPtr;
--- 5748,5754 ----
   * or the end+1 address of the prior segment if we did not need to
   * write a switch record because we are already at segment start.
   */
! XLogRecPtr
  RequestXLogSwitch(void)
  {
  	XLogRecPtr	RecPtr;
***************
*** 6336,6356 ****
  
  /*
   * Report the current WAL location (same format as pg_start_backup etc)
   */
  Datum
  pg_current_xlog_location(PG_FUNCTION_ARGS)
  {
  	text	   *result;
- 	XLogCtlInsert *Insert = &XLogCtl->Insert;
- 	XLogRecPtr	current_recptr;
  	char		location[MAXFNAMELEN];
  
  	/*
! 	 * Get the current end-of-WAL position ... shared lock is sufficient
  	 */
! 	LWLockAcquire(WALInsertLock, LW_SHARED);
! 	INSERT_RECPTR(current_recptr, Insert, Insert->curridx);
! 	LWLockRelease(WALInsertLock);
  
  	snprintf(location, sizeof(location), "%X/%X",
  			 current_recptr.xlogid, current_recptr.xrecoff);
--- 6356,6407 ----
  
  /*
   * Report the current WAL location (same format as pg_start_backup etc)
+  *
+  * This is the current Write pointer, so is useful for determining the
+  * current byte offset within a WAL file that has valid data written to it. 
+  * Note that data written is not always committed yet, see XLogInsert()
   */
  Datum
  pg_current_xlog_location(PG_FUNCTION_ARGS)
  {
  	text	   *result;
  	char		location[MAXFNAMELEN];
  
  	/*
! 	 * Get the current end-of-WAL position by updating LogwrtResult
  	 */
! 	{
! 		/* use volatile pointer to prevent code rearrangement */
! 		volatile XLogCtlData *xlogctl = XLogCtl;
! 
! 		SpinLockAcquire(&xlogctl->info_lck);
! 		LogwrtResult = xlogctl->LogwrtResult;
! 		SpinLockRelease(&xlogctl->info_lck);
! 	}
! 
! 	snprintf(location, sizeof(location), "%X/%X",
! 			 LogwrtResult.Write.xlogid, LogwrtResult.Write.xrecoff);
! 
! 	result = DatumGetTextP(DirectFunctionCall1(textin,
! 											   CStringGetDatum(location)));
! 	PG_RETURN_TEXT_P(result);
! }
! 
! /*
!  * Report the current WAL location (same format as pg_start_backup etc)
!  *
!  * This is the current Insert pointer. The name is deliberately chosen
!  * to be different from pg_current_xlog_location so people do not confuse
!  * the two functions. This function is mostly for debugging purposes.
!  */
! Datum
! pg_current_wal_insert_pointer(PG_FUNCTION_ARGS)
! {
! 	text	   *result;
! 	XLogRecPtr	current_recptr;
! 	char		location[MAXFNAMELEN];
! 
!     current_recptr = GetWALInsertPtr();
  
  	snprintf(location, sizeof(location), "%X/%X",
  			 current_recptr.xlogid, current_recptr.xrecoff);
***************
*** 6372,6378 ****
  pg_xlogfile_name_offset(PG_FUNCTION_ARGS)
  {
  	text	   *location = PG_GETARG_TEXT_P(0);
- 	text	   *result;
  	char	   *locationstr;
  	unsigned int uxlogid;
  	unsigned int uxrecoff;
--- 6423,6428 ----
***************
*** 6381,6387 ****
  	uint32		xrecoff;
  	XLogRecPtr	locationpoint;
  	char		xlogfilename[MAXFNAMELEN];
! 
  	locationstr = DatumGetCString(DirectFunctionCall1(textout,
  												PointerGetDatum(location)));
  
--- 6431,6445 ----
  	uint32		xrecoff;
  	XLogRecPtr	locationpoint;
  	char		xlogfilename[MAXFNAMELEN];
!     Datum       values[2];
!     bool        isnull[2];
!     TupleDesc   resultTupleDesc;
!     HeapTuple   resultHeapTuple;
! 	Datum	    result;
! 
!     /*
!      * Read input and parse
!      */
  	locationstr = DatumGetCString(DirectFunctionCall1(textout,
  												PointerGetDatum(location)));
  
***************
*** 6394,6411 ****
  	locationpoint.xlogid = uxlogid;
  	locationpoint.xrecoff = uxrecoff;
  
  	XLByteToPrevSeg(locationpoint, xlogid, xlogseg);
  	XLogFileName(xlogfilename, ThisTimeLineID, xlogid, xlogseg);
  
  	xrecoff = locationpoint.xrecoff - xlogseg * XLogSegSize;
- 	snprintf(xlogfilename + strlen(xlogfilename),
- 			 sizeof(xlogfilename) - strlen(xlogfilename),
- 			 " %u",
- 			 (unsigned int) xrecoff);
  
! 	result = DatumGetTextP(DirectFunctionCall1(textin,
! 											   CStringGetDatum(xlogfilename)));
! 	PG_RETURN_TEXT_P(result);
  }
  
  /*
--- 6452,6493 ----
  	locationpoint.xlogid = uxlogid;
  	locationpoint.xrecoff = uxrecoff;
  
+ 	/* Construct a tuple descriptor for the result rows. */
+ 	resultTupleDesc = CreateTemplateTupleDesc(2, false);
+ 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "filename",
+ 					   TEXTOID, -1, 0);
+ 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "fileoffset",
+ 					   INT4OID, -1, 0);
+ 
+ 	resultTupleDesc = BlessTupleDesc(resultTupleDesc);
+ 
+     /*
+      * xlogfilename
+      */
  	XLByteToPrevSeg(locationpoint, xlogid, xlogseg);
+ 
  	XLogFileName(xlogfilename, ThisTimeLineID, xlogid, xlogseg);
  
+     values[0] = DirectFunctionCall1(textin,
+ 										CStringGetDatum(xlogfilename));
+     isnull[0] = false;
+ 
+     /*
+      * offset
+      */
  	xrecoff = locationpoint.xrecoff - xlogseg * XLogSegSize;
  
!     values[1] = UInt32GetDatum(xrecoff);
!     isnull[1] = false;
! 
!     /*
!      * Tuple jam: Having first prepared your Datums, then squash together
!      */
!     resultHeapTuple = heap_form_tuple(resultTupleDesc, values, isnull);
! 
!     result = HeapTupleGetDatum(resultHeapTuple);
! 
!     PG_RETURN_DATUM(result);
  }
  
  /*
Index: src/backend/postmaster/bgwriter.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/postmaster/bgwriter.c,v
retrieving revision 1.26
diff -c -r1.26 bgwriter.c
*** src/backend/postmaster/bgwriter.c	14 Jul 2006 14:52:22 -0000	1.26
--- src/backend/postmaster/bgwriter.c	16 Aug 2006 22:05:22 -0000
***************
*** 48,53 ****
--- 48,54 ----
  
  #include "libpq/pqsignal.h"
  #include "miscadmin.h"
+ #include "access/xlog_internal.h"
  #include "postmaster/bgwriter.h"
  #include "storage/fd.h"
  #include "storage/freespace.h"
***************
*** 144,149 ****
--- 145,154 ----
  static bool ckpt_active = false;
  
  static time_t last_checkpoint_time;
+ static time_t last_check_xlog_time;
+ static uint32 last_check_xlogid;
+ static uint32 last_check_xlogseg;
+ static XLogRecPtr pre_switch_xlog_recptr;
  
  
  static void bg_quickdie(SIGNAL_ARGS);
***************
*** 205,214 ****
  #endif
  
  	/*
! 	 * Initialize so that first time-driven checkpoint happens at the correct
  	 * time.
  	 */
! 	last_checkpoint_time = time(NULL);
  
  	/*
  	 * Create a resource owner to keep track of our resources (currently
--- 210,231 ----
  #endif
  
  	/*
! 	 * Initialize so that first time-driven event happens at the correct
  	 * time.
  	 */
! 	last_check_xlog_time = last_checkpoint_time = time(NULL);
! 
!     /*
!      * Allow bgwriter to read xlog details
!      */
!     InitXLOGAccess();
! 
!     /*
!      * Initialize the values for logid and segid, so we tell whether
!      * we need to force log switching
!      */
!     pre_switch_xlog_recptr = GetWALInsertPtr();
! 	XLByteToPrevSeg(pre_switch_xlog_recptr, last_check_xlogid, last_check_xlogseg);
  
  	/*
  	 * Create a resource owner to keep track of our resources (currently
***************
*** 309,315 ****
  		bool		do_checkpoint = false;
  		bool		force_checkpoint = false;
  		time_t		now;
! 		int			elapsed_secs;
  		long		udelay;
  
  		/*
--- 326,333 ----
  		bool		do_checkpoint = false;
  		bool		force_checkpoint = false;
  		time_t		now;
! 		int			elapsed_since_checkpoint_secs;
! 		int			elapsed_since_switch_xlog_secs;
  		long		udelay;
  
  		/*
***************
*** 348,355 ****
  		 * last one.
  		 */
  		now = time(NULL);
! 		elapsed_secs = now - last_checkpoint_time;
! 		if (elapsed_secs >= CheckPointTimeout)
  			do_checkpoint = true;
  
  		/*
--- 366,373 ----
  		 * last one.
  		 */
  		now = time(NULL);
! 		elapsed_since_checkpoint_secs = now - last_checkpoint_time;
! 		if (elapsed_since_checkpoint_secs >= CheckPointTimeout)
  			do_checkpoint = true;
  
  		/*
***************
*** 366,375 ****
  			 * CheckPointTimeout < CheckPointWarning.
  			 */
  			if (BgWriterShmem->ckpt_time_warn &&
! 				elapsed_secs < CheckPointWarning)
  				ereport(LOG,
  						(errmsg("checkpoints are occurring too frequently (%d seconds apart)",
! 								elapsed_secs),
  						 errhint("Consider increasing the configuration parameter \"checkpoint_segments\".")));
  			BgWriterShmem->ckpt_time_warn = false;
  
--- 384,393 ----
  			 * CheckPointTimeout < CheckPointWarning.
  			 */
  			if (BgWriterShmem->ckpt_time_warn &&
! 				elapsed_since_checkpoint_secs < CheckPointWarning)
  				ereport(LOG,
  						(errmsg("checkpoints are occurring too frequently (%d seconds apart)",
! 								elapsed_since_checkpoint_secs),
  						 errhint("Consider increasing the configuration parameter \"checkpoint_segments\".")));
  			BgWriterShmem->ckpt_time_warn = false;
  
***************
*** 403,408 ****
--- 421,483 ----
  		else
  			BgBufferSync();
  
+         /*
+          * Check for archive_timeout, if so, switch xlog files 
+          */
+         if (XLogArchiveTimeout > 0)
+         {
+     		/*
+     		 * If we did a checkpoint, we probably need to get the time again
+     		 * since its likely to be a while since that started
+     		 */
+             if (do_checkpoint)
+         		now = time(NULL);
+ 
+     		elapsed_since_switch_xlog_secs = now - last_check_xlog_time;
+ 
+             /*
+              * Check whether the timeout is due
+              */
+     		if (elapsed_since_switch_xlog_secs >= XLogArchiveTimeout)
+             {
+             	uint32		current_xlogid;
+             	uint32		current_xlogseg;
+ 
+                 /*
+                  * If the timeout is due, check whether or not we're still
+                  * in the same xlog file as last switch. If we are then we 
+                  * know we want to force a switch. We check the Insert
+                  * pointer here, not the Write pointer, but it's not important
+                  */
+                 pre_switch_xlog_recptr = GetWALInsertPtr();
+             	XLByteToPrevSeg(pre_switch_xlog_recptr, current_xlogid, current_xlogseg);
+ 
+                 if (current_xlogid == last_check_xlogid &&
+                     current_xlogseg == last_check_xlogseg)
+                 {
+                     XLogRecPtr  switch_xlog_recptr = RequestXLogSwitch();
+ 
+                     /*
+                      * Report activity and reset last_switch values
+                      * only if we actually performed a switch
+                      */
+                     if (XLByteLT(pre_switch_xlog_recptr, switch_xlog_recptr))
+                     {
+         				ereport(LOG,
+     						(errmsg("automatic xlog switch performed (archive_timeout=%d)",
+                                     XLogArchiveTimeout)));
+                        	XLByteToPrevSeg(switch_xlog_recptr, last_check_xlogid, last_check_xlogseg);
+                     }
+                 	last_check_xlog_time = time(NULL);
+                 }
+                 else
+                 {
+                     last_check_xlogid = current_xlogid;
+                     last_check_xlogseg = current_xlogseg;
+                 }
+             }
+         }
+ 
  		/*
  		 * Nap for the configured time, or sleep for 10 seconds if there is no
  		 * bgwriter activity configured.
***************
*** 416,425 ****
  		 */
  		if ((bgwriter_all_percent > 0.0 && bgwriter_all_maxpages > 0) ||
  			(bgwriter_lru_percent > 0.0 && bgwriter_lru_maxpages > 0))
! 			udelay = BgWriterDelay * 1000L;
! 		else
! 			udelay = 10000000L;
! 		while (udelay > 1000000L)
  		{
  			if (got_SIGHUP || checkpoint_requested || shutdown_requested)
  				break;
--- 491,503 ----
  		 */
  		if ((bgwriter_all_percent > 0.0 && bgwriter_all_maxpages > 0) ||
  			(bgwriter_lru_percent > 0.0 && bgwriter_lru_maxpages > 0))
!    			udelay = BgWriterDelay * 1000L;
! 		else if (XLogArchiveTimeout > 0)
! 			udelay = 1000000L;   /* One second */
!         else
! 			udelay = 10000000L;  /* Ten seconds */
! 
! 		while (udelay > 999999L)
  		{
  			if (got_SIGHUP || checkpoint_requested || shutdown_requested)
  				break;
***************
*** 427,432 ****
--- 505,511 ----
  			AbsorbFsyncRequests();
  			udelay -= 1000000L;
  		}
+ 
  		if (!(got_SIGHUP || checkpoint_requested || shutdown_requested))
  			pg_usleep(udelay);
  	}
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.342
diff -c -r1.342 guc.c
*** src/backend/utils/misc/guc.c	15 Aug 2006 18:26:59 -0000	1.342
--- src/backend/utils/misc/guc.c	16 Aug 2006 22:05:25 -0000
***************
*** 29,34 ****
--- 29,35 ----
  #include "access/gin.h"
  #include "access/twophase.h"
  #include "access/xact.h"
+ #include "access/xlog_internal.h"
  #include "catalog/namespace.h"
  #include "commands/async.h"
  #include "commands/vacuum.h"
***************
*** 1020,1025 ****
--- 1021,1035 ----
  static struct config_int ConfigureNamesInt[] =
  {
  	{
+ 		{"archive_timeout", PGC_SIGHUP, WAL_SETTINGS,
+ 		 gettext_noop("Will force a switch to the next xlog file if a new file has not "
+                       "been started within N seconds."),
+ 		 gettext_noop("This allows regular continuous archiving to take place.")
+ 		},
+ 		&XLogArchiveTimeout,
+ 		0, 0, 60, NULL, NULL
+ 	},
+ 	{
  		{"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS,
  		 gettext_noop("Waits N seconds on connection startup after authentication."),
  		 gettext_noop("This allows attaching a debugger to the process."),
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.186
diff -c -r1.186 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample	15 Aug 2006 18:26:59 -0000	1.186
--- src/backend/utils/misc/postgresql.conf.sample	16 Aug 2006 22:05:25 -0000
***************
*** 167,174 ****
  
  # - Archiving -
  
! #archive_command = ''			# command to use to archive a logfile 
! 					# segment
  
  
  #---------------------------------------------------------------------------
--- 167,176 ----
  
  # - Archiving -
  
! # command to use to archive a logfile segment
! #archive_command = ''		
! #archive_timeout = 0        # automatic xlog switch gives regular archiving
!                             # range 0-60 in seconds, 0 is off 
  
  
  #---------------------------------------------------------------------------
Index: src/include/access/xlog.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/xlog.h,v
retrieving revision 1.72
diff -c -r1.72 xlog.h
*** src/include/access/xlog.h	13 Jul 2006 16:49:19 -0000	1.72
--- src/include/access/xlog.h	16 Aug 2006 22:05:25 -0000
***************
*** 139,144 ****
--- 139,145 ----
  extern int	CheckPointSegments;
  extern int	XLOGbuffers;
  extern char *XLogArchiveCommand;
+ /* extern int XLogArchiveTimeout; -- included in xlog_internal.h */
  extern char *XLOG_sync_method;
  extern const char XLOG_sync_method_default[];
  
Index: src/include/access/xlog_internal.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/xlog_internal.h,v
retrieving revision 1.15
diff -c -r1.15 xlog_internal.h
*** src/include/access/xlog_internal.h	7 Aug 2006 16:57:57 -0000	1.15
--- src/include/access/xlog_internal.h	16 Aug 2006 22:05:25 -0000
***************
*** 237,242 ****
--- 237,249 ----
  
  extern const RmgrData RmgrTable[];
  
+ /* 
+  * These are required to allow xlog switching from bgwriter
+  */
+ extern XLogRecPtr RequestXLogSwitch(void);
+ extern XLogRecPtr GetWALInsertPtr(void);
+ extern int XLogArchiveTimeout;
+ 
  /*
   * These aren't in xlog.h because I'd rather not include fmgr.h there.
   */
***************
*** 244,249 ****
--- 251,257 ----
  extern Datum pg_stop_backup(PG_FUNCTION_ARGS);
  extern Datum pg_switch_xlog(PG_FUNCTION_ARGS);
  extern Datum pg_current_xlog_location(PG_FUNCTION_ARGS);
+ extern Datum pg_current_wal_insert_pointer(PG_FUNCTION_ARGS);
  extern Datum pg_xlogfile_name_offset(PG_FUNCTION_ARGS);
  extern Datum pg_xlogfile_name(PG_FUNCTION_ARGS);
  
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.420
diff -c -r1.420 pg_proc.h
*** src/include/catalog/pg_proc.h	6 Aug 2006 03:53:44 -0000	1.420
--- src/include/catalog/pg_proc.h	16 Aug 2006 22:05:31 -0000
***************
*** 3105,3111 ****
  DESCR("Switch to new xlog file");
  DATA(insert OID = 2849 ( pg_current_xlog_location	PGNSP PGUID 12 f f t f v 0 25 "" _null_ _null_ _null_ pg_current_xlog_location - _null_ ));
  DESCR("current xlog location");
! DATA(insert OID = 2850 ( pg_xlogfile_name_offset	PGNSP PGUID 12 f f t f i 1 25 "25" _null_ _null_ _null_ pg_xlogfile_name_offset - _null_ ));
  DESCR("xlog filename and byte offset, given an xlog location");
  DATA(insert OID = 2851 ( pg_xlogfile_name			PGNSP PGUID 12 f f t f i 1 25 "25" _null_ _null_ _null_ pg_xlogfile_name - _null_ ));
  DESCR("xlog filename, given an xlog location");
--- 3105,3113 ----
  DESCR("Switch to new xlog file");
  DATA(insert OID = 2849 ( pg_current_xlog_location	PGNSP PGUID 12 f f t f v 0 25 "" _null_ _null_ _null_ pg_current_xlog_location - _null_ ));
  DESCR("current xlog location");
! DATA(insert OID = 2852 ( pg_current_wal_insert_pointer	PGNSP PGUID 12 f f t f v 0 25 "" _null_ _null_ _null_ pg_current_wal_insert_pointer - _null_ ));
! DESCR("current wal insert pointer");
! DATA(insert OID = 2850 ( pg_xlogfile_name_offset	PGNSP PGUID 12 f f t f i 1 2249 "25" "{25,25,23}" "{i,o,o}" "{wal_location,filename,fileoffset}" pg_xlogfile_name_offset - _null_ ));
  DESCR("xlog filename and byte offset, given an xlog location");
  DATA(insert OID = 2851 ( pg_xlogfile_name			PGNSP PGUID 12 f f t f i 1 25 "25" _null_ _null_ _null_ pg_xlogfile_name - _null_ ));
  DESCR("xlog filename, given an xlog location");
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faq

Reply via email to