Implement archive_timeout feature to force xlog file switches to occur no more

than N seconds apart.  This allows a simple, if not very high performance,
means of guaranteeing that a PITR archive is no more than N seconds behind
real time.  Also make pg_current_xlog_location return the WAL Write pointer,
add pg_current_xlog_insert_location to return the Insert pointer, and fix
pg_xlogfile_name_offset to return its results as a two-element record instead
of a smashed-together string, as per recent discussion.

Simon Riggs
This commit is contained in:
Tom Lane 2006-08-17 23:04:10 +00:00
parent bb764e94ce
commit e8ea9e9587
11 changed files with 279 additions and 74 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.82 2006/08/06 03:53:43 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.83 2006/08/17 23:04:02 tgl Exp $ -->
<chapter id="backup">
<title>Backup and Restore</title>
@ -492,7 +492,7 @@ tar -cf backup.tar /usr/local/pgsql/data
the archiving will be done. Instead, <productname>PostgreSQL</> lets
the administrator specify a shell command to be executed to copy a
completed segment file to wherever it needs to go. The command could be
as simple as a <application>cp</>, or it could invoke a complex shell
as simple as a <literal>cp</>, or it could invoke a complex shell
script &mdash; it's all up to you.
</para>
@ -576,36 +576,6 @@ archive_command = 'test ! -f .../%f &amp;&amp; cp %p .../%f'
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>
Another way to limit your exposure to data loss is to call
<function>pg_switch_xlog()</> periodically, such as once a minute.
This function forces the current WAL segment file to be completed
and made available to the archiving command. This approach does
not work well for extremely short update intervals, however, since
copying a new 16MB segment file every few seconds is expensive.
</para>
<para>
In writing your archive command, you should assume that the file names to
be archived may be up to 64 characters long and may contain any
@ -626,6 +596,29 @@ archive_command = 'test ! -f .../%f &amp;&amp; cp %p .../%f'
<xref linkend="runtime-config-file-locations"> for how to relocate the
configuration files.
</para>
<para>
The archive command is only invoked on completed WAL segments. Hence,
if your server generates only little WAL traffic (or has slack periods
where it does so), there could be a long delay between the completion
of a transaction and its safe recording in archive storage. To put
a limit on how old unarchived data can be, you can set
<xref linkend="guc-archive-timeout"> to force the server to switch
to a new WAL segment file at least that often. Note that archived
files that are ended early due to a forced switch are still the same
length as completely full files. It is therefore unwise to set a very
short <varname>archive_timeout</> &mdash; it will bloat your archive
storage. <varname>archive_timeout</> settings of a minute or so are
usually reasonable.
</para>
<para>
Also, you can force a segment switch manually with
<function>pg_switch_xlog()</>,
if you want to ensure that a just-finished transaction is archived
immediately. Other utility functions related to WAL management are
listed in <xref linkend="functions-admin-backup-table">.
</para>
</sect2>
<sect2 id="backup-base-backup">

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.74 2006/08/15 18:26:58 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.75 2006/08/17 23:04:03 tgl Exp $ -->
<chapter Id="runtime-config">
<title>Server Configuration</title>
@ -1584,6 +1584,35 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Windows
</listitem>
</varlistentry>
<varlistentry id="guc-archive-timeout" xreflabel="archive_timeout">
<term><varname>archive_timeout</varname> (<type>integer</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. Hence,
if your server generates only little WAL traffic (or has slack periods
where it does so), there could be a long delay between the completion
of a transaction and its safe recording in archive storage. To put
a limit on how old unarchived data can be, you can set
<varname>archive_timeout</> to force the server to switch
to a new WAL segment file periodically. When this parameter is
greater than zero, the server will switch to a new segment file
whenever this many seconds elapse since the last segment file switch.
Note that archived
files that are ended early due to a forced switch are still the same
length as completely full files. It is therefore unwise to set a very
short <varname>archive_timeout</> &mdash; it will bloat your archive
storage. <varname>archive_timeout</> settings of a minute or so are
usually reasonable.
This parameter can only be set in the <filename>postgresql.conf</>
file or on the server command line.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.329 2006/08/06 03:53:43 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.330 2006/08/17 23:04:03 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
@ -10148,6 +10148,9 @@ SELECT set_config('log_statement_stats', 'off', false);
<indexterm zone="functions-admin">
<primary>pg_current_xlog_location</primary>
</indexterm>
<indexterm zone="functions-admin">
<primary>pg_current_xlog_insert_location</primary>
</indexterm>
<indexterm zone="functions-admin">
<primary>pg_xlogfile_name_offset</primary>
</indexterm>
@ -10199,13 +10202,20 @@ SELECT set_config('log_statement_stats', 'off', false);
<literal><function>pg_current_xlog_location</function>()</literal>
</entry>
<entry><type>text</type></entry>
<entry>Get current xlog location</entry>
<entry>Get current xlog write location</entry>
</row>
<row>
<entry>
<literal><function>pg_current_xlog_insert_location</function>()</literal>
</entry>
<entry><type>text</type></entry>
<entry>Get current xlog insert location</entry>
</row>
<row>
<entry>
<literal><function>pg_xlogfile_name_offset</function>(<parameter>location</> <type>text</>)</literal>
</entry>
<entry><type>text</type></entry>
<entry><type>text</>, <type>integer</></entry>
<entry>Convert xlog location string to filename and decimal byte offset within file</entry>
</row>
<row>
@ -10258,9 +10268,17 @@ postgres=# select pg_start_backup('label_goes_here');
</para>
<para>
<function>pg_current_xlog_location</> displays the current xlog insertion
point in the same format used by the above functions. This is a
read-only operation and does not require superuser permissions.
<function>pg_current_xlog_location</> displays the current xlog write
location in the same format used by the above functions. Similarly
<function>pg_current_xlog_insert_location</> displays the current xlog
insertion point. The insertion point is the <quote>logical</> end of xlog
at any instant, while the write location is the end of what has actually
been written out from the server's internal buffers. The write location
is the end of what can be examined from outside the server, and is usually
what you want if you are interested in archiving partially-complete xlog
files. The insertion point is made available primarily for server
debugging purposes. These are both read-only operations and do not
require superuser permissions.
</para>
<para>
@ -10268,10 +10286,10 @@ postgres=# select pg_start_backup('label_goes_here');
corresponding xlog filename and byte offset from the results of any of the
above functions. For example:
<programlisting>
postgres=# select pg_xlogfile_name_offset(pg_stop_backup());
pg_xlogfile_name_offset
----------------------------------
00000001000000000000000D 4039624
postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup());
file_name | file_offset
--------------------------+-------------
00000001000000000000000D | 4039624
(1 row)
</programlisting>
Similarly, <function>pg_xlogfile_name</> extracts just the xlog filename.

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.247 2006/08/07 16:57:56 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.248 2006/08/17 23:04:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -23,6 +23,7 @@
#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,6 +33,8 @@
#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,6 +131,7 @@
/* 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;
@ -347,8 +351,9 @@ typedef struct XLogCtlInsert
*/
typedef struct XLogCtlWrite
{
XLogwrtResult LogwrtResult; /* current value of LogwrtResult */
int curridx; /* cache index of next block to write */
XLogwrtResult LogwrtResult; /* current value of LogwrtResult */
int curridx; /* cache index of next block to write */
time_t lastSegSwitchTime; /* time of last xlog segment switch */
} XLogCtlWrite;
/*
@ -1660,7 +1665,8 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
* switch.
*
* This is also the right place to notify the Archiver that the
* segment is ready to copy to archival storage.
* segment is ready to copy to archival storage, and to update
* the timer for archive_timeout.
*/
if (finishing_seg || (xlog_switch && last_iteration))
{
@ -1669,6 +1675,8 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
if (XLogArchivingActive())
XLogArchiveNotifySeg(openLogId, openLogSeg);
Write->lastSegSwitchTime = time(NULL);
}
}
@ -5124,6 +5132,9 @@ StartupXLOG(void)
ControlFile->time = time(NULL);
UpdateControlFile();
/* start the archive_timeout timer running */
XLogCtl->Write.lastSegSwitchTime = ControlFile->time;
/* Start up the commit log and related stuff, too */
StartupCLOG();
StartupSUBTRANS(oldestActiveXID);
@ -5307,6 +5318,22 @@ GetRedoRecPtr(void)
return RedoRecPtr;
}
/*
* Get the time of the last xlog segment switch
*/
time_t
GetLastSegSwitchTime(void)
{
time_t result;
/* Need WALWriteLock, but shared lock is sufficient */
LWLockAcquire(WALWriteLock, LW_SHARED);
result = XLogCtl->Write.lastSegSwitchTime;
LWLockRelease(WALWriteLock);
return result;
}
/*
* GetRecentNextXid - get the nextXid value saved by the most recent checkpoint
*
@ -5728,7 +5755,7 @@ XLogPutNextOid(Oid nextOid)
* 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
XLogRecPtr
RequestXLogSwitch(void)
{
XLogRecPtr RecPtr;
@ -6335,10 +6362,43 @@ pg_switch_xlog(PG_FUNCTION_ARGS)
}
/*
* Report the current WAL location (same format as pg_start_backup etc)
* Report the current WAL write location (same format as pg_start_backup etc)
*
* This is useful for determining how much of WAL is visible to an external
* archiving process. Note that the data before this point is written out
* to the kernel, but is not necessarily synced to disk.
*/
Datum
pg_current_xlog_location(PG_FUNCTION_ARGS)
{
text *result;
char location[MAXFNAMELEN];
/* Make sure we have an up-to-date local 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 insert location (same format as pg_start_backup etc)
*
* This function is mostly for debugging purposes.
*/
Datum
pg_current_xlog_insert_location(PG_FUNCTION_ARGS)
{
text *result;
XLogCtlInsert *Insert = &XLogCtl->Insert;
@ -6372,7 +6432,6 @@ Datum
pg_xlogfile_name_offset(PG_FUNCTION_ARGS)
{
text *location = PG_GETARG_TEXT_P(0);
text *result;
char *locationstr;
unsigned int uxlogid;
unsigned int uxrecoff;
@ -6381,7 +6440,15 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS)
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,18 +6461,44 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS)
locationpoint.xlogid = uxlogid;
locationpoint.xrecoff = uxrecoff;
/*
* Construct a tuple descriptor for the result row. This must match
* this function's pg_proc entry!
*/
resultTupleDesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "file_name",
TEXTOID, -1, 0);
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "file_offset",
INT4OID, -1, 0);
resultTupleDesc = BlessTupleDesc(resultTupleDesc);
/*
* xlogfilename
*/
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);
values[0] = DirectFunctionCall1(textin,
CStringGetDatum(xlogfilename));
isnull[0] = false;
result = DatumGetTextP(DirectFunctionCall1(textin,
CStringGetDatum(xlogfilename)));
PG_RETURN_TEXT_P(result);
/*
* 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);
}
/*

View File

@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.26 2006/07/14 14:52:22 momjian Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.27 2006/08/17 23:04:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -46,6 +46,7 @@
#include <signal.h>
#include <time.h>
#include "access/xlog_internal.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "postmaster/bgwriter.h"
@ -144,6 +145,7 @@ static bool am_bg_writer = false;
static bool ckpt_active = false;
static time_t last_checkpoint_time;
static time_t last_xlog_switch_time;
static void bg_quickdie(SIGNAL_ARGS);
@ -205,10 +207,10 @@ BackgroundWriterMain(void)
#endif
/*
* Initialize so that first time-driven checkpoint happens at the correct
* Initialize so that first time-driven event happens at the correct
* time.
*/
last_checkpoint_time = time(NULL);
last_checkpoint_time = last_xlog_switch_time = time(NULL);
/*
* Create a resource owner to keep track of our resources (currently
@ -403,6 +405,49 @@ BackgroundWriterMain(void)
else
BgBufferSync();
/*
* Check for archive_timeout, if so, switch xlog files. First
* we do a quick check using possibly-stale local state.
*/
if (XLogArchiveTimeout > 0 &&
(int) (now - last_xlog_switch_time) >= XLogArchiveTimeout)
{
/*
* Update local state ... note that last_xlog_switch_time is
* the last time a switch was performed *or requested*.
*/
time_t last_time = GetLastSegSwitchTime();
last_xlog_switch_time = Max(last_xlog_switch_time, last_time);
/* if we did a checkpoint, 'now' might be stale too */
if (do_checkpoint)
now = time(NULL);
/* Now we can do the real check */
if ((int) (now - last_xlog_switch_time) >= XLogArchiveTimeout)
{
XLogRecPtr switchpoint;
/* OK, it's time to switch */
switchpoint = RequestXLogSwitch();
/*
* If the returned pointer points exactly to a segment
* boundary, assume nothing happened.
*/
if ((switchpoint.xrecoff % XLogSegSize) != 0)
ereport(DEBUG1,
(errmsg("xlog switch forced (archive_timeout=%d)",
XLogArchiveTimeout)));
/*
* Update state in any case, so we don't retry constantly
* when the system is idle.
*/
last_xlog_switch_time = now;
}
}
/*
* Nap for the configured time, or sleep for 10 seconds if there is no
* bgwriter activity configured.
@ -417,9 +462,12 @@ BackgroundWriterMain(void)
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;
while (udelay > 1000000L)
udelay = 10000000L; /* Ten seconds */
while (udelay > 999999L)
{
if (got_SIGHUP || checkpoint_requested || shutdown_requested)
break;
@ -427,6 +475,7 @@ BackgroundWriterMain(void)
AbsorbFsyncRequests();
udelay -= 1000000L;
}
if (!(got_SIGHUP || checkpoint_requested || shutdown_requested))
pg_usleep(udelay);
}

