Commit f5b2f60b authored by Tom Lane's avatar Tom Lane

Change WAL-logging scheme for multixacts to be more like regular

transaction IDs, rather than like subtrans; in particular, the information
now survives a database restart.  Per previous discussion, this is
essential for PITR log shipping and for 2PC.
parent 593badd3
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.10 2005/04/28 21:47:10 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.11 2005/06/08 15:50:21 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -23,6 +23,7 @@ PostgreSQL documentation ...@@ -23,6 +23,7 @@ PostgreSQL documentation
<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> -m <replaceable class="parameter">mxid</replaceable> </arg> <arg> -m <replaceable class="parameter">mxid</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>
<arg choice="plain"><replaceable>datadir</replaceable></arg> <arg choice="plain"><replaceable>datadir</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
...@@ -32,8 +33,8 @@ PostgreSQL documentation ...@@ -32,8 +33,8 @@ PostgreSQL documentation
<title>Description</title> <title>Description</title>
<para> <para>
<command>pg_resetxlog</command> clears the write-ahead log (WAL) and <command>pg_resetxlog</command> clears the write-ahead log (WAL) and
optionally resets some other control information (stored in the optionally resets some other control information stored in the
<filename>pg_control</> file). This function is sometimes needed <filename>pg_control</> file. This function is sometimes needed
if these files have become corrupted. It should be used only as a if these files have become corrupted. It should be used only as a
last resort, when the server will not start due to such corruption. last resort, when the server will not start due to such corruption.
</para> </para>
...@@ -60,8 +61,9 @@ PostgreSQL documentation ...@@ -60,8 +61,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, WAL starting address, and database locale fields. next transaction ID, next multi-transaction ID and offset,
The first three of these can be set using the switches discussed below. WAL starting address, and database locale fields.
The first five 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.
...@@ -74,9 +76,10 @@ PostgreSQL documentation ...@@ -74,9 +76,10 @@ PostgreSQL documentation
</para> </para>
<para> <para>
The <literal>-o</>, <literal>-x</>, <literal>-m</>, and <literal>-l</> The <literal>-o</>, <literal>-x</>, <literal>-m</>, <literal>-O</>,
and <literal>-l</>
switches allow the next OID, next transaction ID, next multi-transaction switches allow the next OID, next transaction ID, next multi-transaction
ID, and WAL starting address values to ID, next multi-transaction offset, and WAL starting address values to
be set manually. These are only needed when 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
...@@ -108,6 +111,17 @@ PostgreSQL documentation ...@@ -108,6 +111,17 @@ PostgreSQL documentation
</para> </para>
</listitem> </listitem>
<listitem>
<para>
A safe value for the next multi-transaction offset (<literal>-O</>)
may be determined by looking for the numerically largest
file name in the directory <filename>pg_multixact/members</> under the
data directory, adding one, and then multiplying by 65536. As above,
the file names are in hexadecimal, so the easiest way to do this is to
specify the switch value in hexadecimal and add four zeroes.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The WAL starting address (<literal>-l</>) should be The WAL starting address (<literal>-l</>) should be
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.193 2005/06/06 20:22:56 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.194 2005/06/08 15:50:21 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -2219,6 +2219,8 @@ l3: ...@@ -2219,6 +2219,8 @@ l3:
* Else the same IDs might be re-used after a crash, which would be * Else the same IDs might be re-used after a crash, which would be
* disastrous if this page made it to disk before the crash. Essentially * disastrous if this page made it to disk before the crash. Essentially
* we have to enforce the WAL log-before-data rule even in this case. * we have to enforce the WAL log-before-data rule even in this case.
* (Also, in a PITR log-shipping or 2PC environment, we have to have XLOG
* entries for everything anyway.)
*/ */
if (!relation->rd_istemp) if (!relation->rd_istemp)
{ {
...@@ -2228,6 +2230,8 @@ l3: ...@@ -2228,6 +2230,8 @@ l3:
xlrec.target.node = relation->rd_node; xlrec.target.node = relation->rd_node;
xlrec.target.tid = tuple->t_self; xlrec.target.tid = tuple->t_self;
xlrec.locking_xid = xid;
xlrec.xid_is_mxact = ((new_infomask & HEAP_XMAX_IS_MULTI) != 0);
xlrec.shared_lock = (mode == LockTupleShared); xlrec.shared_lock = (mode == LockTupleShared);
rdata[0].data = (char *) &xlrec; rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfHeapLock; rdata[0].len = SizeOfHeapLock;
...@@ -2900,17 +2904,18 @@ heap_xlog_lock(XLogRecPtr lsn, XLogRecord *record) ...@@ -2900,17 +2904,18 @@ heap_xlog_lock(XLogRecPtr lsn, XLogRecord *record)
htup = (HeapTupleHeader) PageGetItem(page, lp); htup = (HeapTupleHeader) PageGetItem(page, lp);
/*
* Presently, we don't bother to restore the locked state, but
* just set the XMAX_INVALID bit.
*/
htup->t_infomask &= ~(HEAP_XMAX_COMMITTED | htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
HEAP_XMAX_INVALID | HEAP_XMAX_INVALID |
HEAP_XMAX_IS_MULTI | HEAP_XMAX_IS_MULTI |
HEAP_IS_LOCKED | HEAP_IS_LOCKED |
HEAP_MOVED); HEAP_MOVED);
htup->t_infomask |= HEAP_XMAX_INVALID; if (xlrec->xid_is_mxact)
HeapTupleHeaderSetXmax(htup, record->xl_xid); htup->t_infomask |= HEAP_XMAX_IS_MULTI;
if (xlrec->shared_lock)
htup->t_infomask |= HEAP_XMAX_SHARED_LOCK;
else
htup->t_infomask |= HEAP_XMAX_EXCL_LOCK;
HeapTupleHeaderSetXmax(htup, xlrec->locking_xid);
HeapTupleHeaderSetCmax(htup, FirstCommandId); HeapTupleHeaderSetCmax(htup, FirstCommandId);
/* Make sure there is no forward chain link in t_ctid */ /* Make sure there is no forward chain link in t_ctid */
htup->t_ctid = xlrec->target.tid; htup->t_ctid = xlrec->target.tid;
...@@ -3010,6 +3015,11 @@ heap_desc(char *buf, uint8 xl_info, char *rec) ...@@ -3010,6 +3015,11 @@ heap_desc(char *buf, uint8 xl_info, char *rec)
strcat(buf, "shared_lock: "); strcat(buf, "shared_lock: ");
else else
strcat(buf, "exclusive_lock: "); strcat(buf, "exclusive_lock: ");
if (xlrec->xid_is_mxact)
strcat(buf, "mxid ");
else
strcat(buf, "xid ");
sprintf(buf + strlen(buf), "%u ", xlrec->locking_xid);
out_target(buf, &(xlrec->target)); out_target(buf, &(xlrec->target));
} }
else else
......
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Resource managers definition * Resource managers definition
* *
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.18 2005/06/06 17:01:22 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.19 2005/06/08 15:50:26 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "access/gist_private.h" #include "access/gist_private.h"
#include "access/hash.h" #include "access/hash.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/multixact.h"
#include "access/nbtree.h" #include "access/nbtree.h"
#include "access/rtree.h" #include "access/rtree.h"
#include "access/xact.h" #include "access/xact.h"
...@@ -28,7 +29,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = { ...@@ -28,7 +29,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = {
{"CLOG", clog_redo, clog_desc, NULL, NULL}, {"CLOG", clog_redo, clog_desc, NULL, NULL},
{"Database", dbase_redo, dbase_desc, NULL, NULL}, {"Database", dbase_redo, dbase_desc, NULL, NULL},
{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL}, {"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL},
{"Reserved 6", NULL, NULL, NULL, NULL}, {"MultiXact", multixact_redo, multixact_desc, NULL, NULL},
{"Reserved 7", NULL, NULL, NULL, NULL}, {"Reserved 7", NULL, NULL, NULL, NULL},
{"Reserved 8", NULL, NULL, NULL, NULL}, {"Reserved 8", NULL, NULL, NULL, NULL},
{"Reserved 9", NULL, NULL, NULL, NULL}, {"Reserved 9", NULL, NULL, NULL, NULL},
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, 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.197 2005/06/06 20:22:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.198 2005/06/08 15:50:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -3688,12 +3688,13 @@ BootStrapXLOG(void) ...@@ -3688,12 +3688,13 @@ BootStrapXLOG(void)
checkPoint.nextXid = FirstNormalTransactionId; checkPoint.nextXid = FirstNormalTransactionId;
checkPoint.nextOid = FirstBootstrapObjectId; checkPoint.nextOid = FirstBootstrapObjectId;
checkPoint.nextMulti = FirstMultiXactId; checkPoint.nextMulti = FirstMultiXactId;
checkPoint.nextMultiOffset = 0;
checkPoint.time = time(NULL); checkPoint.time = time(NULL);
ShmemVariableCache->nextXid = checkPoint.nextXid; ShmemVariableCache->nextXid = checkPoint.nextXid;
ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->nextOid = checkPoint.nextOid;
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
MultiXactSetNextMXact(checkPoint.nextMulti); MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
/* Set up the XLOG page header */ /* Set up the XLOG page header */
page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_magic = XLOG_PAGE_MAGIC;
...@@ -4344,8 +4345,11 @@ StartupXLOG(void) ...@@ -4344,8 +4345,11 @@ 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; next MultiXactId: %u", (errmsg("next transaction ID: %u; next OID: %u",
checkPoint.nextXid, checkPoint.nextOid, checkPoint.nextMulti))); checkPoint.nextXid, checkPoint.nextOid)));
ereport(LOG,
(errmsg("next MultiXactId: %u; next MultiXactOffset: %u",
checkPoint.nextMulti, checkPoint.nextMultiOffset)));
if (!TransactionIdIsNormal(checkPoint.nextXid)) if (!TransactionIdIsNormal(checkPoint.nextXid))
ereport(PANIC, ereport(PANIC,
(errmsg("invalid next transaction ID"))); (errmsg("invalid next transaction ID")));
...@@ -4353,7 +4357,7 @@ StartupXLOG(void) ...@@ -4353,7 +4357,7 @@ StartupXLOG(void)
ShmemVariableCache->nextXid = checkPoint.nextXid; ShmemVariableCache->nextXid = checkPoint.nextXid;
ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->nextOid = checkPoint.nextOid;
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
MultiXactSetNextMXact(checkPoint.nextMulti); MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
/* /*
* We must replay WAL entries using the same TimeLineID they were * We must replay WAL entries using the same TimeLineID they were
...@@ -5080,7 +5084,9 @@ CreateCheckPoint(bool shutdown, bool force) ...@@ -5080,7 +5084,9 @@ CreateCheckPoint(bool shutdown, bool force)
checkPoint.nextOid += ShmemVariableCache->oidCount; checkPoint.nextOid += ShmemVariableCache->oidCount;
LWLockRelease(OidGenLock); LWLockRelease(OidGenLock);
checkPoint.nextMulti = MultiXactGetCheckptMulti(shutdown); MultiXactGetCheckptMulti(shutdown,
&checkPoint.nextMulti,
&checkPoint.nextMultiOffset);
/* /*
* Having constructed the checkpoint record, ensure all shmem disk * Having constructed the checkpoint record, ensure all shmem disk
...@@ -5228,25 +5234,6 @@ XLogPutNextOid(Oid nextOid) ...@@ -5228,25 +5234,6 @@ XLogPutNextOid(Oid nextOid)
*/ */
} }
/*
* Write a NEXT_MULTIXACT log record
*/
void
XLogPutNextMultiXactId(MultiXactId nextMulti)
{
XLogRecData rdata;
rdata.data = (char *) (&nextMulti);
rdata.len = sizeof(MultiXactId);
rdata.buffer = InvalidBuffer;
rdata.next = NULL;
(void) XLogInsert(RM_XLOG_ID, XLOG_NEXTMULTI, &rdata);
/*
* We do not flush here either; this assumes that heap_lock_tuple() will
* always generate a WAL record. See notes therein.
*/
}
/* /*
* XLOG resource manager's routines * XLOG resource manager's routines
*/ */
...@@ -5266,14 +5253,6 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -5266,14 +5253,6 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
} }
} }
else if (info == XLOG_NEXTMULTI)
{
MultiXactId nextMulti;
memcpy(&nextMulti, XLogRecGetData(record), sizeof(MultiXactId));
MultiXactAdvanceNextMXact(nextMulti);
}
else if (info == XLOG_CHECKPOINT_SHUTDOWN) else if (info == XLOG_CHECKPOINT_SHUTDOWN)
{ {
CheckPoint checkPoint; CheckPoint checkPoint;
...@@ -5283,7 +5262,8 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -5283,7 +5262,8 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
ShmemVariableCache->nextXid = checkPoint.nextXid; ShmemVariableCache->nextXid = checkPoint.nextXid;
ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->nextOid = checkPoint.nextOid;
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
MultiXactSetNextMXact(checkPoint.nextMulti); MultiXactSetNextMXact(checkPoint.nextMulti,
checkPoint.nextMultiOffset);
/* /*
* TLI may change in a shutdown checkpoint, but it shouldn't * TLI may change in a shutdown checkpoint, but it shouldn't
...@@ -5315,7 +5295,8 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -5315,7 +5295,8 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->nextOid = checkPoint.nextOid;
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
} }
MultiXactAdvanceNextMXact(checkPoint.nextMulti); MultiXactAdvanceNextMXact(checkPoint.nextMulti,
checkPoint.nextMultiOffset);
/* 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,
...@@ -5335,12 +5316,13 @@ xlog_desc(char *buf, uint8 xl_info, char *rec) ...@@ -5335,12 +5316,13 @@ xlog_desc(char *buf, uint8 xl_info, char *rec)
CheckPoint *checkpoint = (CheckPoint *) rec; CheckPoint *checkpoint = (CheckPoint *) rec;
sprintf(buf + strlen(buf), "checkpoint: redo %X/%X; undo %X/%X; " sprintf(buf + strlen(buf), "checkpoint: redo %X/%X; undo %X/%X; "
"tli %u; xid %u; oid %u; multi %u; %s", "tli %u; xid %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->nextXid,
checkpoint->nextOid, checkpoint->nextOid,
checkpoint->nextMulti, checkpoint->nextMulti,
checkpoint->nextMultiOffset,
(info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online"); (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
} }
else if (info == XLOG_NEXTOID) else if (info == XLOG_NEXTOID)
...@@ -5350,13 +5332,6 @@ xlog_desc(char *buf, uint8 xl_info, char *rec) ...@@ -5350,13 +5332,6 @@ xlog_desc(char *buf, uint8 xl_info, char *rec)
memcpy(&nextOid, rec, sizeof(Oid)); memcpy(&nextOid, rec, sizeof(Oid));
sprintf(buf + strlen(buf), "nextOid: %u", nextOid); sprintf(buf + strlen(buf), "nextOid: %u", nextOid);
} }
else if (info == XLOG_NEXTMULTI)
{
MultiXactId multi;
memcpy(&multi, rec, sizeof(MultiXactId));
sprintf(buf + strlen(buf), "nextMultiXact: %u", multi);
}
else else
strcat(buf, "UNKNOWN"); strcat(buf, "UNKNOWN");
} }
......
...@@ -6,7 +6,7 @@ ...@@ -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.24 2005/06/02 05:55:29 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_controldata/pg_controldata.c,v 1.25 2005/06/08 15:50:27 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -166,6 +166,7 @@ main(int argc, char *argv[]) ...@@ -166,6 +166,7 @@ main(int argc, char *argv[])
printf(_("Latest checkpoint's NextXID: %u\n"), ControlFile.checkPointCopy.nextXid); printf(_("Latest checkpoint's NextXID: %u\n"), ControlFile.checkPointCopy.nextXid);
printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid); printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid);
printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti); printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti);
printf(_("Latest checkpoint's NextMultiOffset: %u\n"), ControlFile.checkPointCopy.nextMultiOffset);
printf(_("Time of latest checkpoint: %s\n"), ckpttime_str); printf(_("Time of latest checkpoint: %s\n"), ckpttime_str);
printf(_("Database block size: %u\n"), ControlFile.blcksz); printf(_("Database block size: %u\n"), ControlFile.blcksz);
printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size); printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size);
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, 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.33 2005/06/02 05:55:29 tgl Exp $ * $PostgreSQL: pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.34 2005/06/08 15:50:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -77,6 +77,7 @@ main(int argc, char *argv[]) ...@@ -77,6 +77,7 @@ main(int argc, char *argv[])
TransactionId set_xid = 0; TransactionId set_xid = 0;
Oid set_oid = 0; Oid set_oid = 0;
MultiXactId set_mxid = 0; MultiXactId set_mxid = 0;
MultiXactOffset set_mxoff = -1;
uint32 minXlogTli = 0, uint32 minXlogTli = 0,
minXlogId = 0, minXlogId = 0,
minXlogSeg = 0; minXlogSeg = 0;
...@@ -106,7 +107,7 @@ main(int argc, char *argv[]) ...@@ -106,7 +107,7 @@ main(int argc, char *argv[])
} }
while ((c = getopt(argc, argv, "fl:m:no:x:")) != -1) while ((c = getopt(argc, argv, "fl:m:no:O:x:")) != -1)
{ {
switch (c) switch (c)
{ {
...@@ -163,6 +164,21 @@ main(int argc, char *argv[]) ...@@ -163,6 +164,21 @@ main(int argc, char *argv[])
} }
break; break;
case 'O':
set_mxoff = strtoul(optarg, &endptr, 0);
if (endptr == optarg || *endptr != '\0')
{
fprintf(stderr, _("%s: invalid argument for option -O\n"), progname);
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
}
if (set_mxoff == -1)
{
fprintf(stderr, _("%s: multi transaction offset (-O) must not be -1\n"), progname);
exit(1);
}
break;
case 'l': case 'l':
minXlogTli = strtoul(optarg, &endptr, 0); minXlogTli = strtoul(optarg, &endptr, 0);
if (endptr == optarg || *endptr != ',') if (endptr == optarg || *endptr != ',')
...@@ -265,6 +281,9 @@ main(int argc, char *argv[]) ...@@ -265,6 +281,9 @@ main(int argc, char *argv[])
if (set_mxid != 0) if (set_mxid != 0)
ControlFile.checkPointCopy.nextMulti = set_mxid; ControlFile.checkPointCopy.nextMulti = set_mxid;
if (set_mxoff != -1)
ControlFile.checkPointCopy.nextMultiOffset = set_mxoff;
if (minXlogTli > ControlFile.checkPointCopy.ThisTimeLineID) if (minXlogTli > ControlFile.checkPointCopy.ThisTimeLineID)
ControlFile.checkPointCopy.ThisTimeLineID = minXlogTli; ControlFile.checkPointCopy.ThisTimeLineID = minXlogTli;
...@@ -426,6 +445,7 @@ GuessControlValues(void) ...@@ -426,6 +445,7 @@ GuessControlValues(void)
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;
ControlFile.checkPointCopy.nextMultiOffset = 0;
ControlFile.checkPointCopy.time = time(NULL); ControlFile.checkPointCopy.time = time(NULL);
ControlFile.state = DB_SHUTDOWNED; ControlFile.state = DB_SHUTDOWNED;
...@@ -463,7 +483,7 @@ GuessControlValues(void) ...@@ -463,7 +483,7 @@ GuessControlValues(void)
/* /*
* XXX eventually, should try to grovel through old XLOG to develop * XXX eventually, should try to grovel through old XLOG to develop
* more accurate values for TimeLineID, nextXID, and nextOID. * more accurate values for TimeLineID, nextXID, etc.
*/ */
} }
...@@ -500,6 +520,7 @@ PrintControlValues(bool guessed) ...@@ -500,6 +520,7 @@ PrintControlValues(bool guessed)
printf(_("Latest checkpoint's NextXID: %u\n"), ControlFile.checkPointCopy.nextXid); printf(_("Latest checkpoint's NextXID: %u\n"), ControlFile.checkPointCopy.nextXid);
printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid); printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid);
printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti); printf(_("Latest checkpoint's NextMultiXactId: %u\n"), ControlFile.checkPointCopy.nextMulti);
printf(_("Latest checkpoint's NextMultiOffset: %u\n"), ControlFile.checkPointCopy.nextMultiOffset);
printf(_("Database block size: %u\n"), ControlFile.blcksz); printf(_("Database block size: %u\n"), ControlFile.blcksz);
printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size); printf(_("Blocks per segment of large relation: %u\n"), ControlFile.relseg_size);
printf(_("Maximum length of identifiers: %u\n"), ControlFile.nameDataLen); printf(_("Maximum length of identifiers: %u\n"), ControlFile.nameDataLen);
...@@ -777,6 +798,7 @@ usage(void) ...@@ -777,6 +798,7 @@ usage(void)
printf(_(" -o OID set next OID\n")); printf(_(" -o OID set next OID\n"));
printf(_(" -x XID set next transaction ID\n")); printf(_(" -x XID set next transaction ID\n"));
printf(_(" -m multiXID set next multi transaction ID\n")); printf(_(" -m multiXID set next multi transaction ID\n"));
printf(_(" -O multiOffset set next multi transaction offset\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"));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, 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/htup.h,v 1.74 2005/04/28 21:47:17 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.75 2005/06/08 15:50:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -505,6 +505,8 @@ typedef struct xl_heap_newpage ...@@ -505,6 +505,8 @@ typedef struct xl_heap_newpage
typedef struct xl_heap_lock typedef struct xl_heap_lock
{ {
xl_heaptid target; /* locked tuple id */ xl_heaptid target; /* locked tuple id */
TransactionId locking_xid; /* might be a MultiXactId not xid */
bool xid_is_mxact; /* is it? */
bool shared_lock; /* shared or exclusive row lock? */ bool shared_lock; /* shared or exclusive row lock? */
} xl_heap_lock; } xl_heap_lock;
......
...@@ -6,16 +6,38 @@ ...@@ -6,16 +6,38 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, 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/multixact.h,v 1.2 2005/05/03 19:42:41 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/multixact.h,v 1.3 2005/06/08 15:50:28 tgl Exp $
*/ */
#ifndef MULTIXACT_H #ifndef MULTIXACT_H
#define MULTIXACT_H #define MULTIXACT_H
#include "access/xlog.h"
#define InvalidMultiXactId ((MultiXactId) 0) #define InvalidMultiXactId ((MultiXactId) 0)
#define FirstMultiXactId ((MultiXactId) 1) #define FirstMultiXactId ((MultiXactId) 1)
#define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId) #define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId)
/* ----------------
* multixact-related XLOG entries
* ----------------
*/
#define XLOG_MULTIXACT_ZERO_OFF_PAGE 0x00
#define XLOG_MULTIXACT_ZERO_MEM_PAGE 0x10
#define XLOG_MULTIXACT_CREATE_ID 0x20
typedef struct xl_multixact_create
{
MultiXactId mid; /* new MultiXact's ID */
MultiXactOffset moff; /* its starting offset in members file */
int32 nxids; /* number of member XIDs */
TransactionId xids[1]; /* VARIABLE LENGTH ARRAY */
} xl_multixact_create;
#define MinSizeOfMultiXactCreate offsetof(xl_multixact_create, xids)
extern MultiXactId MultiXactIdCreate(TransactionId xid1, TransactionId xid2); extern MultiXactId MultiXactIdCreate(TransactionId xid1, TransactionId xid2);
extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid); extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid);
extern bool MultiXactIdIsRunning(MultiXactId multi); extern bool MultiXactIdIsRunning(MultiXactId multi);
...@@ -29,9 +51,16 @@ extern void MultiXactShmemInit(void); ...@@ -29,9 +51,16 @@ extern void MultiXactShmemInit(void);
extern void BootStrapMultiXact(void); extern void BootStrapMultiXact(void);
extern void StartupMultiXact(void); extern void StartupMultiXact(void);
extern void ShutdownMultiXact(void); extern void ShutdownMultiXact(void);
extern MultiXactId MultiXactGetCheckptMulti(bool is_shutdown); extern void MultiXactGetCheckptMulti(bool is_shutdown,
MultiXactId *nextMulti,
MultiXactOffset *nextMultiOffset);
extern void CheckPointMultiXact(void); extern void CheckPointMultiXact(void);
extern void MultiXactSetNextMXact(MultiXactId nextMulti); extern void MultiXactSetNextMXact(MultiXactId nextMulti,
extern void MultiXactAdvanceNextMXact(MultiXactId minMulti); MultiXactOffset nextMultiOffset);
extern void MultiXactAdvanceNextMXact(MultiXactId minMulti,
MultiXactOffset minMultiOffset);
extern void multixact_redo(XLogRecPtr lsn, XLogRecord *record);
extern void multixact_desc(char *buf, uint8 xl_info, char *rec);
#endif /* MULTIXACT_H */ #endif /* MULTIXACT_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, 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.64 2005/06/06 20:22:58 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.65 2005/06/08 15:50:28 tgl Exp $
*/ */
#ifndef XLOG_H #ifndef XLOG_H
#define XLOG_H #define XLOG_H
...@@ -165,7 +165,6 @@ extern void ShutdownXLOG(int code, Datum arg); ...@@ -165,7 +165,6 @@ extern void ShutdownXLOG(int code, Datum arg);
extern void InitXLOGAccess(void); extern void InitXLOGAccess(void);
extern void CreateCheckPoint(bool shutdown, bool force); extern void CreateCheckPoint(bool shutdown, bool force);
extern void XLogPutNextOid(Oid nextOid); extern void XLogPutNextOid(Oid nextOid);
extern void XLogPutNextMultiXactId(MultiXactId multi);
extern XLogRecPtr GetRedoRecPtr(void); extern XLogRecPtr GetRedoRecPtr(void);
#endif /* XLOG_H */ #endif /* XLOG_H */
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, 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/c.h,v 1.184 2005/05/25 21:40:41 momjian Exp $ * $PostgreSQL: pgsql/src/include/c.h,v 1.185 2005/06/08 15:50:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -388,6 +388,8 @@ typedef uint32 SubTransactionId; ...@@ -388,6 +388,8 @@ typedef uint32 SubTransactionId;
/* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */ /* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */
typedef TransactionId MultiXactId; typedef TransactionId MultiXactId;
typedef uint32 MultiXactOffset;
typedef uint32 CommandId; typedef uint32 CommandId;
#define FirstCommandId ((CommandId) 0) #define FirstCommandId ((CommandId) 0)
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, 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.22 2005/06/02 05:55:29 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_control.h,v 1.23 2005/06/08 15:50:28 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
/* Version identifier for this pg_control format */ /* Version identifier for this pg_control format */
#define PG_CONTROL_VERSION 810 #define PG_CONTROL_VERSION 811
/* /*
* Body of CheckPoint XLOG records. This is declared here because we keep * Body of CheckPoint XLOG records. This is declared here because we keep
...@@ -40,13 +40,13 @@ typedef struct CheckPoint ...@@ -40,13 +40,13 @@ typedef struct CheckPoint
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 */
MultiXactOffset nextMultiOffset; /* next free MultiXact offset */
time_t time; /* time stamp of checkpoint */ time_t time; /* time stamp of checkpoint */
} CheckPoint; } CheckPoint;
/* XLOG info values for XLOG rmgr */ /* XLOG info values for XLOG rmgr */
#define XLOG_CHECKPOINT_SHUTDOWN 0x00 #define XLOG_CHECKPOINT_SHUTDOWN 0x00
#define XLOG_CHECKPOINT_ONLINE 0x10 #define XLOG_CHECKPOINT_ONLINE 0x10
#define XLOG_NEXTMULTI 0x20
#define XLOG_NEXTOID 0x30 #define XLOG_NEXTOID 0x30
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment