codekingpro/portable-devtools
114k
1/*-------------------------------------------------------------------------2 *3 * heapam.h4 * POSTGRES heap access method definitions.5 *6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 * Portions Copyright (c) 1994, Regents of the University of California9 *10 * src/include/access/heapam.h11 *12 *-------------------------------------------------------------------------13 */14#ifndef HEAPAM_H15#define HEAPAM_H16 17#include "access/relation.h" /* for backward compatibility */18#include "access/relscan.h"19#include "access/sdir.h"20#include "access/skey.h"21#include "access/table.h" /* for backward compatibility */22#include "access/tableam.h"23#include "nodes/lockoptions.h"24#include "nodes/primnodes.h"25#include "storage/bufpage.h"26#include "storage/dsm.h"27#include "storage/lockdefs.h"28#include "storage/shm_toc.h"29#include "utils/relcache.h"30#include "utils/snapshot.h"31 32 33/* "options" flag bits for heap_insert */34#define HEAP_INSERT_SKIP_FSM TABLE_INSERT_SKIP_FSM35#define HEAP_INSERT_FROZEN TABLE_INSERT_FROZEN36#define HEAP_INSERT_NO_LOGICAL TABLE_INSERT_NO_LOGICAL37#define HEAP_INSERT_SPECULATIVE 0x001038 39typedef struct BulkInsertStateData *BulkInsertState;40struct TupleTableSlot;41struct VacuumCutoffs;42 43#define MaxLockTupleMode LockTupleExclusive44 45/*46 * Descriptor for heap table scans.47 */48typedef struct HeapScanDescData49{50 TableScanDescData rs_base; /* AM independent part of the descriptor */51 52 /* state set up at initscan time */53 BlockNumber rs_nblocks; /* total number of blocks in rel */54 BlockNumber rs_startblock; /* block # to start at */55 BlockNumber rs_numblocks; /* max number of blocks to scan */56 /* rs_numblocks is usually InvalidBlockNumber, meaning "scan whole rel" */57 58 /* scan current state */59 bool rs_inited; /* false = scan not init'd yet */60 OffsetNumber rs_coffset; /* current offset # in non-page-at-a-time mode */61 BlockNumber rs_cblock; /* current block # in scan, if any */62 Buffer rs_cbuf; /* current buffer in scan, if any */63 /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */64 65 BufferAccessStrategy rs_strategy; /* access strategy for reads */66 67 HeapTupleData rs_ctup; /* current tuple in scan, if any */68 69 /*70 * For parallel scans to store page allocation data. NULL when not71 * performing a parallel scan.72 */73 ParallelBlockTableScanWorkerData *rs_parallelworkerdata;74 75 /* these fields only used in page-at-a-time mode and for bitmap scans */76 int rs_cindex; /* current tuple's index in vistuples */77 int rs_ntuples; /* number of visible tuples on page */78 OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]; /* their offsets */79} HeapScanDescData;80typedef struct HeapScanDescData *HeapScanDesc;81 82/*83 * Descriptor for fetches from heap via an index.84 */85typedef struct IndexFetchHeapData86{87 IndexFetchTableData xs_base; /* AM independent part of the descriptor */88 89 Buffer xs_cbuf; /* current heap buffer in scan, if any */90 /* NB: if xs_cbuf is not InvalidBuffer, we hold a pin on that buffer */91} IndexFetchHeapData;92 93/* Result codes for HeapTupleSatisfiesVacuum */94typedef enum95{96 HEAPTUPLE_DEAD, /* tuple is dead and deletable */97 HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */98 HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */99 HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */100 HEAPTUPLE_DELETE_IN_PROGRESS /* deleting xact is still in progress */101} HTSV_Result;102 103/*104 * heap_prepare_freeze_tuple may request that heap_freeze_execute_prepared105 * check any tuple's to-be-frozen xmin and/or xmax status using pg_xact106 */107#define HEAP_FREEZE_CHECK_XMIN_COMMITTED 0x01108#define HEAP_FREEZE_CHECK_XMAX_ABORTED 0x02109 110/* heap_prepare_freeze_tuple state describing how to freeze a tuple */111typedef struct HeapTupleFreeze112{113 /* Fields describing how to process tuple */114 TransactionId xmax;115 uint16 t_infomask2;116 uint16 t_infomask;117 uint8 frzflags;118 119 /* xmin/xmax check flags */120 uint8 checkflags;121 /* Page offset number for tuple */122 OffsetNumber offset;123} HeapTupleFreeze;124 125/*126 * State used by VACUUM to track the details of freezing all eligible tuples127 * on a given heap page.128 *129 * VACUUM prepares freeze plans for each page via heap_prepare_freeze_tuple130 * calls (every tuple with storage gets its own call). This page-level freeze131 * state is updated across each call, which ultimately determines whether or132 * not freezing the page is required.133 *134 * Aside from the basic question of whether or not freezing will go ahead, the135 * state also tracks the oldest extant XID/MXID in the table as a whole, for136 * the purposes of advancing relfrozenxid/relminmxid values in pg_class later137 * on. Each heap_prepare_freeze_tuple call pushes NewRelfrozenXid and/or138 * NewRelminMxid back as required to avoid unsafe final pg_class values. Any139 * and all unfrozen XIDs or MXIDs that remain after VACUUM finishes _must_140 * have values >= the final relfrozenxid/relminmxid values in pg_class. This141 * includes XIDs that remain as MultiXact members from any tuple's xmax.142 *143 * When 'freeze_required' flag isn't set after all tuples are examined, the144 * final choice on freezing is made by vacuumlazy.c. It can decide to trigger145 * freezing based on whatever criteria it deems appropriate. However, it is146 * recommended that vacuumlazy.c avoid early freezing when freezing does not147 * enable setting the target page all-frozen in the visibility map afterwards.148 */149typedef struct HeapPageFreeze150{151 /* Is heap_prepare_freeze_tuple caller required to freeze page? */152 bool freeze_required;153 154 /*155 * "Freeze" NewRelfrozenXid/NewRelminMxid trackers.156 *157 * Trackers used when heap_freeze_execute_prepared freezes, or when there158 * are zero freeze plans for a page. It is always valid for vacuumlazy.c159 * to freeze any page, by definition. This even includes pages that have160 * no tuples with storage to consider in the first place. That way the161 * 'totally_frozen' results from heap_prepare_freeze_tuple can always be162 * used in the same way, even when no freeze plans need to be executed to163 * "freeze the page". Only the "freeze" path needs to consider the need164 * to set pages all-frozen in the visibility map under this scheme.165 *166 * When we freeze a page, we generally freeze all XIDs < OldestXmin, only167 * leaving behind XIDs that are ineligible for freezing, if any. And so168 * you might wonder why these trackers are necessary at all; why should169 * _any_ page that VACUUM freezes _ever_ be left with XIDs/MXIDs that170 * ratchet back the top-level NewRelfrozenXid/NewRelminMxid trackers?171 *172 * It is useful to use a definition of "freeze the page" that does not173 * overspecify how MultiXacts are affected. heap_prepare_freeze_tuple174 * generally prefers to remove Multis eagerly, but lazy processing is used175 * in cases where laziness allows VACUUM to avoid allocating a new Multi.176 * The "freeze the page" trackers enable this flexibility.177 */178 TransactionId FreezePageRelfrozenXid;179 MultiXactId FreezePageRelminMxid;180 181 /*182 * "No freeze" NewRelfrozenXid/NewRelminMxid trackers.183 *184 * These trackers are maintained in the same way as the trackers used when185 * VACUUM scans a page that isn't cleanup locked. Both code paths are186 * based on the same general idea (do less work for this page during the187 * ongoing VACUUM, at the cost of having to accept older final values).188 */189 TransactionId NoFreezePageRelfrozenXid;190 MultiXactId NoFreezePageRelminMxid;191 192} HeapPageFreeze;193 194/* ----------------195 * function prototypes for heap access method196 *197 * heap_create, heap_create_with_catalog, and heap_drop_with_catalog198 * are declared in catalog/heap.h199 * ----------------200 */201 202 203/*204 * HeapScanIsValid205 * True iff the heap scan is valid.206 */207#define HeapScanIsValid(scan) PointerIsValid(scan)208 209extern TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot,210 int nkeys, ScanKey key,211 ParallelTableScanDesc parallel_scan,212 uint32 flags);213extern void heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk,214 BlockNumber numBlks);215extern void heapgetpage(TableScanDesc sscan, BlockNumber block);216extern void heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,217 bool allow_strat, bool allow_sync, bool allow_pagemode);218extern void heap_endscan(TableScanDesc sscan);219extern HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction);220extern bool heap_getnextslot(TableScanDesc sscan,221 ScanDirection direction, struct TupleTableSlot *slot);222extern void heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid,223 ItemPointer maxtid);224extern bool heap_getnextslot_tidrange(TableScanDesc sscan,225 ScanDirection direction,226 TupleTableSlot *slot);227extern bool heap_fetch(Relation relation, Snapshot snapshot,228 HeapTuple tuple, Buffer *userbuf, bool keep_buf);229extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation,230 Buffer buffer, Snapshot snapshot, HeapTuple heapTuple,231 bool *all_dead, bool first_call);232 233extern void heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid);234 235extern BulkInsertState GetBulkInsertState(void);236extern void FreeBulkInsertState(BulkInsertState);237extern void ReleaseBulkInsertStatePin(BulkInsertState bistate);238 239extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid,240 int options, BulkInsertState bistate);241extern void heap_multi_insert(Relation relation, struct TupleTableSlot **slots,242 int ntuples, CommandId cid, int options,243 BulkInsertState bistate);244extern TM_Result heap_delete(Relation relation, ItemPointer tid,245 CommandId cid, Snapshot crosscheck, bool wait,246 struct TM_FailureData *tmfd, bool changingPart);247extern void heap_finish_speculative(Relation relation, ItemPointer tid);248extern void heap_abort_speculative(Relation relation, ItemPointer tid);249extern TM_Result heap_update(Relation relation, ItemPointer otid,250 HeapTuple newtup,251 CommandId cid, Snapshot crosscheck, bool wait,252 struct TM_FailureData *tmfd, LockTupleMode *lockmode,253 TU_UpdateIndexes *update_indexes);254extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple,255 CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy,256 bool follow_updates,257 Buffer *buffer, struct TM_FailureData *tmfd);258 259extern void heap_inplace_update(Relation relation, HeapTuple tuple);260extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple,261 const struct VacuumCutoffs *cutoffs,262 HeapPageFreeze *pagefrz,263 HeapTupleFreeze *frz, bool *totally_frozen);264extern void heap_freeze_execute_prepared(Relation rel, Buffer buffer,265 TransactionId snapshotConflictHorizon,266 HeapTupleFreeze *tuples, int ntuples);267extern bool heap_freeze_tuple(HeapTupleHeader tuple,268 TransactionId relfrozenxid, TransactionId relminmxid,269 TransactionId FreezeLimit, TransactionId MultiXactCutoff);270extern bool heap_tuple_should_freeze(HeapTupleHeader tuple,271 const struct VacuumCutoffs *cutoffs,272 TransactionId *NoFreezePageRelfrozenXid,273 MultiXactId *NoFreezePageRelminMxid);274extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple);275 276extern void simple_heap_insert(Relation relation, HeapTuple tup);277extern void simple_heap_delete(Relation relation, ItemPointer tid);278extern void simple_heap_update(Relation relation, ItemPointer otid,279 HeapTuple tup, TU_UpdateIndexes *update_indexes);280 281extern TransactionId heap_index_delete_tuples(Relation rel,282 TM_IndexDeleteOp *delstate);283 284/* in heap/pruneheap.c */285struct GlobalVisState;286extern void heap_page_prune_opt(Relation relation, Buffer buffer);287extern int heap_page_prune(Relation relation, Buffer buffer,288 struct GlobalVisState *vistest,289 TransactionId old_snap_xmin,290 TimestampTz old_snap_ts,291 int *nnewlpdead,292 OffsetNumber *off_loc);293extern void heap_page_prune_execute(Buffer buffer,294 OffsetNumber *redirected, int nredirected,295 OffsetNumber *nowdead, int ndead,296 OffsetNumber *nowunused, int nunused);297extern void heap_get_root_tuples(Page page, OffsetNumber *root_offsets);298 299/* in heap/vacuumlazy.c */300struct VacuumParams;301extern void heap_vacuum_rel(Relation rel,302 struct VacuumParams *params, BufferAccessStrategy bstrategy);303 304/* in heap/heapam_visibility.c */305extern bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot,306 Buffer buffer);307extern TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,308 Buffer buffer);309extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,310 Buffer buffer);311extern HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer,312 TransactionId *dead_after);313extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,314 uint16 infomask, TransactionId xid);315extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple);316extern bool HeapTupleIsSurelyDead(HeapTuple htup,317 struct GlobalVisState *vistest);318 319/*320 * To avoid leaking too much knowledge about reorderbuffer implementation321 * details this is implemented in reorderbuffer.c not heapam_visibility.c322 */323struct HTAB;324extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data,325 Snapshot snapshot,326 HeapTuple htup,327 Buffer buffer,328 CommandId *cmin, CommandId *cmax);329extern void HeapCheckForSerializableConflictOut(bool visible, Relation relation, HeapTuple tuple,330 Buffer buffer, Snapshot snapshot);331 332#endif /* HEAPAM_H */333 