PostgreSQL Source Code  git master
heapam_xlog.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * heapam_xlog.h
4  * POSTGRES heap access XLOG definitions.
5  *
6  *
7  * Portions Copyright (c) 1996-2024, 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 
17 #include "access/htup.h"
18 #include "access/xlogreader.h"
19 #include "lib/stringinfo.h"
20 #include "storage/buf.h"
21 #include "storage/bufpage.h"
22 #include "storage/relfilelocator.h"
23 #include "utils/relcache.h"
24 
25 
26 /*
27  * WAL record definitions for heapam.c's WAL operations
28  *
29  * XLOG allows to store some information in high 4 bits of log
30  * record xl_info field. We use 3 for opcode and one for init bit.
31  */
32 #define XLOG_HEAP_INSERT 0x00
33 #define XLOG_HEAP_DELETE 0x10
34 #define XLOG_HEAP_UPDATE 0x20
35 #define XLOG_HEAP_TRUNCATE 0x30
36 #define XLOG_HEAP_HOT_UPDATE 0x40
37 #define XLOG_HEAP_CONFIRM 0x50
38 #define XLOG_HEAP_LOCK 0x60
39 #define XLOG_HEAP_INPLACE 0x70
40 
41 #define XLOG_HEAP_OPMASK 0x70
42 /*
43  * When we insert 1st item on new page in INSERT, UPDATE, HOT_UPDATE,
44  * or MULTI_INSERT, we can (and we do) restore entire page in redo
45  */
46 #define XLOG_HEAP_INIT_PAGE 0x80
47 /*
48  * We ran out of opcodes, so heapam.c now has a second RmgrId. These opcodes
49  * are associated with RM_HEAP2_ID, but are not logically different from
50  * the ones above associated with RM_HEAP_ID. XLOG_HEAP_OPMASK applies to
51  * these, too.
52  *
53  * There's no difference between XLOG_HEAP2_PRUNE_ON_ACCESS,
54  * XLOG_HEAP2_PRUNE_VACUUM_SCAN and XLOG_HEAP2_PRUNE_VACUUM_CLEANUP records.
55  * They have separate opcodes just for debugging and analysis purposes, to
56  * indicate why the WAL record was emitted.
57  */
58 #define XLOG_HEAP2_REWRITE 0x00
59 #define XLOG_HEAP2_PRUNE_ON_ACCESS 0x10
60 #define XLOG_HEAP2_PRUNE_VACUUM_SCAN 0x20
61 #define XLOG_HEAP2_PRUNE_VACUUM_CLEANUP 0x30
62 #define XLOG_HEAP2_VISIBLE 0x40
63 #define XLOG_HEAP2_MULTI_INSERT 0x50
64 #define XLOG_HEAP2_LOCK_UPDATED 0x60
65 #define XLOG_HEAP2_NEW_CID 0x70
66 
67 /*
68  * xl_heap_insert/xl_heap_multi_insert flag values, 8 bits are available.
69  */
70 /* PD_ALL_VISIBLE was cleared */
71 #define XLH_INSERT_ALL_VISIBLE_CLEARED (1<<0)
72 #define XLH_INSERT_LAST_IN_MULTI (1<<1)
73 #define XLH_INSERT_IS_SPECULATIVE (1<<2)
74 #define XLH_INSERT_CONTAINS_NEW_TUPLE (1<<3)
75 #define XLH_INSERT_ON_TOAST_RELATION (1<<4)
76 
77 /* all_frozen_set always implies all_visible_set */
78 #define XLH_INSERT_ALL_FROZEN_SET (1<<5)
79 
80 /*
81  * xl_heap_update flag values, 8 bits are available.
82  */
83 /* PD_ALL_VISIBLE was cleared */
84 #define XLH_UPDATE_OLD_ALL_VISIBLE_CLEARED (1<<0)
85 /* PD_ALL_VISIBLE was cleared in the 2nd page */
86 #define XLH_UPDATE_NEW_ALL_VISIBLE_CLEARED (1<<1)
87 #define XLH_UPDATE_CONTAINS_OLD_TUPLE (1<<2)
88 #define XLH_UPDATE_CONTAINS_OLD_KEY (1<<3)
89 #define XLH_UPDATE_CONTAINS_NEW_TUPLE (1<<4)
90 #define XLH_UPDATE_PREFIX_FROM_OLD (1<<5)
91 #define XLH_UPDATE_SUFFIX_FROM_OLD (1<<6)
92 
93 /* convenience macro for checking whether any form of old tuple was logged */
94 #define XLH_UPDATE_CONTAINS_OLD \
95  (XLH_UPDATE_CONTAINS_OLD_TUPLE | XLH_UPDATE_CONTAINS_OLD_KEY)
96 
97 /*
98  * xl_heap_delete flag values, 8 bits are available.
99  */
100 /* PD_ALL_VISIBLE was cleared */
101 #define XLH_DELETE_ALL_VISIBLE_CLEARED (1<<0)
102 #define XLH_DELETE_CONTAINS_OLD_TUPLE (1<<1)
103 #define XLH_DELETE_CONTAINS_OLD_KEY (1<<2)
104 #define XLH_DELETE_IS_SUPER (1<<3)
105 #define XLH_DELETE_IS_PARTITION_MOVE (1<<4)
106 
107 /* convenience macro for checking whether any form of old tuple was logged */
108 #define XLH_DELETE_CONTAINS_OLD \
109  (XLH_DELETE_CONTAINS_OLD_TUPLE | XLH_DELETE_CONTAINS_OLD_KEY)
110 
111 /* This is what we need to know about delete */
112 typedef struct xl_heap_delete
113 {
114  TransactionId xmax; /* xmax of the deleted tuple */
115  OffsetNumber offnum; /* deleted tuple's offset */
116  uint8 infobits_set; /* infomask bits */
119 
120 #define SizeOfHeapDelete (offsetof(xl_heap_delete, flags) + sizeof(uint8))
121 
122 /*
123  * xl_heap_truncate flag values, 8 bits are available.
124  */
125 #define XLH_TRUNCATE_CASCADE (1<<0)
126 #define XLH_TRUNCATE_RESTART_SEQS (1<<1)
127 
128 /*
129  * For truncate we list all truncated relids in an array, followed by all
130  * sequence relids that need to be restarted, if any.
131  * All rels are always within the same database, so we just list dbid once.
132  */
133 typedef struct xl_heap_truncate
134 {
140 
141 #define SizeOfHeapTruncate (offsetof(xl_heap_truncate, relids))
142 
143 /*
144  * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted
145  * or updated tuple in WAL; we can save a few bytes by reconstructing the
146  * fields that are available elsewhere in the WAL record, or perhaps just
147  * plain needn't be reconstructed. These are the fields we must store.
148  */
149 typedef struct xl_heap_header
150 {
155 
156 #define SizeOfHeapHeader (offsetof(xl_heap_header, t_hoff) + sizeof(uint8))
157 
158 /* This is what we need to know about insert */
159 typedef struct xl_heap_insert
160 {
161  OffsetNumber offnum; /* inserted tuple's offset */
163 
164  /* xl_heap_header & TUPLE DATA in backup block 0 */
166 
167 #define SizeOfHeapInsert (offsetof(xl_heap_insert, flags) + sizeof(uint8))
168 
169 /*
170  * This is what we need to know about a multi-insert.
171  *
172  * The main data of the record consists of this xl_heap_multi_insert header.
173  * 'offsets' array is omitted if the whole page is reinitialized
174  * (XLOG_HEAP_INIT_PAGE).
175  *
176  * In block 0's data portion, there is an xl_multi_insert_tuple struct,
177  * followed by the tuple data for each tuple. There is padding to align
178  * each xl_multi_insert_tuple struct.
179  */
180 typedef struct xl_heap_multi_insert
181 {
186 
187 #define SizeOfHeapMultiInsert offsetof(xl_heap_multi_insert, offsets)
188 
189 typedef struct xl_multi_insert_tuple
190 {
191  uint16 datalen; /* size of tuple data that follows */
195  /* TUPLE DATA FOLLOWS AT END OF STRUCT */
197 
198 #define SizeOfMultiInsertTuple (offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8))
199 
200 /*
201  * This is what we need to know about update|hot_update
202  *
203  * Backup blk 0: new page
204  *
205  * If XLH_UPDATE_PREFIX_FROM_OLD or XLH_UPDATE_SUFFIX_FROM_OLD flags are set,
206  * the prefix and/or suffix come first, as one or two uint16s.
207  *
208  * After that, xl_heap_header and new tuple data follow. The new tuple
209  * data doesn't include the prefix and suffix, which are copied from the
210  * old tuple on replay.
211  *
212  * If XLH_UPDATE_CONTAINS_NEW_TUPLE flag is given, the tuple data is
213  * included even if a full-page image was taken.
214  *
215  * Backup blk 1: old page, if different. (no data, just a reference to the blk)
216  */
217 typedef struct xl_heap_update
218 {
219  TransactionId old_xmax; /* xmax of the old tuple */
220  OffsetNumber old_offnum; /* old tuple's offset */
221  uint8 old_infobits_set; /* infomask bits to set on old tuple */
223  TransactionId new_xmax; /* xmax of the new tuple */
224  OffsetNumber new_offnum; /* new tuple's offset */
225 
226  /*
227  * If XLH_UPDATE_CONTAINS_OLD_TUPLE or XLH_UPDATE_CONTAINS_OLD_KEY flags
228  * are set, xl_heap_header and tuple data for the old tuple follow.
229  */
231 
232 #define SizeOfHeapUpdate (offsetof(xl_heap_update, new_offnum) + sizeof(OffsetNumber))
233 
234 /*
235  * These structures and flags encode VACUUM pruning and freezing and on-access
236  * pruning page modifications.
237  *
238  * xl_heap_prune is the main record. The XLHP_HAS_* flags indicate which
239  * "sub-records" are included and the other XLHP_* flags provide additional
240  * information about the conditions for replay.
241  *
242  * The data for block reference 0 contains "sub-records" depending on which of
243  * the XLHP_HAS_* flags are set. See xlhp_* struct definitions below. The
244  * sub-records appear in the same order as the XLHP_* flags. An example
245  * record with every sub-record included:
246  *
247  *-----------------------------------------------------------------------------
248  * Main data section:
249  *
250  * xl_heap_prune
251  * uint8 flags
252  * TransactionId snapshot_conflict_horizon
253  *
254  * Block 0 data section:
255  *
256  * xlhp_freeze_plans
257  * uint16 nplans
258  * [2 bytes of padding]
259  * xlhp_freeze_plan plans[nplans]
260  *
261  * xlhp_prune_items
262  * uint16 nredirected
263  * OffsetNumber redirected[2 * nredirected]
264  *
265  * xlhp_prune_items
266  * uint16 ndead
267  * OffsetNumber nowdead[ndead]
268  *
269  * xlhp_prune_items
270  * uint16 nunused
271  * OffsetNumber nowunused[nunused]
272  *
273  * OffsetNumber frz_offsets[sum([plan.ntuples for plan in plans])]
274  *-----------------------------------------------------------------------------
275  *
276  * NOTE: because the record data is assembled from many optional parts, we
277  * have to pay close attention to alignment. In the main data section,
278  * 'snapshot_conflict_horizon' is stored unaligned after 'flags', to save
279  * space. In the block 0 data section, the freeze plans appear first, because
280  * they contain TransactionId fields that require 4-byte alignment. All the
281  * other fields require only 2-byte alignment. This is also the reason that
282  * 'frz_offsets' is stored separately from the xlhp_freeze_plan structs.
283  */
284 typedef struct xl_heap_prune
285 {
288 
289  /*
290  * If XLHP_HAS_CONFLICT_HORIZON is set, the conflict horzion XID follows,
291  * unaligned
292  */
294 
295 #define SizeOfHeapPrune (offsetof(xl_heap_prune, flags) + sizeof(uint8))
296 
297 /* to handle recovery conflict during logical decoding on standby */
298 #define XLHP_IS_CATALOG_REL (1 << 1)
299 
300 /*
301  * Does replaying the record require a cleanup-lock?
302  *
303  * Pruning, in VACUUM's first pass or when otherwise accessing a page,
304  * requires a cleanup lock. For freezing, and VACUUM's second pass which
305  * marks LP_DEAD line pointers as unused without moving any tuple data, an
306  * ordinary exclusive lock is sufficient.
307  */
308 #define XLHP_CLEANUP_LOCK (1 << 2)
309 
310 /*
311  * If we remove or freeze any entries that contain xids, we need to include a
312  * snapshot conflict horizon. It's used in Hot Standby mode to ensure that
313  * there are no queries running for which the removed tuples are still
314  * visible, or which still consider the frozen XIDs as running.
315  */
316 #define XLHP_HAS_CONFLICT_HORIZON (1 << 3)
317 
318 /*
319  * Indicates that an xlhp_freeze_plans sub-record and one or more
320  * xlhp_freeze_plan sub-records are present.
321  */
322 #define XLHP_HAS_FREEZE_PLANS (1 << 4)
323 
324 /*
325  * XLHP_HAS_REDIRECTIONS, XLHP_HAS_DEAD_ITEMS, and XLHP_HAS_NOW_UNUSED
326  * indicate that xlhp_prune_items sub-records with redirected, dead, and
327  * unused item offsets are present.
328  */
329 #define XLHP_HAS_REDIRECTIONS (1 << 5)
330 #define XLHP_HAS_DEAD_ITEMS (1 << 6)
331 #define XLHP_HAS_NOW_UNUSED_ITEMS (1 << 7)
332 
333 /*
334  * xlhp_freeze_plan describes how to freeze a group of one or more heap tuples
335  * (appears in xl_heap_prune's xlhp_freeze_plans sub-record)
336  */
337 /* 0x01 was XLH_FREEZE_XMIN */
338 #define XLH_FREEZE_XVAC 0x02
339 #define XLH_INVALID_XVAC 0x04
340 
341 typedef struct xlhp_freeze_plan
342 {
347 
348  /* Length of individual page offset numbers array for this plan */
351 
352 /*
353  * This is what we need to know about a block being frozen during vacuum
354  *
355  * The backup block's data contains an array of xlhp_freeze_plan structs (with
356  * nplans elements). The individual item offsets are located in an array at
357  * the end of the entire record with with nplans * (each plan's ntuples)
358  * members. Those offsets are in the same order as the plans. The REDO
359  * routine uses the offsets to freeze the corresponding heap tuples.
360  *
361  * (As of PostgreSQL 17, XLOG_HEAP2_PRUNE_VACUUM_SCAN records replace the
362  * separate XLOG_HEAP2_FREEZE_PAGE records.)
363  */
364 typedef struct xlhp_freeze_plans
365 {
369 
370 /*
371  * Generic sub-record type contained in block reference 0 of an xl_heap_prune
372  * record and used for redirect, dead, and unused items if any of
373  * XLHP_HAS_REDIRECTIONS/XLHP_HAS_DEAD_ITEMS/XLHP_HAS_NOW_UNUSED_ITEMS are
374  * set. Note that in the XLHP_HAS_REDIRECTIONS variant, there are actually 2
375  * * length number of OffsetNumbers in the data.
376  */
377 typedef struct xlhp_prune_items
378 {
382 
383 
384 /* flags for infobits_set */
385 #define XLHL_XMAX_IS_MULTI 0x01
386 #define XLHL_XMAX_LOCK_ONLY 0x02
387 #define XLHL_XMAX_EXCL_LOCK 0x04
388 #define XLHL_XMAX_KEYSHR_LOCK 0x08
389 #define XLHL_KEYS_UPDATED 0x10
390 
391 /* flag bits for xl_heap_lock / xl_heap_lock_updated's flag field */
392 #define XLH_LOCK_ALL_FROZEN_CLEARED 0x01
393 
394 /* This is what we need to know about lock */
395 typedef struct xl_heap_lock
396 {
397  TransactionId xmax; /* might be a MultiXactId */
398  OffsetNumber offnum; /* locked tuple's offset on page */
399  uint8 infobits_set; /* infomask and infomask2 bits to set */
400  uint8 flags; /* XLH_LOCK_* flag bits */
402 
403 #define SizeOfHeapLock (offsetof(xl_heap_lock, flags) + sizeof(uint8))
404 
405 /* This is what we need to know about locking an updated version of a row */
406 typedef struct xl_heap_lock_updated
407 {
413 
414 #define SizeOfHeapLockUpdated (offsetof(xl_heap_lock_updated, flags) + sizeof(uint8))
415 
416 /* This is what we need to know about confirmation of speculative insertion */
417 typedef struct xl_heap_confirm
418 {
419  OffsetNumber offnum; /* confirmed tuple's offset on page */
421 
422 #define SizeOfHeapConfirm (offsetof(xl_heap_confirm, offnum) + sizeof(OffsetNumber))
423 
424 /* This is what we need to know about in-place update */
425 typedef struct xl_heap_inplace
426 {
427  OffsetNumber offnum; /* updated tuple's offset on page */
428  /* TUPLE DATA FOLLOWS AT END OF STRUCT */
430 
431 #define SizeOfHeapInplace (offsetof(xl_heap_inplace, offnum) + sizeof(OffsetNumber))
432 
433 /*
434  * This is what we need to know about setting a visibility map bit
435  *
436  * Backup blk 0: visibility map buffer
437  * Backup blk 1: heap buffer
438  */
439 typedef struct xl_heap_visible
440 {
444 
445 #define SizeOfHeapVisible (offsetof(xl_heap_visible, flags) + sizeof(uint8))
446 
447 typedef struct xl_heap_new_cid
448 {
449  /*
450  * store toplevel xid so we don't have to merge cids from different
451  * transactions
452  */
456  CommandId combocid; /* just for debugging */
457 
458  /*
459  * Store the relfilelocator/ctid pair to facilitate lookups.
460  */
464 
465 #define SizeOfHeapNewCid (offsetof(xl_heap_new_cid, target_tid) + sizeof(ItemPointerData))
466 
467 /* logical rewrite xlog record header */
469 {
470  TransactionId mapped_xid; /* xid that might need to see the row */
471  Oid mapped_db; /* DbOid or InvalidOid for shared rels */
472  Oid mapped_rel; /* Oid of the mapped relation */
473  off_t offset; /* How far have we written so far */
474  uint32 num_mappings; /* Number of in-memory mappings */
475  XLogRecPtr start_lsn; /* Insert LSN at begin of rewrite */
477 
479  TransactionId *snapshotConflictHorizon);
480 
481 extern void heap_redo(XLogReaderState *record);
482 extern void heap_desc(StringInfo buf, XLogReaderState *record);
483 extern const char *heap_identify(uint8 info);
484 extern void heap_mask(char *pagedata, BlockNumber blkno);
485 extern void heap2_redo(XLogReaderState *record);
486 extern void heap2_desc(StringInfo buf, XLogReaderState *record);
487 extern const char *heap2_identify(uint8 info);
489 
490 extern XLogRecPtr log_heap_visible(Relation rel, Buffer heap_buffer,
491  Buffer vm_buffer,
492  TransactionId snapshotConflictHorizon,
493  uint8 vmflags);
494 
495 /* in heapdesc.c, so it can be shared between frontend/backend code */
496 extern void heap_xlog_deserialize_prune_and_freeze(char *cursor, uint8 flags,
497  int *nplans, xlhp_freeze_plan **plans,
498  OffsetNumber **frz_offsets,
499  int *nredirected, OffsetNumber **redirected,
500  int *ndead, OffsetNumber **nowdead,
501  int *nunused, OffsetNumber **nowunused);
502 
503 #endif /* HEAPAM_XLOG_H */
uint32 BlockNumber
Definition: block.h:31
int Buffer
Definition: buf.h:23
unsigned short uint16
Definition: c.h:505
unsigned int uint32
Definition: c.h:506
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:398
unsigned char uint8
Definition: c.h:504
uint32 CommandId
Definition: c.h:666
uint32 TransactionId
Definition: c.h:652
struct xlhp_freeze_plan xlhp_freeze_plan
struct xl_heap_rewrite_mapping xl_heap_rewrite_mapping
XLogRecPtr log_heap_visible(Relation rel, Buffer heap_buffer, Buffer vm_buffer, TransactionId snapshotConflictHorizon, uint8 vmflags)
Definition: heapam.c:8314
struct xl_heap_delete xl_heap_delete
void heap_desc(StringInfo buf, XLogReaderState *record)
Definition: heapdesc.c:183
void heap_redo(XLogReaderState *record)
Definition: heapam.c:9871
const char * heap_identify(uint8 info)
Definition: heapdesc.c:385
void heap2_desc(StringInfo buf, XLogReaderState *record)
Definition: heapdesc.c:260
void heap_xlog_deserialize_prune_and_freeze(char *cursor, uint8 flags, int *nplans, xlhp_freeze_plan **plans, OffsetNumber **frz_offsets, int *nredirected, OffsetNumber **redirected, int *ndead, OffsetNumber **nowdead, int *nunused, OffsetNumber **nowunused)
Definition: heapdesc.c:104
void heap_mask(char *pagedata, BlockNumber blkno)
Definition: heapam.c:9956
void HeapTupleHeaderAdvanceConflictHorizon(HeapTupleHeader tuple, TransactionId *snapshotConflictHorizon)
Definition: heapam.c:7482
struct xl_heap_new_cid xl_heap_new_cid
const char * heap2_identify(uint8 info)
Definition: heapdesc.c:430
struct xl_heap_lock xl_heap_lock
void heap_xlog_logical_rewrite(XLogReaderState *r)
Definition: rewriteheap.c:1073
struct xl_heap_prune xl_heap_prune
struct xl_heap_multi_insert xl_heap_multi_insert
struct xl_heap_confirm xl_heap_confirm
struct xl_heap_insert xl_heap_insert
struct xlhp_freeze_plans xlhp_freeze_plans
struct xl_heap_lock_updated xl_heap_lock_updated
struct xl_heap_inplace xl_heap_inplace
struct xlhp_prune_items xlhp_prune_items
void heap2_redo(XLogReaderState *record)
Definition: heapam.c:9917
struct xl_heap_header xl_heap_header
struct xl_multi_insert_tuple xl_multi_insert_tuple
struct xl_heap_visible xl_heap_visible
struct xl_heap_update xl_heap_update
struct xl_heap_truncate xl_heap_truncate
uint16 OffsetNumber
Definition: off.h:24
static char * buf
Definition: pg_test_fsync.c:73
unsigned int Oid
Definition: postgres_ext.h:31
Definition: type.h:137
OffsetNumber offnum
Definition: heapam_xlog.h:419
TransactionId xmax
Definition: heapam_xlog.h:114
OffsetNumber offnum
Definition: heapam_xlog.h:115
uint8 infobits_set
Definition: heapam_xlog.h:116
uint16 t_infomask
Definition: heapam_xlog.h:152
uint16 t_infomask2
Definition: heapam_xlog.h:151
OffsetNumber offnum
Definition: heapam_xlog.h:427
OffsetNumber offnum
Definition: heapam_xlog.h:161
TransactionId xmax
Definition: heapam_xlog.h:408
OffsetNumber offnum
Definition: heapam_xlog.h:409
uint8 infobits_set
Definition: heapam_xlog.h:399
OffsetNumber offnum
Definition: heapam_xlog.h:398
TransactionId xmax
Definition: heapam_xlog.h:397
OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]
Definition: heapam_xlog.h:184
CommandId cmin
Definition: heapam_xlog.h:454
CommandId combocid
Definition: heapam_xlog.h:456
ItemPointerData target_tid
Definition: heapam_xlog.h:462
TransactionId top_xid
Definition: heapam_xlog.h:453
CommandId cmax
Definition: heapam_xlog.h:455
RelFileLocator target_locator
Definition: heapam_xlog.h:461
TransactionId mapped_xid
Definition: heapam_xlog.h:470
Oid relids[FLEXIBLE_ARRAY_MEMBER]
Definition: heapam_xlog.h:138
TransactionId new_xmax
Definition: heapam_xlog.h:223
uint8 old_infobits_set
Definition: heapam_xlog.h:221
TransactionId old_xmax
Definition: heapam_xlog.h:219
OffsetNumber old_offnum
Definition: heapam_xlog.h:220
OffsetNumber new_offnum
Definition: heapam_xlog.h:224
TransactionId snapshotConflictHorizon
Definition: heapam_xlog.h:441
TransactionId xmax
Definition: heapam_xlog.h:343
xlhp_freeze_plan plans[FLEXIBLE_ARRAY_MEMBER]
Definition: heapam_xlog.h:367
OffsetNumber data[FLEXIBLE_ARRAY_MEMBER]
Definition: heapam_xlog.h:380
uint64 XLogRecPtr
Definition: xlogdefs.h:21