213 prune_xid = ((
PageHeader) page)->pd_prune_xid;
240 minfree =
Max(minfree, BLCKSZ / 10);
399 Assert(new_relfrozen_xid && new_relmin_mxid);
407 Assert(new_relfrozen_xid == NULL && new_relmin_mxid == NULL);
492 for (offnum = maxoff;
506 prstate.
htsv[offnum] = -1;
634 elog(
ERROR,
"dead heap-only tuple (%u, %d) is not linked to from any HOT chain",
643#ifdef USE_ASSERT_CHECKING
776 if (!do_freeze && !do_prune)
780 if (do_prune || do_freeze)
833 conflict_xid = frz_conflict_horizon;
1017 offnum = rootoffnum;
1033 if (offnum > maxoff)
1059 chainitems[nchain++] = offnum;
1078 chainitems[nchain++] = offnum;
1085 ndeadchain = nchain;
1117 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
1155 if (ndeadchain == 0)
1168 for (;
i < nchain;
i++)
1171 else if (ndeadchain == nchain)
1178 for (
int i = 1;
i < nchain;
i++)
1190 for (
int i = 1;
i < ndeadchain;
i++)
1194 for (
int i = ndeadchain;
i < nchain;
i++)
1361 switch (prstate->
htsv[offnum])
1473 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result %d",
1474 prstate->
htsv[offnum]);
1481 bool totally_frozen;
1498 if (!totally_frozen)
1571 Assert(nredirected > 0 || ndead > 0 || nunused > 0);
1574 Assert(!lp_truncate_only || (nredirected == 0 && ndead == 0));
1577 offnum = redirected;
1578 for (
int i = 0;
i < nredirected;
i++)
1585#ifdef USE_ASSERT_CHECKING
1635 for (
int i = 0;
i < ndead;
i++)
1640#ifdef USE_ASSERT_CHECKING
1667 for (
int i = 0;
i < nunused;
i++)
1672#ifdef USE_ASSERT_CHECKING
1674 if (lp_truncate_only)
1704 if (lp_truncate_only)
1739#ifdef USE_ASSERT_CHECKING
1821 root_offsets[offnum - 1] = offnum;
1858 if (offnum > maxoff)
1874 root_offsets[nextoffnum - 1] = offnum;
1987 for (
int i = 0;
i < ntuples;
i++)
2023 Assert(nplans > 0 && nplans <= ntuples);
2095 freeze_plans.
nplans = nplans;
2101 if (nredirected > 0)
2105 redirect_items.
ntargets = nredirected;
2147 Assert(nredirected == 0 && ndead == 0);
2166 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(const PageData *page)
void PageRepairFragmentation(Page page)
void PageTruncateLinePointerArray(Page page)
PageHeaderData * PageHeader
static void PageClearFull(Page page)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static bool PageIsFull(const PageData *page)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *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
static bool HeapTupleHeaderIsHeapOnly(const HeapTupleHeaderData *tup)
static TransactionId HeapTupleHeaderGetXmin(const HeapTupleHeaderData *tup)
static bool HeapTupleHeaderIndicatesMovedPartitions(const HeapTupleHeaderData *tup)
static bool HeapTupleHeaderIsHotUpdated(const HeapTupleHeaderData *tup)
static TransactionId HeapTupleHeaderGetUpdateXid(const HeapTupleHeaderData *tup)
#define MaxHeapTuplesPerPage
static bool HeapTupleHeaderXminCommitted(const HeapTupleHeaderData *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 NormalTransactionIdPrecedes(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
bool RecoveryInProgress(void)
#define XLogHintBitIsNeeded()
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, const void *data, uint32 len)
bool XLogCheckBufferNeedsBackup(Buffer buffer)
void XLogRegisterData(const void *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)