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  */
59 typedef struct FullTransactionId
60 {
61 	uint64		value;
62 } FullTransactionId;
63 
64 static inline FullTransactionId
FullTransactionIdFromEpochAndXid(uint32 epoch,TransactionId xid)65 FullTransactionIdFromEpochAndXid(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 */
83 static inline void
FullTransactionIdAdvance(FullTransactionId * dest)84 FullTransactionIdAdvance(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  */
153 typedef 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 
192 typedef VariableCacheData *VariableCache;
193 
194 
195 /* ----------------
196  *		extern declarations
197  * ----------------
198  */
199 
200 /* in transam/xact.c */
201 extern bool TransactionStartedDuringRecovery(void);
202 
203 /* in transam/varsup.c */
204 extern PGDLLIMPORT VariableCache ShmemVariableCache;
205 
206 /*
207  * prototypes for functions in transam/transam.c
208  */
209 extern bool TransactionIdDidCommit(TransactionId transactionId);
210 extern bool TransactionIdDidAbort(TransactionId transactionId);
211 extern bool TransactionIdIsKnownCompleted(TransactionId transactionId);
212 extern void TransactionIdAbort(TransactionId transactionId);
213 extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids);
214 extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn);
215 extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids);
216 extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2);
217 extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2);
218 extern bool TransactionIdFollows(TransactionId id1, TransactionId id2);
219 extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2);
220 extern TransactionId TransactionIdLatest(TransactionId mainxid,
221 										 int nxids, const TransactionId *xids);
222 extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
223 
224 /* in transam/varsup.c */
225 extern FullTransactionId GetNewTransactionId(bool isSubXact);
226 extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid);
227 extern FullTransactionId ReadNextFullTransactionId(void);
228 extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
229 								  Oid oldest_datoid);
230 extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid);
231 extern bool ForceTransactionIdLimitUpdate(void);
232 extern 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  */
244 static inline TransactionId
ReadNewTransactionId(void)245 ReadNewTransactionId(void)
246 {
247 	return XidFromFullTransactionId(ReadNextFullTransactionId());
248 }
249 
250 #endif							/* FRONTEND */
251 
252 #endif							/* TRANSAM_H */
253