Skip to content

Commit f009c31

Browse files
committed
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.
1 parent 37d937e commit f009c31

File tree

7 files changed

+40
-56
lines changed

7 files changed

+40
-56
lines changed

src/backend/access/transam/subtrans.c

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
1616
* Portions Copyright (c) 1994, Regents of the University of California
1717
*
18-
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.1 2004/07/01 00:49:42 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.2 2004/08/22 02:41:57 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -30,6 +30,7 @@
3030
#include "access/subtrans.h"
3131
#include "miscadmin.h"
3232
#include "storage/lwlock.h"
33+
#include "utils/tqual.h"
3334

3435

3536
/*
@@ -113,6 +114,9 @@ SubTransGetParent(TransactionId xid)
113114
TransactionId *ptr;
114115
TransactionId parent;
115116

117+
/* Can't ask about stuff that might not be around anymore */
118+
Assert(TransactionIdFollowsOrEquals(xid, RecentXmin));
119+
116120
/* Bootstrap and frozen XIDs have no parent */
117121
if (!TransactionIdIsNormal(xid))
118122
return InvalidTransactionId;
@@ -133,16 +137,28 @@ SubTransGetParent(TransactionId xid)
133137
* SubTransGetTopmostTransaction
134138
*
135139
* Returns the topmost transaction of the given transaction id.
140+
*
141+
* Because we cannot look back further than RecentXmin, it is possible
142+
* that this function will lie and return an intermediate subtransaction ID
143+
* instead of the true topmost parent ID. This is OK, because in practice
144+
* we only care about detecting whether the topmost parent is still running
145+
* or is part of a current snapshot's list of still-running transactions.
146+
* Therefore, any XID before RecentXmin is as good as any other.
136147
*/
137148
TransactionId
138149
SubTransGetTopmostTransaction(TransactionId xid)
139150
{
140151
TransactionId parentXid = xid,
141152
previousXid = xid;
142153

154+
/* Can't ask about stuff that might not be around anymore */
155+
Assert(TransactionIdFollowsOrEquals(xid, RecentXmin));
156+
143157
while (TransactionIdIsValid(parentXid))
144158
{
145159
previousXid = parentXid;
160+
if (TransactionIdPrecedes(parentXid, RecentXmin))
161+
break;
146162
parentXid = SubTransGetParent(parentXid);
147163
}
148164

@@ -151,30 +167,6 @@ SubTransGetTopmostTransaction(TransactionId xid)
151167
return previousXid;
152168
}
153169

154-
/*
155-
* SubTransXidsHaveCommonAncestor
156-
*
157-
* Returns true iff the Xids have a common ancestor
158-
*/
159-
bool
160-
SubTransXidsHaveCommonAncestor(TransactionId xid1, TransactionId xid2)
161-
{
162-
if (TransactionIdEquals(xid1, xid2))
163-
return true;
164-
165-
while (TransactionIdIsValid(xid1) && TransactionIdIsValid(xid2))
166-
{
167-
if (TransactionIdPrecedes(xid2, xid1))
168-
xid1 = SubTransGetParent(xid1);
169-
else
170-
xid2 = SubTransGetParent(xid2);
171-
172-
if (TransactionIdEquals(xid1, xid2))
173-
return true;
174-
}
175-
176-
return false;
177-
}
178170

179171
/*
180172
* Initialization of shared memory for Subtrans

src/backend/access/transam/transam.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.57 2004/07/01 00:49:42 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.58 2004/08/22 02:41:57 tgl Exp $
1212
*
1313
* NOTES
1414
* This file contains the high level access-method interface to the
@@ -22,6 +22,7 @@
2222
#include "access/clog.h"
2323
#include "access/subtrans.h"
2424
#include "access/transam.h"
25+
#include "utils/tqual.h"
2526

2627

2728
/* ----------------
@@ -199,11 +200,15 @@ TransactionIdDidCommit(TransactionId transactionId)
199200

200201
/*
201202
* If it's marked subcommitted, we have to check the parent recursively.
203+
* However, if it's older than RecentXmin, we can't look at pg_subtrans;
204+
* instead assume that the parent crashed without cleaning up its children.
202205
*/
203206
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
204207
{
205208
TransactionId parentXid;
206-
209+
210+
if (TransactionIdPrecedes(transactionId, RecentXmin))
211+
return false;
207212
parentXid = SubTransGetParent(transactionId);
208213
Assert(TransactionIdIsValid(parentXid));
209214
return TransactionIdDidCommit(parentXid);
@@ -243,24 +248,17 @@ TransactionIdDidAbort(TransactionId transactionId)
243248

244249
/*
245250
* If it's marked subcommitted, we have to check the parent recursively.
246-
*
247-
* If we detect that the parent has aborted, update pg_clog to show the
248-
* subtransaction as aborted. This is only needed when the parent
249-
* crashed before either committing or aborting. We want to clean up
250-
* pg_clog so future visitors don't need to make this check again.
251+
* However, if it's older than RecentXmin, we can't look at pg_subtrans;
252+
* instead assume that the parent crashed without cleaning up its children.
251253
*/
252254
if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
253255
{
254256
TransactionId parentXid;
255-
bool parentAborted;
256-
257-
parentXid = SubTransGetParent(transactionId);
258-
parentAborted = TransactionIdDidAbort(parentXid);
259257

260-
if (parentAborted)
261-
TransactionIdAbort(transactionId);
262-
263-
return parentAborted;
258+
if (TransactionIdPrecedes(transactionId, RecentXmin))
259+
return true;
260+
parentXid = SubTransGetParent(transactionId);
261+
return TransactionIdDidAbort(parentXid);
264262
}
265263

266264
/*

src/backend/storage/ipc/sinval.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.68 2004/08/15 17:03:36 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.69 2004/08/22 02:41:57 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -526,7 +526,7 @@ TransactionIdIsInProgress(TransactionId xid)
526526
/*
527527
* Don't bother checking a very old transaction.
528528
*/
529-
if (TransactionIdPrecedes(xid, RecentGlobalXmin))
529+
if (TransactionIdPrecedes(xid, RecentXmin))
530530
{
531531
xc_by_recent_xmin_inc();
532532
return false;
@@ -912,6 +912,7 @@ CountActiveBackends(void)
912912
return count;
913913
}
914914

915+
#ifdef NOT_USED
915916
/*
916917
* GetUndoRecPtr -- returns oldest PGPROC->logRec.
917918
*/
@@ -947,6 +948,7 @@ GetUndoRecPtr(void)
947948

948949
return (urec);
949950
}
951+
#endif /* NOT_USED */
950952

