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 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"> <chapter id="catalogs">
...@@ -840,11 +840,34 @@ ...@@ -840,11 +840,34 @@
<entry><type>oid</type></entry> <entry><type>oid</type></entry>
<entry></entry> <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> particularly to <application>pg_dump</application>
</entry> </entry>
</row> </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> <row>
<entry>datpath</entry> <entry>datpath</entry>
<entry><type>text</type></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 Postgres documentation
--> -->
...@@ -284,6 +284,20 @@ comment from Olly; response from Thomas... ...@@ -284,6 +284,20 @@ comment from Olly; response from Thomas...
simply by setting the flag false). The <literal>template0</literal> simply by setting the flag false). The <literal>template0</literal>
database is normally marked this way to prevent modification of it. database is normally marked this way to prevent modification of it.
</para> </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> </refsect2>
</refsect1> </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 Postgres documentation
--> -->
...@@ -20,11 +20,11 @@ Postgres documentation ...@@ -20,11 +20,11 @@ Postgres documentation
</refnamediv> </refnamediv>
<refsynopsisdiv> <refsynopsisdiv>
<refsynopsisdivinfo> <refsynopsisdivinfo>
<date>2001-07-10</date> <date>2001-08-26</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
VACUUM [ FULL ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ] VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ <replaceable class="PARAMETER">table</replaceable> ]
VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ] VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</replaceable> [ (<replaceable class="PARAMETER">column</replaceable> [, ...] ) ] ]
</synopsis> </synopsis>
<refsect2 id="R2-SQL-VACUUM-1"> <refsect2 id="R2-SQL-VACUUM-1">
...@@ -46,6 +46,14 @@ VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</repl ...@@ -46,6 +46,14 @@ VACUUM [ FULL ] [ VERBOSE ] ANALYZE [ <replaceable class="PARAMETER">table</repl
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>FREEZE</term>
<listitem>
<para>
Selects aggressive <quote>freezing</quote> of tuples.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>VERBOSE</term> <term>VERBOSE</term>
<listitem> <listitem>
...@@ -169,21 +177,38 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28; ...@@ -169,21 +177,38 @@ NOTICE: Index <replaceable class="PARAMETER">index</replaceable>: Pages 28;
</para> </para>
<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 available for re-use. This form of the command can operate in parallel
with normal reading and writing of the table. <command>VACUUM with normal reading and writing of the table. <command>VACUUM
FULL</command> does more extensive processing, including moving of tuples FULL</command> does more extensive processing, including moving of tuples
across blocks to try to compact the table to the minimum number of disk 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 blocks. This form is much slower and requires an exclusive lock on each
while it is being processed. table while it is being processed.
</para> </para>
<para> <para>
<command>VACUUM ANALYZE</command> performs a <command>VACUUM</command> <command>FREEZE</command> is a special-purpose option that
and then an <command>ANALYZE</command> for each selected table. This causes tuples to be marked <quote>frozen</quote> as soon as possible,
is a handy combination form for routine maintenance scripts. See rather than waiting until they are quite old. If this is done when there
<xref linkend="sql-analyze" endterm="sql-analyze-title"> are no other open transactions in the same database, then it is guaranteed
for more details about its processing. 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> </para>
<refsect2 id="R2-SQL-VACUUM-3"> <refsect2 id="R2-SQL-VACUUM-3">
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -762,8 +762,12 @@ ExtendCLOG(TransactionId newestXact)
{ {
int pageno; 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; return;
pageno = TransactionIdToPage(newestXact); pageno = TransactionIdToPage(newestXact);
...@@ -818,6 +822,18 @@ TruncateCLOG(TransactionId oldestXact) ...@@ -818,6 +822,18 @@ TruncateCLOG(TransactionId oldestXact)
S_LOCK(&(ClogCtl->control_lck)); S_LOCK(&(ClogCtl->control_lck));
restart:; 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++) for (slotno = 0; slotno < NUM_CLOG_BUFFERS; slotno++)
{ {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* This file contains the high level access-method interface to the * This file contains the high level access-method interface to the
...@@ -236,3 +236,68 @@ TransactionIdAbort(TransactionId transactionId) ...@@ -236,3 +236,68 @@ TransactionIdAbort(TransactionId transactionId)
TransactionLogUpdate(transactionId, TRANSACTION_STATUS_ABORTED); 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 @@ ...@@ -6,23 +6,18 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: xid.c,v 1.32 2001/08/23 23:06:37 tgl Exp $ * $Id: xid.c,v 1.33 2001/08/26 16:55:59 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
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include <limits.h>
#include "access/xact.h" #include "access/xact.h"
#define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n)) #define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n))
#define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x) #define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x)
...@@ -30,9 +25,9 @@ ...@@ -30,9 +25,9 @@
Datum Datum
xidin(PG_FUNCTION_ARGS) 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 Datum
...@@ -40,21 +35,15 @@ xidout(PG_FUNCTION_ARGS) ...@@ -40,21 +35,15 @@ xidout(PG_FUNCTION_ARGS)
{ {
TransactionId transactionId = PG_GETARG_TRANSACTIONID(0); TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
/* maximum 32 bit unsigned integer representation takes 10 chars */ /* 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 * xideq - are two xids equal?
* 0 else;
*/ */
Datum Datum
xideq(PG_FUNCTION_ARGS) xideq(PG_FUNCTION_ARGS)
...@@ -64,3 +53,19 @@ xideq(PG_FUNCTION_ARGS) ...@@ -64,3 +53,19 @@ xideq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(TransactionIdEquals(xid1, xid2)); 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 @@ ...@@ -10,7 +10,7 @@
# #
# #
# IDENTIFICATION # 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 # NOTES
# non-essential whitespace is removed from the generated file. # non-essential whitespace is removed from the generated file.
...@@ -155,12 +155,14 @@ INDEXMAXKEYS4=`expr $INDEXMAXKEYS '*' 4` || exit ...@@ -155,12 +155,14 @@ INDEXMAXKEYS4=`expr $INDEXMAXKEYS '*' 4` || exit
touch ${OUTPUT_PREFIX}.description.$$ touch ${OUTPUT_PREFIX}.description.$$
# ---------------- # ----------------
# strip comments and trash from .h before we generate # Strip comments and other trash from .h
# the .bki file... #
# 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 | \ cat $INFILES | \
sed -e 's;/\*.*\*/;;g' \ sed -e 's;/\*.*\*/;;g' \
...@@ -173,11 +175,14 @@ sed -e 's;/\*.*\*/;;g' \ ...@@ -173,11 +175,14 @@ sed -e 's;/\*.*\*/;;g' \
sed -e "s/;[ ]*$//g" \ sed -e "s/;[ ]*$//g" \
-e "s/^[ ]*//" \ -e "s/^[ ]*//" \
-e "s/[ ]Oid/ oid/g" \ -e "s/[ ]Oid/ oid/g" \
-e "s/[ ]NameData/ name/g" \
-e "s/^Oid/oid/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/(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/NAMEDATALEN/$NAMEDATALEN/g" \
-e "s/DEFAULT_ATTSTATTARGET/$DEFAULTATTSTATTARGET/g" \ -e "s/DEFAULT_ATTSTATTARGET/$DEFAULTATTSTATTARGET/g" \
-e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \ -e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * INTERFACE ROUTINES
...@@ -1692,7 +1692,7 @@ IndexBuildHeapScan(Relation heapRelation, ...@@ -1692,7 +1692,7 @@ IndexBuildHeapScan(Relation heapRelation,
TupleTableSlot *slot; TupleTableSlot *slot;
ExprContext *econtext; ExprContext *econtext;
Snapshot snapshot; Snapshot snapshot;
TransactionId XmaxRecent; TransactionId OldestXmin;
/* /*
* sanity checks * sanity checks
...@@ -1731,12 +1731,12 @@ IndexBuildHeapScan(Relation heapRelation, ...@@ -1731,12 +1731,12 @@ IndexBuildHeapScan(Relation heapRelation,
if (IsBootstrapProcessingMode()) if (IsBootstrapProcessingMode())
{ {
snapshot = SnapshotNow; snapshot = SnapshotNow;
XmaxRecent = InvalidTransactionId; OldestXmin = InvalidTransactionId;
} }
else else
{ {
snapshot = SnapshotAny; snapshot = SnapshotAny;
GetXmaxRecent(&XmaxRecent); OldestXmin = GetOldestXmin(heapRelation->rd_rel->relisshared);
} }
scan = heap_beginscan(heapRelation, /* relation */ scan = heap_beginscan(heapRelation, /* relation */
...@@ -1769,7 +1769,7 @@ IndexBuildHeapScan(Relation heapRelation, ...@@ -1769,7 +1769,7 @@ IndexBuildHeapScan(Relation heapRelation,
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
sv_infomask = heapTuple->t_data->t_infomask; sv_infomask = heapTuple->t_data->t_infomask;
switch (HeapTupleSatisfiesVacuum(heapTuple->t_data, XmaxRecent)) switch (HeapTupleSatisfiesVacuum(heapTuple->t_data, OldestXmin))
{ {
case HEAPTUPLE_DEAD: case HEAPTUPLE_DEAD:
indexIt = false; indexIt = false;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -39,8 +39,9 @@
/* non-export function prototypes */ /* non-export function prototypes */
static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP, int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
Oid *dbLastSysOidP, char *dbpath); TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
char *dbpath);
static bool get_user_info(Oid use_sysid, bool *use_super, bool *use_createdb); 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 char *resolve_alt_dbpath(const char *dbpath, Oid dboid);
static bool remove_dbdirs(const char *real_loc, const char *altloc); static bool remove_dbdirs(const char *real_loc, const char *altloc);
...@@ -65,6 +66,8 @@ createdb(const char *dbname, const char *dbpath, ...@@ -65,6 +66,8 @@ createdb(const char *dbname, const char *dbpath,
int src_encoding; int src_encoding;
bool src_istemplate; bool src_istemplate;
Oid src_lastsysoid; Oid src_lastsysoid;
TransactionId src_vacuumxid;
TransactionId src_frozenxid;
char src_dbpath[MAXPGPATH]; char src_dbpath[MAXPGPATH];
Relation pg_database_rel; Relation pg_database_rel;
HeapTuple tuple; HeapTuple tuple;
...@@ -91,7 +94,7 @@ createdb(const char *dbname, const char *dbpath, ...@@ -91,7 +94,7 @@ createdb(const char *dbname, const char *dbpath,
* idea, so accept possibility of race to create. We will check again * idea, so accept possibility of race to create. We will check again
* after we grab the exclusive lock. * 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); elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
/* /*
...@@ -101,7 +104,9 @@ createdb(const char *dbname, const char *dbpath, ...@@ -101,7 +104,9 @@ createdb(const char *dbname, const char *dbpath,
dbtemplate = "template1"; /* Default template database name */ dbtemplate = "template1"; /* Default template database name */
if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding, 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", elog(ERROR, "CREATE DATABASE: template \"%s\" does not exist",
dbtemplate); dbtemplate);
...@@ -208,8 +213,10 @@ createdb(const char *dbname, const char *dbpath, ...@@ -208,8 +213,10 @@ createdb(const char *dbname, const char *dbpath,
pg_database_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock); pg_database_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
/* Check to see if someone else created same DB name meanwhile. */ /* 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); remove_dbdirs(nominal_loc, alt_loc);
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname); elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
} }
...@@ -227,6 +234,8 @@ createdb(const char *dbname, const char *dbpath, ...@@ -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_datistemplate - 1] = BoolGetDatum(false);
new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true); new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
new_record[Anum_pg_database_datlastsysoid - 1] = ObjectIdGetDatum(src_lastsysoid); 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 */ /* no nulls here, GetRawDatabaseInfo doesn't like them */
new_record[Anum_pg_database_datpath - 1] = new_record[Anum_pg_database_datpath - 1] =
DirectFunctionCall1(textin, CStringGetDatum(dbpath ? dbpath : "")); DirectFunctionCall1(textin, CStringGetDatum(dbpath ? dbpath : ""));
...@@ -307,7 +316,7 @@ dropdb(const char *dbname) ...@@ -307,7 +316,7 @@ dropdb(const char *dbname)
pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock); pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
if (!get_db_info(dbname, &db_id, &db_owner, NULL, 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); elog(ERROR, "DROP DATABASE: database \"%s\" does not exist", dbname);
if (!use_super && GetUserId() != db_owner) if (!use_super && GetUserId() != db_owner)
...@@ -397,13 +406,15 @@ dropdb(const char *dbname) ...@@ -397,13 +406,15 @@ dropdb(const char *dbname)
static bool static bool
get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
int *encodingP, bool *dbIsTemplateP, int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
Oid *dbLastSysOidP, char *dbpath) TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
char *dbpath)
{ {
Relation relation; Relation relation;
ScanKeyData scanKey; ScanKeyData scanKey;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple tuple; HeapTuple tuple;
bool gottuple;
AssertArg(name); AssertArg(name);
...@@ -414,12 +425,11 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, ...@@ -414,12 +425,11 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
F_NAMEEQ, NameGetDatum(name)); F_NAMEEQ, NameGetDatum(name));
scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scanKey); scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scanKey);
if (!HeapScanIsValid(scan))
elog(ERROR, "Cannot begin scan of %s", DatabaseRelationName);
tuple = heap_getnext(scan, 0); tuple = heap_getnext(scan, 0);
if (HeapTupleIsValid(tuple)) gottuple = HeapTupleIsValid(tuple);
if (gottuple)
{ {
Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple); Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple);
text *tmptext; text *tmptext;
...@@ -428,7 +438,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, ...@@ -428,7 +438,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* oid of the database */ /* oid of the database */
if (dbIdP) if (dbIdP)
*dbIdP = tuple->t_data->t_oid; *dbIdP = tuple->t_data->t_oid;
/* uid of the owner */ /* sysid of the owner */
if (ownerIdP) if (ownerIdP)
*ownerIdP = dbform->datdba; *ownerIdP = dbform->datdba;
/* multibyte encoding */ /* multibyte encoding */
...@@ -440,6 +450,12 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, ...@@ -440,6 +450,12 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* last system OID used in database */ /* last system OID used in database */
if (dbLastSysOidP) if (dbLastSysOidP)
*dbLastSysOidP = dbform->datlastsysoid; *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) */ /* database path (as registered in pg_database) */
if (dbpath) if (dbpath)
{ {
...@@ -462,7 +478,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, ...@@ -462,7 +478,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
heap_endscan(scan); heap_endscan(scan);
heap_close(relation, AccessShareLock); heap_close(relation, AccessShareLock);
return HeapTupleIsValid(tuple); return gottuple;
} }
static bool static bool
......
This diff is collapsed.
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* *
* *
* IDENTIFICATION * 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 ...@@ -94,7 +94,8 @@ typedef struct LVRelStats
static int MESSAGE_LEVEL; /* message level */ static int MESSAGE_LEVEL; /* message level */
static TransactionId XmaxRecent; static TransactionId OldestXmin;
static TransactionId FreezeLimit;
/* non-export function prototypes */ /* non-export function prototypes */
...@@ -143,7 +144,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) ...@@ -143,7 +144,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
else else
MESSAGE_LEVEL = DEBUG; MESSAGE_LEVEL = DEBUG;
GetXmaxRecent(&XmaxRecent); vacuum_set_xid_limits(vacstmt, onerel->rd_rel->relisshared,
&OldestXmin, &FreezeLimit);
vacrelstats = (LVRelStats *) palloc(sizeof(LVRelStats)); vacrelstats = (LVRelStats *) palloc(sizeof(LVRelStats));
MemSet(vacrelstats, 0, sizeof(LVRelStats)); MemSet(vacrelstats, 0, sizeof(LVRelStats));
...@@ -307,12 +309,25 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, ...@@ -307,12 +309,25 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
tupgone = false; tupgone = false;
sv_infomask = tuple.t_data->t_infomask; sv_infomask = tuple.t_data->t_infomask;
switch (HeapTupleSatisfiesVacuum(tuple.t_data, XmaxRecent)) switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin))
{ {
case HEAPTUPLE_DEAD: case HEAPTUPLE_DEAD:
tupgone = true; /* we can delete the tuple */ tupgone = true; /* we can delete the tuple */
break; break;
case HEAPTUPLE_LIVE: 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; break;
case HEAPTUPLE_RECENTLY_DEAD: case HEAPTUPLE_RECENTLY_DEAD:
/* /*
...@@ -783,12 +798,13 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) ...@@ -783,12 +798,13 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
tupgone = false; tupgone = false;
sv_infomask = tuple.t_data->t_infomask; sv_infomask = tuple.t_data->t_infomask;
switch (HeapTupleSatisfiesVacuum(tuple.t_data, XmaxRecent)) switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin))
{ {
case HEAPTUPLE_DEAD: case HEAPTUPLE_DEAD:
tupgone = true; /* we can delete the tuple */ tupgone = true; /* we can delete the tuple */
break; break;
case HEAPTUPLE_LIVE: case HEAPTUPLE_LIVE:
/* Shouldn't be necessary to re-freeze anything */
break; break;
case HEAPTUPLE_RECENTLY_DEAD: case HEAPTUPLE_RECENTLY_DEAD:
/* /*
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -2246,6 +2246,7 @@ _copyVacuumStmt(VacuumStmt *from)
newnode->vacuum = from->vacuum; newnode->vacuum = from->vacuum;
newnode->full = from->full; newnode->full = from->full;
newnode->analyze = from->analyze; newnode->analyze = from->analyze;
newnode->freeze = from->freeze;
newnode->verbose = from->verbose; newnode->verbose = from->verbose;
if (from->vacrel) if (from->vacrel)
newnode->vacrel = pstrdup(from->vacrel); newnode->vacrel = pstrdup(from->vacrel);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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) ...@@ -1116,6 +1116,8 @@ _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
return false; return false;
if (a->analyze != b->analyze) if (a->analyze != b->analyze)
return false; return false;
if (a->freeze != b->freeze)
return false;
if (a->verbose != b->verbose) if (a->verbose != b->verbose)
return false; return false;
if (!equalstr(a->vacrel, b->vacrel)) if (!equalstr(a->vacrel, b->vacrel))
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -215,7 +215,7 @@ static void doNegateFloat(Value *v); ...@@ -215,7 +215,7 @@ static void doNegateFloat(Value *v);
%type <boolean> opt_binary, opt_using, opt_instead, opt_cursor %type <boolean> opt_binary, opt_using, opt_instead, opt_cursor
%type <boolean> opt_with_copy, index_opt_unique, opt_verbose, opt_full %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, %type <ival> copy_dirn, direction, reindex_type, drop_type,
opt_column, event, comment_type, comment_cl, opt_column, event, comment_type, comment_cl,
...@@ -346,7 +346,7 @@ static void doNegateFloat(Value *v); ...@@ -346,7 +346,7 @@ static void doNegateFloat(Value *v);
CACHE, CHECKPOINT, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, CACHE, CHECKPOINT, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
DATABASE, DELIMITERS, DO, DATABASE, DELIMITERS, DO,
EACH, ENCODING, EXCLUSIVE, EXPLAIN, EACH, ENCODING, EXCLUSIVE, EXPLAIN,
FORCE, FORWARD, FUNCTION, HANDLER, FORCE, FORWARD, FREEZE, FUNCTION, HANDLER,
ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL, ILIKE, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P, LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
MAXVALUE, MINVALUE, MODE, MOVE, MAXVALUE, MINVALUE, MODE, MOVE,
...@@ -3082,34 +3082,37 @@ ClusterStmt: CLUSTER index_name ON relation_name ...@@ -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); VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = true; n->vacuum = true;
n->analyze = false; n->analyze = false;
n->full = $2; n->full = $2;
n->verbose = $3; n->freeze = $3;
n->verbose = $4;
n->vacrel = NULL; n->vacrel = NULL;
n->va_cols = NIL; n->va_cols = NIL;
$$ = (Node *)n; $$ = (Node *)n;
} }
| VACUUM opt_full opt_verbose relation_name | VACUUM opt_full opt_freeze opt_verbose relation_name
{ {
VacuumStmt *n = makeNode(VacuumStmt); VacuumStmt *n = makeNode(VacuumStmt);
n->vacuum = true; n->vacuum = true;
n->analyze = false; n->analyze = false;
n->full = $2; n->full = $2;
n->verbose = $3; n->freeze = $3;
n->vacrel = $4; n->verbose = $4;
n->vacrel = $5;
n->va_cols = NIL; n->va_cols = NIL;
$$ = (Node *)n; $$ = (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->vacuum = true;
n->full = $2; n->full = $2;
n->verbose |= $3; n->freeze = $3;
n->verbose |= $4;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
...@@ -3120,6 +3123,7 @@ AnalyzeStmt: analyze_keyword opt_verbose ...@@ -3120,6 +3123,7 @@ AnalyzeStmt: analyze_keyword opt_verbose
n->vacuum = false; n->vacuum = false;
n->analyze = true; n->analyze = true;
n->full = false; n->full = false;
n->freeze = false;
n->verbose = $2; n->verbose = $2;
n->vacrel = NULL; n->vacrel = NULL;
n->va_cols = NIL; n->va_cols = NIL;
...@@ -3131,6 +3135,7 @@ AnalyzeStmt: analyze_keyword opt_verbose ...@@ -3131,6 +3135,7 @@ AnalyzeStmt: analyze_keyword opt_verbose
n->vacuum = false; n->vacuum = false;
n->analyze = true; n->analyze = true;
n->full = false; n->full = false;
n->freeze = false;
n->verbose = $2; n->verbose = $2;
n->vacrel = $3; n->vacrel = $3;
n->va_cols = $4; n->va_cols = $4;
...@@ -3150,6 +3155,10 @@ opt_full: FULL { $$ = TRUE; } ...@@ -3150,6 +3155,10 @@ opt_full: FULL { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; }
; ;
opt_freeze: FREEZE { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
opt_name_list: '(' name_list ')' { $$ = $2; } opt_name_list: '(' name_list ')' { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; }
; ;
...@@ -5615,6 +5624,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; } ...@@ -5615,6 +5624,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; }
| DROP { $$ = "drop"; } | DROP { $$ = "drop"; }
| EACH { $$ = "each"; } | EACH { $$ = "each"; }
| ENCODING { $$ = "encoding"; } | ENCODING { $$ = "encoding"; }
| ENCRYPTED { $$ = "encrypted"; }
| ESCAPE { $$ = "escape"; } | ESCAPE { $$ = "escape"; }
| EXCLUSIVE { $$ = "exclusive"; } | EXCLUSIVE { $$ = "exclusive"; }
| EXECUTE { $$ = "execute"; } | EXECUTE { $$ = "execute"; }
...@@ -5693,6 +5703,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; } ...@@ -5693,6 +5703,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; }
| TRUNCATE { $$ = "truncate"; } | TRUNCATE { $$ = "truncate"; }
| TRUSTED { $$ = "trusted"; } | TRUSTED { $$ = "trusted"; }
| TYPE_P { $$ = "type"; } | TYPE_P { $$ = "type"; }
| UNENCRYPTED { $$ = "unencrypted"; }
| UNLISTEN { $$ = "unlisten"; } | UNLISTEN { $$ = "unlisten"; }
| UNTIL { $$ = "until"; } | UNTIL { $$ = "until"; }
| UPDATE { $$ = "update"; } | UPDATE { $$ = "update"; }
...@@ -5753,7 +5764,6 @@ ColLabel: ColId { $$ = $1; } ...@@ -5753,7 +5764,6 @@ ColLabel: ColId { $$ = $1; }
| DISTINCT { $$ = "distinct"; } | DISTINCT { $$ = "distinct"; }
| DO { $$ = "do"; } | DO { $$ = "do"; }
| ELSE { $$ = "else"; } | ELSE { $$ = "else"; }
| ENCRYPTED { $$ = "encrypted"; }
| END_TRANS { $$ = "end"; } | END_TRANS { $$ = "end"; }
| EXCEPT { $$ = "except"; } | EXCEPT { $$ = "except"; }
| EXISTS { $$ = "exists"; } | EXISTS { $$ = "exists"; }
...@@ -5763,6 +5773,7 @@ ColLabel: ColId { $$ = $1; } ...@@ -5763,6 +5773,7 @@ ColLabel: ColId { $$ = $1; }
| FLOAT { $$ = "float"; } | FLOAT { $$ = "float"; }
| FOR { $$ = "for"; } | FOR { $$ = "for"; }
| FOREIGN { $$ = "foreign"; } | FOREIGN { $$ = "foreign"; }
| FREEZE { $$ = "freeze"; }
| FROM { $$ = "from"; } | FROM { $$ = "from"; }
| FULL { $$ = "full"; } | FULL { $$ = "full"; }
| GLOBAL { $$ = "global"; } | GLOBAL { $$ = "global"; }
...@@ -5825,7 +5836,6 @@ ColLabel: ColId { $$ = $1; } ...@@ -5825,7 +5836,6 @@ ColLabel: ColId { $$ = $1; }
| TRANSACTION { $$ = "transaction"; } | TRANSACTION { $$ = "transaction"; }
| TRIM { $$ = "trim"; } | TRIM { $$ = "trim"; }
| TRUE_P { $$ = "true"; } | TRUE_P { $$ = "true"; }
| UNENCRYPTED { $$ = "unencrypted"; }
| UNION { $$ = "union"; } | UNION { $$ = "union"; }
| UNIQUE { $$ = "unique"; } | UNIQUE { $$ = "unique"; }
| UNKNOWN { $$ = "unknown"; } | UNKNOWN { $$ = "unknown"; }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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[] = { ...@@ -118,6 +118,7 @@ static ScanKeyword ScanKeywords[] = {
{"force", FORCE}, {"force", FORCE},
{"foreign", FOREIGN}, {"foreign", FOREIGN},
{"forward", FORWARD}, {"forward", FORWARD},
{"freeze", FREEZE},
{"from", FROM}, {"from", FROM},
{"full", FULL}, {"full", FULL},
{"function", FUNCTION}, {"function", FUNCTION},
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -20,6 +20,8 @@
#include "storage/sinval.h" #include "storage/sinval.h"
#include "storage/sinvaladt.h" #include "storage/sinvaladt.h"
#include "utils/tqual.h" #include "utils/tqual.h"
#include "miscadmin.h"
SPINLOCK SInvalLock = (SPINLOCK) NULL; SPINLOCK SInvalLock = (SPINLOCK) NULL;
...@@ -210,17 +212,23 @@ TransactionIdIsInProgress(TransactionId xid) ...@@ -210,17 +212,23 @@ TransactionIdIsInProgress(TransactionId xid)
} }
/* /*
* GetXmaxRecent -- returns oldest transaction that was running * GetOldestXmin -- returns oldest transaction that was running
* when all current transaction were started. * when any current transaction was started.
* It's used by vacuum to decide what deleted *
* tuples must be preserved in a table. * 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, * 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. * when it does set the snapshot it cannot set xmin less than what we compute.
*/ */
void TransactionId
GetXmaxRecent(TransactionId *XmaxRecent) GetOldestXmin(bool allDbs)
{ {
SISeg *segP = shmInvalBuffer; SISeg *segP = shmInvalBuffer;
ProcState *stateP = segP->procState; ProcState *stateP = segP->procState;
...@@ -238,24 +246,28 @@ GetXmaxRecent(TransactionId *XmaxRecent) ...@@ -238,24 +246,28 @@ GetXmaxRecent(TransactionId *XmaxRecent)
if (pOffset != INVALID_OFFSET) if (pOffset != INVALID_OFFSET)
{ {
PROC *proc = (PROC *) MAKE_PTR(pOffset); 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)) /* Fetch xid just once - see GetNewTransactionId */
result = xid; TransactionId xid = proc->xid;
xid = proc->xmin;
if (TransactionIdIsNormal(xid)) if (TransactionIdIsNormal(xid))
{
if (TransactionIdPrecedes(xid, result)) if (TransactionIdPrecedes(xid, result))
result = xid; result = xid;
xid = proc->xmin;
if (TransactionIdIsNormal(xid))
if (TransactionIdPrecedes(xid, result))
result = xid;
}
} }
} }
} }
SpinRelease(SInvalLock); SpinRelease(SInvalLock);
*XmaxRecent = result; return result;
} }
/*---------- /*----------
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -592,8 +592,8 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
* HeapTupleSatisfiesVacuum - determine tuple status for VACUUM and related * HeapTupleSatisfiesVacuum - determine tuple status for VACUUM and related
* operations * operations
* *
* XmaxRecent is a cutoff XID (obtained from GetXmaxRecent()). Tuples * OldestXmin is a cutoff XID (obtained from GetOldestXmin()). Tuples
* deleted by XIDs >= XmaxRecent are deemed "recently dead"; they might * deleted by XIDs >= OldestXmin are deemed "recently dead"; they might
* still be visible to some open transaction, so we can't remove them, * still be visible to some open transaction, so we can't remove them,
* even if we see that the deleting transaction has committed. * even if we see that the deleting transaction has committed.
* *
...@@ -603,7 +603,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot) ...@@ -603,7 +603,7 @@ HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, Snapshot snapshot)
* change in t_infomask and scheduling a disk write if so. * change in t_infomask and scheduling a disk write if so.
*/ */
HTSV_Result HTSV_Result
HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent) HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
{ {
/* /*
* Has inserting transaction committed? * Has inserting transaction committed?
...@@ -712,7 +712,7 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent) ...@@ -712,7 +712,7 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId XmaxRecent)
return HEAPTUPLE_DEAD; 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 */ /* deleting xact is too recent, tuple could still be visible */
return HEAPTUPLE_RECENTLY_DEAD; return HEAPTUPLE_RECENTLY_DEAD;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # 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" ...@@ -841,7 +841,7 @@ echo "ok"
$ECHO_N "vacuuming database template1... "$ECHO_C $ECHO_N "vacuuming database template1... "$ECHO_C
"$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF "$PGPATH"/postgres $PGSQL_OPT template1 >/dev/null <<EOF
VACUUM FULL ANALYZE; VACUUM FULL FREEZE;
EOF EOF
if [ "$?" -ne 0 ]; then if [ "$?" -ne 0 ]; then
exit_nicely exit_nicely
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -31,6 +31,7 @@
#define BootstrapTransactionId ((TransactionId) 1) #define BootstrapTransactionId ((TransactionId) 1)
#define FrozenTransactionId ((TransactionId) 2) #define FrozenTransactionId ((TransactionId) 2)
#define FirstNormalTransactionId ((TransactionId) 3) #define FirstNormalTransactionId ((TransactionId) 3)
#define MaxTransactionId ((TransactionId) 0xFFFFFFFF)
/* ---------------- /* ----------------
* transaction ID manipulation macros * transaction ID manipulation macros
...@@ -38,11 +39,7 @@ ...@@ -38,11 +39,7 @@
*/ */
#define TransactionIdIsValid(xid) ((xid) != InvalidTransactionId) #define TransactionIdIsValid(xid) ((xid) != InvalidTransactionId)
#define TransactionIdIsNormal(xid) ((xid) >= FirstNormalTransactionId) #define TransactionIdIsNormal(xid) ((xid) >= FirstNormalTransactionId)
#define TransactionIdEquals(id1, id2) ((id1) == (id2)) #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 TransactionIdStore(xid, dest) (*(dest) = (xid)) #define TransactionIdStore(xid, dest) (*(dest) = (xid))
#define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId) #define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId)
/* advance a transaction ID variable, handling wraparound correctly */ /* advance a transaction ID variable, handling wraparound correctly */
...@@ -105,6 +102,10 @@ extern bool TransactionIdDidCommit(TransactionId transactionId); ...@@ -105,6 +102,10 @@ extern bool TransactionIdDidCommit(TransactionId transactionId);
extern bool TransactionIdDidAbort(TransactionId transactionId); extern bool TransactionIdDidAbort(TransactionId transactionId);
extern void TransactionIdCommit(TransactionId transactionId); extern void TransactionIdCommit(TransactionId transactionId);
extern void TransactionIdAbort(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 */ /* in transam/varsup.c */
extern TransactionId GetNewTransactionId(void); extern TransactionId GetNewTransactionId(void);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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); ...@@ -130,5 +130,6 @@ extern void xact_desc(char *buf, uint8 xl_info, char *rec);
extern Datum xidin(PG_FUNCTION_ARGS); extern Datum xidin(PG_FUNCTION_ARGS);
extern Datum xidout(PG_FUNCTION_ARGS); extern Datum xidout(PG_FUNCTION_ARGS);
extern Datum xideq(PG_FUNCTION_ARGS); extern Datum xideq(PG_FUNCTION_ARGS);
extern Datum xid_age(PG_FUNCTION_ARGS);
#endif /* XACT_H */ #endif /* XACT_H */
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200108241 #define CATALOG_VERSION_NO 200108251
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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)); ...@@ -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 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 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 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 */ /* 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 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 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)); DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 ...@@ -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(""); 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_ )); 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(""); 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(""); 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_ )); 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(""); DESCR("");
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -33,13 +33,14 @@ ...@@ -33,13 +33,14 @@
*/ */
CATALOG(pg_database) BOOTSTRAP CATALOG(pg_database) BOOTSTRAP
{ {
NameData datname; NameData datname; /* database name */
int4 datdba; int4 datdba; /* sysid of owner */
int4 encoding; int4 encoding; /* multibyte encoding, if any */
bool datistemplate; /* allowed as template for CREATE bool datistemplate; /* allowed as CREATE DATABASE template? */
* DATABASE? */
bool datallowconn; /* new connections allowed? */ 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 */ text datpath; /* VARIABLE LENGTH FIELD */
} FormData_pg_database; } FormData_pg_database;
...@@ -54,16 +55,18 @@ typedef FormData_pg_database *Form_pg_database; ...@@ -54,16 +55,18 @@ typedef FormData_pg_database *Form_pg_database;
* compiler constants for 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_datname 1
#define Anum_pg_database_datdba 2 #define Anum_pg_database_datdba 2
#define Anum_pg_database_encoding 3 #define Anum_pg_database_encoding 3
#define Anum_pg_database_datistemplate 4 #define Anum_pg_database_datistemplate 4
#define Anum_pg_database_datallowconn 5 #define Anum_pg_database_datallowconn 5
#define Anum_pg_database_datlastsysoid 6 #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"); DESCR("Default template database");
#define TemplateDbOid 1 #define TemplateDbOid 1
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * 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 ...@@ -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"); 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 - )); 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"); 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 - )); 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"); DESCR("subtract");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -44,6 +44,9 @@ extern void vac_update_relstats(Oid relid,
BlockNumber num_pages, BlockNumber num_pages,
double num_tuples, double num_tuples,
bool hasindex); 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 bool vac_is_partial_index(Relation indrel);
extern void vac_init_rusage(VacRUsage *ru0); extern void vac_init_rusage(VacRUsage *ru0);
extern const char *vac_show_rusage(VacRUsage *ru0); extern const char *vac_show_rusage(VacRUsage *ru0);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -694,6 +694,7 @@ typedef struct VacuumStmt
bool vacuum; /* do VACUUM step */ bool vacuum; /* do VACUUM step */
bool full; /* do FULL (non-concurrent) vacuum */ bool full; /* do FULL (non-concurrent) vacuum */
bool analyze; /* do ANALYZE step */ bool analyze; /* do ANALYZE step */
bool freeze; /* early-freeze option */
bool verbose; /* print progress info */ bool verbose; /* print progress info */
char *vacrel; /* name of single table to process, or NULL */ char *vacrel; /* name of single table to process, or NULL */
List *va_cols; /* list of column names, or NIL for all */ List *va_cols; /* list of column names, or NIL for all */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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( ...@@ -76,7 +76,7 @@ extern void ReceiveSharedInvalidMessages(
extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself); extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
extern bool TransactionIdIsInProgress(TransactionId xid); extern bool TransactionIdIsInProgress(TransactionId xid);
extern void GetXmaxRecent(TransactionId *XmaxRecent); extern TransactionId GetOldestXmin(bool allDbs);
extern int CountActiveBackends(void); extern int CountActiveBackends(void);
/* Use "struct proc", not PROC, to avoid including proc.h here */ /* Use "struct proc", not PROC, to avoid including proc.h here */
extern struct proc *BackendIdGetProc(BackendId procId); extern struct proc *BackendIdGetProc(BackendId procId);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -104,7 +104,7 @@ extern bool HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple,
Snapshot snapshot); Snapshot snapshot);
extern int HeapTupleSatisfiesUpdate(HeapTuple tuple); extern int HeapTupleSatisfiesUpdate(HeapTuple tuple);
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
TransactionId XmaxRecent); TransactionId OldestXmin);
extern Snapshot GetSnapshotData(bool serializable); extern Snapshot GetSnapshotData(bool serializable);
extern void SetQuerySnapshot(void); 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