transam.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*-------------------------------------------------------------------------
  2. *
  3. * transam.h
  4. * postgres transaction access method support code
  5. *
  6. *
  7. * Portions Copyright (c) 1996-2022, 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. #include "access/xlogdefs.h"
  17. /* ----------------
  18. * Special transaction ID values
  19. *
  20. * BootstrapTransactionId is the XID for "bootstrap" operations, and
  21. * FrozenTransactionId is used for very old tuples. Both should
  22. * always be considered valid.
  23. *
  24. * FirstNormalTransactionId is the first "normal" transaction id.
  25. * Note: if you need to change it, you must change pg_class.h as well.
  26. * ----------------
  27. */
  28. #define InvalidTransactionId ((TransactionId) 0)
  29. #define BootstrapTransactionId ((TransactionId) 1)
  30. #define FrozenTransactionId ((TransactionId) 2)
  31. #define FirstNormalTransactionId ((TransactionId) 3)
  32. #define MaxTransactionId ((TransactionId) 0xFFFFFFFF)
  33. /* ----------------
  34. * transaction ID manipulation macros
  35. * ----------------
  36. */
  37. #define TransactionIdIsValid(xid) ((xid) != InvalidTransactionId)
  38. #define TransactionIdIsNormal(xid) ((xid) >= FirstNormalTransactionId)
  39. #define TransactionIdEquals(id1, id2) ((id1) == (id2))
  40. #define TransactionIdStore(xid, dest) (*(dest) = (xid))
  41. #define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId)
  42. #define EpochFromFullTransactionId(x) ((uint32) ((x).value >> 32))
  43. #define XidFromFullTransactionId(x) ((uint32) (x).value)
  44. #define U64FromFullTransactionId(x) ((x).value)
  45. #define FullTransactionIdEquals(a, b) ((a).value == (b).value)
  46. #define FullTransactionIdPrecedes(a, b) ((a).value < (b).value)
  47. #define FullTransactionIdPrecedesOrEquals(a, b) ((a).value <= (b).value)
  48. #define FullTransactionIdFollows(a, b) ((a).value > (b).value)
  49. #define FullTransactionIdFollowsOrEquals(a, b) ((a).value >= (b).value)
  50. #define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x))
  51. #define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId)
  52. #define FirstNormalFullTransactionId FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId)
  53. #define FullTransactionIdIsNormal(x) FullTransactionIdFollowsOrEquals(x, FirstNormalFullTransactionId)
  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. static inline FullTransactionId
  64. FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
  65. {
  66. FullTransactionId result;
  67. result.value = ((uint64) epoch) << 32 | xid;
  68. return result;
  69. }
  70. static inline FullTransactionId
  71. FullTransactionIdFromU64(uint64 value)
  72. {
  73. FullTransactionId result;
  74. result.value = value;
  75. return result;
  76. }
  77. /* advance a transaction ID variable, handling wraparound correctly */
  78. #define TransactionIdAdvance(dest) \
  79. do { \
  80. (dest)++; \
  81. if ((dest) < FirstNormalTransactionId) \
  82. (dest) = FirstNormalTransactionId; \
  83. } while(0)
  84. /*
  85. * Retreat a FullTransactionId variable, stepping over xids that would appear
  86. * to be special only when viewed as 32bit XIDs.
  87. */
  88. static inline void
  89. FullTransactionIdRetreat(FullTransactionId *dest)
  90. {
  91. dest->value--;
  92. /*
  93. * In contrast to 32bit XIDs don't step over the "actual" special xids.
  94. * For 64bit xids these can't be reached as part of a wraparound as they
  95. * can in the 32bit case.
  96. */
  97. if (FullTransactionIdPrecedes(*dest, FirstNormalFullTransactionId))
  98. return;
  99. /*
  100. * But we do need to step over XIDs that'd appear special only for 32bit
  101. * XIDs.
  102. */
  103. while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId)
  104. dest->value--;
  105. }
  106. /*
  107. * Advance a FullTransactionId variable, stepping over xids that would appear
  108. * to be special only when viewed as 32bit XIDs.
  109. */
  110. static inline void
  111. FullTransactionIdAdvance(FullTransactionId *dest)
  112. {
  113. dest->value++;
  114. /* see FullTransactionIdAdvance() */
  115. if (FullTransactionIdPrecedes(*dest, FirstNormalFullTransactionId))
  116. return;
  117. while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId)
  118. dest->value++;
  119. }
  120. /* back up a transaction ID variable, handling wraparound correctly */
  121. #define TransactionIdRetreat(dest) \
  122. do { \
  123. (dest)--; \
  124. } while ((dest) < FirstNormalTransactionId)
  125. /* compare two XIDs already known to be normal; this is a macro for speed */
  126. #define NormalTransactionIdPrecedes(id1, id2) \
  127. (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \
  128. (int32) ((id1) - (id2)) < 0)
  129. /* compare two XIDs already known to be normal; this is a macro for speed */
  130. #define NormalTransactionIdFollows(id1, id2) \
  131. (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \
  132. (int32) ((id1) - (id2)) > 0)
  133. /* ----------
  134. * Object ID (OID) zero is InvalidOid.
  135. *
  136. * OIDs 1-9999 are reserved for manual assignment (see .dat files in
  137. * src/include/catalog/). Of these, 8000-9999 are reserved for
  138. * development purposes (such as in-progress patches and forks);
  139. * they should not appear in released versions.
  140. *
  141. * OIDs 10000-11999 are reserved for assignment by genbki.pl, for use
  142. * when the .dat files in src/include/catalog/ do not specify an OID
  143. * for a catalog entry that requires one. Note that genbki.pl assigns
  144. * these OIDs independently in each catalog, so they're not guaranteed
  145. * to be globally unique. Furthermore, the bootstrap backend and
  146. * initdb's post-bootstrap processing can also assign OIDs in this range.
  147. * The normal OID-generation logic takes care of any OID conflicts that
  148. * might arise from that.
  149. *
  150. * OIDs 12000-16383 are reserved for unpinned objects created by initdb's
  151. * post-bootstrap processing. initdb forces the OID generator up to
  152. * 12000 as soon as it's made the pinned objects it's responsible for.
  153. *
  154. * OIDs beginning at 16384 are assigned from the OID generator
  155. * during normal multiuser operation. (We force the generator up to
  156. * 16384 as soon as we are in normal operation.)
  157. *
  158. * The choices of 8000, 10000 and 12000 are completely arbitrary, and can be
  159. * moved if we run low on OIDs in any category. Changing the macros below,
  160. * and updating relevant documentation (see bki.sgml and RELEASE_CHANGES),
  161. * should be sufficient to do this. Moving the 16384 boundary between
  162. * initdb-assigned OIDs and user-defined objects would be substantially
  163. * more painful, however, since some user-defined OIDs will appear in
  164. * on-disk data; such a change would probably break pg_upgrade.
  165. *
  166. * NOTE: if the OID generator wraps around, we skip over OIDs 0-16383
  167. * and resume with 16384. This minimizes the odds of OID conflict, by not
  168. * reassigning OIDs that might have been assigned during initdb. Critically,
  169. * it also ensures that no user-created object will be considered pinned.
  170. * ----------
  171. */
  172. #define FirstGenbkiObjectId 10000
  173. #define FirstUnpinnedObjectId 12000
  174. #define FirstNormalObjectId 16384
  175. /*
  176. * VariableCache is a data structure in shared memory that is used to track
  177. * OID and XID assignment state. For largely historical reasons, there is
  178. * just one struct with different fields that are protected by different
  179. * LWLocks.
  180. *
  181. * Note: xidWrapLimit and oldestXidDB are not "active" values, but are
  182. * used just to generate useful messages when xidWarnLimit or xidStopLimit
  183. * are exceeded.
  184. */
  185. typedef struct VariableCacheData
  186. {
  187. /*
  188. * These fields are protected by OidGenLock.
  189. */
  190. Oid nextOid; /* next OID to assign */
  191. uint32 oidCount; /* OIDs available before must do XLOG work */
  192. /*
  193. * These fields are protected by XidGenLock.
  194. */
  195. FullTransactionId nextXid; /* next XID to assign */
  196. TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */
  197. TransactionId xidVacLimit; /* start forcing autovacuums here */
  198. TransactionId xidWarnLimit; /* start complaining here */
  199. TransactionId xidStopLimit; /* refuse to advance nextXid beyond here */
  200. TransactionId xidWrapLimit; /* where the world ends */
  201. Oid oldestXidDB; /* database with minimum datfrozenxid */
  202. /*
  203. * These fields are protected by CommitTsLock
  204. */
  205. TransactionId oldestCommitTsXid;
  206. TransactionId newestCommitTsXid;
  207. /*
  208. * These fields are protected by ProcArrayLock.
  209. */
  210. FullTransactionId latestCompletedXid; /* newest full XID that has
  211. * committed or aborted */
  212. /*
  213. * Number of top-level transactions with xids (i.e. which may have
  214. * modified the database) that completed in some form since the start of
  215. * the server. This currently is solely used to check whether
  216. * GetSnapshotData() needs to recompute the contents of the snapshot, or
  217. * not. There are likely other users of this. Always above 1.
  218. */
  219. uint64 xactCompletionCount;
  220. /*
  221. * These fields are protected by XactTruncationLock
  222. */
  223. TransactionId oldestClogXid; /* oldest it's safe to look up in clog */
  224. } VariableCacheData;
  225. typedef VariableCacheData *VariableCache;
  226. /* ----------------
  227. * extern declarations
  228. * ----------------
  229. */
  230. /* in transam/xact.c */
  231. extern bool TransactionStartedDuringRecovery(void);
  232. /* in transam/varsup.c */
  233. extern PGDLLIMPORT VariableCache ShmemVariableCache;
  234. /*
  235. * prototypes for functions in transam/transam.c
  236. */
  237. extern bool TransactionIdDidCommit(TransactionId transactionId);
  238. extern bool TransactionIdDidAbort(TransactionId transactionId);
  239. extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids);
  240. extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn);
  241. extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids);
  242. extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2);
  243. extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2);
  244. extern bool TransactionIdFollows(TransactionId id1, TransactionId id2);
  245. extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2);
  246. extern TransactionId TransactionIdLatest(TransactionId mainxid,
  247. int nxids, const TransactionId *xids);
  248. extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
  249. /* in transam/varsup.c */
  250. extern FullTransactionId GetNewTransactionId(bool isSubXact);
  251. extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid);
  252. extern FullTransactionId ReadNextFullTransactionId(void);
  253. extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
  254. Oid oldest_datoid);
  255. extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid);
  256. extern bool ForceTransactionIdLimitUpdate(void);
  257. extern Oid GetNewObjectId(void);
  258. extern void StopGeneratingPinnedObjectIds(void);
  259. #ifdef USE_ASSERT_CHECKING
  260. extern void AssertTransactionIdInAllowableRange(TransactionId xid);
  261. #else
  262. #define AssertTransactionIdInAllowableRange(xid) ((void)true)
  263. #endif
  264. /*
  265. * Some frontend programs include this header. For compilers that emit static
  266. * inline functions even when they're unused, that leads to unsatisfied
  267. * external references; hence hide them with #ifndef FRONTEND.
  268. */
  269. #ifndef FRONTEND
  270. /*
  271. * For callers that just need the XID part of the next transaction ID.
  272. */
  273. static inline TransactionId
  274. ReadNextTransactionId(void)
  275. {
  276. return XidFromFullTransactionId(ReadNextFullTransactionId());
  277. }
  278. /* return transaction ID backed up by amount, handling wraparound correctly */
  279. static inline TransactionId
  280. TransactionIdRetreatedBy(TransactionId xid, uint32 amount)
  281. {
  282. xid -= amount;
  283. while (xid < FirstNormalTransactionId)
  284. xid--;
  285. return xid;
  286. }
  287. /* return the older of the two IDs */
  288. static inline TransactionId
  289. TransactionIdOlder(TransactionId a, TransactionId b)
  290. {
  291. if (!TransactionIdIsValid(a))
  292. return b;
  293. if (!TransactionIdIsValid(b))
  294. return a;
  295. if (TransactionIdPrecedes(a, b))
  296. return a;
  297. return b;
  298. }
  299. /* return the older of the two IDs, assuming they're both normal */
  300. static inline TransactionId
  301. NormalTransactionIdOlder(TransactionId a, TransactionId b)
  302. {
  303. Assert(TransactionIdIsNormal(a));
  304. Assert(TransactionIdIsNormal(b));
  305. if (NormalTransactionIdPrecedes(a, b))
  306. return a;
  307. return b;
  308. }
  309. /* return the newer of the two IDs */
  310. static inline FullTransactionId
  311. FullTransactionIdNewer(FullTransactionId a, FullTransactionId b)
  312. {
  313. if (!FullTransactionIdIsValid(a))
  314. return b;
  315. if (!FullTransactionIdIsValid(b))
  316. return a;
  317. if (FullTransactionIdFollows(a, b))
  318. return a;
  319. return b;
  320. }
  321. #endif /* FRONTEND */
  322. #endif /* TRANSAM_H */