116 prune_xid = ((
PageHeader) page)->pd_prune_xid;
143 minfree =
Max(minfree, BLCKSZ / 10);
178 if (ndeleted > nnewlpdead)
180 ndeleted - nnewlpdead);
241 prstate.
rel = relation;
270 for (offnum = maxoff;
280 prstate.
htsv[offnum] = -1;
308 if (prstate.
marked[offnum])
386 if (prstate.
ndead > 0)
422 *nnewlpdead = prstate.
ndead;
559 if (prstate->
marked[offnum])
577 chainitems[nchain++] = offnum;
604 chainitems[nchain++] = offnum;
609 tupdead = recent_dead =
false;
650 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
667 else if (!recent_dead)
703 for (
i = 1; (
i < nchain) && (chainitems[
i - 1] != latestdead);
i++)
766 prstate->
marked[offnum] =
true;
768 prstate->
marked[rdoffnum] =
true;
779 prstate->
marked[offnum] =
true;
790 prstate->
marked[offnum] =
true;
810 Assert(nredirected > 0 || ndead > 0 || nunused > 0);
814 for (
int i = 0;
i < nredirected;
i++)
821 #ifdef USE_ASSERT_CHECKING
871 for (
int i = 0;
i < ndead;
i++)
876 #ifdef USE_ASSERT_CHECKING
903 for (
int i = 0;
i < nunused;
i++)
908 #ifdef USE_ASSERT_CHECKING
953 #ifdef USE_ASSERT_CHECKING
1035 root_offsets[offnum - 1] = offnum;
1072 if (offnum > maxoff)
1088 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 PG_USED_FOR_ASSERTS_ONLY
#define MemSet(start, val, len)
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)
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)
static void heap_prune_record_prunable(PruneState *prstate, TransactionId xid)
static HTSV_Result heap_prune_satisfies_vacuum(PruneState *prstate, HeapTuple tup, Buffer buffer)
int heap_page_prune(Relation relation, Buffer buffer, GlobalVisState *vistest, int *nnewlpdead, OffsetNumber *off_loc)
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 RelationIsAccessibleInLogicalDecoding(relation)
#define RelationNeedsWAL(relation)
#define HEAP_DEFAULT_FILLFACTOR
TransactionId new_prune_xid
OffsetNumber nowdead[MaxHeapTuplesPerPage]
bool marked[MaxHeapTuplesPerPage+1]
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)