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