mirror of https://github.com/postgres/postgres
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:
parent
37d937ea2c
commit
f009c316ba
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.68 2004/08/15 17:03:36 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.69 2004/08/22 02:41:57 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -526,7 +526,7 @@ TransactionIdIsInProgress(TransactionId xid)
|
|||
/*
|
||||
* Don't bother checking a very old transaction.
|
||||
*/
|
||||
if (TransactionIdPrecedes(xid, RecentGlobalXmin))
|
||||
if (TransactionIdPrecedes(xid, RecentXmin))
|
||||
{
|
||||
xc_by_recent_xmin_inc();
|
||||
return false;
|
||||
|
@ -912,6 +912,7 @@ CountActiveBackends(void)
|
|||
return count;
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
/*
|
||||
* GetUndoRecPtr -- returns oldest PGPROC->logRec.
|
||||
*/
|
||||
|
@ -947,6 +948,7 @@ GetUndoRecPtr(void)
|
|||
|
||||
return (urec);
|
||||
}
|
||||
#endif /* NOT_USED */
|
||||
|
||||
/*
|
||||
* BackendIdGetProc - given a BackendId, find its PGPROC structure
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.66 2004/07/28 14:23:29 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.67 2004/08/22 02:41:57 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -345,7 +345,7 @@ XactLockTableWait(TransactionId xid)
|
|||
LOCKTAG tag;
|
||||
TransactionId myxid = GetTopTransactionId();
|
||||
|
||||
Assert(!SubTransXidsHaveCommonAncestor(xid, myxid));
|
||||
Assert(!TransactionIdEquals(xid, myxid));
|
||||
|
||||
MemSet(&tag, 0, sizeof(tag));
|
||||
tag.relId = XactLockTableId;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.74 2004/07/28 14:23:30 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.75 2004/08/22 02:41:57 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -933,8 +933,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
|
|||
{
|
||||
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
|
||||
return HEAPTUPLE_INSERT_IN_PROGRESS;
|
||||
Assert(SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmin(tuple),
|
||||
HeapTupleHeaderGetXmax(tuple)));
|
||||
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
|
||||
return HEAPTUPLE_INSERT_IN_PROGRESS;
|
||||
/* inserted and then deleted by same xact */
|
||||
|
@ -1008,7 +1006,7 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
|
|||
* Deleter committed, but check special cases.
|
||||
*/
|
||||
|
||||
if (SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmin(tuple),
|
||||
if (TransactionIdEquals(HeapTupleHeaderGetXmin(tuple),
|
||||
HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.1 2004/07/01 00:51:38 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.2 2004/08/22 02:41:58 tgl Exp $
|
||||
*/
|
||||
#ifndef SUBTRANS_H
|
||||
#define SUBTRANS_H
|
||||
|
@ -20,7 +20,6 @@
|
|||
extern void SubTransSetParent(TransactionId xid, TransactionId parent);
|
||||
extern TransactionId SubTransGetParent(TransactionId xid);
|
||||
extern TransactionId SubTransGetTopmostTransaction(TransactionId xid);
|
||||
extern bool SubTransXidsHaveCommonAncestor(TransactionId xid1, TransactionId xid2);
|
||||
|
||||
extern int SUBTRANSShmemSize(void);
|
||||
extern void SUBTRANSShmemInit(void);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.54 2004/07/21 22:31:25 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.55 2004/08/22 02:41:58 tgl Exp $
|
||||
*/
|
||||
#ifndef XLOG_H
|
||||
#define XLOG_H
|
||||
|
@ -135,9 +135,4 @@ extern void CreateCheckPoint(bool shutdown, bool force);
|
|||
extern void XLogPutNextOid(Oid nextOid);
|
||||
extern XLogRecPtr GetRedoRecPtr(void);
|
||||
|
||||
/* in storage/ipc/sinval.c, but don't want to declare in sinval.h because
|
||||
* we'd have to include xlog.h into that ...
|
||||
*/
|
||||
extern XLogRecPtr GetUndoRecPtr(void);
|
||||
|
||||
#endif /* XLOG_H */
|
||||
|
|
Loading…
Reference in New Issue