951953
/*
952954
* BackendIdGetProc - given a BackendId, find its PGPROC structure

src/backend/storage/lmgr/lmgr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.66 2004/07/28 14:23:29 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.67 2004/08/22 02:41:57 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -345,7 +345,7 @@ XactLockTableWait(TransactionId xid)
345345
LOCKTAG tag;
346346
TransactionId myxid = GetTopTransactionId();
347347

348-
Assert(!SubTransXidsHaveCommonAncestor(xid, myxid));
348+
Assert(!TransactionIdEquals(xid, myxid));
349349

350350
MemSet(&tag, 0, sizeof(tag));
351351
tag.relId = XactLockTableId;

src/backend/utils/time/tqual.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* Portions Copyright (c) 1994, Regents of the University of California
1717
*
1818
* IDENTIFICATION
19-
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.74 2004/07/28 14:23:30 tgl Exp $
19+
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.75 2004/08/22 02:41:57 tgl Exp $
2020
*
2121
*-------------------------------------------------------------------------
2222
*/
@@ -933,8 +933,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
933933
{
934934
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
935935
return HEAPTUPLE_INSERT_IN_PROGRESS;
936-
Assert(SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmin(tuple),
937-
HeapTupleHeaderGetXmax(tuple)));
938936
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
939937
return HEAPTUPLE_INSERT_IN_PROGRESS;
940938
/* inserted and then deleted by same xact */
@@ -1008,7 +1006,7 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
10081006
* Deleter committed, but check special cases.
10091007
*/
10101008

1011-
if (SubTransXidsHaveCommonAncestor(HeapTupleHeaderGetXmin(tuple),
1009+
if (TransactionIdEquals(HeapTupleHeaderGetXmin(tuple),
10121010
HeapTupleHeaderGetXmax(tuple)))
10131011
{
10141012
/*

src/include/access/subtrans.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.1 2004/07/01 00:51:38 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/access/subtrans.h,v 1.2 2004/08/22 02:41:58 tgl Exp $
1010
*/
1111
#ifndef SUBTRANS_H
1212
#define SUBTRANS_H
@@ -20,7 +20,6 @@
2020
extern void SubTransSetParent(TransactionId xid, TransactionId parent);
2121
extern TransactionId SubTransGetParent(TransactionId xid);
2222
extern TransactionId SubTransGetTopmostTransaction(TransactionId xid);
23-
extern bool SubTransXidsHaveCommonAncestor(TransactionId xid1, TransactionId xid2);
2423

2524
extern int SUBTRANSShmemSize(void);
2625
extern void SUBTRANSShmemInit(void);

src/include/access/xlog.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.54 2004/07/21 22:31:25 tgl Exp $
9+
* $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.55 2004/08/22 02:41:58 tgl Exp $
1010
*/
1111
#ifndef XLOG_H
1212
#define XLOG_H
@@ -135,9 +135,4 @@ extern void CreateCheckPoint(bool shutdown, bool force);
135135
extern void XLogPutNextOid(Oid nextOid);
136136
extern XLogRecPtr GetRedoRecPtr(void);
137137

138-
/* in storage/ipc/sinval.c, but don't want to declare in sinval.h because
139-
* we'd have to include xlog.h into that ...
140-
*/
141-
extern XLogRecPtr GetUndoRecPtr(void);
142-
143138
#endif /* XLOG_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy