1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Tweak code so that pg_subtrans is never consulted for XIDs older than

RecentXmin (== MyProc->xmin).  This ensures that it will be safe to
truncate pg_subtrans at RecentGlobalXmin, which should largely eliminate
any fear of bloat.  Along the way, eliminate SubTransXidsHaveCommonAncestor,
which isn't really needed and could not give a trustworthy result anyway
under the lookback restriction.
In an unrelated but nearby change, #ifdef out GetUndoRecPtr, which has
been dead code since 2001 and seems unlikely to ever be resurrected.
This commit is contained in:
Tom Lane
2004-08-22 02:41:58 +00:00
parent 37d937ea2c
commit f009c316ba
7 changed files with 40 additions and 56 deletions

View File

@@ -15,7 +15,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.1 2004/07/01 00:49:42 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.2 2004/08/22 02:41:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,6 +30,7 @@
#include "access/subtrans.h"
#include "miscadmin.h"
#include "storage/lwlock.h"
#include "utils/tqual.h"
/*
@@ -113,6 +114,9 @@ SubTransGetParent(TransactionId xid)
TransactionId *ptr;
TransactionId parent;
/* Can't ask about stuff that might not be around anymore */
Assert(TransactionIdFollowsOrEquals(xid, RecentXmin));
/* Bootstrap and frozen XIDs have no parent */
if (!TransactionIdIsNormal(xid))
return InvalidTransactionId;
@@ -133,6 +137,13 @@ SubTransGetParent(TransactionId xid)
* SubTransGetTopmostTransaction
*
* Returns the topmost transaction of the given transaction id.
*
* Because we cannot look back further than RecentXmin, it is possible
* that this function will lie and return an intermediate subtransaction ID
* 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
* or is part of a current snapshot's list of still-running transactions.
* Therefore, any XID before RecentXmin is as good as any other.
*/
TransactionId
SubTransGetTopmostTransaction(TransactionId xid)
@@ -140,9 +151,14 @@ SubTransGetTopmostTransaction(TransactionId xid)
TransactionId parentXid = xid,
previousXid = xid;
/* Can't ask about stuff that might not be around anymore */
Assert(TransactionIdFollowsOrEquals(xid, RecentXmin));
while (TransactionIdIsValid(parentXid))
{
previousXid = parentXid;
if (TransactionIdPrecedes(parentXid, RecentXmin))
break;
parentXid = SubTransGetParent(parentXid);
}
@@ -151,30 +167,6 @@ SubTransGetTopmostTransaction(TransactionId xid)
return previousXid;
}
/*
* SubTransXidsHaveCommonAncestor
*
* Returns true iff the Xids have a common ancestor
*/
bool
SubTransXidsHaveCommonAncestor(TransactionId xid1, TransactionId xid2)
{
if (TransactionIdEquals(xid1, xid2))
return true;
while (TransactionIdIsValid(xid1) && TransactionIdIsValid(xid2))
{
if (TransactionIdPrecedes(xid2, xid1))
xid1 = SubTransGetParent(xid1);
else
xid2 = SubTransGetParent(xid2);
if (TransactionIdEquals(xid1, xid2))
return true;
}
return false;
}
/*
* Initialization of shared memory for Subtrans

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.57 2004/07/01 00:49:42 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.58 2004/08/22 02:41:57 tgl Exp $
*
* NOTES
* This file contains the high level access-method interface to the
@@ -22,6 +22,7 @@
#include "access/clog.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "utils/tqual.h"
/* ----------------
@@ -199,11 +200,15 @@ TransactionIdDidCommit(TransactionId transactionId)
/*
* If it's marked subcommitted, we have to check the parent recursively.
* However, if it's older than RecentXmin, we can't look at pg_subtrans;
* instead assume that the parent crashed without cleaning up its children.
*/
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
{
TransactionId parentXid;
if (TransactionIdPrecedes(transactionId, RecentXmin))
return false;
parentXid = SubTransGetParent(transactionId);
Assert(TransactionIdIsValid(parentXid));
return TransactionIdDidCommit(parentXid);
@@ -243,24 +248,17 @@ TransactionIdDidAbort(TransactionId transactionId)
/*
* If it's marked subcommitted, we have to check the parent recursively.
*
* If we detect that the parent has aborted, update pg_clog to show the
* subtransaction as aborted. This is only needed when the parent
* crashed before either committing or aborting. We want to clean up
* pg_clog so future visitors don't need to make this check again.
* However, if it's older than RecentXmin, we can't look at pg_subtrans;
* instead assume that the parent crashed without cleaning up its children.
*/
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
{
TransactionId parentXid;
bool parentAborted;
if (TransactionIdPrecedes(transactionId, RecentXmin))
return true;
parentXid = SubTransGetParent(transactionId);
parentAborted = TransactionIdDidAbort(parentXid);
if (parentAborted)
TransactionIdAbort(transactionId);
return parentAborted;
return TransactionIdDidAbort(parentXid);
}
/*