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(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 NormalTransactionIdPrecedes(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
bool RecoveryInProgress(void)
#define XLogHintBitIsNeeded()
void XLogRegisterBufData(uint8 block_id, const char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
bool XLogCheckBufferNeedsBackup(Buffer buffer)
void XLogRegisterData(const char *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)