diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c index 1babedbe5900ba127ae2ad56be26d5f5497a5191..ace1bb1434a868cf7a2429d58589cee5f7a497bb 100644 --- a/src/backend/access/transam/subtrans.c +++ b/src/backend/access/transam/subtrans.c @@ -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 diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c index 34d281de58785684f6452370ab65432e803b10cf..2a32960f9e375d9210296c2fac29db09542f3123 100644 --- a/src/backend/access/transam/transam.c +++ b/src/backend/access/transam/transam.c @@ -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; - - parentXid = SubTransGetParent(transactionId); - parentAborted = TransactionIdDidAbort(parentXid); - if (parentAborted) - TransactionIdAbort(transactionId); - - return parentAborted; + if (TransactionIdPrecedes(transactionId, RecentXmin)) + return true; + parentXid = SubTransGetParent(transactionId); + return TransactionIdDidAbort(parentXid); } /* diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c index af046a3f1ec9a16260740defe2073e7dadd4aae9..f28a883572eadc1eb4c7f5e83321d69b55f009c0 100644 --- a/src/backend/storage/ipc/sinval.c +++ b/src/backend/storage/ipc/sinval.c @@ -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 diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c index 11d73c583001b68aaace31a2fdc806aceafa5c4a..b6119025716ed563fdb302519538c274c92bab43 100644 --- a/src/backend/storage/lmgr/lmgr.c +++ b/src/backend/storage/lmgr/lmgr.c @@ -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; diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index d1a7179484e3fd57f36d6acd60863e48f4ec29ce..99ad9e52dd0716f251e8db86a91f3d12d6f0b170 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -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))) { /* diff --git a/src/include/access/subtrans.h b/src/include/access/subtrans.h index 2c601752d123188f4af323478e6f6c1de94541f5..bf6cec64ec748126f415a74399d78eafa1cc6ce2 100644 --- a/src/include/access/subtrans.h +++ b/src/include/access/subtrans.h @@ -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); diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index f2542d6fc7143f59357716cec87a605f9fd0bc57..ef33ae72158b0dd0e3127b5e4ec3d56fbb17aa73 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -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 */