summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc/sinval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/ipc/sinval.c')
-rw-r--r--src/backend/storage/ipc/sinval.c43
1 files changed, 35 insertions, 8 deletions
diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index a32c8ae7035..6415271bea6 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.46 2002/05/21 22:05:55 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinval.c,v 1.47 2002/05/24 18:57:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -297,6 +297,10 @@ GetOldestXmin(bool allDbs)
* it is considered running or not.
* This ensures that the set of transactions seen as "running" by the
* current xact will not change after it takes the snapshot.
+ *
+ * Also, we compute the current global xmin (oldest xmin across all running
+ * transactions) and save it in RecentGlobalXmin. This is the same
+ * computation done by GetOldestXmin(TRUE).
*----------
*/
Snapshot
@@ -305,6 +309,9 @@ GetSnapshotData(bool serializable)
Snapshot snapshot = (Snapshot) malloc(sizeof(SnapshotData));
SISeg *segP = shmInvalBuffer;
ProcState *stateP = segP->procState;
+ TransactionId xmin;
+ TransactionId xmax;
+ TransactionId globalxmin;
int index;
int count = 0;
@@ -321,7 +328,7 @@ GetSnapshotData(bool serializable)
if (snapshot->xip == NULL)
elog(ERROR, "Memory exhausted in GetSnapshotData");
- snapshot->xmin = GetCurrentTransactionId();
+ globalxmin = xmin = GetCurrentTransactionId();
/*
* If we are going to set MyProc->xmin then we'd better get exclusive
@@ -356,7 +363,7 @@ GetSnapshotData(bool serializable)
*--------------------
*/
- snapshot->xmax = ReadNewTransactionId();
+ xmax = ReadNewTransactionId();
for (index = 0; index < segP->lastBackend; index++)
{
@@ -374,28 +381,48 @@ GetSnapshotData(bool serializable)
* running a transaction, and xacts started since we read the
* next transaction ID. There's no need to store XIDs above
* what we got from ReadNewTransactionId, since we'll treat
- * them as running anyway.
+ * them as running anyway. We also assume that such xacts can't
+ * compute an xmin older than ours, so they needn't be considered
+ * in computing globalxmin.
*/
if (proc == MyProc ||
!TransactionIdIsNormal(xid) ||
- TransactionIdFollowsOrEquals(xid, snapshot->xmax))
+ TransactionIdFollowsOrEquals(xid, xmax))
continue;
- if (TransactionIdPrecedes(xid, snapshot->xmin))
- snapshot->xmin = xid;
+ if (TransactionIdPrecedes(xid, xmin))
+ xmin = xid;
snapshot->xip[count] = xid;
count++;
+
+ /* Update globalxmin to be the smallest valid xmin */
+ xid = proc->xmin;
+ if (TransactionIdIsNormal(xid))
+ if (TransactionIdPrecedes(xid, globalxmin))
+ globalxmin = xid;
}
}
if (serializable)
- MyProc->xmin = snapshot->xmin;
+ MyProc->xmin = xmin;
LWLockRelease(SInvalLock);
/* Serializable snapshot must be computed before any other... */
Assert(TransactionIdIsValid(MyProc->xmin));
+ /*
+ * Update globalxmin to include actual process xids. This is a slightly
+ * different way of computing it than GetOldestXmin uses, but should give
+ * the same result.
+ */
+ if (TransactionIdPrecedes(xmin, globalxmin))
+ globalxmin = xmin;
+
+ RecentGlobalXmin = globalxmin;
+
+ snapshot->xmin = xmin;
+ snapshot->xmax = xmax;
snapshot->xcnt = count;
snapshot->curcid = GetCurrentCommandId();