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