Make the server track an 'XID epoch', that is, maintain higher-order bits

of the transaction ID counter.  Nothing is done with the epoch except to
store it in checkpoint records, but this provides a foundation with which
add-on code can pretend that XIDs never wrap around.  This is a severely
trimmed and rewritten version of the xxid patch submitted by Marko Kreen.
Per discussion, the epoch counter seems the only part of xxid that really
needs to be in the core server.
This commit is contained in:
Tom Lane 2006-08-21 16:16:31 +00:00
parent 1054c38069
commit 35af5422f6
6 changed files with 177 additions and 44 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.16 2006/06/18 15:38:36 petere Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.17 2006/08/21 16:16:31 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -22,6 +22,7 @@ PostgreSQL documentation
<arg>-n</arg> <arg>-n</arg>
<arg>-o<replaceable class="parameter">oid</replaceable> </arg> <arg>-o<replaceable class="parameter">oid</replaceable> </arg>
<arg>-x <replaceable class="parameter">xid</replaceable> </arg> <arg>-x <replaceable class="parameter">xid</replaceable> </arg>
<arg>-e <replaceable class="parameter">xid_epoch</replaceable> </arg>
<arg>-m <replaceable class="parameter">mxid</replaceable> </arg> <arg>-m <replaceable class="parameter">mxid</replaceable> </arg>
<arg>-O <replaceable class="parameter">mxoff</replaceable> </arg> <arg>-O <replaceable class="parameter">mxoff</replaceable> </arg>
<arg>-l <replaceable class="parameter">timelineid</replaceable>,<replaceable class="parameter">fileid</replaceable>,<replaceable class="parameter">seg</replaceable> </arg> <arg>-l <replaceable class="parameter">timelineid</replaceable>,<replaceable class="parameter">fileid</replaceable>,<replaceable class="parameter">seg</replaceable> </arg>
@ -61,9 +62,9 @@ PostgreSQL documentation
by specifying the <literal>-f</> (force) switch. In this case plausible by specifying the <literal>-f</> (force) switch. In this case plausible
values will be substituted for the missing data. Most of the fields can be values will be substituted for the missing data. Most of the fields can be
expected to match, but manual assistance may be needed for the next OID, expected to match, but manual assistance may be needed for the next OID,
next transaction ID, next multitransaction ID and offset, next transaction ID and epoch, next multitransaction ID and offset,
WAL starting address, and database locale fields. WAL starting address, and database locale fields.
The first five of these can be set using the switches discussed below. The first six of these can be set using the switches discussed below.
<command>pg_resetxlog</command>'s own environment is the source for its <command>pg_resetxlog</command>'s own environment is the source for its
guess at the locale fields; take care that <envar>LANG</> and so forth guess at the locale fields; take care that <envar>LANG</> and so forth
match the environment that <command>initdb</> was run in. match the environment that <command>initdb</> was run in.
@ -76,11 +77,12 @@ PostgreSQL documentation
</para> </para>
<para> <para>
The <literal>-o</>, <literal>-x</>, <literal>-m</>, <literal>-O</>, The <literal>-o</>, <literal>-x</>, <literal>-e</>,
<literal>-m</>, <literal>-O</>,
and <literal>-l</> and <literal>-l</>
switches allow the next OID, next transaction ID, next multitransaction switches allow the next OID, next transaction ID, next transaction ID's
ID, next multitransaction offset, and WAL starting address values to epoch, next multitransaction ID, next multitransaction offset, and WAL
be set manually. These are only needed when starting address values to be set manually. These are only needed when
<command>pg_resetxlog</command> is unable to determine appropriate values <command>pg_resetxlog</command> is unable to determine appropriate values
by reading <filename>pg_control</>. Safe values may be determined as by reading <filename>pg_control</>. Safe values may be determined as
follows: follows:
@ -146,6 +148,18 @@ PostgreSQL documentation
get the next-OID setting right. get the next-OID setting right.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The transaction ID epoch is not actually stored anywhere in the database
except in the field that is set by <command>pg_resetxlog</command>,
so any value will work so far as the database itself is concerned.
You might need to adjust this value to ensure that replication
systems such as <application>Slony-I</> work correctly &mdash;
if so, an appropriate value should be obtainable from the state of
the downstream replicated database.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</para> </para>

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.248 2006/08/17 23:04:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.249 2006/08/21 16:16:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -312,10 +312,8 @@ static XLogRecPtr RedoRecPtr;
* new log file. * new log file.
* *
* CheckpointLock: must be held to do a checkpoint (ensures only one * CheckpointLock: must be held to do a checkpoint (ensures only one
* checkpointer at a time; even though the postmaster won't launch * checkpointer at a time; currently, with all checkpoints done by the
* parallel checkpoint processes, we need this because manual checkpoints * bgwriter, this is just pro forma).
* could be launched simultaneously). XXX now that all checkpoints are
* done by the bgwriter, isn't this lock redundant?
* *
*---------- *----------
*/ */
@ -363,9 +361,13 @@ typedef struct XLogCtlData
{ {
/* Protected by WALInsertLock: */ /* Protected by WALInsertLock: */
XLogCtlInsert Insert; XLogCtlInsert Insert;
/* Protected by info_lck: */ /* Protected by info_lck: */
XLogwrtRqst LogwrtRqst; XLogwrtRqst LogwrtRqst;
XLogwrtResult LogwrtResult; XLogwrtResult LogwrtResult;
uint32 ckptXidEpoch; /* nextXID & epoch of latest checkpoint */
TransactionId ckptXid;
/* Protected by WALWriteLock: */ /* Protected by WALWriteLock: */
XLogCtlWrite Write; XLogCtlWrite Write;
@ -380,7 +382,7 @@ typedef struct XLogCtlData
int XLogCacheBlck; /* highest allocated xlog buffer index */ int XLogCacheBlck; /* highest allocated xlog buffer index */
TimeLineID ThisTimeLineID; TimeLineID ThisTimeLineID;
slock_t info_lck; /* locks shared LogwrtRqst/LogwrtResult */ slock_t info_lck; /* locks shared variables shown above */
} XLogCtlData; } XLogCtlData;
static XLogCtlData *XLogCtl = NULL; static XLogCtlData *XLogCtl = NULL;
@ -4086,6 +4088,7 @@ BootStrapXLOG(void)
checkPoint.redo.xrecoff = SizeOfXLogLongPHD; checkPoint.redo.xrecoff = SizeOfXLogLongPHD;
checkPoint.undo = checkPoint.redo; checkPoint.undo = checkPoint.redo;
checkPoint.ThisTimeLineID = ThisTimeLineID; checkPoint.ThisTimeLineID = ThisTimeLineID;
checkPoint.nextXidEpoch = 0;
checkPoint.nextXid = FirstNormalTransactionId; checkPoint.nextXid = FirstNormalTransactionId;
checkPoint.nextOid = FirstBootstrapObjectId; checkPoint.nextOid = FirstBootstrapObjectId;
checkPoint.nextMulti = FirstMultiXactId; checkPoint.nextMulti = FirstMultiXactId;
@ -4752,8 +4755,9 @@ StartupXLOG(void)
checkPoint.undo.xlogid, checkPoint.undo.xrecoff, checkPoint.undo.xlogid, checkPoint.undo.xrecoff,
wasShutdown ? "TRUE" : "FALSE"))); wasShutdown ? "TRUE" : "FALSE")));
ereport(LOG, ereport(LOG,
(errmsg("next transaction ID: %u; next OID: %u", (errmsg("next transaction ID: %u/%u; next OID: %u",
checkPoint.nextXid, checkPoint.nextOid))); checkPoint.nextXidEpoch, checkPoint.nextXid,
checkPoint.nextOid)));
ereport(LOG, ereport(LOG,
(errmsg("next MultiXactId: %u; next MultiXactOffset: %u", (errmsg("next MultiXactId: %u; next MultiXactOffset: %u",
checkPoint.nextMulti, checkPoint.nextMultiOffset))); checkPoint.nextMulti, checkPoint.nextMultiOffset)));
@ -5135,6 +5139,10 @@ StartupXLOG(void)
/* start the archive_timeout timer running */ /* start the archive_timeout timer running */
XLogCtl->Write.lastSegSwitchTime = ControlFile->time; XLogCtl->Write.lastSegSwitchTime = ControlFile->time;
/* initialize shared-memory copy of latest checkpoint XID/epoch */
XLogCtl->ckptXidEpoch = ControlFile->checkPointCopy.nextXidEpoch;
XLogCtl->ckptXid = ControlFile->checkPointCopy.nextXid;
/* Start up the commit log and related stuff, too */ /* Start up the commit log and related stuff, too */
StartupCLOG(); StartupCLOG();
StartupSUBTRANS(oldestActiveXID); StartupSUBTRANS(oldestActiveXID);
@ -5364,6 +5372,46 @@ GetRecentNextXid(void)
return ControlFile->checkPointCopy.nextXid; return ControlFile->checkPointCopy.nextXid;
} }
/*
* GetNextXidAndEpoch - get the current nextXid value and associated epoch
*
* This is exported for use by code that would like to have 64-bit XIDs.
* We don't really support such things, but all XIDs within the system
* can be presumed "close to" the result, and thus the epoch associated
* with them can be determined.
*/
void
GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch)
{
uint32 ckptXidEpoch;
TransactionId ckptXid;
TransactionId nextXid;
/* Must read checkpoint info first, else have race condition */
{
/* use volatile pointer to prevent code rearrangement */
volatile XLogCtlData *xlogctl = XLogCtl;
SpinLockAcquire(&xlogctl->info_lck);
ckptXidEpoch = xlogctl->ckptXidEpoch;
ckptXid = xlogctl->ckptXid;
SpinLockRelease(&xlogctl->info_lck);
}
/* Now fetch current nextXid */
nextXid = ReadNewTransactionId();
/*
* nextXid is certainly logically later than ckptXid. So if it's
* numerically less, it must have wrapped into the next epoch.
*/
if (nextXid < ckptXid)
ckptXidEpoch++;
*xid = nextXid;
*epoch = ckptXidEpoch;
}
/* /*
* This must be called ONCE during postmaster or standalone-backend shutdown * This must be called ONCE during postmaster or standalone-backend shutdown
*/ */
@ -5531,6 +5579,11 @@ CreateCheckPoint(bool shutdown, bool force)
checkPoint.nextXid = ShmemVariableCache->nextXid; checkPoint.nextXid = ShmemVariableCache->nextXid;
LWLockRelease(XidGenLock); LWLockRelease(XidGenLock);
/* Increase XID epoch if we've wrapped around since last checkpoint */
checkPoint.nextXidEpoch = ControlFile->checkPointCopy.nextXidEpoch;
if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
checkPoint.nextXidEpoch++;
LWLockAcquire(OidGenLock, LW_SHARED); LWLockAcquire(OidGenLock, LW_SHARED);
checkPoint.nextOid = ShmemVariableCache->nextOid; checkPoint.nextOid = ShmemVariableCache->nextOid;
if (!shutdown) if (!shutdown)
@ -5600,6 +5653,17 @@ CreateCheckPoint(bool shutdown, bool force)
UpdateControlFile(); UpdateControlFile();
LWLockRelease(ControlFileLock); LWLockRelease(ControlFileLock);
/* Update shared-memory copy of checkpoint XID/epoch */
{
/* use volatile pointer to prevent code rearrangement */
volatile XLogCtlData *xlogctl = XLogCtl;
SpinLockAcquire(&xlogctl->info_lck);
xlogctl->ckptXidEpoch = checkPoint.nextXidEpoch;
xlogctl->ckptXid = checkPoint.nextXid;
SpinLockRelease(&xlogctl->info_lck);
}
/* /*
* We are now done with critical updates; no need for system panic if we * We are now done with critical updates; no need for system panic if we
* have trouble while fooling with offline log segments. * have trouble while fooling with offline log segments.
@ -5803,6 +5867,10 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
MultiXactSetNextMXact(checkPoint.nextMulti, MultiXactSetNextMXact(checkPoint.nextMulti,
checkPoint.nextMultiOffset); checkPoint.nextMultiOffset);
/* ControlFile->checkPointCopy always tracks the latest ckpt XID */
ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch;
ControlFile->checkPointCopy.nextXid = checkPoint.nextXid;
/* /*
* TLI may change in a shutdown checkpoint, but it shouldn't decrease * TLI may change in a shutdown checkpoint, but it shouldn't decrease
*/ */
@ -5836,6 +5904,11 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
} }
MultiXactAdvanceNextMXact(checkPoint.nextMulti, MultiXactAdvanceNextMXact(checkPoint.nextMulti,
checkPoint.nextMultiOffset); checkPoint.nextMultiOffset);
/* ControlFile->checkPointCopy always tracks the latest ckpt XID */
ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch;
ControlFile->checkPointCopy.nextXid = checkPoint.nextXid;
/* TLI should not change in an on-line checkpoint */ /* TLI should not change in an on-line checkpoint */
if (checkPoint.ThisTimeLineID != ThisTimeLineID) if (checkPoint.ThisTimeLineID != ThisTimeLineID)
ereport(PANIC, ereport(PANIC,
@ -5861,10 +5934,11 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
CheckPoint *checkpoint = (CheckPoint *) rec; CheckPoint *checkpoint = (CheckPoint *) rec;
appendStringInfo(buf, "checkpoint: redo %X/%X; undo %X/%X; " appendStringInfo(buf, "checkpoint: redo %X/%X; undo %X/%X; "
"tli %u; xid %u; oid %u; multi %u; offset %u; %s", "tli %u; xid %u/%u; oid %u; multi %u; offset %u; %s",
checkpoint->redo.xlogid, checkpoint->redo.xrecoff, checkpoint->redo.xlogid, checkpoint->redo.xrecoff,
checkpoint->undo.xlogid, checkpoint->undo.xrecoff, checkpoint->undo.xlogid, checkpoint->undo.xrecoff,
checkpoint->ThisTimeLineID, checkpoint->nextXid, checkpoint->ThisTimeLineID,
checkpoint->nextXidEpoch, checkpoint->nextXid,
checkpoint->nextOid, checkpoint->nextOid,
checkpoint->nextMulti, checkpoint->nextMulti,
checkpoint->nextMultiOffset, checkpoint->nextMultiOffset,

View File

@ -6,7 +6,7 @@
* copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001; * copyright (c) Oliver Elphick <olly@lfix.co.uk>, 2001;
* licence: BSD * licence: BSD
* *
* $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.30 2006/08/07 16:57:56 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.31 2006/08/21 16:16:31 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
@ -177,7 +177,8 @@ main(int argc, char *argv[])
ControlFile.checkPointCopy.undo.xrecoff); ControlFile.checkPointCopy.undo.xrecoff);
printf(_("Latest checkpoint's TimeLineID: %u\n"), printf(_("Latest checkpoint's TimeLineID: %u\n"),
ControlFile.checkPointCopy.ThisTimeLineID); ControlFile.checkPointCopy.ThisTimeLineID);
printf(_("Latest checkpoint's NextXID: %u\n"), printf(_("Latest checkpoint's NextXID: %u/%u\n"),
ControlFile.checkPointCopy.nextXidEpoch,
ControlFile.checkPointCopy.nextXid); ControlFile.checkPointCopy.nextXid);
printf(_("Latest checkpoint's NextOID: %u\n"), printf(_("Latest checkpoint's NextOID: %u\n"),
ControlFile.checkPointCopy.nextOid); ControlFile.checkPointCopy.nextOid);

View File

@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.51 2006/08/07 16:57:56 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.52 2006/08/21 16:16:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -71,6 +71,7 @@ main(int argc, char *argv[])
int c; int c;
bool force = false; bool force = false;
bool noupdate = false; bool noupdate = false;
uint32 set_xid_epoch = -1;
TransactionId set_xid = 0; TransactionId set_xid = 0;
Oid set_oid = 0; Oid set_oid = 0;
MultiXactId set_mxid = 0; MultiXactId set_mxid = 0;
@ -104,7 +105,7 @@ main(int argc, char *argv[])
} }
while ((c = getopt(argc, argv, "fl:m:no:O:x:")) != -1) while ((c = getopt(argc, argv, "fl:m:no:O:x:e:")) != -1)
{ {
switch (c) switch (c)
{ {
@ -116,6 +117,21 @@ main(int argc, char *argv[])
noupdate = true; noupdate = true;
break; break;
case 'e':
set_xid_epoch = strtoul(optarg, &endptr, 0);
if (endptr == optarg || *endptr != '\0')
{
fprintf(stderr, _("%s: invalid argument for option -e\n"), progname);
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
}
if (set_xid_epoch == -1)
{
fprintf(stderr, _("%s: transaction ID epoch (-e) must not be -1\n"), progname);
exit(1);
}
break;
case 'x': case 'x':
set_xid = strtoul(optarg, &endptr, 0); set_xid = strtoul(optarg, &endptr, 0);
if (endptr == optarg || *endptr != '\0') if (endptr == optarg || *endptr != '\0')
@ -271,6 +287,9 @@ main(int argc, char *argv[])
* Adjust fields if required by switches. (Do this now so that printout, * Adjust fields if required by switches. (Do this now so that printout,
* if any, includes these values.) * if any, includes these values.)
*/ */
if (set_xid_epoch != -1)
ControlFile.checkPointCopy.nextXidEpoch = set_xid_epoch;
if (set_xid != 0) if (set_xid != 0)
ControlFile.checkPointCopy.nextXid = set_xid; ControlFile.checkPointCopy.nextXid = set_xid;
@ -441,6 +460,7 @@ GuessControlValues(void)
ControlFile.checkPointCopy.redo.xrecoff = SizeOfXLogLongPHD; ControlFile.checkPointCopy.redo.xrecoff = SizeOfXLogLongPHD;
ControlFile.checkPointCopy.undo = ControlFile.checkPointCopy.redo; ControlFile.checkPointCopy.undo = ControlFile.checkPointCopy.redo;
ControlFile.checkPointCopy.ThisTimeLineID = 1; ControlFile.checkPointCopy.ThisTimeLineID = 1;
ControlFile.checkPointCopy.nextXidEpoch = 0;
ControlFile.checkPointCopy.nextXid = (TransactionId) 514; /* XXX */ ControlFile.checkPointCopy.nextXid = (TransactionId) 514; /* XXX */
ControlFile.checkPointCopy.nextOid = FirstBootstrapObjectId; ControlFile.checkPointCopy.nextOid = FirstBootstrapObjectId;
ControlFile.checkPointCopy.nextMulti = FirstMultiXactId; ControlFile.checkPointCopy.nextMulti = FirstMultiXactId;
@ -513,29 +533,50 @@ PrintControlValues(bool guessed)
snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT, snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
ControlFile.system_identifier); ControlFile.system_identifier);
printf(_("pg_control version number: %u\n"), ControlFile.pg_control_version); printf(_("pg_control version number: %u\n"),
printf(_("Catalog version number: %u\n"), ControlFile.catalog_version_no); ControlFile.pg_control_version);
printf(_("Database system identifier: %s\n"), sysident_str); printf(_("Catalog version number: %u\n"),
printf(_("Current log file ID: %u\n"), ControlFile.logId); ControlFile.catalog_version_no);
printf(_("Next log file segment: %u\n"), ControlFile.logSeg); printf(_("Database system identifier: %s\n"),
printf(_("Latest checkpoint's TimeLineID: %u\n"), ControlFile.checkPointCopy.ThisTimeLineID); sysident_str);
printf(_("Latest checkpoint's NextXID: %u\n"), ControlFile.checkPointCopy.nextXid); printf(_("Current log file ID: %u\n"),
printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid); ControlFile.logId);
printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti); printf(_("Next log file segment: %u\n"),
printf(_("Latest checkpoint's NextMultiOffset: %u\n"), ControlFile.checkPointCopy.nextMultiOffset); ControlFile.logSeg);
printf(_("Maximum data alignment: %u\n"), ControlFile.maxAlign); printf(_("Latest checkpoint's TimeLineID: %u\n"),
ControlFile.checkPointCopy.ThisTimeLineID);
printf(_("Latest checkpoint's NextXID: %u/%u\n"),
ControlFile.checkPointCopy.nextXidEpoch,
ControlFile.checkPointCopy.nextXid);
printf(_("Latest checkpoint's NextOID: %u\n"),
ControlFile.checkPointCopy.nextOid);
printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
ControlFile.checkPointCopy.nextMulti);
printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
ControlFile.checkPointCopy.nextMultiOffset);
printf(_("Maximum data alignment: %u\n"),
ControlFile.maxAlign);
/* we don't print floatFormat since can't say much useful about it */ /* we don't print floatFormat since can't say much useful about it */
printf(_("Database block size: %u\n"), ControlFile.blcksz); printf(_("Database block size: %u\n"),
printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size); ControlFile.blcksz);
printf(_("WAL block size: %u\n"), ControlFile.xlog_blcksz); printf(_("Blocks per segment of large relation: %u\n"),
printf(_("Bytes per WAL segment: %u\n"), ControlFile.xlog_seg_size); ControlFile.relseg_size);
printf(_("Maximum length of identifiers: %u\n"), ControlFile.nameDataLen); printf(_("WAL block size: %u\n"),
printf(_("Maximum columns in an index: %u\n"), ControlFile.indexMaxKeys); ControlFile.xlog_blcksz);
printf(_("Bytes per WAL segment: %u\n"),
ControlFile.xlog_seg_size);
printf(_("Maximum length of identifiers: %u\n"),
ControlFile.nameDataLen);
printf(_("Maximum columns in an index: %u\n"),
ControlFile.indexMaxKeys);
printf(_("Date/time type storage: %s\n"), printf(_("Date/time type storage: %s\n"),
(ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers"))); (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
printf(_("Maximum length of locale name: %u\n"), ControlFile.localeBuflen); printf(_("Maximum length of locale name: %u\n"),
printf(_("LC_COLLATE: %s\n"), ControlFile.lc_collate); ControlFile.localeBuflen);
printf(_("LC_CTYPE: %s\n"), ControlFile.lc_ctype); printf(_("LC_COLLATE: %s\n"),
ControlFile.lc_collate);
printf(_("LC_CTYPE: %s\n"),
ControlFile.lc_ctype);
} }
@ -810,6 +851,7 @@ usage(void)
printf(_(" -o OID set next OID\n")); printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n")); printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -x XID set next transaction ID\n")); printf(_(" -x XID set next transaction ID\n"));
printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
printf(_(" --help show this help, then exit\n")); printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n")); printf(_(" --version output version information, then exit\n"));
printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n")); printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.73 2006/08/17 23:04:08 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.74 2006/08/21 16:16:31 tgl Exp $
*/ */
#ifndef XLOG_H #ifndef XLOG_H
#define XLOG_H #define XLOG_H
@ -166,5 +166,6 @@ extern void CreateCheckPoint(bool shutdown, bool force);
extern void XLogPutNextOid(Oid nextOid); extern void XLogPutNextOid(Oid nextOid);
extern XLogRecPtr GetRedoRecPtr(void); extern XLogRecPtr GetRedoRecPtr(void);
extern TransactionId GetRecentNextXid(void); extern TransactionId GetRecentNextXid(void);
extern void GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch);
#endif /* XLOG_H */ #endif /* XLOG_H */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.31 2006/08/07 16:57:57 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.32 2006/08/21 16:16:31 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -22,7 +22,7 @@
/* Version identifier for this pg_control format */ /* Version identifier for this pg_control format */
#define PG_CONTROL_VERSION 821 #define PG_CONTROL_VERSION 822
/* /*
* Body of CheckPoint XLOG records. This is declared here because we keep * Body of CheckPoint XLOG records. This is declared here because we keep
@ -36,6 +36,7 @@ typedef struct CheckPoint
* transaction when we started (i.e. UNDO end * transaction when we started (i.e. UNDO end
* point) */ * point) */
TimeLineID ThisTimeLineID; /* current TLI */ TimeLineID ThisTimeLineID; /* current TLI */
uint32 nextXidEpoch; /* higher-order bits of nextXid */
TransactionId nextXid; /* next free XID */ TransactionId nextXid; /* next free XID */
Oid nextOid; /* next free OID */ Oid nextOid; /* next free OID */
MultiXactId nextMulti; /* next free MultiXactId */ MultiXactId nextMulti; /* next free MultiXactId */