aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/heap/heapam.c5
-rw-r--r--src/backend/access/index/indexam.c4
-rw-r--r--src/backend/commands/vacuum.c47
-rw-r--r--src/backend/executor/nodeBitmapHeapscan.c4
-rw-r--r--src/backend/utils/init/postinit.c10
-rw-r--r--src/backend/utils/time/snapmgr.c8
6 files changed, 43 insertions, 35 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 6d3528323bf..eb9f8701ae1 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.262 2008/08/11 11:05:10 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.263 2008/09/11 14:01:09 alvherre Exp $
*
*
* INTERFACE ROUTINES
@@ -219,6 +219,7 @@ heapgetpage(HeapScanDesc scan, BlockNumber page)
/*
* Prune and repair fragmentation for the whole page, if possible.
*/
+ Assert(TransactionIdIsValid(RecentGlobalXmin));
heap_page_prune_opt(scan->rs_rd, buffer, RecentGlobalXmin);
/*
@@ -1469,6 +1470,8 @@ heap_hot_search_buffer(ItemPointer tid, Buffer buffer, Snapshot snapshot,
if (all_dead)
*all_dead = true;
+ Assert(TransactionIdIsValid(RecentGlobalXmin));
+
Assert(ItemPointerGetBlockNumber(tid) == BufferGetBlockNumber(buffer));
offnum = ItemPointerGetOffsetNumber(tid);
at_chain_start = true;
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 7d6028804a5..0c132d5fc09 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.109 2008/06/19 00:46:03 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.110 2008/09/11 14:01:09 alvherre Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
@@ -419,6 +419,8 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
SCAN_CHECKS;
GET_SCAN_PROCEDURE(amgettuple);
+ Assert(TransactionIdIsValid(RecentGlobalXmin));
+
/*
* We always reset xs_hot_dead; if we are here then either we are just
* starting the scan, or we previously returned a visible tuple, and in
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 7eb5777d3ab..af7b6646d28 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.376 2008/08/13 00:07:50 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.377 2008/09/11 14:01:09 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -790,14 +790,12 @@ vac_update_datfrozenxid(void)
bool dirty = false;
/*
- * Initialize the "min" calculation with RecentGlobalXmin. Any
- * not-yet-committed pg_class entries for new tables must have
- * relfrozenxid at least this high, because any other open xact must have
- * RecentXmin >= its PGPROC.xmin >= our RecentGlobalXmin; see
- * AddNewRelationTuple(). So we cannot produce a wrong minimum by
- * starting with this.
+ * Initialize the "min" calculation with GetOldestXmin, which is a
+ * reasonable approximation to the minimum relfrozenxid for not-yet-
+ * committed pg_class entries for new tables; see AddNewRelationTuple().
+ * Se we cannot produce a wrong minimum by starting with this.
*/
- newFrozenXid = RecentGlobalXmin;
+ newFrozenXid = GetOldestXmin(true, true);
/*
* We must seqscan pg_class to find the minimum Xid, because there is no
@@ -990,18 +988,16 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
/* Begin a transaction for vacuuming this relation */
StartTransactionCommand();
- if (vacstmt->full)
- {
- /* functions in indexes may want a snapshot set */
- PushActiveSnapshot(GetTransactionSnapshot());
- }
- else
+ /*
+ * Functions in indexes may want a snapshot set. Also, setting
+ * a snapshot ensures that RecentGlobalXmin is kept truly recent.
+ */
+ PushActiveSnapshot(GetTransactionSnapshot());
+
+ if (!vacstmt->full)
{
/*
- * During a lazy VACUUM we do not run any user-supplied functions, and
- * so it should be safe to not create a transaction snapshot.
- *
- * We can furthermore set the PROC_IN_VACUUM flag, which lets other
+ * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets other
* concurrent VACUUMs know that they can ignore this one while
* determining their OldestXmin. (The reason we don't set it during a
* full VACUUM is exactly that we may have to run user- defined
@@ -1050,8 +1046,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
if (!onerel)
{
- if (vacstmt->full)
- PopActiveSnapshot();
+ PopActiveSnapshot();
CommitTransactionCommand();
return;
}
@@ -1082,8 +1077,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
(errmsg("skipping \"%s\" --- only table or database owner can vacuum it",
RelationGetRelationName(onerel))));
relation_close(onerel, lmode);
- if (vacstmt->full)
- PopActiveSnapshot();
+ PopActiveSnapshot();
CommitTransactionCommand();
return;
}
@@ -1099,8 +1093,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
(errmsg("skipping \"%s\" --- cannot vacuum indexes, views, or special system tables",
RelationGetRelationName(onerel))));
relation_close(onerel, lmode);
- if (vacstmt->full)
- PopActiveSnapshot();
+ PopActiveSnapshot();
CommitTransactionCommand();
return;
}
@@ -1115,8 +1108,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
if (isOtherTempNamespace(RelationGetNamespace(onerel)))
{
relation_close(onerel, lmode);
- if (vacstmt->full)
- PopActiveSnapshot();
+ PopActiveSnapshot();
CommitTransactionCommand();
return;
}
@@ -1168,8 +1160,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
/*
* Complete the transaction and free all temporary memory used.
*/
- if (vacstmt->full)
- PopActiveSnapshot();
+ PopActiveSnapshot();
CommitTransactionCommand();
/*
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index e09ece65375..41b9da62eab 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -21,7 +21,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.29 2008/06/19 00:46:04 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.30 2008/09/11 14:01:09 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -37,6 +37,7 @@
#include "access/heapam.h"
#include "access/relscan.h"
+#include "access/transam.h"
#include "executor/execdebug.h"
#include "executor/nodeBitmapHeapscan.h"
#include "pgstat.h"
@@ -262,6 +263,7 @@ bitgetpage(HeapScanDesc scan, TBMIterateResult *tbmres)
/*
* Prune and repair fragmentation for the whole page, if possible.
*/
+ Assert(TransactionIdIsValid(RecentGlobalXmin));
heap_page_prune_opt(scan->rs_rd, buffer, RecentGlobalXmin);
/*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index e0dbbf93111..6b66b2e3926 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.184 2008/05/12 00:00:52 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.185 2008/09/11 14:01:09 alvherre Exp $
*
*
*-------------------------------------------------------------------------
@@ -47,6 +47,7 @@
#include "utils/plancache.h"
#include "utils/portal.h"
#include "utils/relcache.h"
+#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
@@ -461,10 +462,15 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
on_shmem_exit(ShutdownPostgres, 0);
/*
- * Start a new transaction here before first access to db
+ * Start a new transaction here before first access to db, and get a
+ * snapshot. We don't have a use for the snapshot itself, but we're
+ * interested in the secondary effect that it sets RecentGlobalXmin.
*/
if (!bootstrap)
+ {
StartTransactionCommand();
+ (void) GetTransactionSnapshot();
+ }
/*
* Now that we have a transaction, we can take locks. Take a writer's
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 841a92567d1..0add5f489c4 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -22,7 +22,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.4 2008/07/11 02:10:14 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/time/snapmgr.c,v 1.5 2008/09/11 14:01:10 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -59,10 +59,14 @@ static Snapshot SecondarySnapshot = NULL;
* These are updated by GetSnapshotData. We initialize them this way
* for the convenience of TransactionIdIsInProgress: even in bootstrap
* mode, we don't want it to say that BootstrapTransactionId is in progress.
+ *
+ * RecentGlobalXmin is initialized to InvalidTransactionId, to ensure that no
+ * one tries to use a stale value. Readers should ensure that it has been set
+ * to something else before using it.
*/
TransactionId TransactionXmin = FirstNormalTransactionId;
TransactionId RecentXmin = FirstNormalTransactionId;
-TransactionId RecentGlobalXmin = FirstNormalTransactionId;
+TransactionId RecentGlobalXmin = InvalidTransactionId;
/*
* Elements of the list of registered snapshots.