View File

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.342 2006/08/15 18:26:59 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.343 2006/08/17 23:04:06 tgl Exp $
*
*--------------------------------------------------------------------
*/
@ -1001,7 +1001,7 @@ static struct config_bool ConfigureNamesBool[] =
{
{"ignore_system_indexes", PGC_BACKEND, DEVELOPER_OPTIONS,
gettext_noop("Disabled reading from system indexes."),
gettext_noop("Disables reading from system indexes."),
gettext_noop("It does not prevent updating the indexes, so it is safe "
"to use. The worst consequence is slowness."),
GUC_NOT_IN_SAMPLE
@ -1019,6 +1019,16 @@ static struct config_bool ConfigureNamesBool[] =
static struct config_int ConfigureNamesInt[] =
{
{
{"archive_timeout", PGC_SIGHUP, WAL_SETTINGS,
gettext_noop("Forces a switch to the next xlog file if a "
"new file has not been started within N seconds."),
NULL,
GUC_UNIT_S
},
&XLogArchiveTimeout,
0, 0, INT_MAX, NULL, NULL
},
{
{"post_auth_delay", PGC_BACKEND, DEVELOPER_OPTIONS,
gettext_noop("Waits N seconds on connection startup after authentication."),

View File

@ -167,8 +167,9 @@
# - Archiving -
#archive_command = '' # command to use to archive a logfile
# segment
#archive_command = '' # command to use to archive a logfile segment
#archive_timeout = 0 # force a logfile segment switch after this
# many seconds; 0 is off
#---------------------------------------------------------------------------

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.72 2006/07/13 16:49:19 momjian Exp $
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.73 2006/08/17 23:04:08 tgl Exp $
*/
#ifndef XLOG_H
#define XLOG_H
@ -139,6 +139,7 @@ extern XLogRecPtr ProcLastRecEnd;
extern int CheckPointSegments;
extern int XLOGbuffers;
extern char *XLogArchiveCommand;
extern int XLogArchiveTimeout;
extern char *XLOG_sync_method;
extern const char XLOG_sync_method_default[];

View File

@ -11,11 +11,13 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.15 2006/08/07 16:57:57 tgl Exp $
* $PostgreSQL: pgsql/src/include/access/xlog_internal.h,v 1.16 2006/08/17 23:04:08 tgl Exp $
*/
#ifndef XLOG_INTERNAL_H
#define XLOG_INTERNAL_H
#include <time.h>
#include "access/xlog.h"
#include "fmgr.h"
#include "storage/block.h"
@ -237,6 +239,12 @@ typedef struct RmgrData
extern const RmgrData RmgrTable[];
/*
* Exported to support xlog switching from bgwriter
*/
extern time_t GetLastSegSwitchTime(void);
extern XLogRecPtr RequestXLogSwitch(void);
/*
* These aren't in xlog.h because I'd rather not include fmgr.h there.
*/
@ -244,6 +252,7 @@ extern Datum pg_start_backup(PG_FUNCTION_ARGS);
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_xlog_insert_location(PG_FUNCTION_ARGS);
extern Datum pg_xlogfile_name_offset(PG_FUNCTION_ARGS);
extern Datum pg_xlogfile_name(PG_FUNCTION_ARGS);

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.349 2006/08/12 02:52:06 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.350 2006/08/17 23:04:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200608101
#define CATALOG_VERSION_NO 200608171
#endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.420 2006/08/06 03:53:44 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.421 2006/08/17 23:04:10 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@ -3104,8 +3104,10 @@ DESCR("Finish taking an online backup");
DATA(insert OID = 2848 ( pg_switch_xlog PGNSP PGUID 12 f f t f v 0 25 "" _null_ _null_ _null_ pg_switch_xlog - _null_ ));
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("current xlog write location");
DATA(insert OID = 2852 ( pg_current_xlog_insert_location PGNSP PGUID 12 f f t f v 0 25 "" _null_ _null_ _null_ pg_current_xlog_insert_location - _null_ ));
DESCR("current xlog insert location");
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,file_name,file_offset}" 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");