heapam_xlog.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. /*-------------------------------------------------------------------------
  2. *
  3. * heapam_xlog.h
  4. * POSTGRES heap access XLOG definitions.
  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/heapam_xlog.h
  11. *
  12. *-------------------------------------------------------------------------
  13. */
  14. #ifndef HEAPAM_XLOG_H
  15. #define HEAPAM_XLOG_H
  16. #include "access/htup.h"
  17. #include "access/xlogreader.h"
  18. #include "lib/stringinfo.h"
  19. #include "storage/buf.h"
  20. #include "storage/bufpage.h"
  21. #include "storage/relfilenode.h"
  22. #include "utils/relcache.h"
  23. /*
  24. * WAL record definitions for heapam.c's WAL operations
  25. *
  26. * XLOG allows to store some information in high 4 bits of log
  27. * record xl_info field. We use 3 for opcode and one for init bit.
  28. */
  29. #define XLOG_HEAP_INSERT 0x00
  30. #define XLOG_HEAP_DELETE 0x10
  31. #define XLOG_HEAP_UPDATE 0x20
  32. #define XLOG_HEAP_TRUNCATE 0x30
  33. #define XLOG_HEAP_HOT_UPDATE 0x40
  34. #define XLOG_HEAP_CONFIRM 0x50
  35. #define XLOG_HEAP_LOCK 0x60
  36. #define XLOG_HEAP_INPLACE 0x70
  37. #define XLOG_HEAP_OPMASK 0x70
  38. /*
  39. * When we insert 1st item on new page in INSERT, UPDATE, HOT_UPDATE,
  40. * or MULTI_INSERT, we can (and we do) restore entire page in redo
  41. */
  42. #define XLOG_HEAP_INIT_PAGE 0x80
  43. /*
  44. * We ran out of opcodes, so heapam.c now has a second RmgrId. These opcodes
  45. * are associated with RM_HEAP2_ID, but are not logically different from
  46. * the ones above associated with RM_HEAP_ID. XLOG_HEAP_OPMASK applies to
  47. * these, too.
  48. */
  49. #define XLOG_HEAP2_REWRITE 0x00
  50. #define XLOG_HEAP2_PRUNE 0x10
  51. #define XLOG_HEAP2_VACUUM 0x20
  52. #define XLOG_HEAP2_FREEZE_PAGE 0x30
  53. #define XLOG_HEAP2_VISIBLE 0x40
  54. #define XLOG_HEAP2_MULTI_INSERT 0x50
  55. #define XLOG_HEAP2_LOCK_UPDATED 0x60
  56. #define XLOG_HEAP2_NEW_CID 0x70
  57. /*
  58. * xl_heap_insert/xl_heap_multi_insert flag values, 8 bits are available.
  59. */
  60. /* PD_ALL_VISIBLE was cleared */
  61. #define XLH_INSERT_ALL_VISIBLE_CLEARED (1<<0)
  62. #define XLH_INSERT_LAST_IN_MULTI (1<<1)
  63. #define XLH_INSERT_IS_SPECULATIVE (1<<2)
  64. #define XLH_INSERT_CONTAINS_NEW_TUPLE (1<<3)
  65. #define XLH_INSERT_ON_TOAST_RELATION (1<<4)
  66. /* all_frozen_set always implies all_visible_set */
  67. #define XLH_INSERT_ALL_FROZEN_SET (1<<5)
  68. /*
  69. * xl_heap_update flag values, 8 bits are available.
  70. */
  71. /* PD_ALL_VISIBLE was cleared */
  72. #define XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED (1<<0)
  73. /* PD_ALL_VISIBLE was cleared in the 2nd page */
  74. #define XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED (1<<1)
  75. #define XLH_UPDATE_CONTAINS_OLD_TUPLE (1<<2)
  76. #define XLH_UPDATE_CONTAINS_OLD_KEY (1<<3)
  77. #define XLH_UPDATE_CONTAINS_NEW_TUPLE (1<<4)
  78. #define XLH_UPDATE_PREFIX_FROM_OLD (1<<5)
  79. #define XLH_UPDATE_SUFFIX_FROM_OLD (1<<6)
  80. /* convenience macro for checking whether any form of old tuple was logged */
  81. #define XLH_UPDATE_CONTAINS_OLD \
  82. (XLH_UPDATE_CONTAINS_OLD_TUPLE | XLH_UPDATE_CONTAINS_OLD_KEY)
  83. /*
  84. * xl_heap_delete flag values, 8 bits are available.
  85. */
  86. /* PD_ALL_VISIBLE was cleared */
  87. #define XLH_DELETE_ALL_VISIBLE_CLEARED (1<<0)
  88. #define XLH_DELETE_CONTAINS_OLD_TUPLE (1<<1)
  89. #define XLH_DELETE_CONTAINS_OLD_KEY (1<<2)
  90. #define XLH_DELETE_IS_SUPER (1<<3)
  91. #define XLH_DELETE_IS_PARTITION_MOVE (1<<4)
  92. /* convenience macro for checking whether any form of old tuple was logged */
  93. #define XLH_DELETE_CONTAINS_OLD \
  94. (XLH_DELETE_CONTAINS_OLD_TUPLE | XLH_DELETE_CONTAINS_OLD_KEY)
  95. /* This is what we need to know about delete */
  96. typedef struct xl_heap_delete
  97. {
  98. TransactionId xmax; /* xmax of the deleted tuple */
  99. OffsetNumber offnum; /* deleted tuple's offset */
  100. uint8 infobits_set; /* infomask bits */
  101. uint8 flags;
  102. } xl_heap_delete;
  103. #define SizeOfHeapDelete (offsetof(xl_heap_delete, flags) + sizeof(uint8))
  104. /*
  105. * xl_heap_truncate flag values, 8 bits are available.
  106. */
  107. #define XLH_TRUNCATE_CASCADE (1<<0)
  108. #define XLH_TRUNCATE_RESTART_SEQS (1<<1)
  109. /*
  110. * For truncate we list all truncated relids in an array, followed by all
  111. * sequence relids that need to be restarted, if any.
  112. * All rels are always within the same database, so we just list dbid once.
  113. */
  114. typedef struct xl_heap_truncate
  115. {
  116. Oid dbId;
  117. uint32 nrelids;
  118. uint8 flags;
  119. Oid relids[FLEXIBLE_ARRAY_MEMBER];
  120. } xl_heap_truncate;
  121. #define SizeOfHeapTruncate (offsetof(xl_heap_truncate, relids))
  122. /*
  123. * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted
  124. * or updated tuple in WAL; we can save a few bytes by reconstructing the
  125. * fields that are available elsewhere in the WAL record, or perhaps just
  126. * plain needn't be reconstructed. These are the fields we must store.
  127. */
  128. typedef struct xl_heap_header
  129. {
  130. uint16 t_infomask2;
  131. uint16 t_infomask;
  132. uint8 t_hoff;
  133. } xl_heap_header;
  134. #define SizeOfHeapHeader (offsetof(xl_heap_header, t_hoff) + sizeof(uint8))
  135. /* This is what we need to know about insert */
  136. typedef struct xl_heap_insert
  137. {
  138. OffsetNumber offnum; /* inserted tuple's offset */
  139. uint8 flags;
  140. /* xl_heap_header & TUPLE DATA in backup block 0 */
  141. } xl_heap_insert;
  142. #define SizeOfHeapInsert (offsetof(xl_heap_insert, flags) + sizeof(uint8))
  143. /*
  144. * This is what we need to know about a multi-insert.
  145. *
  146. * The main data of the record consists of this xl_heap_multi_insert header.
  147. * 'offsets' array is omitted if the whole page is reinitialized
  148. * (XLOG_HEAP_INIT_PAGE).
  149. *
  150. * In block 0's data portion, there is an xl_multi_insert_tuple struct,
  151. * followed by the tuple data for each tuple. There is padding to align
  152. * each xl_multi_insert_tuple struct.
  153. */
  154. typedef struct xl_heap_multi_insert
  155. {
  156. uint8 flags;
  157. uint16 ntuples;
  158. OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
  159. } xl_heap_multi_insert;
  160. #define SizeOfHeapMultiInsert offsetof(xl_heap_multi_insert, offsets)
  161. typedef struct xl_multi_insert_tuple
  162. {
  163. uint16 datalen; /* size of tuple data that follows */
  164. uint16 t_infomask2;
  165. uint16 t_infomask;
  166. uint8 t_hoff;
  167. /* TUPLE DATA FOLLOWS AT END OF STRUCT */
  168. } xl_multi_insert_tuple;
  169. #define SizeOfMultiInsertTuple (offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8))
  170. /*
  171. * This is what we need to know about update|hot_update
  172. *
  173. * Backup blk 0: new page
  174. *
  175. * If XLH_UPDATE_PREFIX_FROM_OLD or XLH_UPDATE_SUFFIX_FROM_OLD flags are set,
  176. * the prefix and/or suffix come first, as one or two uint16s.
  177. *
  178. * After that, xl_heap_header and new tuple data follow. The new tuple
  179. * data doesn't include the prefix and suffix, which are copied from the
  180. * old tuple on replay.
  181. *
  182. * If XLH_UPDATE_CONTAINS_NEW_TUPLE flag is given, the tuple data is
  183. * included even if a full-page image was taken.
  184. *
  185. * Backup blk 1: old page, if different. (no data, just a reference to the blk)
  186. */
  187. typedef struct xl_heap_update
  188. {
  189. TransactionId old_xmax; /* xmax of the old tuple */
  190. OffsetNumber old_offnum; /* old tuple's offset */
  191. uint8 old_infobits_set; /* infomask bits to set on old tuple */
  192. uint8 flags;
  193. TransactionId new_xmax; /* xmax of the new tuple */
  194. OffsetNumber new_offnum; /* new tuple's offset */
  195. /*
  196. * If XLH_UPDATE_CONTAINS_OLD_TUPLE or XLH_UPDATE_CONTAINS_OLD_KEY flags
  197. * are set, xl_heap_header and tuple data for the old tuple follow.
  198. */
  199. } xl_heap_update;
  200. #define SizeOfHeapUpdate (offsetof(xl_heap_update, new_offnum) + sizeof(OffsetNumber))
  201. /*
  202. * This is what we need to know about page pruning (both during VACUUM and
  203. * during opportunistic pruning)
  204. *
  205. * The array of OffsetNumbers following the fixed part of the record contains:
  206. * * for each redirected item: the item offset, then the offset redirected to
  207. * * for each now-dead item: the item offset
  208. * * for each now-unused item: the item offset
  209. * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused.
  210. * Note that nunused is not explicitly stored, but may be found by reference
  211. * to the total record length.
  212. *
  213. * Acquires a full cleanup lock.
  214. */
  215. typedef struct xl_heap_prune
  216. {
  217. TransactionId latestRemovedXid;
  218. uint16 nredirected;
  219. uint16 ndead;
  220. /* OFFSET NUMBERS are in the block reference 0 */
  221. } xl_heap_prune;
  222. #define SizeOfHeapPrune (offsetof(xl_heap_prune, ndead) + sizeof(uint16))
  223. /*
  224. * The vacuum page record is similar to the prune record, but can only mark
  225. * already LP_DEAD items LP_UNUSED (during VACUUM's second heap pass)
  226. *
  227. * Acquires an ordinary exclusive lock only.
  228. */
  229. typedef struct xl_heap_vacuum
  230. {
  231. uint16 nunused;
  232. /* OFFSET NUMBERS are in the block reference 0 */
  233. } xl_heap_vacuum;
  234. #define SizeOfHeapVacuum (offsetof(xl_heap_vacuum, nunused) + sizeof(uint16))
  235. /* flags for infobits_set */
  236. #define XLHL_XMAX_IS_MULTI 0x01
  237. #define XLHL_XMAX_LOCK_ONLY 0x02
  238. #define XLHL_XMAX_EXCL_LOCK 0x04
  239. #define XLHL_XMAX_KEYSHR_LOCK 0x08
  240. #define XLHL_KEYS_UPDATED 0x10
  241. /* flag bits for xl_heap_lock / xl_heap_lock_updated's flag field */
  242. #define XLH_LOCK_ALL_FROZEN_CLEARED 0x01
  243. /* This is what we need to know about lock */
  244. typedef struct xl_heap_lock
  245. {
  246. TransactionId locking_xid; /* might be a MultiXactId not xid */
  247. OffsetNumber offnum; /* locked tuple's offset on page */
  248. int8 infobits_set; /* infomask and infomask2 bits to set */
  249. uint8 flags; /* XLH_LOCK_* flag bits */
  250. } xl_heap_lock;
  251. #define SizeOfHeapLock (offsetof(xl_heap_lock, flags) + sizeof(int8))
  252. /* This is what we need to know about locking an updated version of a row */
  253. typedef struct xl_heap_lock_updated
  254. {
  255. TransactionId xmax;
  256. OffsetNumber offnum;
  257. uint8 infobits_set;
  258. uint8 flags;
  259. } xl_heap_lock_updated;
  260. #define SizeOfHeapLockUpdated (offsetof(xl_heap_lock_updated, flags) + sizeof(uint8))
  261. /* This is what we need to know about confirmation of speculative insertion */
  262. typedef struct xl_heap_confirm
  263. {
  264. OffsetNumber offnum; /* confirmed tuple's offset on page */
  265. } xl_heap_confirm;
  266. #define SizeOfHeapConfirm (offsetof(xl_heap_confirm, offnum) + sizeof(OffsetNumber))
  267. /* This is what we need to know about in-place update */
  268. typedef struct xl_heap_inplace
  269. {
  270. OffsetNumber offnum; /* updated tuple's offset on page */
  271. /* TUPLE DATA FOLLOWS AT END OF STRUCT */
  272. } xl_heap_inplace;
  273. #define SizeOfHeapInplace (offsetof(xl_heap_inplace, offnum) + sizeof(OffsetNumber))
  274. /*
  275. * This struct represents a 'freeze plan', which is what we need to know about
  276. * a single tuple being frozen during vacuum.
  277. */
  278. /* 0x01 was XLH_FREEZE_XMIN */
  279. #define XLH_FREEZE_XVAC 0x02
  280. #define XLH_INVALID_XVAC 0x04
  281. typedef struct xl_heap_freeze_tuple
  282. {
  283. TransactionId xmax;
  284. OffsetNumber offset;
  285. uint16 t_infomask2;
  286. uint16 t_infomask;
  287. uint8 frzflags;
  288. } xl_heap_freeze_tuple;
  289. /*
  290. * This is what we need to know about a block being frozen during vacuum
  291. *
  292. * Backup block 0's data contains an array of xl_heap_freeze_tuple structs,
  293. * one for each tuple.
  294. */
  295. typedef struct xl_heap_freeze_page
  296. {
  297. TransactionId cutoff_xid;
  298. uint16 ntuples;
  299. } xl_heap_freeze_page;
  300. #define SizeOfHeapFreezePage (offsetof(xl_heap_freeze_page, ntuples) + sizeof(uint16))
  301. /*
  302. * This is what we need to know about setting a visibility map bit
  303. *
  304. * Backup blk 0: visibility map buffer
  305. * Backup blk 1: heap buffer
  306. */
  307. typedef struct xl_heap_visible
  308. {
  309. TransactionId cutoff_xid;
  310. uint8 flags;
  311. } xl_heap_visible;
  312. #define SizeOfHeapVisible (offsetof(xl_heap_visible, flags) + sizeof(uint8))
  313. typedef struct xl_heap_new_cid
  314. {
  315. /*
  316. * store toplevel xid so we don't have to merge cids from different
  317. * transactions
  318. */
  319. TransactionId top_xid;
  320. CommandId cmin;
  321. CommandId cmax;
  322. CommandId combocid; /* just for debugging */
  323. /*
  324. * Store the relfilenode/ctid pair to facilitate lookups.
  325. */
  326. RelFileNode target_node;
  327. ItemPointerData target_tid;
  328. } xl_heap_new_cid;
  329. #define SizeOfHeapNewCid (offsetof(xl_heap_new_cid, target_tid) + sizeof(ItemPointerData))
  330. /* logical rewrite xlog record header */
  331. typedef struct xl_heap_rewrite_mapping
  332. {
  333. TransactionId mapped_xid; /* xid that might need to see the row */
  334. Oid mapped_db; /* DbOid or InvalidOid for shared rels */
  335. Oid mapped_rel; /* Oid of the mapped relation */
  336. off_t offset; /* How far have we written so far */
  337. uint32 num_mappings; /* Number of in-memory mappings */
  338. XLogRecPtr start_lsn; /* Insert LSN at begin of rewrite */
  339. } xl_heap_rewrite_mapping;
  340. extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
  341. TransactionId *latestRemovedXid);
  342. extern void heap_redo(XLogReaderState *record);
  343. extern void heap_desc(StringInfo buf, XLogReaderState *record);
  344. extern const char *heap_identify(uint8 info);
  345. extern void heap_mask(char *pagedata, BlockNumber blkno);
  346. extern void heap2_redo(XLogReaderState *record);
  347. extern void heap2_desc(StringInfo buf, XLogReaderState *record);
  348. extern const char *heap2_identify(uint8 info);
  349. extern void heap_xlog_logical_rewrite(XLogReaderState *r);
  350. extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer,
  351. TransactionId cutoff_xid, xl_heap_freeze_tuple *tuples,
  352. int ntuples);
  353. extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple,
  354. TransactionId relfrozenxid,
  355. TransactionId relminmxid,
  356. TransactionId cutoff_xid,
  357. TransactionId cutoff_multi,
  358. xl_heap_freeze_tuple *frz,
  359. bool *totally_frozen,
  360. TransactionId *relfrozenxid_out,
  361. MultiXactId *relminmxid_out);
  362. extern void heap_execute_freeze_tuple(HeapTupleHeader tuple,
  363. xl_heap_freeze_tuple *xlrec_tp);
  364. extern XLogRecPtr log_heap_visible(RelFileNode rnode, Buffer heap_buffer,
  365. Buffer vm_buffer, TransactionId cutoff_xid, uint8 flags);
  366. #endif /* HEAPAM_XLOG_H */