447 prstate->pagefrz.freeze_required =
false;
468 prstate->recently_dead_tuples = 0;
561 for (offnum = maxoff;
574 prstate->processed[offnum] =
false;
633 for (
int i =
prstate->nroot_items - 1;
i >= 0;
i--)
638 if (
prstate->processed[offnum])
652 for (
int i =
prstate->nheaponly_items - 1;
i >= 0;
i--)
654 offnum =
prstate->heaponly_items[
i];
656 if (
prstate->processed[offnum])
696 elog(
ERROR,
"dead heap-only tuple (%u, %d) is not linked to from any HOT chain",
705#ifdef USE_ASSERT_CHECKING
751 if (
prstate->pagefrz.freeze_required)
808 prstate->cutoffs->OldestXmin));
818 prstate->set_all_frozen =
false;
866 errmsg(
"dead line pointer found on page marked all-visible"),
867 errcontext(
"relation \"%s\", page %u, tuple %u",
890 errmsg(
"tuple not visible to all transactions found on page marked all-visible"),
891 errcontext(
"relation \"%s\", page %u, tuple %u",
911 errmsg(
"page is not marked all-visible but visibility map bit is set"),
1150 if (
prstate.set_all_visible &&
1291 prstate.relation->rd_locator);
1327#ifdef USE_ASSERT_CHECKING
1365 presult->newly_all_visible =
false;
1366 presult->newly_all_frozen =
false;
1367 presult->newly_all_visible_frozen =
false;
1372 presult->newly_all_visible =
true;
1374 presult->newly_all_visible_frozen =
true;
1378 presult->newly_all_frozen =
true;
1518 if (offnum > maxoff)
1522 if (
prstate->processed[offnum])
1572 &
prstate->latest_xid_removed);
1602 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
1714 prstate->processed[offnum] =
true;
1744 prstate->processed[offnum] =
true;
1804 prstate->processed[offnum] =
true;
1826 prstate->processed[offnum] =
true;
1841 prstate->processed[offnum] =
true;
1867 switch (
prstate->htsv[offnum])
1887 prstate->set_all_visible =
false;
1888 prstate->set_all_frozen =
false;
1904 prstate->newest_live_xid = xmin;
1909 prstate->recently_dead_tuples++;
1910 prstate->set_all_visible =
false;
1911 prstate->set_all_frozen =
false;
1931 prstate->set_all_visible =
false;
1932 prstate->set_all_frozen =
false;
1952 prstate->set_all_visible =
false;
1953 prstate->set_all_frozen =
false;
1970 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result %d",
1996 prstate->set_all_frozen =
false;
2008 prstate->processed[offnum] =
true;
2051 prstate->processed[offnum] =
true;
2075 Assert(nredirected > 0 || ndead > 0 || nunused > 0);
2081 offnum = redirected;
2082 for (
int i = 0;
i < nredirected;
i++)
2089#ifdef USE_ASSERT_CHECKING
2139 for (
int i = 0;
i < ndead;
i++)
2144#ifdef USE_ASSERT_CHECKING
2171 for (
int i = 0;
i < nunused;
i++)
2176#ifdef USE_ASSERT_CHECKING
2243#ifdef USE_ASSERT_CHECKING
2362 if (offnum > maxoff)
2402 if (
plan->xmax ==
frz->xmax &&
2403 plan->t_infomask2 ==
frz->t_infomask2 &&
2404 plan->t_infomask ==
frz->t_infomask &&
2405 plan->frzflags ==
frz->frzflags)
2426 if (
frz1->t_infomask2 <
frz2->t_infomask2)
2428 else if (
frz1->t_infomask2 >
frz2->t_infomask2)
2431 if (
frz1->t_infomask <
frz2->t_infomask)
2433 else if (
frz1->t_infomask >
frz2->t_infomask)
2436 if (
frz1->frzflags <
frz2->frzflags)
2438 else if (
frz1->frzflags >
frz2->frzflags)
2450 else if (
frz1->offset >
frz2->offset)
2465 plan->t_infomask2 =
frz->t_infomask2;
2466 plan->t_infomask =
frz->t_infomask;
2467 plan->frzflags =
frz->frzflags;
2491 for (
int i = 0;
i < ntuples;
i++)
2527 Assert(nplans > 0 && nplans <= ntuples);
2585 bool do_prune = nredirected > 0 || ndead > 0 || nunused > 0;
2643 if (nredirected > 0)
2695 Assert(nredirected == 0 && ndead == 0);
2714 elog(
ERROR,
"unrecognized prune reason: %d", (
int) reason);
BlockNumber BufferGetBlockNumber(Buffer buffer)
bool BufferIsLockedByMeInMode(Buffer buffer, BufferLockMode mode)
bool BufferIsDirty(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
bool ConditionalLockBufferForCleanup(Buffer buffer)
static Page BufferGetPage(Buffer buffer)
static void LockBuffer(Buffer buffer, BufferLockMode mode)
static bool BufferIsValid(Buffer bufnum)
Size PageGetHeapFreeSpace(const PageData *page)
void PageRepairFragmentation(Page page)
void PageTruncateLinePointerArray(Page page)
static bool PageIsEmpty(const PageData *page)
PageHeaderData * PageHeader
static bool PageIsAllVisible(const PageData *page)
static void PageClearAllVisible(Page page)
static TransactionId PageGetPruneXid(const PageData *page)
static void PageClearFull(Page page)
static void PageSetAllVisible(Page page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void * PageGetItem(PageData *page, const ItemIdData *itemId)
static void PageSetLSN(Page page, XLogRecPtr lsn)
#define PageClearPrunable(page)
static XLogRecPtr PageGetLSN(const PageData *page)
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)
int errcode(int sqlerrcode)
#define ereport(elevel,...)
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
#define HEAP_PAGE_PRUNE_ALLOW_FAST_PATH
@ HEAPTUPLE_RECENTLY_DEAD
@ HEAPTUPLE_INSERT_IN_PROGRESS
@ HEAPTUPLE_DELETE_IN_PROGRESS
#define HEAP_PAGE_PRUNE_SET_VM
#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_VM_ALL_VISIBLE
#define XLHP_HAS_NOW_UNUSED_ITEMS
#define XLHP_VM_ALL_FROZEN
#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)
#define ERRCODE_DATA_CORRUPTED
void pgstat_update_heap_dead_tuples(Relation rel, int delta)
#define qsort(a, b, c, d)
GlobalVisState * GlobalVisTestFor(Relation rel)
bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid, bool allow_update)
bool GlobalVisTestXidConsideredRunning(GlobalVisState *state, TransactionId xid, bool allow_update)
static void prune_freeze_fast_path(PruneState *prstate, PruneFreezeResult *presult)
void heap_page_prune_opt(Relation relation, Buffer buffer, Buffer *vmbuffer, bool rel_read_only)
static void prune_freeze_plan(PruneState *prstate, OffsetNumber *off_loc)
void heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
static bool heap_page_will_freeze(bool did_tuple_hint_fpi, bool do_prune, bool do_hint_prune, PruneState *prstate)
void heap_page_prune_and_freeze(PruneFreezeParams *params, PruneFreezeResult *presult, 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 bool heap_page_will_set_vm(PruneState *prstate, PruneReason reason, bool do_prune, bool do_freeze)
static void heap_prune_chain(OffsetNumber maxoff, OffsetNumber rootoffnum, PruneState *prstate)
@ VM_CORRUPT_MISSING_PAGE_HINT
@ VM_CORRUPT_TUPLE_VISIBILITY
void log_heap_prune_and_freeze(Relation relation, Buffer buffer, Buffer vmbuffer, uint8 vmflags, 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_unused(PruneState *prstate, OffsetNumber offnum, bool was_normal)
static void heap_prune_record_redirect(PruneState *prstate, OffsetNumber offnum, OffsetNumber rdoffnum, bool was_normal)
static int heap_log_freeze_cmp(const void *arg1, const void *arg2)
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, OffsetNumber offnum)
static void heap_log_freeze_new_plan(xlhp_freeze_plan *plan, HeapTupleFreeze *frz)
static void prune_freeze_setup(PruneFreezeParams *params, TransactionId *new_relfrozen_xid, MultiXactId *new_relmin_mxid, PruneFreezeResult *presult, PruneState *prstate)
static void heap_prune_record_dead_or_unused(PruneState *prstate, OffsetNumber offnum, bool was_normal)
static void heap_prune_record_unchanged_lp_unused(PruneState *prstate, OffsetNumber offnum)
static void heap_prune_record_unchanged_lp_dead(PruneState *prstate, OffsetNumber offnum)
static void heap_page_fix_vm_corruption(PruneState *prstate, OffsetNumber offnum, VMCorruptionType ctype)
void heap_page_prune_execute(Buffer buffer, bool lp_truncate_only, OffsetNumber *redirected, int nredirected, OffsetNumber *nowdead, int ndead, OffsetNumber *nowunused, int nunused)
static HTSV_Result heap_prune_satisfies_vacuum(PruneState *prstate, HeapTuple tup)
static void heap_prune_record_unchanged_lp_redirect(PruneState *prstate, OffsetNumber offnum)
static void heap_prune_record_unchanged_lp_normal(PruneState *prstate, OffsetNumber offnum)
#define RelationGetRelid(relation)
#define RelationGetTargetPageFreeSpace(relation, defaultff)
#define RelationGetRelationName(relation)
#define RelationIsAccessibleInLogicalDecoding(relation)
#define RelationNeedsWAL(relation)
#define HEAP_DEFAULT_FILLFACTOR
TransactionId new_prune_xid
struct VacuumCutoffs * cutoffs
TransactionId newest_live_xid
TransactionId latest_xid_removed
OffsetNumber * deadoffsets
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
#define InvalidTransactionId
#define TransactionIdEquals(id1, id2)
#define NormalTransactionIdPrecedes(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
void visibilitymap_set(BlockNumber heapBlk, Buffer vmBuf, uint8 flags, const RelFileLocator rlocator)
bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags)
void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
#define VISIBILITYMAP_VALID_BITS
#define VISIBILITYMAP_ALL_FROZEN
#define VISIBILITYMAP_ALL_VISIBLE
bool RecoveryInProgress(void)
#define XLogHintBitIsNeeded()
#define XLogRecPtrIsValid(r)
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)
#define REGBUF_FORCE_IMAGE