/src/postgres/src/include/access/heapam.h
Line | Count | Source |
1 | | /*------------------------------------------------------------------------- |
2 | | * |
3 | | * heapam.h |
4 | | * POSTGRES heap access method definitions. |
5 | | * |
6 | | * |
7 | | * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group |
8 | | * Portions Copyright (c) 1994, Regents of the University of California |
9 | | * |
10 | | * src/include/access/heapam.h |
11 | | * |
12 | | *------------------------------------------------------------------------- |
13 | | */ |
14 | | #ifndef HEAPAM_H |
15 | | #define HEAPAM_H |
16 | | |
17 | | #include "access/heapam_xlog.h" |
18 | | #include "access/relation.h" /* for backward compatibility */ |
19 | | #include "access/relscan.h" |
20 | | #include "access/sdir.h" |
21 | | #include "access/skey.h" |
22 | | #include "access/table.h" /* for backward compatibility */ |
23 | | #include "access/tableam.h" |
24 | | #include "nodes/lockoptions.h" |
25 | | #include "nodes/primnodes.h" |
26 | | #include "storage/bufpage.h" |
27 | | #include "storage/dsm.h" |
28 | | #include "storage/lockdefs.h" |
29 | | #include "storage/read_stream.h" |
30 | | #include "storage/shm_toc.h" |
31 | | #include "utils/relcache.h" |
32 | | #include "utils/snapshot.h" |
33 | | |
34 | | |
35 | | /* "options" flag bits for heap_insert */ |
36 | 0 | #define HEAP_INSERT_SKIP_FSM TABLE_INSERT_SKIP_FSM |
37 | 0 | #define HEAP_INSERT_FROZEN TABLE_INSERT_FROZEN |
38 | 0 | #define HEAP_INSERT_NO_LOGICAL TABLE_INSERT_NO_LOGICAL |
39 | 0 | #define HEAP_INSERT_SPECULATIVE 0x0010 |
40 | | |
41 | | /* "options" flag bits for heap_page_prune_and_freeze */ |
42 | 0 | #define HEAP_PAGE_PRUNE_MARK_UNUSED_NOW (1 << 0) |
43 | 0 | #define HEAP_PAGE_PRUNE_FREEZE (1 << 1) |
44 | 0 | #define HEAP_PAGE_PRUNE_ALLOW_FAST_PATH (1 << 2) |
45 | 0 | #define HEAP_PAGE_PRUNE_SET_VM (1 << 3) |
46 | | |
47 | | typedef struct BulkInsertStateData *BulkInsertState; |
48 | | typedef struct GlobalVisState GlobalVisState; |
49 | | typedef struct TupleTableSlot TupleTableSlot; |
50 | | typedef struct VacuumCutoffs VacuumCutoffs; |
51 | | typedef struct VacuumParams VacuumParams; |
52 | | |
53 | | #define MaxLockTupleMode LockTupleExclusive |
54 | | |
55 | | /* |
56 | | * Descriptor for heap table scans. |
57 | | */ |
58 | | typedef struct HeapScanDescData |
59 | | { |
60 | | TableScanDescData rs_base; /* AM independent part of the descriptor */ |
61 | | |
62 | | /* state set up at initscan time */ |
63 | | BlockNumber rs_nblocks; /* total number of blocks in rel */ |
64 | | BlockNumber rs_startblock; /* block # to start at */ |
65 | | BlockNumber rs_numblocks; /* max number of blocks to scan */ |
66 | | /* rs_numblocks is usually InvalidBlockNumber, meaning "scan whole rel" */ |
67 | | |
68 | | /* scan current state */ |
69 | | bool rs_inited; /* false = scan not init'd yet */ |
70 | | OffsetNumber rs_coffset; /* current offset # in non-page-at-a-time mode */ |
71 | | BlockNumber rs_cblock; /* current block # in scan, if any */ |
72 | | Buffer rs_cbuf; /* current buffer in scan, if any */ |
73 | | /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ |
74 | | |
75 | | BufferAccessStrategy rs_strategy; /* access strategy for reads */ |
76 | | |
77 | | HeapTupleData rs_ctup; /* current tuple in scan, if any */ |
78 | | |
79 | | /* For scans that stream reads */ |
80 | | ReadStream *rs_read_stream; |
81 | | |
82 | | /* |
83 | | * For sequential scans and TID range scans to stream reads. The read |
84 | | * stream is allocated at the beginning of the scan and reset on rescan or |
85 | | * when the scan direction changes. The scan direction is saved each time |
86 | | * a new page is requested. If the scan direction changes from one page to |
87 | | * the next, the read stream releases all previously pinned buffers and |
88 | | * resets the prefetch block. |
89 | | */ |
90 | | ScanDirection rs_dir; |
91 | | BlockNumber rs_prefetch_block; |
92 | | |
93 | | /* |
94 | | * For parallel scans to store page allocation data. NULL when not |
95 | | * performing a parallel scan. |
96 | | */ |
97 | | ParallelBlockTableScanWorkerData *rs_parallelworkerdata; |
98 | | |
99 | | /* Current heap block's corresponding page in the visibility map */ |
100 | | Buffer rs_vmbuffer; |
101 | | |
102 | | /* these fields only used in page-at-a-time mode and for bitmap scans */ |
103 | | uint32 rs_cindex; /* current tuple's index in vistuples */ |
104 | | uint32 rs_ntuples; /* number of visible tuples on page */ |
105 | | OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]; /* their offsets */ |
106 | | } HeapScanDescData; |
107 | | typedef struct HeapScanDescData *HeapScanDesc; |
108 | | |
109 | | typedef struct BitmapHeapScanDescData |
110 | | { |
111 | | HeapScanDescData rs_heap_base; |
112 | | |
113 | | /* Holds no data */ |
114 | | } BitmapHeapScanDescData; |
115 | | typedef struct BitmapHeapScanDescData *BitmapHeapScanDesc; |
116 | | |
117 | | /* |
118 | | * heapam-specific IndexScanDescData opaque state |
119 | | */ |
120 | | typedef struct IndexScanHeapData |
121 | | { |
122 | | /* |
123 | | * Current heap buffer in scan (and its block number), if any. NB: if |
124 | | * xs_blk is not InvalidBlockNumber, we hold a pin in xs_cbuf. |
125 | | */ |
126 | | Buffer xs_cbuf; |
127 | | BlockNumber xs_blk; |
128 | | |
129 | | Buffer xs_vmbuffer; /* visibility map buffer */ |
130 | | |
131 | | bool xs_readonly; /* scan is read-only? */ |
132 | | |
133 | | uint16 xs_blkswitch_count; /* number of heap blocks fetched */ |
134 | | } IndexScanHeapData; |
135 | | |
136 | | /* Result codes for HeapTupleSatisfiesVacuum */ |
137 | | typedef enum |
138 | | { |
139 | | HEAPTUPLE_DEAD, /* tuple is dead and deletable */ |
140 | | HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */ |
141 | | HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */ |
142 | | HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */ |
143 | | HEAPTUPLE_DELETE_IN_PROGRESS, /* deleting xact is still in progress */ |
144 | | } HTSV_Result; |
145 | | |
146 | | /* |
147 | | * heap_prepare_freeze_tuple may request that heap_freeze_execute_prepared |
148 | | * check any tuple's to-be-frozen xmin and/or xmax status using pg_xact |
149 | | */ |
150 | 0 | #define HEAP_FREEZE_CHECK_XMIN_COMMITTED 0x01 |
151 | 0 | #define HEAP_FREEZE_CHECK_XMAX_ABORTED 0x02 |
152 | | |
153 | | /* heap_prepare_freeze_tuple state describing how to freeze a tuple */ |
154 | | typedef struct HeapTupleFreeze |
155 | | { |
156 | | /* Fields describing how to process tuple */ |
157 | | TransactionId xmax; |
158 | | uint16 t_infomask2; |
159 | | uint16 t_infomask; |
160 | | uint8 frzflags; |
161 | | |
162 | | /* xmin/xmax check flags */ |
163 | | uint8 checkflags; |
164 | | /* Page offset number for tuple */ |
165 | | OffsetNumber offset; |
166 | | } HeapTupleFreeze; |
167 | | |
168 | | /* |
169 | | * State used by VACUUM to track the details of freezing all eligible tuples |
170 | | * on a given heap page. |
171 | | * |
172 | | * VACUUM prepares freeze plans for each page via heap_prepare_freeze_tuple |
173 | | * calls (every tuple with storage gets its own call). This page-level freeze |
174 | | * state is updated across each call, which ultimately determines whether or |
175 | | * not freezing the page is required. |
176 | | * |
177 | | * Aside from the basic question of whether or not freezing will go ahead, the |
178 | | * state also tracks the oldest extant XID/MXID in the table as a whole, for |
179 | | * the purposes of advancing relfrozenxid/relminmxid values in pg_class later |
180 | | * on. Each heap_prepare_freeze_tuple call pushes NewRelfrozenXid and/or |
181 | | * NewRelminMxid back as required to avoid unsafe final pg_class values. Any |
182 | | * and all unfrozen XIDs or MXIDs that remain after VACUUM finishes _must_ |
183 | | * have values >= the final relfrozenxid/relminmxid values in pg_class. This |
184 | | * includes XIDs that remain as MultiXact members from any tuple's xmax. |
185 | | * |
186 | | * When 'freeze_required' flag isn't set after all tuples are examined, the |
187 | | * final choice on freezing is made by vacuumlazy.c. It can decide to trigger |
188 | | * freezing based on whatever criteria it deems appropriate. However, it is |
189 | | * recommended that vacuumlazy.c avoid early freezing when freezing does not |
190 | | * enable setting the target page all-frozen in the visibility map afterwards. |
191 | | */ |
192 | | typedef struct HeapPageFreeze |
193 | | { |
194 | | /* Is heap_prepare_freeze_tuple caller required to freeze page? */ |
195 | | bool freeze_required; |
196 | | |
197 | | /* |
198 | | * "Freeze" NewRelfrozenXid/NewRelminMxid trackers. |
199 | | * |
200 | | * Trackers used when heap_freeze_execute_prepared freezes, or when there |
201 | | * are zero freeze plans for a page. It is always valid for vacuumlazy.c |
202 | | * to freeze any page, by definition. This even includes pages that have |
203 | | * no tuples with storage to consider in the first place. That way the |
204 | | * 'totally_frozen' results from heap_prepare_freeze_tuple can always be |
205 | | * used in the same way, even when no freeze plans need to be executed to |
206 | | * "freeze the page". Only the "freeze" path needs to consider the need |
207 | | * to set pages all-frozen in the visibility map under this scheme. |
208 | | * |
209 | | * When we freeze a page, we generally freeze all XIDs < OldestXmin, only |
210 | | * leaving behind XIDs that are ineligible for freezing, if any. And so |
211 | | * you might wonder why these trackers are necessary at all; why should |
212 | | * _any_ page that VACUUM freezes _ever_ be left with XIDs/MXIDs that |
213 | | * ratchet back the top-level NewRelfrozenXid/NewRelminMxid trackers? |
214 | | * |
215 | | * It is useful to use a definition of "freeze the page" that does not |
216 | | * overspecify how MultiXacts are affected. heap_prepare_freeze_tuple |
217 | | * generally prefers to remove Multis eagerly, but lazy processing is used |
218 | | * in cases where laziness allows VACUUM to avoid allocating a new Multi. |
219 | | * The "freeze the page" trackers enable this flexibility. |
220 | | */ |
221 | | TransactionId FreezePageRelfrozenXid; |
222 | | MultiXactId FreezePageRelminMxid; |
223 | | |
224 | | /* |
225 | | * Newest XID that this page's freeze actions will remove from tuple |
226 | | * visibility metadata (currently xmin and/or xvac). It is used to derive |
227 | | * the snapshot conflict horizon for a WAL record that freezes tuples. On |
228 | | * a standby, we must not replay that change while any snapshot could |
229 | | * still treat that XID as running. |
230 | | * |
231 | | * It's only used if we execute freeze plans for this page, so there is no |
232 | | * corresponding "no freeze" tracker. |
233 | | */ |
234 | | TransactionId FreezePageConflictXid; |
235 | | |
236 | | /* |
237 | | * "No freeze" NewRelfrozenXid/NewRelminMxid trackers. |
238 | | * |
239 | | * These trackers are maintained in the same way as the trackers used when |
240 | | * VACUUM scans a page that isn't cleanup locked. Both code paths are |
241 | | * based on the same general idea (do less work for this page during the |
242 | | * ongoing VACUUM, at the cost of having to accept older final values). |
243 | | */ |
244 | | TransactionId NoFreezePageRelfrozenXid; |
245 | | MultiXactId NoFreezePageRelminMxid; |
246 | | |
247 | | } HeapPageFreeze; |
248 | | |
249 | | |
250 | | /* 'reason' codes for heap_page_prune_and_freeze() */ |
251 | | typedef enum |
252 | | { |
253 | | PRUNE_ON_ACCESS, /* on-access pruning */ |
254 | | PRUNE_VACUUM_SCAN, /* VACUUM 1st heap pass */ |
255 | | PRUNE_VACUUM_CLEANUP, /* VACUUM 2nd heap pass */ |
256 | | } PruneReason; |
257 | | |
258 | | /* |
259 | | * Input parameters to heap_page_prune_and_freeze() |
260 | | */ |
261 | | typedef struct PruneFreezeParams |
262 | | { |
263 | | Relation relation; /* relation containing buffer to be pruned */ |
264 | | Buffer buffer; /* buffer to be pruned */ |
265 | | |
266 | | /* |
267 | | * Callers should provide a pinned vmbuffer corresponding to the heap |
268 | | * block in buffer. We will check for and repair any corruption in the VM |
269 | | * and set the VM after pruning if the page is all-visible/all-frozen. |
270 | | */ |
271 | | Buffer vmbuffer; |
272 | | |
273 | | /* |
274 | | * The reason pruning was performed. It is used to set the WAL record |
275 | | * opcode which is used for debugging and analysis purposes. |
276 | | */ |
277 | | PruneReason reason; |
278 | | |
279 | | /* |
280 | | * Contains flag bits: |
281 | | * |
282 | | * HEAP_PAGE_PRUNE_MARK_UNUSED_NOW indicates that dead items can be set |
283 | | * LP_UNUSED during pruning. |
284 | | * |
285 | | * HEAP_PAGE_PRUNE_FREEZE indicates that we will also freeze tuples. |
286 | | */ |
287 | | int options; |
288 | | |
289 | | /* |
290 | | * vistest is used to distinguish whether tuples are DEAD or RECENTLY_DEAD |
291 | | * (see heap_prune_satisfies_vacuum). |
292 | | */ |
293 | | GlobalVisState *vistest; |
294 | | |
295 | | /* |
296 | | * Contains the cutoffs used for freezing. They are required if the |
297 | | * HEAP_PAGE_PRUNE_FREEZE option is set. cutoffs->OldestXmin is also used |
298 | | * to determine if dead tuples are HEAPTUPLE_RECENTLY_DEAD or |
299 | | * HEAPTUPLE_DEAD. Currently only vacuum passes in cutoffs. Vacuum |
300 | | * calculates them once, at the beginning of vacuuming the relation. |
301 | | */ |
302 | | VacuumCutoffs *cutoffs; |
303 | | } PruneFreezeParams; |
304 | | |
305 | | /* |
306 | | * Per-page state returned by heap_page_prune_and_freeze() |
307 | | */ |
308 | | typedef struct PruneFreezeResult |
309 | | { |
310 | | int ndeleted; /* Number of tuples deleted from the page */ |
311 | | int nnewlpdead; /* Number of newly LP_DEAD items */ |
312 | | int nfrozen; /* Number of tuples we froze */ |
313 | | |
314 | | /* Number of live and recently dead tuples on the page, after pruning */ |
315 | | int live_tuples; |
316 | | int recently_dead_tuples; |
317 | | |
318 | | /* |
319 | | * Whether or not the page was newly set all-visible and all-frozen during |
320 | | * phase I of vacuuming. |
321 | | */ |
322 | | bool newly_all_visible; |
323 | | bool newly_all_visible_frozen; |
324 | | bool newly_all_frozen; |
325 | | |
326 | | /* |
327 | | * Whether or not the page makes rel truncation unsafe. This is set to |
328 | | * 'true', even if the page contains LP_DEAD items. VACUUM will remove |
329 | | * them before attempting to truncate. |
330 | | */ |
331 | | bool hastup; |
332 | | |
333 | | /* |
334 | | * LP_DEAD items on the page after pruning. Includes existing LP_DEAD |
335 | | * items. |
336 | | */ |
337 | | int lpdead_items; |
338 | | OffsetNumber deadoffsets[MaxHeapTuplesPerPage]; |
339 | | } PruneFreezeResult; |
340 | | |
341 | | |
342 | | /* ---------------- |
343 | | * function prototypes for heap access method |
344 | | * |
345 | | * heap_create, heap_create_with_catalog, and heap_drop_with_catalog |
346 | | * are declared in catalog/heap.h |
347 | | * ---------------- |
348 | | */ |
349 | | |
350 | | |
351 | | extern TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot, |
352 | | int nkeys, ScanKey key, |
353 | | ParallelTableScanDesc parallel_scan, |
354 | | uint32 flags); |
355 | | extern void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, |
356 | | BlockNumber numBlks); |
357 | | extern void heap_prepare_pagescan(TableScanDesc sscan); |
358 | | extern void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params, |
359 | | bool allow_strat, bool allow_sync, bool allow_pagemode); |
360 | | extern void heap_endscan(TableScanDesc sscan); |
361 | | extern HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction); |
362 | | extern bool heap_getnextslot(TableScanDesc sscan, |
363 | | ScanDirection direction, TupleTableSlot *slot); |
364 | | extern void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid, |
365 | | ItemPointer maxtid); |
366 | | extern bool heap_getnextslot_tidrange(TableScanDesc sscan, |
367 | | ScanDirection direction, |
368 | | TupleTableSlot *slot); |
369 | | extern bool heap_fetch(Relation relation, Snapshot snapshot, |
370 | | HeapTuple tuple, Buffer *userbuf, bool keep_buf); |
371 | | |
372 | | extern void heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid); |
373 | | |
374 | | extern BulkInsertState GetBulkInsertState(void); |
375 | | extern void FreeBulkInsertState(BulkInsertState); |
376 | | extern void ReleaseBulkInsertStatePin(BulkInsertState bistate); |
377 | | |
378 | | extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid, |
379 | | uint32 options, BulkInsertState bistate); |
380 | | extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, |
381 | | int ntuples, CommandId cid, uint32 options, |
382 | | BulkInsertState bistate); |
383 | | extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid, |
384 | | CommandId cid, uint32 options, Snapshot crosscheck, |
385 | | bool wait, TM_FailureData *tmfd); |
386 | | extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid); |
387 | | extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid); |
388 | | extern TM_Result heap_update(Relation relation, const ItemPointerData *otid, |
389 | | HeapTuple newtup, |
390 | | CommandId cid, uint32 options, |
391 | | Snapshot crosscheck, bool wait, |
392 | | TM_FailureData *tmfd, LockTupleMode *lockmode, |
393 | | TU_UpdateIndexes *update_indexes); |
394 | | extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, |
395 | | CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, |
396 | | bool follow_updates, |
397 | | Buffer *buffer, TM_FailureData *tmfd); |
398 | | |
399 | | extern bool heap_inplace_lock(Relation relation, |
400 | | HeapTuple oldtup_ptr, Buffer buffer, |
401 | | void (*release_callback) (void *), void *arg); |
402 | | extern void heap_inplace_update_and_unlock(Relation relation, |
403 | | HeapTuple oldtup, HeapTuple tuple, |
404 | | Buffer buffer); |
405 | | extern void heap_inplace_unlock(Relation relation, |
406 | | HeapTuple oldtup, Buffer buffer); |
407 | | extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, |
408 | | const VacuumCutoffs *cutoffs, |
409 | | HeapPageFreeze *pagefrz, |
410 | | HeapTupleFreeze *frz, bool *totally_frozen); |
411 | | |
412 | | extern void heap_pre_freeze_checks(Buffer buffer, |
413 | | HeapTupleFreeze *tuples, int ntuples); |
414 | | extern void heap_freeze_prepared_tuples(Buffer buffer, |
415 | | HeapTupleFreeze *tuples, int ntuples); |
416 | | extern bool heap_freeze_tuple(HeapTupleHeader tuple, |
417 | | TransactionId relfrozenxid, TransactionId relminmxid, |
418 | | TransactionId FreezeLimit, TransactionId MultiXactCutoff); |
419 | | extern bool heap_tuple_should_freeze(HeapTupleHeader tuple, |
420 | | const VacuumCutoffs *cutoffs, |
421 | | TransactionId *NoFreezePageRelfrozenXid, |
422 | | MultiXactId *NoFreezePageRelminMxid); |
423 | | extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple); |
424 | | |
425 | | extern void simple_heap_insert(Relation relation, HeapTuple tup); |
426 | | extern void simple_heap_delete(Relation relation, const ItemPointerData *tid); |
427 | | extern void simple_heap_update(Relation relation, const ItemPointerData *otid, |
428 | | HeapTuple tup, TU_UpdateIndexes *update_indexes); |
429 | | |
430 | | extern TransactionId heap_index_delete_tuples(Relation rel, |
431 | | TM_IndexDeleteOp *delstate); |
432 | | |
433 | | /* in heap/heapam_indexscan.c */ |
434 | | extern bool heapam_fetch_tid(Relation rel, ItemPointer tid, Snapshot snapshot, |
435 | | bool *all_dead); |
436 | | extern void heapam_index_scan_begin(IndexScanDesc scan, uint32 flags); |
437 | | extern void heapam_index_scan_reset(IndexScanDesc scan); |
438 | | extern void heapam_index_scan_end(IndexScanDesc scan); |
439 | | extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation, |
440 | | Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, |
441 | | bool *all_dead, bool first_call); |
442 | | |
443 | | /* in heap/pruneheap.c */ |
444 | | extern void heap_page_prune_opt(Relation relation, Buffer buffer, |
445 | | Buffer *vmbuffer, bool rel_read_only); |
446 | | extern void heap_page_prune_and_freeze(PruneFreezeParams *params, |
447 | | PruneFreezeResult *presult, |
448 | | OffsetNumber *off_loc, |
449 | | TransactionId *new_relfrozen_xid, |
450 | | MultiXactId *new_relmin_mxid); |
451 | | extern void heap_page_prune_execute(Buffer buffer, bool lp_truncate_only, |
452 | | OffsetNumber *redirected, int nredirected, |
453 | | OffsetNumber *nowdead, int ndead, |
454 | | OffsetNumber *nowunused, int nunused); |
455 | | extern void heap_get_root_tuples(Page page, OffsetNumber *root_offsets); |
456 | | extern void log_heap_prune_and_freeze(Relation relation, Buffer buffer, |
457 | | Buffer vmbuffer, uint8 vmflags, |
458 | | TransactionId conflict_xid, |
459 | | bool cleanup_lock, |
460 | | PruneReason reason, |
461 | | HeapTupleFreeze *frozen, int nfrozen, |
462 | | OffsetNumber *redirected, int nredirected, |
463 | | OffsetNumber *dead, int ndead, |
464 | | OffsetNumber *unused, int nunused); |
465 | | |
466 | | /* in heap/vacuumlazy.c */ |
467 | | extern void heap_vacuum_rel(Relation rel, |
468 | | const VacuumParams *params, BufferAccessStrategy bstrategy); |
469 | | #ifdef USE_ASSERT_CHECKING |
470 | | extern bool heap_page_is_all_visible(Relation rel, Buffer buf, |
471 | | GlobalVisState *vistest, |
472 | | bool *all_frozen, |
473 | | TransactionId *newest_live_xid, |
474 | | OffsetNumber *logging_offnum); |
475 | | #endif |
476 | | |
477 | | /* in heap/heapam_visibility.c */ |
478 | | extern bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, |
479 | | Buffer buffer); |
480 | | extern TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, |
481 | | Buffer buffer); |
482 | | extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, |
483 | | Buffer buffer); |
484 | | extern HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, |
485 | | TransactionId *dead_after); |
486 | | extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, |
487 | | uint16 infomask, TransactionId xid); |
488 | | extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple); |
489 | | extern bool HeapTupleIsSurelyDead(HeapTuple htup, |
490 | | GlobalVisState *vistest); |
491 | | |
492 | | /* |
493 | | * Some of the input/output to/from HeapTupleSatisfiesMVCCBatch() is passed |
494 | | * via this struct, as otherwise the increased number of arguments to |
495 | | * HeapTupleSatisfiesMVCCBatch() leads to on-stack argument passing on x86-64, |
496 | | * which causes a small regression. |
497 | | */ |
498 | | typedef struct BatchMVCCState |
499 | | { |
500 | | HeapTupleData tuples[MaxHeapTuplesPerPage]; |
501 | | bool visible[MaxHeapTuplesPerPage]; |
502 | | } BatchMVCCState; |
503 | | |
504 | | extern int HeapTupleSatisfiesMVCCBatch(Snapshot snapshot, Buffer buffer, |
505 | | int ntups, |
506 | | BatchMVCCState *batchmvcc, |
507 | | OffsetNumber *vistuples_dense); |
508 | | |
509 | | /* |
510 | | * To avoid leaking too much knowledge about reorderbuffer implementation |
511 | | * details this is implemented in reorderbuffer.c not heapam_visibility.c |
512 | | */ |
513 | | struct HTAB; |
514 | | extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data, |
515 | | Snapshot snapshot, |
516 | | HeapTuple htup, |
517 | | Buffer buffer, |
518 | | CommandId *cmin, CommandId *cmax); |
519 | | extern void HeapCheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple, |
520 | | Buffer buffer, Snapshot snapshot); |
521 | | |
522 | | /* |
523 | | * heap_execute_freeze_tuple |
524 | | * Execute the prepared freezing of a tuple with caller's freeze plan. |
525 | | * |
526 | | * Caller is responsible for ensuring that no other backend can access the |
527 | | * storage underlying this tuple, either by holding an exclusive lock on the |
528 | | * buffer containing it (which is what lazy VACUUM does), or by having it be |
529 | | * in private storage (which is what CLUSTER and friends do). |
530 | | */ |
531 | | static inline void |
532 | | heap_execute_freeze_tuple(HeapTupleHeader tuple, HeapTupleFreeze *frz) |
533 | 0 | { |
534 | 0 | HeapTupleHeaderSetXmax(tuple, frz->xmax); |
535 | |
|
536 | 0 | if (frz->frzflags & XLH_FREEZE_XVAC) |
537 | 0 | HeapTupleHeaderSetXvac(tuple, FrozenTransactionId); |
538 | |
|
539 | 0 | if (frz->frzflags & XLH_INVALID_XVAC) |
540 | 0 | HeapTupleHeaderSetXvac(tuple, InvalidTransactionId); |
541 | |
|
542 | 0 | tuple->t_infomask = frz->t_infomask; |
543 | 0 | tuple->t_infomask2 = frz->t_infomask2; |
544 | 0 | } Unexecuted instantiation: toast_internals.c:heap_execute_freeze_tuple Unexecuted instantiation: heapam.c:heap_execute_freeze_tuple Unexecuted instantiation: heapam_handler.c:heap_execute_freeze_tuple Unexecuted instantiation: heapam_indexscan.c:heap_execute_freeze_tuple Unexecuted instantiation: heapam_visibility.c:heap_execute_freeze_tuple Unexecuted instantiation: heapam_xlog.c:heap_execute_freeze_tuple Unexecuted instantiation: heaptoast.c:heap_execute_freeze_tuple Unexecuted instantiation: hio.c:heap_execute_freeze_tuple Unexecuted instantiation: pruneheap.c:heap_execute_freeze_tuple Unexecuted instantiation: rewriteheap.c:heap_execute_freeze_tuple Unexecuted instantiation: vacuumlazy.c:heap_execute_freeze_tuple Unexecuted instantiation: genam.c:heap_execute_freeze_tuple Unexecuted instantiation: bootstrap.c:heap_execute_freeze_tuple Unexecuted instantiation: aclchk.c:heap_execute_freeze_tuple Unexecuted instantiation: index.c:heap_execute_freeze_tuple Unexecuted instantiation: indexing.c:heap_execute_freeze_tuple Unexecuted instantiation: pg_db_role_setting.c:heap_execute_freeze_tuple Unexecuted instantiation: pg_publication.c:heap_execute_freeze_tuple Unexecuted instantiation: pg_subscription.c:heap_execute_freeze_tuple Unexecuted instantiation: toasting.c:heap_execute_freeze_tuple Unexecuted instantiation: copyfrom.c:heap_execute_freeze_tuple Unexecuted instantiation: createas.c:heap_execute_freeze_tuple Unexecuted instantiation: dbcommands.c:heap_execute_freeze_tuple Unexecuted instantiation: event_trigger.c:heap_execute_freeze_tuple Unexecuted instantiation: indexcmds.c:heap_execute_freeze_tuple Unexecuted instantiation: matview.c:heap_execute_freeze_tuple Unexecuted instantiation: repack.c:heap_execute_freeze_tuple Unexecuted instantiation: tablecmds.c:heap_execute_freeze_tuple Unexecuted instantiation: tablespace.c:heap_execute_freeze_tuple Unexecuted instantiation: vacuum.c:heap_execute_freeze_tuple Unexecuted instantiation: execReplication.c:heap_execute_freeze_tuple Unexecuted instantiation: autovacuum.c:heap_execute_freeze_tuple Unexecuted instantiation: datachecksum_state.c:heap_execute_freeze_tuple Unexecuted instantiation: launcher.c:heap_execute_freeze_tuple Unexecuted instantiation: reorderbuffer.c:heap_execute_freeze_tuple Unexecuted instantiation: attribute_stats.c:heap_execute_freeze_tuple Unexecuted instantiation: extended_stats_funcs.c:heap_execute_freeze_tuple Unexecuted instantiation: relation_stats.c:heap_execute_freeze_tuple Unexecuted instantiation: postinit.c:heap_execute_freeze_tuple |
545 | | |
546 | | #endif /* HEAPAM_H */ |