1 /*-------------------------------------------------------------------------
2  *
3  * transam.h
4  *	  postgres transaction access method support code
5  *
6  *
7  * Portions Copyright (c) 1996-2017, 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 /* advance a transaction ID variable, handling wraparound correctly */
48 #define TransactionIdAdvance(dest)	\
49 	do { \
50 		(dest)++; \
51 		if ((dest) < FirstNormalTransactionId) \
52 			(dest) = FirstNormalTransactionId; \
53 	} while(0)
54 
55 /* back up a transaction ID variable, handling wraparound correctly */
56 #define TransactionIdRetreat(dest)	\
57 	do { \
58 		(dest)--; \
59 	} while ((dest) < FirstNormalTransactionId)
60 
61 /* compare two XIDs already known to be normal; this is a macro for speed */
62 #define NormalTransactionIdPrecedes(id1, id2) \
63 	(AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \
64 	(int32) ((id1) - (id2)) < 0)
65 
66 /* compare two XIDs already known to be normal; this is a macro for speed */
67 #define NormalTransactionIdFollows(id1, id2) \
68 	(AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \
69 	(int32) ((id1) - (id2)) > 0)
70 
71 /* ----------
72  *		Object ID (OID) zero is InvalidOid.
73  *
74  *		OIDs 1-9999 are reserved for manual assignment (see the files
75  *		in src/include/catalog/).
76  *
77  *		OIDS 10000-16383 are reserved for assignment during initdb
78  *		using the OID generator.  (We start the generator at 10000.)
79  *
80  *		OIDs beginning at 16384 are assigned from the OID generator
81  *		during normal multiuser operation.  (We force the generator up to
82  *		16384 as soon as we are in normal operation.)
83  *
84  * The choices of 10000 and 16384 are completely arbitrary, and can be moved
85  * if we run low on OIDs in either category.  Changing the macros below
86  * should be sufficient to do this.
87  *
88  * NOTE: if the OID generator wraps around, we skip over OIDs 0-16383
89  * and resume with 16384.  This minimizes the odds of OID conflict, by not
90  * reassigning OIDs that might have been assigned during initdb.
91  * ----------
92  */
93 #define FirstBootstrapObjectId	10000
94 #define FirstNormalObjectId		16384
95 
96 /*
97  * VariableCache is a data structure in shared memory that is used to track
98  * OID and XID assignment state.  For largely historical reasons, there is
99  * just one struct with different fields that are protected by different
100  * LWLocks.
101  *
102  * Note: xidWrapLimit and oldestXidDB are not "active" values, but are
103  * used just to generate useful messages when xidWarnLimit or xidStopLimit
104  * are exceeded.
105  */
106 typedef struct VariableCacheData
107 {
108 	/*
109 	 * These fields are protected by OidGenLock.
110 	 */
111 	Oid			nextOid;		/* next OID to assign */
112 	uint32		oidCount;		/* OIDs available before must do XLOG work */
113 
114 	/*
115 	 * These fields are protected by XidGenLock.
116 	 */
117 	TransactionId nextXid;		/* next XID to assign */
118 
119 	TransactionId oldestXid;	/* cluster-wide minimum datfrozenxid */
120 	TransactionId xidVacLimit;	/* start forcing autovacuums here */
121 	TransactionId xidWarnLimit; /* start complaining here */
122 	TransactionId xidStopLimit; /* refuse to advance nextXid beyond here */
123 	TransactionId xidWrapLimit; /* where the world ends */
124 	Oid			oldestXidDB;	/* database with minimum datfrozenxid */
125 
126 	/*
127 	 * These fields are protected by CommitTsLock
128 	 */
129 	TransactionId oldestCommitTsXid;
130 	TransactionId newestCommitTsXid;
131 
132 	/*
133 	 * These fields are protected by ProcArrayLock.
134 	 */
135 	TransactionId latestCompletedXid;	/* newest XID that has committed or
136 										 * aborted */
137 
138 	/*
139 	 * These fields are protected by CLogTruncationLock
140 	 */
141 	TransactionId oldestClogXid;	/* oldest it's safe to look up in clog */
142 
143 } VariableCacheData;
144 
145 typedef VariableCacheData *VariableCache;
146 
147 
148 /* ----------------
149  *		extern declarations
150  * ----------------
151  */
152 
153 /* in transam/xact.c */
154 extern bool TransactionStartedDuringRecovery(void);
155 
156 /* in transam/varsup.c */
157 extern PGDLLIMPORT VariableCache ShmemVariableCache;
158 
159 /*
160  * prototypes for functions in transam/transam.c
161  */
162 extern bool TransactionIdDidCommit(TransactionId transactionId);
163 extern bool TransactionIdDidAbort(TransactionId transactionId);
164 extern bool TransactionIdIsKnownCompleted(TransactionId transactionId);
165 extern void TransactionIdAbort(TransactionId transactionId);
166 extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids);
167 extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn);
168 extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids);
169 extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2);
170 extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2);
171 extern bool TransactionIdFollows(TransactionId id1, TransactionId id2);
172 extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2);
173 extern TransactionId TransactionIdLatest(TransactionId mainxid,
174 					int nxids, const TransactionId *xids);
175 extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
176 
177 /* in transam/varsup.c */
178 extern TransactionId GetNewTransactionId(bool isSubXact);
179 extern TransactionId ReadNewTransactionId(void);
180 extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
181 					  Oid oldest_datoid);
182 extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid);
183 extern bool ForceTransactionIdLimitUpdate(void);
184 extern Oid	GetNewObjectId(void);
185 
186 #endif							/* TRAMSAM_H */
187