139 prune_xid = ((
PageHeader) page)->pd_prune_xid;
169 &limited_xmin, &limited_ts))
190 minfree =
Max(minfree, BLCKSZ / 10);
210 limited_ts, &nnewlpdead, NULL);
226 if (ndeleted > nnewlpdead)
228 ndeleted - nnewlpdead);
293 prstate.
rel = relation;
325 for (offnum = maxoff;
335 prstate.
htsv[offnum] = -1;
363 if (prstate.
marked[offnum])
440 if (prstate.
ndead > 0)
476 *nnewlpdead = prstate.
ndead;
671 if (prstate->
marked[offnum])
689 chainitems[nchain++] = offnum;
716 chainitems[nchain++] = offnum;
721 tupdead = recent_dead =
false;
762 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
779 else if (!recent_dead)
815 for (
i = 1; (
i < nchain) && (chainitems[
i - 1] != latestdead);
i++)
878 prstate->
marked[offnum] =
true;
880 prstate->
marked[rdoffnum] =
true;
891 prstate->
marked[offnum] =
true;
902 prstate->
marked[offnum] =
true;
922 Assert(nredirected > 0 || ndead > 0 || nunused > 0);
926 for (
int i = 0;
i < nredirected;
i++)
933 #ifdef USE_ASSERT_CHECKING
983 for (
int i = 0;
i < ndead;
i++)
988 #ifdef USE_ASSERT_CHECKING
1015 for (
int i = 0;
i < nunused;
i++)
1020 #ifdef USE_ASSERT_CHECKING
1065 #ifdef USE_ASSERT_CHECKING
1147 root_offsets[offnum - 1] = offnum;
1184 if (offnum > maxoff)
1200 root_offsets[nextoffnum - 1] = offnum;
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)
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 MemSet(start, val, len)
#define PG_USED_FOR_ASSERTS_ONLY
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
void HeapTupleHeaderAdvanceConflictHorizon(HeapTupleHeader tuple, TransactionId *snapshotConflictHorizon)
@ HEAPTUPLE_RECENTLY_DEAD
@ HEAPTUPLE_INSERT_IN_PROGRESS
@ HEAPTUPLE_DELETE_IN_PROGRESS
HTSV_Result HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *dead_after)
HeapTupleHeaderData * HeapTupleHeader
#define HeapTupleHeaderIsHeapOnly(tup)
#define HeapTupleHeaderIndicatesMovedPartitions(tup)
#define HeapTupleHeaderGetXmin(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)
Assert(fmt[strlen(fmt) - 1] !='\n')
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
#define OffsetNumberPrev(offsetNumber)
void pgstat_update_heap_dead_tuples(Relation rel, int delta)
bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid)
TransactionId GlobalVisTestNonRemovableHorizon(GlobalVisState *state)
GlobalVisState * GlobalVisTestFor(Relation rel)
static void heap_prune_record_redirect(PruneState *prstate, OffsetNumber offnum, OffsetNumber rdoffnum)
static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum)
void heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
void heap_page_prune_opt(Relation relation, Buffer buffer)
static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum)
static void page_verify_redirects(Page page)
static int heap_prune_chain(Buffer buffer, OffsetNumber rootoffnum, PruneState *prstate)
int heap_page_prune(Relation relation, Buffer buffer, GlobalVisState *vistest, TransactionId old_snap_xmin, TimestampTz old_snap_ts, int *nnewlpdead, OffsetNumber *off_loc)
static void heap_prune_record_prunable(PruneState *prstate, TransactionId xid)
static HTSV_Result heap_prune_satisfies_vacuum(PruneState *prstate, HeapTuple tup, Buffer buffer)
void heap_page_prune_execute(Buffer buffer, OffsetNumber *redirected, int nredirected, OffsetNumber *nowdead, int ndead, OffsetNumber *nowunused, int nunused)
#define RelationGetRelid(relation)
#define RelationGetTargetPageFreeSpace(relation, defaultff)
#define RelationNeedsWAL(relation)
#define HEAP_DEFAULT_FILLFACTOR
void SnapshotTooOldMagicForTest(void)
bool TransactionIdLimitedForOldSnapshots(TransactionId recentXmin, Relation relation, TransactionId *limit_xid, TimestampTz *limit_ts)
int old_snapshot_threshold
void SetOldSnapshotThresholdTimestamp(TimestampTz ts, TransactionId xlimit)
static bool OldSnapshotThresholdActive(void)
TransactionId new_prune_xid
OffsetNumber nowdead[MaxHeapTuplesPerPage]
bool marked[MaxHeapTuplesPerPage+1]
TransactionId old_snap_xmin
OffsetNumber nowunused[MaxHeapTuplesPerPage]
OffsetNumber redirected[MaxHeapTuplesPerPage *2]
int8 htsv[MaxHeapTuplesPerPage+1]
TransactionId snapshotConflictHorizon
TransactionId snapshotConflictHorizon
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
#define InvalidTransactionId
#define TransactionIdEquals(id1, id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
bool RecoveryInProgress(void)
void XLogRegisterData(char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, char *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)