Commit bc7d37a5 authored by Tom Lane's avatar Tom Lane

Transaction IDs wrap around, per my proposal of 13-Aug-01. More

documentation to come, but the code is all here.  initdb forced.
parent d1ee78f2
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.21 2001/08/21 16:35:58 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.22 2001/08/26 16:55:58 tgl Exp $
-->
<chapter id="catalogs">
......@@ -840,11 +840,34 @@
<entry><type>oid</type></entry>
<entry></entry>
<entry>
Last oid in existence after the database was created; useful
Last system OID in the database; useful
particularly to <application>pg_dump</application>
</entry>
</row>
<row>
<entry>datvacuumxid</entry>
<entry><type>xid</type></entry>
<entry></entry>
<entry>
All tuples inserted or deleted by transaction IDs before this one
have been marked as known committed or known aborted in this database.
This is used to determine when commit-log space can be recycled.
</entry>
</row>
<row>
<entry>datfrozenxid</entry>
<entry><type>xid</type></entry>
<entry></entry>
<entry>
All tuples inserted by transaction IDs before this one have been
relabeled with a permanent (<quote>frozen</>) transaction ID in this
database. This is useful to check whether a database must be vacuumed
soon to avoid transaction ID wraparound problems.
</entry>
</row>
<row>
<entry>datpath</entry>
<entry><type>text</type></entry>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_database.sgml,v 1.17 2000/11/15 19:43:39 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_database.sgml,v 1.18 2001/08/26 16:55:59 tgl Exp $
Postgres documentation
-->
......@@ -284,6 +284,20 @@ comment from Olly; response from Thomas...
simply by setting the flag false). The <literal>template0</literal>
database is normally marked this way to prevent modification of it.
</para>
<para>
After preparing a template database, or making any changes to one,
it is a good idea to perform
<command>VACUUM FREEZE</> or <command>VACUUM FULL FREEZE</> in that
database. If this is done when there are no other open transactions
in the same database, then it is guaranteed that all tuples in the
database are <quote>frozen</> and will not be subject to transaction
ID wraparound problems. This is particularly important for a database
that will have <literal>datallowconn</literal> set to false, since it
will be impossible to do routine maintenance <command>VACUUM</>s on
such a database.
See the Administrator's Guide for more information.
</para>
</refsect2>
</refsect1>
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.17 2001/07/10 22:09:28 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/vacuum.sgml,v 1.18 2001/08/26 16:55:59 tgl Exp $
Postgres documentation
-->
......@@ -20,11 +20,11 @@ Postgres documentation
</refnamediv>
<refsynopsisdiv>
<refsynopsisdivinfo>
<date>2001-07-10</date>
<date>2001-08-26</date>
</refsynopsisdivinfo>
<synopsis>
VACUUM [ FULL ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
</synopsis>
<refsect2 id="R2-SQL-VACUUM-1">
......@@ -46,6 +46,14 @@ VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</repl
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>FREEZE</term>
<listitem>
<para>
Selects aggressive <quote>freezing</quote> of tuples.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>VERBOSE</term>
<listitem>
......@@ -169,21 +177,38 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
</para>
<para>
Plain <command>VACUUM</command> simply reclaims space and makes it
<command>VACUUM ANALYZE</command> performs a <command>VACUUM</command>
and then an <command>ANALYZE</command> for each selected table. This
is a handy combination form for routine maintenance scripts. See
<xref linkend="sql-analyze" endterm="sql-analyze-title">
for more details about its processing.
</para>
<para>
Plain <command>VACUUM</command> (without <literal>FULL</>) simply reclaims
space and makes it
available for re-use. This form of the command can operate in parallel
with normal reading and writing of the table. <command>VACUUM
FULL</command> does more extensive processing, including moving of tuples
across blocks to try to compact the table to the minimum number of disk
blocks. This is much slower and requires an exclusive lock on each table
while it is being processed.
blocks. This form is much slower and requires an exclusive lock on each
table while it is being processed.
</para>
<para>
<command>VACUUM ANALYZE</command> performs a <command>VACUUM</command>
and then an <command>ANALYZE</command> for each selected table. This
is a handy combination form for routine maintenance scripts. See
<xref linkend="sql-analyze" endterm="sql-analyze-title">
for more details about its processing.
<command>FREEZE</command> is a special-purpose option that
causes tuples to be marked <quote>frozen</quote> as soon as possible,
rather than waiting until they are quite old. If this is done when there
are no other open transactions in the same database, then it is guaranteed
that all tuples in the database are <quote>frozen</> and will not be
subject to transaction ID wraparound problems, no matter how long the
database is left un-vacuumed.
<command>FREEZE</command> is not recommended for routine use. Its only
intended usage is in connection with preparation of user-defined template
databases, or other databases that are completely read-only and will not
receive routine maintenance <command>VACUUM</> operations.
See <xref linkend="sql-createdatabase" endterm="sql-createdatabase-title">
for details.
</para>
<refsect2 id="R2-SQL-VACUUM-3">
......
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.2 2001/08/25 23:24:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/clog.c,v 1.3 2001/08/26 16:55:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -762,8 +762,12 @@ ExtendCLOG(TransactionId newestXact)
{
int pageno;
/* No work except at first XID of a page */
if (TransactionIdToPgIndex(newestXact) != 0)
/*
* No work except at first XID of a page. But beware: just after
* wraparound, the first XID of page zero is FirstNormalTransactionId.
*/
if (TransactionIdToPgIndex(newestXact) != 0 &&
!TransactionIdEquals(newestXact, FirstNormalTransactionId))
return;
pageno = TransactionIdToPage(newestXact);
......@@ -818,6 +822,18 @@ TruncateCLOG(TransactionId oldestXact)
S_LOCK(&(ClogCtl->control_lck));
restart:;
/*
* While we are holding the lock, make an important safety check:
* the planned cutoff point must be <= the current CLOG endpoint page.
* Otherwise we have already wrapped around, and proceeding with the
* truncation would risk removing the current CLOG segment.
*/
if (CLOGPagePrecedes(ClogCtl->latest_page_number, cutoffPage))
{
S_UNLOCK(&(ClogCtl->control_lck));
elog(LOG, "unable to truncate commit log: apparent wraparound");
return;
}
for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
{
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.47 2001/08/25 18:52:41 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.48 2001/08/26 16:55:59 tgl Exp $
*
* NOTES
* This file contains the high level access-method interface to the
......@@ -236,3 +236,68 @@ TransactionIdAbort(TransactionId transactionId)
TransactionLogUpdate(transactionId, TRANSACTION_STATUS_ABORTED);
}
/*
* TransactionIdPrecedes --- is id1 logically < id2?
*/
bool
TransactionIdPrecedes(TransactionId id1, TransactionId id2)
{
/*
* If either ID is a permanent XID then we can just do unsigned
* comparison. If both are normal, do a modulo-2^31 comparison.
*/
int32 diff;
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
return (id1 < id2);
diff = (int32) (id1 - id2);
return (diff < 0);
}
/*
* TransactionIdPrecedesOrEquals --- is id1 logically <= id2?
*/
bool
TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
{
int32 diff;
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
return (id1 <= id2);
diff = (int32) (id1 - id2);
return (diff <= 0);
}
/*
* TransactionIdFollows --- is id1 logically > id2?
*/
bool
TransactionIdFollows(TransactionId id1, TransactionId id2)
{
int32 diff;
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
return (id1 > id2);
diff = (int32) (id1 - id2);
return (diff > 0);
}
/*
* TransactionIdFollowsOrEquals --- is id1 logically >= id2?
*/
bool
TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
{
int32 diff;
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
return (id1 >= id2);
diff = (int32) (id1 - id2);
return (diff >= 0);
}
......@@ -6,23 +6,18 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: xid.c,v 1.32 2001/08/23 23:06:37 tgl Exp $
*
* OLD COMMENTS
* XXX WARNING
* Much of this file will change when we change our representation
* of transaction ids -cim 3/23/90
*
* It is time to make the switch from 5 byte to 4 byte transaction ids
* This file was totally reworked. -mer 5/22/92
* $Id: xid.c,v 1.33 2001/08/26 16:55:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <limits.h>
#include "access/xact.h"
#define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n))
#define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x)
......@@ -30,9 +25,9 @@
Datum
xidin(PG_FUNCTION_ARGS)
{
char *representation = PG_GETARG_CSTRING(0);
char *str = PG_GETARG_CSTRING(0);
PG_RETURN_TRANSACTIONID((TransactionId) atol(representation));
PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0));
}
Datum
......@@ -40,21 +35,15 @@ xidout(PG_FUNCTION_ARGS)
{
TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
/* maximum 32 bit unsigned integer representation takes 10 chars */
char *representation = palloc(11);
char *str = palloc(11);
snprintf(representation, 11, "%lu", (unsigned long) transactionId);
snprintf(str, 11, "%lu", (unsigned long) transactionId);
PG_RETURN_CSTRING(representation);
PG_RETURN_CSTRING(str);
}
/* ----------------------------------------------------------------
* xideq
* ----------------------------------------------------------------
*/
/*
* xideq - returns 1, iff xid1 == xid2
* 0 else;
* xideq - are two xids equal?
*/
Datum
xideq(PG_FUNCTION_ARGS)
......@@ -64,3 +53,19 @@ xideq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(TransactionIdEquals(xid1, xid2));
}
/*
* xid_age - compute age of an XID (relative to current xact)
*/
Datum
xid_age(PG_FUNCTION_ARGS)
{
TransactionId xid = PG_GETARG_TRANSACTIONID(0);
TransactionId now = GetCurrentTransactionId();
/* Permanent XIDs are always infinitely old */
if (! TransactionIdIsNormal(xid))
PG_RETURN_INT32(INT_MAX);
PG_RETURN_INT32((int32) (now - xid));
}
......@@ -10,7 +10,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.22 2001/08/24 14:07:48 petere Exp $
# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.23 2001/08/26 16:55:59 tgl Exp $
#
# NOTES
# non-essential whitespace is removed from the generated file.
......@@ -155,12 +155,14 @@ INDEXMAXKEYS4=`expr $INDEXMAXKEYS '*' 4` || exit
touch ${OUTPUT_PREFIX}.description.$$
# ----------------
# strip comments and trash from .h before we generate
# the .bki file...
# Strip comments and other trash from .h
#
# Put multi-line start/end comments on a separate line
#
# Rename datatypes that have different names in .h files than in SQL
#
# Substitute values of configuration constants
# ----------------
# also, change Oid to oid. -- AY 8/94.
# also, change NameData to name. -- jolly 8/21/95.
# put multi-line start/end comments on a separate line
#
cat $INFILES | \
sed -e 's;/\*.*\*/;;g' \
......@@ -173,11 +175,14 @@ sed -e 's;/\*.*\*/;;g' \
sed -e "s/;[ ]*$//g" \
-e "s/^[ ]*//" \
-e "s/[ ]Oid/ oid/g" \
-e "s/[ ]NameData/ name/g" \
-e "s/^Oid/oid/g" \
-e "s/(Oid/(oid/g" \
-e "s/[ ]NameData/ name/g" \
-e "s/^NameData/name/g" \
-e "s/(NameData/(name/g" \
-e "s/(Oid/(oid/g" \
-e "s/[ ]TransactionId/ xid/g" \
-e "s/^TransactionId/xid/g" \
-e "s/(TransactionId/(xid/g" \
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
-e "s/DEFAULT_ATTSTATTARGET/$DEFAULTATTSTATTARGET/g" \
-e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.162 2001/08/22 18:24:26 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.163 2001/08/26 16:55:59 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -1692,7 +1692,7 @@ IndexBuildHeapScan(Relation heapRelation,
TupleTableSlot *slot;
ExprContext *econtext;
Snapshot snapshot;
TransactionId XmaxRecent;
TransactionId OldestXmin;
/*
* sanity checks
......@@ -1731,12 +1731,12 @@ IndexBuildHeapScan(Relation heapRelation,
if (IsBootstrapProcessingMode())
{
snapshot = SnapshotNow;
XmaxRecent = InvalidTransactionId;
OldestXmin = InvalidTransactionId;
}
else
{
snapshot = SnapshotAny;
GetXmaxRecent(&XmaxRecent);
OldestXmin = GetOldestXmin(heapRelation->rd_rel->relisshared);
}
scan = heap_beginscan(heapRelation, /* relation */
......@@ -1769,7 +1769,7 @@ IndexBuildHeapScan(Relation heapRelation,
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
sv_infomask = heapTuple->t_data->t_infomask;
switch (HeapTupleSatisfiesVacuum(heapTuple->t_data, XmaxRecent))
switch (HeapTupleSatisfiesVacuum(heapTuple->t_data, OldestXmin))
{
case HEAPTUPLE_DEAD:
indexIt = false;
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.78 2001/08/10 18:57:34 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.79 2001/08/26 16:55:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -39,8 +39,9 @@
/* non-export function prototypes */
static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP,
Oid *dbLastSysOidP, char *dbpath);
int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
char *dbpath);
static bool get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb);
static char *resolve_alt_dbpath(const char *dbpath, Oid dboid);
static bool remove_dbdirs(const char *real_loc, const char *altloc);
......@@ -65,6 +66,8 @@ createdb(const char *dbname, const char *dbpath,
int src_encoding;
bool src_istemplate;
Oid src_lastsysoid;
TransactionId src_vacuumxid;
TransactionId src_frozenxid;
char src_dbpath[MAXPGPATH];
Relation pg_database_rel;
HeapTuple tuple;
......@@ -91,7 +94,7 @@ createdb(const char *dbname, const char *dbpath,
* idea, so accept possibility of race to create. We will check again
* after we grab the exclusive lock.
*/
if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL))
if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
/*
......@@ -101,7 +104,9 @@ createdb(const char *dbname, const char *dbpath,
dbtemplate = "template1"; /* Default template database name */
if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_lastsysoid, src_dbpath))
&src_istemplate, &src_lastsysoid,
&src_vacuumxid, &src_frozenxid,
src_dbpath))
elog(ERROR, "CREATE DATABASE: template \"%s\" does not exist",
dbtemplate);
......@@ -208,8 +213,10 @@ createdb(const char *dbname, const char *dbpath,
pg_database_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
/* Check to see if someone else created same DB name meanwhile. */
if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL))
if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
{
/* Don't hold lock while doing recursive remove */
heap_close(pg_database_rel, AccessExclusiveLock);
remove_dbdirs(nominal_loc, alt_loc);
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
}
......@@ -227,6 +234,8 @@ createdb(const char *dbname, const char *dbpath,
new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false);
new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
new_record[Anum_pg_database_datlastsysoid - 1] = ObjectIdGetDatum(src_lastsysoid);
new_record[Anum_pg_database_datvacuumxid - 1] = TransactionIdGetDatum(src_vacuumxid);
new_record[Anum_pg_database_datfrozenxid - 1] = TransactionIdGetDatum(src_frozenxid);
/* no nulls here, GetRawDatabaseInfo doesn't like them */
new_record[Anum_pg_database_datpath - 1] =
DirectFunctionCall1(textin, CStringGetDatum(dbpath ? dbpath : ""));
......@@ -307,7 +316,7 @@ dropdb(const char *dbname)
pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
if (!get_db_info(dbname, &db_id, &db_owner, NULL,
&db_istemplate, NULL, dbpath))
&db_istemplate, NULL, NULL, NULL, dbpath))
elog(ERROR, "DROP DATABASE: database \"%s\" does not exist", dbname);
if (!use_super && GetUserId() != db_owner)
......@@ -397,13 +406,15 @@ dropdb(const char *dbname)
static bool
get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP,
Oid *dbLastSysOidP, char *dbpath)
int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
char *dbpath)
{
Relation relation;
ScanKeyData scanKey;
HeapScanDesc scan;
HeapTuple tuple;
bool gottuple;
AssertArg(name);
......@@ -414,12 +425,11 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
F_NAMEEQ, NameGetDatum(name));
scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scanKey);
if (!HeapScanIsValid(scan))
elog(ERROR, "Cannot begin scan of %s", DatabaseRelationName);
tuple = heap_getnext(scan, 0);
if (HeapTupleIsValid(tuple))
gottuple = HeapTupleIsValid(tuple);
if (gottuple)
{
Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple);
text *tmptext;
......@@ -428,7 +438,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* oid of the database */
if (dbIdP)
*dbIdP = tuple->t_data->t_oid;
/* uid of the owner */
/* sysid of the owner */
if (ownerIdP)
*ownerIdP = dbform->datdba;
/* multibyte encoding */
......@@ -440,6 +450,12 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* last system OID used in database */
if (dbLastSysOidP)
*dbLastSysOidP = dbform->datlastsysoid;
/* limit of vacuumed XIDs */
if (dbVacuumXidP)
*dbVacuumXidP = dbform->datvacuumxid;
/* limit of frozen XIDs */
if (dbFrozenXidP)
*dbFrozenXidP = dbform->datfrozenxid;
/* database path (as registered in pg_database) */
if (dbpath)
{
......@@ -462,7 +478,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
heap_endscan(scan);
heap_close(relation, AccessShareLock);
return HeapTupleIsValid(tuple);
return gottuple;
}
static bool
......
This diff is collapsed.
......@@ -31,7 +31,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.4 2001/08/10 18:57:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.5 2001/08/26 16:55:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -94,7 +94,8 @@ typedef struct LVRelStats
static int MESSAGE_LEVEL; /* message level */
static TransactionId XmaxRecent;
static TransactionId OldestXmin;
static TransactionId FreezeLimit;
/* non-export function prototypes */
......@@ -143,7 +144,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
else
MESSAGE_LEVEL = DEBUG;
GetXmaxRecent(&XmaxRecent);
vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
&OldestXmin, &FreezeLimit);
vacrelstats = (LVRelStats *) palloc(sizeof(LVRelStats));
MemSet(vacrelstats, 0, sizeof(LVRelStats));
......@@ -307,12 +309,25 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
tupgone = false;
sv_infomask = tuple.t_data->t_infomask;
switch (HeapTupleSatisfiesVacuum(tuple.t_data, XmaxRecent))
switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin))
{
case HEAPTUPLE_DEAD:
tupgone = true; /* we can delete the tuple */
break;
case HEAPTUPLE_LIVE:
/*
* Tuple is good. Consider whether to replace its xmin
* value with FrozenTransactionId.
*/
if (TransactionIdIsNormal(tuple.t_data->t_xmin) &&
TransactionIdPrecedes(tuple.t_data->t_xmin,
FreezeLimit))
{
tuple.t_data->t_xmin = FrozenTransactionId;
tuple.t_data->t_infomask &= ~HEAP_XMIN_INVALID;
tuple.t_data->t_infomask |= HEAP_XMIN_COMMITTED;
pgchanged = true;
}
break;
case HEAPTUPLE_RECENTLY_DEAD:
/*
......@@ -783,12 +798,13 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
tupgone = false;
sv_infomask = tuple.t_data->t_infomask;
switch (HeapTupleSatisfiesVacuum(tuple.t_data, XmaxRecent))
switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin))
{
case HEAPTUPLE_DEAD:
tupgone = true; /* we can delete the tuple */
break;
case HEAPTUPLE_LIVE:
/* Shouldn't be necessary to re-freeze anything */
break;
case HEAPTUPLE_RECENTLY_DEAD:
/*
......
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.154 2001/08/21 16:36:02 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.155 2001/08/26 16:55:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -2246,6 +2246,7 @@ _copyVacuumStmt(VacuumStmt *from)
newnode->vacuum = from->vacuum;
newnode->full = from->full;
newnode->analyze = from->analyze;
newnode->freeze = from->freeze;
newnode->verbose = from->verbose;
if (from->vacrel)
newnode->vacrel = pstrdup(from->vacrel);
......
......@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.102 2001/08/21 16:36:02 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.103 2001/08/26 16:55:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1116,6 +1116,8 @@ _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
return false;
if (a->analyze != b->analyze)
return false;
if (a->freeze != b->freeze)
return false;
if (a->verbose != b->verbose)
return false;
if (!equalstr(a->vacrel, b->vacrel))
......
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.248 2001/08/25 18:52:41 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.249 2001/08/26 16:55:59 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -215,7 +215,7 @@ static void doNegateFloat(Value *v);
%type <boolean> opt_binary, opt_using, opt_instead, opt_cursor
%type <boolean> opt_with_copy, index_opt_unique, opt_verbose, opt_full
%type <boolean> analyze_keyword
%type <boolean> opt_freeze, analyze_keyword
%type <ival> copy_dirn, direction, reindex_type, drop_type,
opt_column, event, comment_type, comment_cl,
......@@ -346,7 +346,7 @@ static void doNegateFloat(Value *v);
CACHE, CHECKPOINT, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
DATABASE, DELIMITERS, DO,
EACH, ENCODING, EXCLUSIVE, EXPLAIN,
FORCE, FORWARD, FUNCTION, HANDLER,
FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
MAXVALUE, MINVALUE, MODE, MOVE,
......@@ -3082,34 +3082,37 @@ ClusterStmt: CLUSTER index_name ON relation_name
*
*****************************************************************************/
VacuumStmt: VACUUM opt_full opt_verbose
VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
{
VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = true;
n->analyze = false;
n->full = $2;
n->verbose = $3;
n->freeze = $3;
n->verbose = $4;
n->vacrel = NULL;
n->va_cols = NIL;
$$ = (Node *)n;
}
| VACUUM opt_full opt_verbose relation_name
| VACUUM opt_full opt_freeze opt_verbose relation_name
{
VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = true;
n->analyze = false;
n->full = $2;
n->verbose = $3;
n->vacrel = $4;
n->freeze = $3;
n->verbose = $4;
n->vacrel = $5;
n->va_cols = NIL;
$$ = (Node *)n;
}
| VACUUM opt_full opt_verbose AnalyzeStmt
| VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
{
VacuumStmt *n = (VacuumStmt *) $4;
VacuumStmt *n = (VacuumStmt *) $5;
n->vacuum = true;
n->full = $2;
n->verbose |= $3;
n->freeze = $3;
n->verbose |= $4;
$$ = (Node *)n;
}
;
......@@ -3120,6 +3123,7 @@ AnalyzeStmt: analyze_keyword opt_verbose
n->vacuum = false;
n->analyze = true;
n->full = false;
n->freeze = false;
n->verbose = $2;
n->vacrel = NULL;
n->va_cols = NIL;
......@@ -3131,6 +3135,7 @@ AnalyzeStmt: analyze_keyword opt_verbose
n->vacuum = false;
n->analyze = true;
n->full = false;
n->freeze = false;
n->verbose = $2;
n->vacrel = $3;
n->va_cols = $4;
......@@ -3150,6 +3155,10 @@ opt_full: FULL { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
opt_freeze: FREEZE { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
opt_name_list: '(' name_list ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
......@@ -5615,6 +5624,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; }
| DROP { $$ = "drop"; }
| EACH { $$ = "each"; }
| ENCODING { $$ = "encoding"; }
| ENCRYPTED { $$ = "encrypted"; }
| ESCAPE { $$ = "escape"; }
| EXCLUSIVE { $$ = "exclusive"; }
| EXECUTE { $$ = "execute"; }
......@@ -5693,6 +5703,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; }
| TRUNCATE { $$ = "truncate"; }
| TRUSTED { $$ = "trusted"; }
| TYPE_P { $$ = "type"; }
| UNENCRYPTED { $$ = "unencrypted"; }
| UNLISTEN { $$ = "unlisten"; }
| UNTIL { $$ = "until"; }
| UPDATE { $$ = "update"; }
......@@ -5753,7 +5764,6 @@ ColLabel: ColId { $$ = $1; }
| DISTINCT { $$ = "distinct"; }
| DO { $$ = "do"; }
| ELSE { $$ = "else"; }
| ENCRYPTED { $$ = "encrypted"; }
| END_TRANS { $$ = "end"; }
| EXCEPT { $$ = "except"; }
| EXISTS { $$ = "exists"; }
......@@ -5763,6 +5773,7 @@ ColLabel: ColId { $$ = $1; }
| FLOAT { $$ = "float"; }
| FOR { $$ = "for"; }
| FOREIGN { $$ = "foreign"; }
| FREEZE { $$ = "freeze"; }
| FROM { $$ = "from"; }
| FULL { $$ = "full"; }
| GLOBAL { $$ = "global"; }
......@@ -5825,7 +5836,6 @@ ColLabel: ColId { $$ = $1; }
| TRANSACTION { $$ = "transaction"; }
| TRIM { $$ = "trim"; }
| TRUE_P { $$ = "true"; }
| UNENCRYPTED { $$ = "unencrypted"; }
| UNION { $$ = "union"; }
| UNIQUE { $$ = "unique"; }
| UNKNOWN { $$ = "unknown"; }
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.96 2001/08/16 20:38:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.97 2001/08/26 16:56:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -118,6 +118,7 @@ static ScanKeyword ScanKeywords[] = {
{"force", FORCE},
{"foreign", FOREIGN},
{"forward", FORWARD},
{"freeze", FREEZE},
{"from", FROM},
{"full", FULL},
{"function", FUNCTION},
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.39 2001/08/25 18:52:42 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.40 2001/08/26 16:56:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -20,6 +20,8 @@
#include "storage/sinval.h"
#include "storage/sinvaladt.h"
#include "utils/tqual.h"
#include "miscadmin.h"
SPINLOCK SInvalLock = (SPINLOCK) NULL;
......@@ -210,17 +212,23 @@ TransactionIdIsInProgress(TransactionId xid)
}
/*
* GetXmaxRecent -- returns oldest transaction that was running
* when all current transaction were started.
* It's used by vacuum to decide what deleted
* tuples must be preserved in a table.
* GetOldestXmin -- returns oldest transaction that was running
* when any current transaction was started.
*
* If allDbs is TRUE then all backends are considered; if allDbs is FALSE
* then only backends running in my own database are considered.
*
* Note: we include all currently running xids in the set of considered xids.
* This is used by VACUUM to decide which deleted tuples must be preserved
* in a table. allDbs = TRUE is needed for shared relations, but allDbs =
* FALSE is sufficient for non-shared relations, since only backends in my
* own database could ever see the tuples in them.
*
* Note: we include the currently running xids in the set of considered xids.
* This ensures that if a just-started xact has not yet set its snapshot,
* when it does set the snapshot it cannot set xmin less than what we compute.
*/
void
GetXmaxRecent(TransactionId *XmaxRecent)
TransactionId
GetOldestXmin(bool allDbs)
{
SISeg *segP = shmInvalBuffer;
ProcState *stateP = segP->procState;
......@@ -238,24 +246,28 @@ GetXmaxRecent(TransactionId *XmaxRecent)
if (pOffset != INVALID_OFFSET)
{
PROC *proc = (PROC *) MAKE_PTR(pOffset);
/* Fetch xid just once - see GetNewTransactionId */
TransactionId xid = proc->xid;
if (TransactionIdIsNormal(xid))
if (allDbs || proc->databaseId == MyDatabaseId)
{
if (TransactionIdPrecedes(xid, result))
result = xid;
xid = proc->xmin;
/* Fetch xid just once - see GetNewTransactionId */
TransactionId xid = proc->xid;
if (TransactionIdIsNormal(xid))
{
if (TransactionIdPrecedes(xid, result))
result = xid;
xid = proc->xmin;
if (TransactionIdIsNormal(xid))
if (TransactionIdPrecedes(xid, result))
result = xid;
}
}
}
}
SpinRelease(SInvalLock);
*XmaxRecent = result;
return result;
}
/*----------
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.41 2001/08/25 18:52:42 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.42 2001/08/26 16:56:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -592,8 +592,8 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
* HeapTupleSatisfiesVacuum - determine tuple status for VACUUM and related
* operations
*
* XmaxRecent is a cutoff XID (obtained from GetXmaxRecent()). Tuples
* deleted by XIDs >= XmaxRecent are deemed "recently dead"; they might
* OldestXmin is a cutoff XID (obtained from GetOldestXmin()). Tuples
* deleted by XIDs >= OldestXmin are deemed "recently dead"; they might
* still be visible to some open transaction, so we can't remove them,
* even if we see that the deleting transaction has committed.
*
......@@ -603,7 +603,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
* change in t_infomask and scheduling a disk write if so.
*/
HTSV_Result
HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent)
HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
{
/*
* Has inserting transaction committed?
......@@ -712,7 +712,7 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent)
return HEAPTUPLE_DEAD;
}
if (!TransactionIdPrecedes(tuple->t_xmax, XmaxRecent))
if (!TransactionIdPrecedes(tuple->t_xmax, OldestXmin))
{
/* deleting xact is too recent, tuple could still be visible */
return HEAPTUPLE_RECENTLY_DEAD;
......
......@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.134 2001/08/25 18:52:42 tgl Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.135 2001/08/26 16:56:00 tgl Exp $
#
#-------------------------------------------------------------------------
......@@ -841,7 +841,7 @@ echo "ok"
$ECHO_N "vacuuming database template1... "$ECHO_C
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
VACUUM FULL ANALYZE;
VACUUM FULL FREEZE;
EOF
if [ "$?" -ne 0 ]; then
exit_nicely
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: transam.h,v 1.39 2001/08/25 18:52:42 tgl Exp $
* $Id: transam.h,v 1.40 2001/08/26 16:56:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -31,6 +31,7 @@
#define BootstrapTransactionId ((TransactionId) 1)
#define FrozenTransactionId ((TransactionId) 2)
#define FirstNormalTransactionId ((TransactionId) 3)
#define MaxTransactionId ((TransactionId) 0xFFFFFFFF)
/* ----------------
* transaction ID manipulation macros
......@@ -38,11 +39,7 @@
*/
#define TransactionIdIsValid(xid) ((xid) != InvalidTransactionId)
#define TransactionIdIsNormal(xid) ((xid) >= FirstNormalTransactionId)
#define TransactionIdEquals(id1, id2) ((id1) == (id2))
#define TransactionIdPrecedes(id1, id2) ((id1) < (id2))
#define TransactionIdPrecedesOrEquals(id1, id2) ((id1) <= (id2))
#define TransactionIdFollows(id1, id2) ((id1) > (id2))
#define TransactionIdFollowsOrEquals(id1, id2) ((id1) >= (id2))
#define TransactionIdEquals(id1, id2) ((id1) == (id2))
#define TransactionIdStore(xid, dest) (*(dest) = (xid))
#define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId)
/* advance a transaction ID variable, handling wraparound correctly */
......@@ -105,6 +102,10 @@ extern bool TransactionIdDidCommit(TransactionId transactionId);
extern bool TransactionIdDidAbort(TransactionId transactionId);
extern void TransactionIdCommit(TransactionId transactionId);
extern void TransactionIdAbort(TransactionId transactionId);
extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2);
extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2);
extern bool TransactionIdFollows(TransactionId id1, TransactionId id2);
extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2);
/* in transam/varsup.c */
extern TransactionId GetNewTransactionId(void);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: xact.h,v 1.35 2001/08/25 18:52:42 tgl Exp $
* $Id: xact.h,v 1.36 2001/08/26 16:56:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -130,5 +130,6 @@ extern void xact_desc(char *buf, uint8 xl_info, char *rec);
extern Datum xidin(PG_FUNCTION_ARGS);
extern Datum xidout(PG_FUNCTION_ARGS);
extern Datum xideq(PG_FUNCTION_ARGS);
extern Datum xid_age(PG_FUNCTION_ARGS);
#endif /* XACT_H */
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.92 2001/08/25 18:52:42 tgl Exp $
* $Id: catversion.h,v 1.93 2001/08/26 16:56:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200108241
#define CATALOG_VERSION_NO 200108251
#endif
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_attribute.h,v 1.75 2001/08/25 18:52:42 tgl Exp $
* $Id: pg_attribute.h,v 1.76 2001/08/26 16:56:00 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -276,8 +276,10 @@ DATA(insert ( 1262 encoding 23 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datistemplate 16 0 1 4 0 -1 -1 t p f c f f));
DATA(insert ( 1262 datallowconn 16 0 1 5 0 -1 -1 t p f c f f));
DATA(insert ( 1262 datlastsysoid 26 0 4 6 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datvacuumxid 28 0 4 7 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datfrozenxid 28 0 4 8 0 -1 -1 t p f i f f));
/* do not mark datpath as toastable; GetRawDatabaseInfo won't cope */
DATA(insert ( 1262 datpath 25 0 -1 7 0 -1 -1 f p f i f f));
DATA(insert ( 1262 datpath 25 0 -1 9 0 -1 -1 f p f i f f));
DATA(insert ( 1262 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1262 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_class.h,v 1.53 2001/08/25 18:52:43 tgl Exp $
* $Id: pg_class.h,v 1.54 2001/08/26 16:56:01 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -142,7 +142,7 @@ DATA(insert OID = 1260 ( pg_shadow 86 PGUID 0 1260 0 0 0 0 f t r 8 0 0 0 0 0
DESCR("");
DATA(insert OID = 1261 ( pg_group 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ ));
DESCR("");
DATA(insert OID = 1262 ( pg_database 88 PGUID 0 1262 0 0 0 0 f t r 7 0 0 0 0 0 t f f f _null_ ));
DATA(insert OID = 1262 ( pg_database 88 PGUID 0 1262 0 0 0 0 f t r 9 0 0 0 0 0 t f f f _null_ ));
DESCR("");
DATA(insert OID = 376 ( pg_xactlock 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ ));
DESCR("");
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_database.h,v 1.17 2001/03/22 04:00:38 momjian Exp $
* $Id: pg_database.h,v 1.18 2001/08/26 16:56:02 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -33,13 +33,14 @@
*/
CATALOG(pg_database) BOOTSTRAP
{
NameData datname;
int4 datdba;
int4 encoding;
bool datistemplate; /* allowed as template for CREATE
* DATABASE? */
NameData datname; /* database name */
int4 datdba; /* sysid of owner */
int4 encoding; /* multibyte encoding, if any */
bool datistemplate; /* allowed as CREATE DATABASE template? */
bool datallowconn; /* new connections allowed? */
Oid datlastsysoid;
Oid datlastsysoid; /* highest OID to consider a system OID */
TransactionId datvacuumxid; /* all XIDs before this are vacuumed */
TransactionId datfrozenxid; /* all XIDs before this are frozen */
text datpath; /* VARIABLE LENGTH FIELD */
} FormData_pg_database;
......@@ -54,16 +55,18 @@ typedef FormData_pg_database *Form_pg_database;
* compiler constants for pg_database
* ----------------
*/
#define Natts_pg_database 7
#define Natts_pg_database 9
#define Anum_pg_database_datname 1
#define Anum_pg_database_datdba 2
#define Anum_pg_database_encoding 3
#define Anum_pg_database_datistemplate 4
#define Anum_pg_database_datallowconn 5
#define Anum_pg_database_datlastsysoid 6
#define Anum_pg_database_datpath 7
#define Anum_pg_database_datvacuumxid 7
#define Anum_pg_database_datfrozenxid 8
#define Anum_pg_database_datpath 9
DATA(insert OID = 1 ( template1 PGUID ENCODING t t 0 "" ));
DATA(insert OID = 1 ( template1 PGUID ENCODING t t 0 0 0 "" ));
DESCR("Default template database");
#define TemplateDbOid 1
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.206 2001/08/16 20:38:54 tgl Exp $
* $Id: pg_proc.h,v 1.207 2001/08/26 16:56:02 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -1450,6 +1450,8 @@ DATA(insert OID = 1179 ( date PGUID 12 f t f t 1 f 1082 "702" 100 0 0 100
DESCR("convert abstime to date");
DATA(insert OID = 1180 ( abstime PGUID 12 f t f t 1 f 702 "1184" 100 0 0 100 timestamp_abstime - ));
DESCR("convert timestamp to abstime");
DATA(insert OID = 1181 ( age PGUID 12 f t f t 1 f 23 "28" 100 0 0 100 xid_age - ));
DESCR("age of a transaction ID, in transactions before current transaction");
DATA(insert OID = 1188 ( timestamp_mi PGUID 12 f t f t 2 f 1186 "1184 1184" 100 0 0 100 timestamp_mi - ));
DESCR("subtract");
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: vacuum.h,v 1.39 2001/07/18 00:46:25 tgl Exp $
* $Id: vacuum.h,v 1.40 2001/08/26 16:56:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -44,6 +44,9 @@ extern void vac_update_relstats(Oid relid,
BlockNumber num_pages,
double num_tuples,
bool hasindex);
extern void vacuum_set_xid_limits(VacuumStmt *vacstmt, bool sharedRel,
TransactionId *oldestXmin,
TransactionId *freezeLimit);
extern bool vac_is_partial_index(Relation indrel);
extern void vac_init_rusage(VacRUsage *ru0);
extern const char *vac_show_rusage(VacRUsage *ru0);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.142 2001/08/21 16:36:06 tgl Exp $
* $Id: parsenodes.h,v 1.143 2001/08/26 16:56:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -694,6 +694,7 @@ typedef struct VacuumStmt
bool vacuum; /* do VACUUM step */
bool full; /* do FULL (non-concurrent) vacuum */
bool analyze; /* do ANALYZE step */
bool freeze; /* early-freeze option */
bool verbose; /* print progress info */
char *vacrel; /* name of single table to process, or NULL */
List *va_cols; /* list of column names, or NIL for all */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: sinval.h,v 1.20 2001/07/06 21:04:26 tgl Exp $
* $Id: sinval.h,v 1.21 2001/08/26 16:56:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -76,7 +76,7 @@ extern void ReceiveSharedInvalidMessages(
extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
extern bool TransactionIdIsInProgress(TransactionId xid);
extern void GetXmaxRecent(TransactionId *XmaxRecent);
extern TransactionId GetOldestXmin(bool allDbs);
extern int CountActiveBackends(void);
/* Use "struct proc", not PROC, to avoid including proc.h here */
extern struct proc *BackendIdGetProc(BackendId procId);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: tqual.h,v 1.33 2001/08/23 23:06:38 tgl Exp $
* $Id: tqual.h,v 1.34 2001/08/26 16:56:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -104,7 +104,7 @@ extern bool HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple,
Snapshot snapshot);
extern int HeapTupleSatisfiesUpdate(HeapTuple tuple);
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
TransactionId XmaxRecent);
TransactionId OldestXmin);
extern Snapshot GetSnapshotData(bool serializable);
extern void SetQuerySnapshot(void);
......
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