213 prune_xid = ((
PageHeader) page)->pd_prune_xid;
240 minfree =
Max(minfree, BLCKSZ / 10);
397 Assert(new_relfrozen_xid && new_relmin_mxid);
405 Assert(new_relfrozen_xid == NULL && new_relmin_mxid == NULL);
490 for (offnum = maxoff;
504 prstate.
htsv[offnum] = -1;
632 elog(
ERROR,
"dead heap-only tuple (%u, %d) is not linked to from any HOT chain",
641 #ifdef USE_ASSERT_CHECKING
774 if (!do_freeze && !do_prune)
778 if (do_prune || do_freeze)
831 conflict_xid = frz_conflict_horizon;
1012 if (offnum > maxoff)
1038 chainitems[nchain++] = offnum;
1057 chainitems[nchain++] = offnum;
1064 ndeadchain = nchain;
1096 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
1134 if (ndeadchain == 0)
1147 for (;
i < nchain;
i++)
1150 else if (ndeadchain == nchain)
1157 for (
int i = 1;
i < nchain;
i++)
1169 for (
int i = 1;
i < ndeadchain;
i++)
1173 for (
int i = ndeadchain;
i < nchain;
i++)
1340 switch (prstate->
htsv[offnum])
1452 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result %d",
1453 prstate->
htsv[offnum]);
1460 bool totally_frozen;
1477 if (!totally_frozen)
1550 Assert(nredirected > 0 || ndead > 0 || nunused > 0);
1553 Assert(!lp_truncate_only || (nredirected == 0 && ndead == 0));
1556 offnum = redirected;
1557 for (
int i = 0;
i < nredirected;
i++)
1564 #ifdef USE_ASSERT_CHECKING
1614 for (
int i = 0;
i < ndead;
i++)
1619 #ifdef USE_ASSERT_CHECKING
1646 for (
int i = 0;
i < nunused;
i++)
1651 #ifdef USE_ASSERT_CHECKING
1653 if (lp_truncate_only)
1683 if (lp_truncate_only)
1718 #ifdef USE_ASSERT_CHECKING
1800 root_offsets[offnum - 1] = offnum;
1837 if (offnum > maxoff)
1853 root_offsets[nextoffnum - 1] = offnum;
1966 for (
int i = 0;
i < ntuples;
i++)
2002 Assert(nplans > 0 && nplans <= ntuples);
2074 freeze_plans.
nplans = nplans;
2080 if (nredirected > 0)
2084 redirect_items.
ntargets = nredirected;
2126 Assert(nredirected == 0 && ndead == 0);
2145 elog(
ERROR,
"unrecognized prune reason: %d", (
int) reason);
BlockNumber BufferGetBlockNumber(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
bool ConditionalLockBufferForCleanup(Buffer buffer)
#define BUFFER_LOCK_UNLOCK
static Page BufferGetPage(Buffer buffer)
Size PageGetHeapFreeSpace(Page page)
void PageRepairFragmentation(Page page)
void PageTruncateLinePointerArray(Page page)
PageHeaderData * PageHeader
static Item PageGetItem(Page page, ItemId itemId)
static void PageClearFull(Page page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static bool PageIsFull(Page page)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
TransactionId MultiXactId
#define MemSet(start, val, len)
static void PGresult * res
void HeapTupleHeaderAdvanceConflictHorizon(HeapTupleHeader tuple, TransactionId *snapshotConflictHorizon)
void heap_freeze_prepared_tuples(Buffer buffer, HeapTupleFreeze *tuples, int ntuples)
bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, const struct VacuumCutoffs *cutoffs, HeapPageFreeze *pagefrz, HeapTupleFreeze *frz, bool *totally_frozen)
void heap_pre_freeze_checks(Buffer buffer, HeapTupleFreeze *tuples, int ntuples)
#define HEAP_PAGE_PRUNE_FREEZE
@ HEAPTUPLE_RECENTLY_DEAD
@ HEAPTUPLE_INSERT_IN_PROGRESS
@ HEAPTUPLE_DELETE_IN_PROGRESS
#define HEAP_PAGE_PRUNE_MARK_UNUSED_NOW
HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *dead_after)
#define XLHP_HAS_CONFLICT_HORIZON
#define XLHP_HAS_FREEZE_PLANS
#define XLHP_HAS_NOW_UNUSED_ITEMS
#define XLHP_HAS_REDIRECTIONS
#define XLOG_HEAP2_PRUNE_VACUUM_SCAN
#define XLOG_HEAP2_PRUNE_ON_ACCESS
#define XLHP_CLEANUP_LOCK
#define XLHP_HAS_DEAD_ITEMS
#define XLOG_HEAP2_PRUNE_VACUUM_CLEANUP
#define XLHP_IS_CATALOG_REL
HeapTupleHeaderData * HeapTupleHeader
#define HeapTupleHeaderIsHeapOnly(tup)
#define HeapTupleHeaderIndicatesMovedPartitions(tup)
#define HeapTupleHeaderGetXmin(tup)
#define HeapTupleHeaderXminCommitted(tup)
#define MaxHeapTuplesPerPage
#define HeapTupleHeaderGetUpdateXid(tup)
#define HeapTupleHeaderIsHotUpdated(tup)
#define ItemIdGetLength(itemId)
#define ItemIdSetRedirect(itemId, link)
#define ItemIdIsNormal(itemId)
#define ItemIdGetRedirect(itemId)
#define ItemIdIsDead(itemId)
#define ItemIdSetDead(itemId)
#define ItemIdIsUsed(itemId)
#define ItemIdSetUnused(itemId)
#define ItemIdIsRedirected(itemId)
#define ItemIdHasStorage(itemId)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define InvalidMultiXactId
#define InvalidOffsetNumber
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
#define OffsetNumberPrev(offsetNumber)
void pgstat_update_heap_dead_tuples(Relation rel, int delta)
#define qsort(a, b, c, d)
bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid)
GlobalVisState * GlobalVisTestFor(Relation rel)
static void heap_prune_chain(Page page, BlockNumber blockno, OffsetNumber maxoff, OffsetNumber rootoffnum, PruneState *prstate)
static void heap_prune_record_unchanged_lp_dead(Page page, PruneState *prstate, OffsetNumber offnum)
void heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
void heap_page_prune_opt(Relation relation, Buffer buffer)
void heap_page_prune_and_freeze(Relation relation, Buffer buffer, GlobalVisState *vistest, int options, struct VacuumCutoffs *cutoffs, PruneFreezeResult *presult, PruneReason reason, OffsetNumber *off_loc, TransactionId *new_relfrozen_xid, MultiXactId *new_relmin_mxid)
static HTSV_Result htsv_get_valid_status(int status)
static int heap_log_freeze_plan(HeapTupleFreeze *tuples, int ntuples, xlhp_freeze_plan *plans_out, OffsetNumber *offsets_out)
static void page_verify_redirects(Page page)
static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum, bool was_normal)
static void heap_prune_record_redirect(PruneState *prstate, OffsetNumber offnum, OffsetNumber rdoffnum, bool was_normal)
static void heap_prune_record_unchanged_lp_normal(Page page, PruneState *prstate, OffsetNumber offnum)
static int heap_log_freeze_cmp(const void *arg1, const void *arg2)
void log_heap_prune_and_freeze(Relation relation, Buffer buffer, TransactionId conflict_xid, bool cleanup_lock, PruneReason reason, HeapTupleFreeze *frozen, int nfrozen, OffsetNumber *redirected, int nredirected, OffsetNumber *dead, int ndead, OffsetNumber *unused, int nunused)
static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum, bool was_normal)
static bool heap_log_freeze_eq(xlhp_freeze_plan *plan, HeapTupleFreeze *frz)
static void heap_prune_record_prunable(PruneState *prstate, TransactionId xid)
static void heap_prune_record_unchanged_lp_unused(Page page, PruneState *prstate, OffsetNumber offnum)
static void heap_log_freeze_new_plan(xlhp_freeze_plan *plan, HeapTupleFreeze *frz)
static HTSV_Result heap_prune_satisfies_vacuum(PruneState *prstate, HeapTuple tup, Buffer buffer)
static void heap_prune_record_dead_or_unused(PruneState *prstate, OffsetNumber offnum, bool was_normal)
void heap_page_prune_execute(Buffer buffer, bool lp_truncate_only, OffsetNumber *redirected, int nredirected, OffsetNumber *nowdead, int ndead, OffsetNumber *nowunused, int nunused)
static void heap_prune_record_unchanged_lp_redirect(PruneState *prstate, OffsetNumber offnum)
#define RelationGetRelid(relation)
#define RelationGetTargetPageFreeSpace(relation, defaultff)
#define RelationIsAccessibleInLogicalDecoding(relation)
#define RelationNeedsWAL(relation)
#define HEAP_DEFAULT_FILLFACTOR
MultiXactId NoFreezePageRelminMxid
TransactionId FreezePageRelfrozenXid
MultiXactId FreezePageRelminMxid
TransactionId NoFreezePageRelfrozenXid
TransactionId vm_conflict_horizon
OffsetNumber deadoffsets[MaxHeapTuplesPerPage]
bool processed[MaxHeapTuplesPerPage+1]
OffsetNumber heaponly_items[MaxHeapTuplesPerPage]
TransactionId new_prune_xid
OffsetNumber nowdead[MaxHeapTuplesPerPage]
OffsetNumber nowunused[MaxHeapTuplesPerPage]
TransactionId visibility_cutoff_xid
struct VacuumCutoffs * cutoffs
HeapTupleFreeze frozen[MaxHeapTuplesPerPage]
OffsetNumber redirected[MaxHeapTuplesPerPage *2]
int8 htsv[MaxHeapTuplesPerPage+1]
TransactionId latest_xid_removed
OffsetNumber root_items[MaxHeapTuplesPerPage]
OffsetNumber * deadoffsets
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
#define TransactionIdRetreat(dest)
#define InvalidTransactionId
#define TransactionIdEquals(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
bool RecoveryInProgress(void)
#define XLogHintBitIsNeeded()
void XLogRegisterData(char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
bool XLogCheckBufferNeedsBackup(Buffer buffer)
void XLogRegisterBufData(uint8 block_id, char *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)