168#define REL_TRUNCATE_MINIMUM 1000
169#define REL_TRUNCATE_FRACTION 16
178#define VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL 20
179#define VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL 50
180#define VACUUM_TRUNCATE_LOCK_TIMEOUT 5000
186#define BYPASS_THRESHOLD_PAGES 0.02
192#define FAILSAFE_EVERY_PAGES \
193 ((BlockNumber) (((uint64) 4 * 1024 * 1024 * 1024) / BLCKSZ))
201#define VACUUM_FSM_EVERY_PAGES \
202 ((BlockNumber) (((uint64) 8 * 1024 * 1024 * 1024) / BLCKSZ))
208#define SKIP_PAGES_THRESHOLD ((BlockNumber) 32)
214#define PREFETCH_SIZE ((BlockNumber) 32)
220#define ParallelVacuumIsActive(vacrel) ((vacrel)->pvs != NULL)
240#define MAX_EAGER_FREEZE_SUCCESS_RATE 0.2
249#define EAGER_SCAN_REGION_SIZE 4096
255#define VAC_BLK_WAS_EAGER_SCANNED (1 << 0)
256#define VAC_BLK_ALL_VISIBLE_ACCORDING_TO_VM (1 << 1)
427 void *callback_private_data,
428 void *per_buffer_data);
432 bool sharelock,
Buffer vmbuffer);
435 Buffer vmbuffer,
bool all_visible_according_to_vm,
436 bool *has_lpdead_items,
bool *vm_page_frozen);
439 bool *has_lpdead_items);
445 int num_offsets,
Buffer vmbuffer);
455 bool estimated_count,
460 bool *lock_waiter_detected);
467#ifdef USE_ASSERT_CHECKING
505 float first_region_ratio;
506 bool oldest_unfrozen_before_cutoff =
false;
558 oldest_unfrozen_before_cutoff =
true;
560 if (!oldest_unfrozen_before_cutoff &&
564 oldest_unfrozen_before_cutoff =
true;
566 if (!oldest_unfrozen_before_cutoff)
579 (allvisible - allfrozen));
647 char **indnames = NULL;
696 errcallback.
arg = vacrel;
705 if (instrument && vacrel->
nindexes > 0)
841 (
errmsg(
"aggressively vacuuming \"%s.%s.%s\"",
846 (
errmsg(
"vacuuming \"%s.%s.%s\"",
930 if (new_rel_allvisible > new_rel_pages)
931 new_rel_allvisible = new_rel_pages;
938 if (new_rel_allfrozen > new_rel_allvisible)
939 new_rel_allfrozen = new_rel_allvisible;
949 new_rel_allvisible, new_rel_allfrozen,
952 &frozenxid_updated, &minmulti_updated,
false);
987 double read_rate = 0,
989 int64 total_blks_hit;
990 int64 total_blks_read;
991 int64 total_blks_dirtied;
994 memset(&walusage, 0,
sizeof(
WalUsage));
1014 msgfmt =
_(
"finished vacuuming \"%s.%s.%s\": index scans: %d\n");
1025 msgfmt =
_(
"automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n");
1027 msgfmt =
_(
"automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n");
1032 msgfmt =
_(
"automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n");
1034 msgfmt =
_(
"automatic vacuum of table \"%s.%s.%s\": index scans: %d\n");
1041 appendStringInfo(&
buf,
_(
"pages: %u removed, %u remain, %u scanned (%.2f%% of total), %u eagerly scanned\n"),
1045 orig_rel_pages == 0 ? 100.0 :
1050 _(
"tuples: %" PRId64
" removed, %" PRId64
" remain, %" PRId64
" are dead but not yet removable\n"),
1056 _(
"tuples missed: %" PRId64
" dead from %u pages not removed due to cleanup lock contention\n"),
1062 _(
"removable cutoff: %u, which was %d XIDs old when operation ended\n"),
1064 if (frozenxid_updated)
1069 _(
"new relfrozenxid: %u, which is %d XIDs ahead of previous value\n"),
1072 if (minmulti_updated)
1077 _(
"new relminmxid: %u, which is %d MXIDs ahead of previous value\n"),
1080 appendStringInfo(&
buf,
_(
"frozen: %u pages from table (%.2f%% of total) had %" PRId64
" tuples frozen\n"),
1082 orig_rel_pages == 0 ? 100.0 :
1088 _(
"visibility map: %u pages set all-visible, %u pages set all-frozen (%u were all-visible)\n"),
1100 msgfmt =
_(
"%u pages from table (%.2f%% of total) had %" PRId64
" dead item identifiers removed\n");
1109 msgfmt =
_(
"%u pages from table (%.2f%% of total) have %" PRId64
" dead item identifiers\n");
1113 orig_rel_pages == 0 ? 100.0 :
1124 _(
"index \"%s\": pages: %u in total, %u newly deleted, %u currently deleted, %u reusable\n"),
1150 if (secs_dur > 0 || usecs_dur > 0)
1152 read_rate = (double) BLCKSZ * total_blks_read /
1153 (1024 * 1024) / (secs_dur + usecs_dur / 1000000.0);
1154 write_rate = (double) BLCKSZ * total_blks_dirtied /
1155 (1024 * 1024) / (secs_dur + usecs_dur / 1000000.0);
1158 read_rate, write_rate);
1160 _(
"buffer usage: %" PRId64
" hits, %" PRId64
" reads, %" PRId64
" dirtied\n"),
1163 total_blks_dirtied);
1165 _(
"WAL usage: %" PRId64
" records, %" PRId64
" full page images, %" PRIu64
" bytes, %" PRIu64
" full page image bytes, %" PRId64
" buffers full\n"),
1232 next_fsm_block_to_vacuum = 0;
1236 const int initprog_index[] = {
1241 int64 initprog_val[3];
1245 initprog_val[1] = rel_pages;
1276 bool has_lpdead_items;
1277 void *per_buffer_data = NULL;
1278 bool vm_page_frozen =
false;
1279 bool got_cleanup_lock =
false;
1330 next_fsm_block_to_vacuum = blkno;
1343 blk_info = *((
uint8 *) per_buffer_data);
1372 if (!got_cleanup_lock)
1391 if (!got_cleanup_lock &&
1401 got_cleanup_lock =
true;
1417 if (got_cleanup_lock)
1421 &has_lpdead_items, &vm_page_frozen);
1437 if (got_cleanup_lock &&
1459 (
errmsg(
"disabling eager scanning after freezing %u eagerly scanned blocks of relation \"%s.%s.%s\"",
1460 orig_eager_scan_success_limit,
1499 || !has_lpdead_items)
1512 if (got_cleanup_lock && vacrel->
nindexes == 0 && ndeleted > 0 &&
1517 next_fsm_block_to_vacuum = blkno;
1563 if (rel_pages > next_fsm_block_to_vacuum)
1600 void *callback_private_data,
1601 void *per_buffer_data)
1660 if (next_block < vacrel->next_unskippable_block)
1669 *((
uint8 *) per_buffer_data) = blk_info;
1685 *((
uint8 *) per_buffer_data) = blk_info;
1709 bool next_unskippable_eager_scanned =
false;
1710 bool next_unskippable_allvis;
1712 *skipsallvis =
false;
1714 for (;; next_unskippable_block++)
1717 next_unskippable_block,
1718 &next_unskippable_vmbuffer);
1739 if (!next_unskippable_allvis)
1755 if (next_unskippable_block == rel_pages - 1)
1783 next_unskippable_eager_scanned =
true;
1791 *skipsallvis =
true;
1976 bool all_visible_according_to_vm,
1977 bool *has_lpdead_items,
1978 bool *vm_page_frozen)
2037#ifdef USE_ASSERT_CHECKING
2041 bool debug_all_frozen;
2047 &debug_cutoff, &vacrel->
offnum));
2097 if (!all_visible_according_to_vm && presult.
all_visible)
2138 *vm_page_frozen =
true;
2145 *vm_page_frozen =
true;
2160 errmsg(
"page is not marked all-visible but visibility map bit is set in relation \"%s\" page %u",
2185 errmsg(
"page containing LP_DEAD items is marked as all-visible in relation \"%s\" page %u",
2198 else if (all_visible_according_to_vm && presult.
all_frozen &&
2239 *vm_page_frozen =
true;
2249 *vm_page_frozen =
true;
2281 bool *has_lpdead_items)
2287 recently_dead_tuples,
2301 recently_dead_tuples = 0;
2302 missed_dead_tuples = 0;
2330 deadoffsets[lpdead_items++] = offnum;
2337 &NoFreezePageRelfrozenXid,
2338 &NoFreezePageRelminMxid))
2391 missed_dead_tuples++;
2398 recently_dead_tuples++;
2407 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
2426 if (lpdead_items > 0)
2437 missed_dead_tuples += lpdead_items;
2440 else if (lpdead_items > 0)
2460 if (missed_dead_tuples > 0)
2468 *has_lpdead_items = (lpdead_items > 0);
2615 bool allindexes =
true;
2616 double old_live_tuples = vacrel->
rel->
rd_rel->reltuples;
2617 const int progress_start_index[] = {
2621 const int progress_end_index[] = {
2626 int64 progress_start_val[2];
2627 int64 progress_end_val[3];
2645 progress_start_val[1] = vacrel->
nindexes;
2704 progress_end_val[0] = 0;
2705 progress_end_val[1] = 0;
2721 void *callback_private_data,
2722 void *per_buffer_data)
2728 if (iter_result == NULL)
2735 memcpy(per_buffer_data, iter_result,
sizeof(*iter_result));
2737 return iter_result->
blkno;
2832 num_offsets, vmbuffer);
2859 (
errmsg(
"table \"%s\": removed %" PRId64
" dead item identifiers in %u pages",
2908 deadoffsets, num_offsets,
2909 &all_frozen, &visibility_cutoff_xid,
2929 for (
int i = 0;
i < num_offsets;
i++)
2938 unused[nunused++] = toff;
2956 conflict_xid = visibility_cutoff_xid;
3015 const int progress_index[] = {
3040 (
errmsg(
"bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans",
3043 errdetail(
"The table's relfrozenxid or relminmxid is too far in the past."),
3044 errhint(
"Consider increasing configuration parameter \"maintenance_work_mem\" or \"autovacuum_work_mem\".\n"
3045 "You might also need to consider other ways for VACUUM to keep up with the allocation of transaction IDs.")));
3065 const int progress_start_index[] = {
3069 const int progress_end_index[] = {
3073 int64 progress_start_val[2];
3074 int64 progress_end_val[2] = {0, 0};
3084 progress_start_val[1] = vacrel->
nindexes;
3096 estimated_count, vacrel);
3135 ivinfo.
index = indrel;
3179 double reltuples,
bool estimated_count,
3185 ivinfo.
index = indrel;
3246 if (possibly_freeable > 0 &&
3262 bool lock_waiter_detected;
3285 lock_waiter_detected =
false;
3306 (
errmsg(
"\"%s\": stopping truncate due to conflicting lock request",
3314 WAIT_EVENT_VACUUM_TRUNCATE);
3324 if (new_rel_pages != orig_rel_pages)
3344 vacrel->
blkno = new_rel_pages;
3346 if (new_rel_pages >= orig_rel_pages)
3376 (
errmsg(
"table \"%s\": truncated %u to %u pages",
3378 orig_rel_pages, new_rel_pages)));
3379 orig_rel_pages = new_rel_pages;
3380 }
while (new_rel_pages > vacrel->
nonempty_pages && lock_waiter_detected);
3392 "prefetch size must be power of 2");
3425 if ((blkno % 32) == 0)
3431 elapsed = currenttime;
3439 (
errmsg(
"table \"%s\": suspending truncate due to conflicting lock request",
3442 *lock_waiter_detected =
true;
3445 starttime = currenttime;
3459 if (prefetchedUntil > blkno)
3465 for (pblkno = prefetchStart; pblkno <= blkno; pblkno++)
3470 prefetchedUntil = prefetchStart;
3558 (
errmsg(
"disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel",
3600 const int prog_index[2] = {
3654#ifdef USE_ASSERT_CHECKING
3673 visibility_cutoff_xid,
3721 bool all_visible =
true;
3722 int matched_dead_count = 0;
3727 Assert(ndeadoffsets == 0 || deadoffsets);
3729#ifdef USE_ASSERT_CHECKING
3731 if (ndeadoffsets > 1)
3733 for (
int i = 1;
i < ndeadoffsets;
i++)
3734 Assert(deadoffsets[
i - 1] < deadoffsets[
i]);
3740 offnum <= maxoff && all_visible;
3750 *logging_offnum = offnum;
3766 matched_dead_count >= ndeadoffsets ||
3767 deadoffsets[matched_dead_count] != offnum)
3769 *all_frozen = all_visible =
false;
3772 matched_dead_count++;
3793 all_visible =
false;
3794 *all_frozen =
false;
3805 all_visible =
false;
3806 *all_frozen =
false;
3813 *visibility_cutoff_xid = xmin;
3816 if (all_visible && *all_frozen &&
3818 *all_frozen =
false;
3827 all_visible =
false;
3828 *all_frozen =
false;
3832 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
3855 for (
int idx = 0;
idx < nindexes;
idx++)
3886 switch (errinfo->
phase)
3892 errcontext(
"while scanning block %u offset %u of relation \"%s.%s\"",
3895 errcontext(
"while scanning block %u of relation \"%s.%s\"",
3899 errcontext(
"while scanning relation \"%s.%s\"",
3907 errcontext(
"while vacuuming block %u offset %u of relation \"%s.%s\"",
3910 errcontext(
"while vacuuming block %u of relation \"%s.%s\"",
3914 errcontext(
"while vacuuming relation \"%s.%s\"",
3919 errcontext(
"while vacuuming index \"%s\" of relation \"%s.%s\"",
3924 errcontext(
"while cleaning up index \"%s\" of relation \"%s.%s\"",
3930 errcontext(
"while truncating relation \"%s.%s\" to %u blocks",
3956 vacrel->
blkno = blkno;
3958 vacrel->
phase = phase;
Datum idx(PG_FUNCTION_ARGS)
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
TimestampTz GetCurrentTimestamp(void)
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
void pgstat_progress_end_command(void)
@ PROGRESS_COMMAND_VACUUM
PgBackendStatus * MyBEEntry
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
void CheckBufferIsPinnedOnce(Buffer buffer)
BlockNumber BufferGetBlockNumber(Buffer buffer)
PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
void LockBuffer(Buffer buffer, BufferLockMode mode)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBufferForCleanup(Buffer buffer)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
bool ConditionalLockBufferForCleanup(Buffer buffer)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static bool BufferIsValid(Buffer bufnum)
Size PageGetHeapFreeSpace(const PageData *page)
void PageTruncateLinePointerArray(Page page)
static bool PageIsEmpty(const PageData *page)
static bool PageIsAllVisible(const PageData *page)
static void PageClearAllVisible(Page page)
static void * PageGetItem(const PageData *page, const ItemIdData *itemId)
static bool PageIsNew(const PageData *page)
#define SizeOfPageHeaderData
static void PageSetAllVisible(Page page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static XLogRecPtr PageGetLSN(const PageData *page)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
TransactionId MultiXactId
#define StaticAssertDecl(condition, errmessage)
int errmsg_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define palloc_object(type)
#define palloc_array(type, count)
#define palloc0_object(type)
void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start, BlockNumber end)
Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk)
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
volatile uint32 CritSectionCount
Assert(PointerIsAligned(start, uint64))
bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple)
bool heap_tuple_should_freeze(HeapTupleHeader tuple, const struct VacuumCutoffs *cutoffs, TransactionId *NoFreezePageRelfrozenXid, MultiXactId *NoFreezePageRelminMxid)
#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 HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, Buffer buffer)
HeapTupleHeaderData * HeapTupleHeader
static TransactionId HeapTupleHeaderGetXmin(const HeapTupleHeaderData *tup)
#define MaxHeapTuplesPerPage
static bool HeapTupleHeaderXminCommitted(const HeapTupleHeaderData *tup)
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_SUBTRACT(x, y)
#define INSTR_TIME_GET_MICROSEC(t)
void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, const WalUsage *sub)
BufferUsage pgBufferUsage
void BufferUsageAccumDiff(BufferUsage *dst, const BufferUsage *add, const BufferUsage *sub)
static int pg_cmp_u16(uint16 a, uint16 b)
#define ItemIdGetLength(itemId)
#define ItemIdIsNormal(itemId)
#define ItemIdIsDead(itemId)
#define ItemIdIsUsed(itemId)
#define ItemIdSetUnused(itemId)
#define ItemIdIsRedirected(itemId)
#define ItemIdHasStorage(itemId)
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
void ResetLatch(Latch *latch)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
void UnlockRelation(Relation relation, LOCKMODE lockmode)
bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode)
#define AccessExclusiveLock
char * get_database_name(Oid dbid)
char * get_namespace_name(Oid nspid)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
#define AmAutoVacuumWorkerProcess()
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define END_CRIT_SECTION()
bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, MultiXactId multi2)
#define MultiXactIdIsValid(multi)
#define InvalidMultiXactId
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
#define ERRCODE_DATA_CORRUPTED
uint32 pg_prng_uint32(pg_prng_state *state)
pg_prng_state pg_global_prng_state
const char * pg_rusage_show(const PGRUsage *ru0)
void pg_rusage_init(PGRUsage *ru0)
static char buf[DEFAULT_XLOG_SEG_SIZE]
PgStat_Counter pgStatBlockReadTime
PgStat_Counter pgStatBlockWriteTime
void pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter livetuples, PgStat_Counter deadtuples, TimestampTz starttime)
#define qsort(a, b, c, d)
GlobalVisState * GlobalVisTestFor(Relation rel)
#define PROGRESS_VACUUM_PHASE_FINAL_CLEANUP
#define PROGRESS_VACUUM_MODE
#define PROGRESS_VACUUM_MODE_NORMAL
#define PROGRESS_VACUUM_STARTED_BY_AUTOVACUUM
#define PROGRESS_VACUUM_DEAD_TUPLE_BYTES
#define PROGRESS_VACUUM_PHASE_SCAN_HEAP
#define PROGRESS_VACUUM_TOTAL_HEAP_BLKS
#define PROGRESS_VACUUM_PHASE
#define PROGRESS_VACUUM_DELAY_TIME
#define PROGRESS_VACUUM_STARTED_BY_AUTOVACUUM_WRAPAROUND
#define PROGRESS_VACUUM_NUM_INDEX_VACUUMS
#define PROGRESS_VACUUM_PHASE_VACUUM_HEAP
#define PROGRESS_VACUUM_NUM_DEAD_ITEM_IDS
#define PROGRESS_VACUUM_MAX_DEAD_TUPLE_BYTES
#define PROGRESS_VACUUM_STARTED_BY_MANUAL
#define PROGRESS_VACUUM_HEAP_BLKS_SCANNED
#define PROGRESS_VACUUM_STARTED_BY
#define PROGRESS_VACUUM_PHASE_INDEX_CLEANUP
#define PROGRESS_VACUUM_PHASE_VACUUM_INDEX
#define PROGRESS_VACUUM_MODE_FAILSAFE
#define PROGRESS_VACUUM_INDEXES_PROCESSED
#define PROGRESS_VACUUM_INDEXES_TOTAL
#define PROGRESS_VACUUM_MODE_AGGRESSIVE
#define PROGRESS_VACUUM_HEAP_BLKS_VACUUMED
#define PROGRESS_VACUUM_PHASE_TRUNCATE
void heap_page_prune_and_freeze(PruneFreezeParams *params, PruneFreezeResult *presult, OffsetNumber *off_loc, TransactionId *new_relfrozen_xid, MultiXactId *new_relmin_mxid)
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)
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
ReadStream * read_stream_begin_relation(int flags, BufferAccessStrategy strategy, Relation rel, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
void read_stream_end(ReadStream *stream)
#define READ_STREAM_MAINTENANCE
#define READ_STREAM_USE_BATCHING
#define RelationGetRelid(relation)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define RelationUsesLocalBuffers(relation)
#define RelationGetNamespace(relation)
void RelationTruncate(Relation rel, BlockNumber nblocks)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void initStringInfo(StringInfo str)
int64 shared_blks_dirtied
struct ErrorContextCallback * previous
void(* callback)(void *arg)
BlockNumber pages_deleted
BlockNumber pages_newly_deleted
BufferAccessStrategy strategy
BlockNumber next_eager_scan_region_start
ParallelVacuumState * pvs
bool next_unskippable_eager_scanned
VacDeadItemsInfo * dead_items_info
BlockNumber vm_new_frozen_pages
Buffer next_unskippable_vmbuffer
BlockNumber nonempty_pages
BlockNumber eager_scan_remaining_fails
BlockNumber scanned_pages
BlockNumber new_frozen_tuple_pages
BlockNumber removed_pages
IndexBulkDeleteResult ** indstats
TransactionId NewRelfrozenXid
bool consider_bypass_optimization
BlockNumber next_unskippable_block
int64 recently_dead_tuples
BlockNumber missed_dead_pages
BlockNumber current_block
BufferAccessStrategy bstrategy
BlockNumber eager_scan_remaining_successes
BlockNumber lpdead_item_pages
BlockNumber eager_scanned_pages
MultiXactId NewRelminMxid
struct VacuumCutoffs cutoffs
bool next_unskippable_allvis
BlockNumber vm_new_visible_pages
BlockNumber eager_scan_max_fails_per_region
BlockNumber vm_new_visible_frozen_pages
int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM]
TransactionId vm_conflict_horizon
OffsetNumber deadoffsets[MaxHeapTuplesPerPage]
RelFileLocator rd_locator
TransactionId FreezeLimit
TransactionId relfrozenxid
MultiXactId MultiXactCutoff
int log_vacuum_min_duration
VacOptValue index_cleanup
double max_eager_freeze_failure_rate
TidStoreIter * TidStoreBeginIterate(TidStore *ts)
void TidStoreEndIterate(TidStoreIter *iter)
TidStoreIterResult * TidStoreIterateNext(TidStoreIter *iter)
TidStore * TidStoreCreateLocal(size_t max_bytes, bool insert_only)
void TidStoreDestroy(TidStore *ts)
int TidStoreGetBlockOffsets(TidStoreIterResult *result, OffsetNumber *offsets, int max_offsets)
void TidStoreSetBlockOffsets(TidStore *ts, BlockNumber blkno, OffsetNumber *offsets, int num_offsets)
size_t TidStoreMemoryUsage(TidStore *ts)
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
static TransactionId ReadNextTransactionId(void)
#define InvalidTransactionId
static bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool track_cost_delay_timing
void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel)
IndexBulkDeleteResult * vac_cleanup_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat)
void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
void vacuum_delay_point(bool is_analyze)
bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs)
bool VacuumFailsafeActive
double vac_estimate_reltuples(Relation relation, BlockNumber total_pages, BlockNumber scanned_pages, double scanned_tuples)
void vac_update_relstats(Relation relation, BlockNumber num_pages, double num_tuples, BlockNumber num_all_visible_pages, BlockNumber num_all_frozen_pages, bool hasindex, TransactionId frozenxid, MultiXactId minmulti, bool *frozenxid_updated, bool *minmulti_updated, bool in_outer_xact)
bool vacuum_get_cutoffs(Relation rel, const VacuumParams params, struct VacuumCutoffs *cutoffs)
IndexBulkDeleteResult * vac_bulkdel_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat, TidStore *dead_items, VacDeadItemsInfo *dead_items_info)
@ VACOPTVALUE_UNSPECIFIED
#define VACOPT_DISABLE_PAGE_SKIPPING
static void dead_items_cleanup(LVRelState *vacrel)
#define VAC_BLK_WAS_EAGER_SCANNED
static void update_relstats_all_indexes(LVRelState *vacrel)
static void dead_items_add(LVRelState *vacrel, BlockNumber blkno, OffsetNumber *offsets, int num_offsets)
static int lazy_scan_prune(LVRelState *vacrel, Buffer buf, BlockNumber blkno, Page page, Buffer vmbuffer, bool all_visible_according_to_vm, bool *has_lpdead_items, bool *vm_page_frozen)
void heap_vacuum_rel(Relation rel, const VacuumParams params, BufferAccessStrategy bstrategy)
static BlockNumber heap_vac_scan_next_block(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
static void heap_vacuum_eager_scan_setup(LVRelState *vacrel, const VacuumParams params)
#define VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL
static void vacuum_error_callback(void *arg)
static bool heap_page_would_be_all_visible(Relation rel, Buffer buf, TransactionId OldestXmin, OffsetNumber *deadoffsets, int ndeadoffsets, bool *all_frozen, TransactionId *visibility_cutoff_xid, OffsetNumber *logging_offnum)
#define EAGER_SCAN_REGION_SIZE
static void lazy_truncate_heap(LVRelState *vacrel)
static void lazy_vacuum(LVRelState *vacrel)
static void lazy_cleanup_all_indexes(LVRelState *vacrel)
#define MAX_EAGER_FREEZE_SUCCESS_RATE
static bool lazy_scan_noprune(LVRelState *vacrel, Buffer buf, BlockNumber blkno, Page page, bool *has_lpdead_items)
static BlockNumber vacuum_reap_lp_read_stream_next(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
#define REL_TRUNCATE_MINIMUM
static bool should_attempt_truncation(LVRelState *vacrel)
static bool lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno, Page page, bool sharelock, Buffer vmbuffer)
@ VACUUM_ERRCB_PHASE_SCAN_HEAP
@ VACUUM_ERRCB_PHASE_VACUUM_INDEX
@ VACUUM_ERRCB_PHASE_TRUNCATE
@ VACUUM_ERRCB_PHASE_INDEX_CLEANUP
@ VACUUM_ERRCB_PHASE_VACUUM_HEAP
@ VACUUM_ERRCB_PHASE_UNKNOWN
static void lazy_scan_heap(LVRelState *vacrel)
#define ParallelVacuumIsActive(vacrel)
static void restore_vacuum_error_info(LVRelState *vacrel, const LVSavedErrInfo *saved_vacrel)
static IndexBulkDeleteResult * lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat, double reltuples, LVRelState *vacrel)
static void find_next_unskippable_block(LVRelState *vacrel, bool *skipsallvis)
static void dead_items_reset(LVRelState *vacrel)
#define REL_TRUNCATE_FRACTION
static bool lazy_check_wraparound_failsafe(LVRelState *vacrel)
struct LVSavedErrInfo LVSavedErrInfo
static IndexBulkDeleteResult * lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat, double reltuples, bool estimated_count, LVRelState *vacrel)
static void lazy_vacuum_heap_page(LVRelState *vacrel, BlockNumber blkno, Buffer buffer, OffsetNumber *deadoffsets, int num_offsets, Buffer vmbuffer)
struct LVRelState LVRelState
#define BYPASS_THRESHOLD_PAGES
static void dead_items_alloc(LVRelState *vacrel, int nworkers)
#define VACUUM_TRUNCATE_LOCK_TIMEOUT
static bool lazy_vacuum_all_indexes(LVRelState *vacrel)
static void update_vacuum_error_info(LVRelState *vacrel, LVSavedErrInfo *saved_vacrel, int phase, BlockNumber blkno, OffsetNumber offnum)
static BlockNumber count_nondeletable_pages(LVRelState *vacrel, bool *lock_waiter_detected)
#define VAC_BLK_ALL_VISIBLE_ACCORDING_TO_VM
#define SKIP_PAGES_THRESHOLD
#define FAILSAFE_EVERY_PAGES
#define VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL
static int cmpOffsetNumbers(const void *a, const void *b)
static void lazy_vacuum_heap_rel(LVRelState *vacrel)
#define VACUUM_FSM_EVERY_PAGES
TidStore * parallel_vacuum_get_dead_items(ParallelVacuumState *pvs, VacDeadItemsInfo **dead_items_info_p)
ParallelVacuumState * parallel_vacuum_init(Relation rel, Relation *indrels, int nindexes, int nrequested_workers, int vac_work_mem, int elevel, BufferAccessStrategy bstrategy)
void parallel_vacuum_bulkdel_all_indexes(ParallelVacuumState *pvs, long num_table_tuples, int num_index_scans)
void parallel_vacuum_reset_dead_items(ParallelVacuumState *pvs)
void parallel_vacuum_cleanup_all_indexes(ParallelVacuumState *pvs, long num_table_tuples, int num_index_scans, bool estimated_count)
void parallel_vacuum_end(ParallelVacuumState *pvs, IndexBulkDeleteResult **istats)
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)
uint8 visibilitymap_set_vmbits(BlockNumber heapBlk, Buffer vmBuf, uint8 flags, const RelFileLocator rlocator)
void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen)
uint8 visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, uint8 flags)
#define VM_ALL_FROZEN(r, b, v)
#define VISIBILITYMAP_VALID_BITS
#define VISIBILITYMAP_ALL_FROZEN
#define VISIBILITYMAP_ALL_VISIBLE
#define WL_EXIT_ON_PM_DEATH
bool IsInParallelMode(void)
#define XLogRecPtrIsValid(r)
#define InvalidXLogRecPtr
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)