heapam_xlog.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*-------------------------------------------------------------------------
  2. *
  3. * heapam_xlog.h
  4. * POSTGRES heap access XLOG definitions.
  5. *
  6. *
  7. * Portions Copyright (c) 1996-2016, 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. /* 0x030 is free, was XLOG_HEAP_MOVE */
  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_CLEAN 0x10
  51. #define XLOG_HEAP2_FREEZE_PAGE 0x20
  52. #define XLOG_HEAP2_CLEANUP_INFO 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. /*
  66. * xl_heap_update flag values, 8 bits are available.
  67. */
  68. /* PD_ALL_VISIBLE was cleared */
  69. #define XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED (1<<0)
  70. /* PD_ALL_VISIBLE was cleared in the 2nd page */
  71. #define XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED (1<<1)
  72. #define XLH_UPDATE_CONTAINS_OLD_TUPLE (1<<2)
  73. #define XLH_UPDATE_CONTAINS_OLD_KEY (1<<3)
  74. #define XLH_UPDATE_CONTAINS_NEW_TUPLE (1<<4)
  75. #define XLH_UPDATE_PREFIX_FROM_OLD (1<<5)
  76. #define XLH_UPDATE_SUFFIX_FROM_OLD (1<<6)
  77. /* convenience macro for checking whether any form of old tuple was logged */
  78. #define XLH_UPDATE_CONTAINS_OLD \
  79. (XLH_UPDATE_CONTAINS_OLD_TUPLE | XLH_UPDATE_CONTAINS_OLD_KEY)
  80. /*
  81. * xl_heap_delete flag values, 8 bits are available.
  82. */
  83. /* PD_ALL_VISIBLE was cleared */
  84. #define XLH_DELETE_ALL_VISIBLE_CLEARED (1<<0)
  85. #define XLH_DELETE_CONTAINS_OLD_TUPLE (1<<1)
  86. #define XLH_DELETE_CONTAINS_OLD_KEY (1<<2)
  87. #define XLH_DELETE_IS_SUPER (1<<3)
  88. /* convenience macro for checking whether any form of old tuple was logged */
  89. #define XLH_DELETE_CONTAINS_OLD \
  90. (XLH_DELETE_CONTAINS_OLD_TUPLE | XLH_DELETE_CONTAINS_OLD_KEY)
  91. /* This is what we need to know about delete */
  92. typedef struct xl_heap_delete
  93. {
  94. TransactionId xmax; /* xmax of the deleted tuple */
  95. OffsetNumber offnum; /* deleted tuple's offset */
  96. uint8 infobits_set; /* infomask bits */
  97. uint8 flags;
  98. } xl_heap_delete;
  99. #define SizeOfHeapDelete (offsetof(xl_heap_delete, flags) + sizeof(uint8))
  100. /*
  101. * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted
  102. * or updated tuple in WAL; we can save a few bytes by reconstructing the
  103. * fields that are available elsewhere in the WAL record, or perhaps just
  104. * plain needn't be reconstructed. These are the fields we must store.
  105. * NOTE: t_hoff could be recomputed, but we may as well store it because
  106. * it will come for free due to alignment considerations.
  107. */
  108. typedef struct xl_heap_header
  109. {
  110. uint16 t_infomask2;
  111. uint16 t_infomask;
  112. uint8 t_hoff;
  113. } xl_heap_header;
  114. #define SizeOfHeapHeader (offsetof(xl_heap_header, t_hoff) + sizeof(uint8))
  115. /* This is what we need to know about insert */
  116. typedef struct xl_heap_insert
  117. {
  118. OffsetNumber offnum; /* inserted tuple's offset */
  119. uint8 flags;
  120. /* xl_heap_header & TUPLE DATA in backup block 0 */
  121. } xl_heap_insert;
  122. #define SizeOfHeapInsert (offsetof(xl_heap_insert, flags) + sizeof(uint8))
  123. /*
  124. * This is what we need to know about a multi-insert.
  125. *
  126. * The main data of the record consists of this xl_heap_multi_insert header.
  127. * 'offsets' array is omitted if the whole page is reinitialized
  128. * (XLOG_HEAP_INIT_PAGE).
  129. *
  130. * In block 0's data portion, there is an xl_multi_insert_tuple struct,
  131. * followed by the tuple data for each tuple. There is padding to align
  132. * each xl_multi_insert struct.
  133. */
  134. typedef struct xl_heap_multi_insert
  135. {
  136. uint8 flags;
  137. uint16 ntuples;
  138. OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER];
  139. } xl_heap_multi_insert;
  140. #define SizeOfHeapMultiInsert offsetof(xl_heap_multi_insert, offsets)
  141. typedef struct xl_multi_insert_tuple
  142. {
  143. uint16 datalen; /* size of tuple data that follows */
  144. uint16 t_infomask2;
  145. uint16 t_infomask;
  146. uint8 t_hoff;
  147. /* TUPLE DATA FOLLOWS AT END OF STRUCT */
  148. } xl_multi_insert_tuple;
  149. #define SizeOfMultiInsertTuple (offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8))
  150. /*
  151. * This is what we need to know about update|hot_update
  152. *
  153. * Backup blk 0: new page
  154. *
  155. * If XLOG_HEAP_PREFIX_FROM_OLD or XLOG_HEAP_SUFFIX_FROM_OLD flags are set,
  156. * the prefix and/or suffix come first, as one or two uint16s.
  157. *
  158. * After that, xl_heap_header and new tuple data follow. The new tuple
  159. * data doesn't include the prefix and suffix, which are copied from the
  160. * old tuple on replay.
  161. *
  162. * If HEAP_CONTAINS_NEW_TUPLE_DATA flag is given, the tuple data is
  163. * included even if a full-page image was taken.
  164. *
  165. * Backup blk 1: old page, if different. (no data, just a reference to the blk)
  166. */
  167. typedef struct xl_heap_update
  168. {
  169. TransactionId old_xmax; /* xmax of the old tuple */
  170. OffsetNumber old_offnum; /* old tuple's offset */
  171. uint8 old_infobits_set; /* infomask bits to set on old tuple */
  172. uint8 flags;
  173. TransactionId new_xmax; /* xmax of the new tuple */
  174. OffsetNumber new_offnum; /* new tuple's offset */
  175. /*
  176. * If XLOG_HEAP_CONTAINS_OLD_TUPLE or XLOG_HEAP_CONTAINS_OLD_KEY flags are
  177. * set, a xl_heap_header struct and tuple data for the old tuple follows.
  178. */
  179. } xl_heap_update;
  180. #define SizeOfHeapUpdate (offsetof(xl_heap_update, new_offnum) + sizeof(OffsetNumber))
  181. /*
  182. * This is what we need to know about vacuum page cleanup/redirect
  183. *
  184. * The array of OffsetNumbers following the fixed part of the record contains:
  185. * * for each redirected item: the item offset, then the offset redirected to
  186. * * for each now-dead item: the item offset
  187. * * for each now-unused item: the item offset
  188. * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused.
  189. * Note that nunused is not explicitly stored, but may be found by reference
  190. * to the total record length.
  191. */
  192. typedef struct xl_heap_clean
  193. {
  194. TransactionId latestRemovedXid;
  195. uint16 nredirected;
  196. uint16 ndead;
  197. /* OFFSET NUMBERS are in the block reference 0 */
  198. } xl_heap_clean;
  199. #define SizeOfHeapClean (offsetof(xl_heap_clean, ndead) + sizeof(uint16))
  200. /*
  201. * Cleanup_info is required in some cases during a lazy VACUUM.
  202. * Used for reporting the results of HeapTupleHeaderAdvanceLatestRemovedXid()
  203. * see vacuumlazy.c for full explanation
  204. */
  205. typedef struct xl_heap_cleanup_info
  206. {
  207. RelFileNode node;
  208. TransactionId latestRemovedXid;
  209. } xl_heap_cleanup_info;
  210. #define SizeOfHeapCleanupInfo (sizeof(xl_heap_cleanup_info))
  211. /* flags for infobits_set */
  212. #define XLHL_XMAX_IS_MULTI 0x01
  213. #define XLHL_XMAX_LOCK_ONLY 0x02
  214. #define XLHL_XMAX_EXCL_LOCK 0x04
  215. #define XLHL_XMAX_KEYSHR_LOCK 0x08
  216. #define XLHL_KEYS_UPDATED 0x10
  217. /* flag bits for xl_heap_lock / xl_heap_lock_updated's flag field */
  218. #define XLH_LOCK_ALL_FROZEN_CLEARED 0x01
  219. /* This is what we need to know about lock */
  220. typedef struct xl_heap_lock
  221. {
  222. TransactionId locking_xid; /* might be a MultiXactId not xid */
  223. OffsetNumber offnum; /* locked tuple's offset on page */
  224. int8 infobits_set; /* infomask and infomask2 bits to set */
  225. uint8 flags; /* XLH_LOCK_* flag bits */
  226. } xl_heap_lock;
  227. #define SizeOfHeapLock (offsetof(xl_heap_lock, flags) + sizeof(int8))
  228. /* This is what we need to know about locking an updated version of a row */
  229. typedef struct xl_heap_lock_updated
  230. {
  231. TransactionId xmax;
  232. OffsetNumber offnum;
  233. uint8 infobits_set;
  234. uint8 flags;
  235. } xl_heap_lock_updated;
  236. #define SizeOfHeapLockUpdated (offsetof(xl_heap_lock_updated, flags) + sizeof(uint8))
  237. /* This is what we need to know about confirmation of speculative insertion */
  238. typedef struct xl_heap_confirm
  239. {
  240. OffsetNumber offnum; /* confirmed tuple's offset on page */
  241. } xl_heap_confirm;
  242. #define SizeOfHeapConfirm (offsetof(xl_heap_confirm, offnum) + sizeof(OffsetNumber))
  243. /* This is what we need to know about in-place update */
  244. typedef struct xl_heap_inplace
  245. {
  246. OffsetNumber offnum; /* updated tuple's offset on page */
  247. /* TUPLE DATA FOLLOWS AT END OF STRUCT */
  248. } xl_heap_inplace;
  249. #define SizeOfHeapInplace (offsetof(xl_heap_inplace, offnum) + sizeof(OffsetNumber))
  250. /*
  251. * This struct represents a 'freeze plan', which is what we need to know about
  252. * a single tuple being frozen during vacuum.
  253. */
  254. /* 0x01 was XLH_FREEZE_XMIN */
  255. #define XLH_FREEZE_XVAC 0x02
  256. #define XLH_INVALID_XVAC 0x04
  257. typedef struct xl_heap_freeze_tuple
  258. {
  259. TransactionId xmax;
  260. OffsetNumber offset;
  261. uint16 t_infomask2;
  262. uint16 t_infomask;
  263. uint8 frzflags;
  264. } xl_heap_freeze_tuple;
  265. /*
  266. * This is what we need to know about a block being frozen during vacuum
  267. *
  268. * Backup block 0's data contains an array of xl_heap_freeze_tuple structs,
  269. * one for each tuple.
  270. */
  271. typedef struct xl_heap_freeze_page
  272. {
  273. TransactionId cutoff_xid;
  274. uint16 ntuples;
  275. } xl_heap_freeze_page;
  276. #define SizeOfHeapFreezePage (offsetof(xl_heap_freeze_page, ntuples) + sizeof(uint16))
  277. /*
  278. * This is what we need to know about setting a visibility map bit
  279. *
  280. * Backup blk 0: visibility map buffer
  281. * Backup blk 1: heap buffer
  282. */
  283. typedef struct xl_heap_visible
  284. {
  285. TransactionId cutoff_xid;
  286. uint8 flags;
  287. } xl_heap_visible;
  288. #define SizeOfHeapVisible (offsetof(xl_heap_visible, flags) + sizeof(uint8))
  289. typedef struct xl_heap_new_cid
  290. {
  291. /*
  292. * store toplevel xid so we don't have to merge cids from different
  293. * transactions
  294. */
  295. TransactionId top_xid;
  296. CommandId cmin;
  297. CommandId cmax;
  298. /*
  299. * don't really need the combocid since we have the actual values right in
  300. * this struct, but the padding makes it free and its useful for
  301. * debugging.
  302. */
  303. CommandId combocid;
  304. /*
  305. * Store the relfilenode/ctid pair to facilitate lookups.
  306. */
  307. RelFileNode target_node;
  308. ItemPointerData target_tid;
  309. } xl_heap_new_cid;
  310. #define SizeOfHeapNewCid (offsetof(xl_heap_new_cid, target_tid) + sizeof(ItemPointerData))
  311. /* logical rewrite xlog record header */
  312. typedef struct xl_heap_rewrite_mapping
  313. {
  314. TransactionId mapped_xid; /* xid that might need to see the row */
  315. Oid mapped_db; /* DbOid or InvalidOid for shared rels */
  316. Oid mapped_rel; /* Oid of the mapped relation */
  317. off_t offset; /* How far have we written so far */
  318. uint32 num_mappings; /* Number of in-memory mappings */
  319. XLogRecPtr start_lsn; /* Insert LSN at begin of rewrite */
  320. } xl_heap_rewrite_mapping;
  321. extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
  322. TransactionId *latestRemovedXid);
  323. extern void heap_redo(XLogReaderState *record);
  324. extern void heap_desc(StringInfo buf, XLogReaderState *record);
  325. extern const char *heap_identify(uint8 info);
  326. extern void heap2_redo(XLogReaderState *record);
  327. extern void heap2_desc(StringInfo buf, XLogReaderState *record);
  328. extern const char *heap2_identify(uint8 info);
  329. extern void heap_xlog_logical_rewrite(XLogReaderState *r);
  330. extern XLogRecPtr log_heap_cleanup_info(RelFileNode rnode,
  331. TransactionId latestRemovedXid);
  332. extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
  333. OffsetNumber *redirected, int nredirected,
  334. OffsetNumber *nowdead, int ndead,
  335. OffsetNumber *nowunused, int nunused,
  336. TransactionId latestRemovedXid);
  337. extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer,
  338. TransactionId cutoff_xid, xl_heap_freeze_tuple *tuples,
  339. int ntuples);
  340. extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple,
  341. TransactionId cutoff_xid,
  342. TransactionId cutoff_multi,
  343. xl_heap_freeze_tuple *frz,
  344. bool *totally_frozen);
  345. extern void heap_execute_freeze_tuple(HeapTupleHeader tuple,
  346. xl_heap_freeze_tuple *xlrec_tp);
  347. extern XLogRecPtr log_heap_visible(RelFileNode rnode, Buffer heap_buffer,
  348. Buffer vm_buffer, TransactionId cutoff_xid, uint8 flags);
  349. #endif /* HEAPAM_XLOG_H */