mirror of
https://github.com/postgres/postgres.git
synced 2025-06-06 00:02:36 -04:00
RecentXmin is too recent to use as the cutoff point for accessing
pg_subtrans --- what we need is the oldest xmin of any snapshot in use in the current top transaction. Introduce a new variable TransactionXmin to play this role. Fixes intermittent regression failure reported by Neil Conway.
This commit is contained in:
parent
8f9f198603
commit
86fff990b2
@ -22,7 +22,7 @@
|
|||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.5 2004/08/29 05:06:40 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.6 2004/09/16 18:35:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -105,7 +105,7 @@ SubTransGetParent(TransactionId xid)
|
|||||||
TransactionId parent;
|
TransactionId parent;
|
||||||
|
|
||||||
/* Can't ask about stuff that might not be around anymore */
|
/* Can't ask about stuff that might not be around anymore */
|
||||||
Assert(TransactionIdFollowsOrEquals(xid, RecentXmin));
|
Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
|
||||||
|
|
||||||
/* Bootstrap and frozen XIDs have no parent */
|
/* Bootstrap and frozen XIDs have no parent */
|
||||||
if (!TransactionIdIsNormal(xid))
|
if (!TransactionIdIsNormal(xid))
|
||||||
@ -129,12 +129,12 @@ SubTransGetParent(TransactionId xid)
|
|||||||
*
|
*
|
||||||
* Returns the topmost transaction of the given transaction id.
|
* Returns the topmost transaction of the given transaction id.
|
||||||
*
|
*
|
||||||
* Because we cannot look back further than RecentXmin, it is possible
|
* Because we cannot look back further than TransactionXmin, it is possible
|
||||||
* that this function will lie and return an intermediate subtransaction ID
|
* that this function will lie and return an intermediate subtransaction ID
|
||||||
* instead of the true topmost parent ID. This is OK, because in practice
|
* instead of the true topmost parent ID. This is OK, because in practice
|
||||||
* we only care about detecting whether the topmost parent is still running
|
* we only care about detecting whether the topmost parent is still running
|
||||||
* or is part of a current snapshot's list of still-running transactions.
|
* or is part of a current snapshot's list of still-running transactions.
|
||||||
* Therefore, any XID before RecentXmin is as good as any other.
|
* Therefore, any XID before TransactionXmin is as good as any other.
|
||||||
*/
|
*/
|
||||||
TransactionId
|
TransactionId
|
||||||
SubTransGetTopmostTransaction(TransactionId xid)
|
SubTransGetTopmostTransaction(TransactionId xid)
|
||||||
@ -143,12 +143,12 @@ SubTransGetTopmostTransaction(TransactionId xid)
|
|||||||
previousXid = xid;
|
previousXid = xid;
|
||||||
|
|
||||||
/* Can't ask about stuff that might not be around anymore */
|
/* Can't ask about stuff that might not be around anymore */
|
||||||
Assert(TransactionIdFollowsOrEquals(xid, RecentXmin));
|
Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
|
||||||
|
|
||||||
while (TransactionIdIsValid(parentXid))
|
while (TransactionIdIsValid(parentXid))
|
||||||
{
|
{
|
||||||
previousXid = parentXid;
|
previousXid = parentXid;
|
||||||
if (TransactionIdPrecedes(parentXid, RecentXmin))
|
if (TransactionIdPrecedes(parentXid, TransactionXmin))
|
||||||
break;
|
break;
|
||||||
parentXid = SubTransGetParent(parentXid);
|
parentXid = SubTransGetParent(parentXid);
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ ExtendSUBTRANS(TransactionId newestXact)
|
|||||||
* Remove all SUBTRANS segments before the one holding the passed transaction ID
|
* Remove all SUBTRANS segments before the one holding the passed transaction ID
|
||||||
*
|
*
|
||||||
* This is normally called during checkpoint, with oldestXact being the
|
* This is normally called during checkpoint, with oldestXact being the
|
||||||
* oldest XMIN of any running transaction.
|
* oldest TransactionXmin of any running transaction.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TruncateSUBTRANS(TransactionId oldestXact)
|
TruncateSUBTRANS(TransactionId oldestXact)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.61 2004/08/29 05:06:40 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.62 2004/09/16 18:35:20 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
|
||||||
@ -200,15 +200,15 @@ TransactionIdDidCommit(TransactionId transactionId)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's marked subcommitted, we have to check the parent
|
* If it's marked subcommitted, we have to check the parent
|
||||||
* recursively. However, if it's older than RecentXmin, we can't look
|
* recursively. However, if it's older than TransactionXmin, we can't
|
||||||
* at pg_subtrans; instead assume that the parent crashed without
|
* look at pg_subtrans; instead assume that the parent crashed without
|
||||||
* cleaning up its children.
|
* cleaning up its children.
|
||||||
*/
|
*/
|
||||||
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
|
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
|
||||||
{
|
{
|
||||||
TransactionId parentXid;
|
TransactionId parentXid;
|
||||||
|
|
||||||
if (TransactionIdPrecedes(transactionId, RecentXmin))
|
if (TransactionIdPrecedes(transactionId, TransactionXmin))
|
||||||
return false;
|
return false;
|
||||||
parentXid = SubTransGetParent(transactionId);
|
parentXid = SubTransGetParent(transactionId);
|
||||||
Assert(TransactionIdIsValid(parentXid));
|
Assert(TransactionIdIsValid(parentXid));
|
||||||
@ -249,15 +249,15 @@ TransactionIdDidAbort(TransactionId transactionId)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's marked subcommitted, we have to check the parent
|
* If it's marked subcommitted, we have to check the parent
|
||||||
* recursively. However, if it's older than RecentXmin, we can't look
|
* recursively. However, if it's older than TransactionXmin, we can't
|
||||||
* at pg_subtrans; instead assume that the parent crashed without
|
* look at pg_subtrans; instead assume that the parent crashed without
|
||||||
* cleaning up its children.
|
* cleaning up its children.
|
||||||
*/
|
*/
|
||||||
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
|
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
|
||||||
{
|
{
|
||||||
TransactionId parentXid;
|
TransactionId parentXid;
|
||||||
|
|
||||||
if (TransactionIdPrecedes(transactionId, RecentXmin))
|
if (TransactionIdPrecedes(transactionId, TransactionXmin))
|
||||||
return true;
|
return true;
|
||||||
parentXid = SubTransGetParent(transactionId);
|
parentXid = SubTransGetParent(transactionId);
|
||||||
Assert(TransactionIdIsValid(parentXid));
|
Assert(TransactionIdIsValid(parentXid));
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.73 2004/09/06 23:33:35 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.74 2004/09/16 18:35:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -521,7 +521,8 @@ TransactionIdIsInProgress(TransactionId xid)
|
|||||||
bool locked;
|
bool locked;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't bother checking a very old transaction.
|
* Don't bother checking a transaction older than RecentXmin; it
|
||||||
|
* could not possibly still be running.
|
||||||
*/
|
*/
|
||||||
if (TransactionIdPrecedes(xid, RecentXmin))
|
if (TransactionIdPrecedes(xid, RecentXmin))
|
||||||
{
|
{
|
||||||
@ -732,10 +733,19 @@ GetOldestXmin(bool allDbs)
|
|||||||
* This ensures that the set of transactions seen as "running" by the
|
* This ensures that the set of transactions seen as "running" by the
|
||||||
* current xact will not change after it takes the snapshot.
|
* current xact will not change after it takes the snapshot.
|
||||||
*
|
*
|
||||||
* We also compute the current global xmin (oldest xmin across all running
|
* Note that only top-level XIDs are included in the snapshot. We can
|
||||||
* transactions) and save it in RecentGlobalXmin. This is the same
|
* still apply the xmin and xmax limits to subtransaction XIDs, but we
|
||||||
* computation done by GetOldestXmin(TRUE). The xmin value is also stored
|
* need to work a bit harder to see if XIDs in [xmin..xmax) are running.
|
||||||
* into RecentXmin.
|
*
|
||||||
|
* We also update the following backend-global variables:
|
||||||
|
* TransactionXmin: the oldest xmin of any snapshot in use in the
|
||||||
|
* current transaction (this is the same as MyProc->xmin). This
|
||||||
|
* is just the xmin computed for the first, serializable snapshot.
|
||||||
|
* RecentXmin: the xmin computed for the most recent snapshot. XIDs
|
||||||
|
* older than this are known not running any more.
|
||||||
|
* RecentGlobalXmin: the global xmin (oldest TransactionXmin across all
|
||||||
|
* running transactions). This is the same computation done by
|
||||||
|
* GetOldestXmin(TRUE).
|
||||||
*----------
|
*----------
|
||||||
*/
|
*/
|
||||||
Snapshot
|
Snapshot
|
||||||
@ -751,6 +761,11 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
|
|||||||
|
|
||||||
Assert(snapshot != NULL);
|
Assert(snapshot != NULL);
|
||||||
|
|
||||||
|
/* Serializable snapshot must be computed before any other... */
|
||||||
|
Assert(serializable ?
|
||||||
|
!TransactionIdIsValid(MyProc->xmin) :
|
||||||
|
TransactionIdIsValid(MyProc->xmin));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocating space for MaxBackends xids is usually overkill;
|
* Allocating space for MaxBackends xids is usually overkill;
|
||||||
* lastBackend would be sufficient. But it seems better to do the
|
* lastBackend would be sufficient. But it seems better to do the
|
||||||
@ -850,13 +865,10 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serializable)
|
if (serializable)
|
||||||
MyProc->xmin = xmin;
|
MyProc->xmin = TransactionXmin = xmin;
|
||||||
|
|
||||||
LWLockRelease(SInvalLock);
|
LWLockRelease(SInvalLock);
|
||||||
|
|
||||||
/* Serializable snapshot must be computed before any other... */
|
|
||||||
Assert(TransactionIdIsValid(MyProc->xmin));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update globalxmin to include actual process xids. This is a
|
* Update globalxmin to include actual process xids. This is a
|
||||||
* slightly different way of computing it than GetOldestXmin uses, but
|
* slightly different way of computing it than GetOldestXmin uses, but
|
||||||
@ -865,7 +877,7 @@ GetSnapshotData(Snapshot snapshot, bool serializable)
|
|||||||
if (TransactionIdPrecedes(xmin, globalxmin))
|
if (TransactionIdPrecedes(xmin, globalxmin))
|
||||||
globalxmin = xmin;
|
globalxmin = xmin;
|
||||||
|
|
||||||
/* Update globals for use by VACUUM */
|
/* Update global variables too */
|
||||||
RecentGlobalXmin = globalxmin;
|
RecentGlobalXmin = globalxmin;
|
||||||
RecentXmin = xmin;
|
RecentXmin = xmin;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.78 2004/09/13 20:07:36 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.79 2004/09/16 18:35:22 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -48,6 +48,7 @@ Snapshot LatestSnapshot = NULL;
|
|||||||
Snapshot ActiveSnapshot = NULL;
|
Snapshot ActiveSnapshot = NULL;
|
||||||
|
|
||||||
/* These are updated by GetSnapshotData: */
|
/* These are updated by GetSnapshotData: */
|
||||||
|
TransactionId TransactionXmin = InvalidTransactionId;
|
||||||
TransactionId RecentXmin = InvalidTransactionId;
|
TransactionId RecentXmin = InvalidTransactionId;
|
||||||
TransactionId RecentGlobalXmin = InvalidTransactionId;
|
TransactionId RecentGlobalXmin = InvalidTransactionId;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.52 2004/09/13 20:08:35 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.53 2004/09/16 18:35:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -59,6 +59,7 @@ extern DLLIMPORT Snapshot SerializableSnapshot;
|
|||||||
extern DLLIMPORT Snapshot LatestSnapshot;
|
extern DLLIMPORT Snapshot LatestSnapshot;
|
||||||
extern DLLIMPORT Snapshot ActiveSnapshot;
|
extern DLLIMPORT Snapshot ActiveSnapshot;
|
||||||
|
|
||||||
|
extern TransactionId TransactionXmin;
|
||||||
extern TransactionId RecentXmin;
|
extern TransactionId RecentXmin;
|
||||||
extern TransactionId RecentGlobalXmin;
|
extern TransactionId RecentGlobalXmin;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user