1/*-------------------------------------------------------------------------
2 *
3 * transam.h
4 * postgres transaction access method support code
5 *
6 *
7 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 * src/include/access/transam.h
11 *
12 *-------------------------------------------------------------------------
13 */
14#ifndef TRANSAM_H
15#define TRANSAM_H
16
17#include "access/xlogdefs.h"
18
19
20/* ----------------
21 * Special transaction ID values
22 *
23 * BootstrapTransactionId is the XID for "bootstrap" operations, and
24 * FrozenTransactionId is used for very old tuples. Both should
25 * always be considered valid.
26 *
27 * FirstNormalTransactionId is the first "normal" transaction id.
28 * Note: if you need to change it, you must change pg_class.h as well.
29 * ----------------
30 */
31#define InvalidTransactionId ((TransactionId) 0)
32#define BootstrapTransactionId ((TransactionId) 1)
33#define FrozenTransactionId ((TransactionId) 2)
34#define FirstNormalTransactionId ((TransactionId) 3)
35#define MaxTransactionId ((TransactionId) 0xFFFFFFFF)
36
37/* ----------------
38 * transaction ID manipulation macros
39 * ----------------
40 */
41#define TransactionIdIsValid(xid) ((xid) != InvalidTransactionId)
42#define TransactionIdIsNormal(xid) ((xid) >= FirstNormalTransactionId)
43#define TransactionIdEquals(id1, id2) ((id1) == (id2))
44#define TransactionIdStore(xid, dest) (*(dest) = (xid))
45#define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId)
46
47#define EpochFromFullTransactionId(x) ((uint32) ((x).value >> 32))
48#define XidFromFullTransactionId(x) ((uint32) (x).value)
49#define U64FromFullTransactionId(x) ((x).value)
50#define FullTransactionIdPrecedes(a, b) ((a).value < (b).value)
51#define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x))
52#define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId)
53
54/*
55 * A 64 bit value that contains an epoch and a TransactionId. This is
56 * wrapped in a struct to prevent implicit conversion to/from TransactionId.
57 * Not all values represent valid normal XIDs.
58 */
59typedef struct FullTransactionId
60{
61 uint64 value;
62} FullTransactionId;
63
64static inline FullTransactionId
65FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
66{
67 FullTransactionId result;
68
69 result.value = ((uint64) epoch) << 32 | xid;
70
71 return result;
72}
73
74/* advance a transaction ID variable, handling wraparound correctly */
75#define TransactionIdAdvance(dest) \
76 do { \
77 (dest)++; \
78 if ((dest) < FirstNormalTransactionId) \
79 (dest) = FirstNormalTransactionId; \
80 } while(0)
81
82/* advance a FullTransactionId variable, stepping over special XIDs */
83static inline void
84FullTransactionIdAdvance(FullTransactionId *dest)
85{
86 dest->value++;
87 while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId)
88 dest->value++;
89}
90
91/* back up a transaction ID variable, handling wraparound correctly */
92#define TransactionIdRetreat(dest) \
93 do { \
94 (dest)--; \
95 } while ((dest) < FirstNormalTransactionId)
96
97/* compare two XIDs already known to be normal; this is a macro for speed */
98#define NormalTransactionIdPrecedes(id1, id2) \
99 (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \
100 (int32) ((id1) - (id2)) < 0)
101
102/* compare two XIDs already known to be normal; this is a macro for speed */
103#define NormalTransactionIdFollows(id1, id2) \
104 (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \
105 (int32) ((id1) - (id2)) > 0)
106
107/* ----------
108 * Object ID (OID) zero is InvalidOid.
109 *
110 * OIDs 1-9999 are reserved for manual assignment (see .dat files in
111 * src/include/catalog/). Of these, 8000-9999 are reserved for
112 * development purposes (such as in-progress patches and forks);
113 * they should not appear in released versions.
114 *
115 * OIDs 10000-11999 are reserved for assignment by genbki.pl, for use
116 * when the .dat files in src/include/catalog/ do not specify an OID
117 * for a catalog entry that requires one.
118 *
119 * OIDS 12000-16383 are reserved for assignment during initdb
120 * using the OID generator. (We start the generator at 12000.)
121 *
122 * OIDs beginning at 16384 are assigned from the OID generator
123 * during normal multiuser operation. (We force the generator up to
124 * 16384 as soon as we are in normal operation.)
125 *
126 * The choices of 8000, 10000 and 12000 are completely arbitrary, and can be
127 * moved if we run low on OIDs in any category. Changing the macros below,
128 * and updating relevant documentation (see bki.sgml and RELEASE_CHANGES),
129 * should be sufficient to do this. Moving the 16384 boundary between
130 * initdb-assigned OIDs and user-defined objects would be substantially
131 * more painful, however, since some user-defined OIDs will appear in
132 * on-disk data; such a change would probably break pg_upgrade.
133 *
134 * NOTE: if the OID generator wraps around, we skip over OIDs 0-16383
135 * and resume with 16384. This minimizes the odds of OID conflict, by not
136 * reassigning OIDs that might have been assigned during initdb.
137 * ----------
138 */
139#define FirstGenbkiObjectId 10000
140#define FirstBootstrapObjectId 12000
141#define FirstNormalObjectId 16384
142
143/*
144 * VariableCache is a data structure in shared memory that is used to track
145 * OID and XID assignment state. For largely historical reasons, there is
146 * just one struct with different fields that are protected by different
147 * LWLocks.
148 *
149 * Note: xidWrapLimit and oldestXidDB are not "active" values, but are
150 * used just to generate useful messages when xidWarnLimit or xidStopLimit
151 * are exceeded.
152 */
153typedef struct VariableCacheData
154{
155 /*
156 * These fields are protected by OidGenLock.
157 */
158 Oid nextOid; /* next OID to assign */
159 uint32 oidCount; /* OIDs available before must do XLOG work */
160
161 /*
162 * These fields are protected by XidGenLock.
163 */
164 FullTransactionId nextFullXid; /* next full XID to assign */
165
166 TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */
167 TransactionId xidVacLimit; /* start forcing autovacuums here */
168 TransactionId xidWarnLimit; /* start complaining here */
169 TransactionId xidStopLimit; /* refuse to advance nextFullXid beyond here */
170 TransactionId xidWrapLimit; /* where the world ends */
171 Oid oldestXidDB; /* database with minimum datfrozenxid */
172
173 /*
174 * These fields are protected by CommitTsLock
175 */
176 TransactionId oldestCommitTsXid;
177 TransactionId newestCommitTsXid;
178
179 /*
180 * These fields are protected by ProcArrayLock.
181 */
182 TransactionId latestCompletedXid; /* newest XID that has committed or
183 * aborted */
184
185 /*
186 * These fields are protected by CLogTruncationLock
187 */
188 TransactionId oldestClogXid; /* oldest it's safe to look up in clog */
189
190} VariableCacheData;
191
192typedef VariableCacheData *VariableCache;
193
194
195/* ----------------
196 * extern declarations
197 * ----------------
198 */
199
200/* in transam/xact.c */
201extern bool TransactionStartedDuringRecovery(void);
202
203/* in transam/varsup.c */
204extern PGDLLIMPORT VariableCache ShmemVariableCache;
205
206/*
207 * prototypes for functions in transam/transam.c
208 */
209extern bool TransactionIdDidCommit(TransactionId transactionId);
210extern bool TransactionIdDidAbort(TransactionId transactionId);
211extern bool TransactionIdIsKnownCompleted(TransactionId transactionId);
212extern void TransactionIdAbort(TransactionId transactionId);
213extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids);
214extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn);
215extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids);
216extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2);
217extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2);
218extern bool TransactionIdFollows(TransactionId id1, TransactionId id2);
219extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2);
220extern TransactionId TransactionIdLatest(TransactionId mainxid,
221 int nxids, const TransactionId *xids);
222extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
223
224/* in transam/varsup.c */
225extern FullTransactionId GetNewTransactionId(bool isSubXact);
226extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid);
227extern FullTransactionId ReadNextFullTransactionId(void);
228extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
229 Oid oldest_datoid);
230extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid);
231extern bool ForceTransactionIdLimitUpdate(void);
232extern Oid GetNewObjectId(void);
233
234/*
235 * Some frontend programs include this header. For compilers that emit static
236 * inline functions even when they're unused, that leads to unsatisfied
237 * external references; hence hide them with #ifndef FRONTEND.
238 */
239#ifndef FRONTEND
240
241/*
242 * For callers that just need the XID part of the next transaction ID.
243 */
244static inline TransactionId
245ReadNewTransactionId(void)
246{
247 return XidFromFullTransactionId(ReadNextFullTransactionId());
248}
249
250#endif /* FRONTEND */
251
252#endif /* TRANSAM_H */
253