71 #define REL_TRUNCATE_MINIMUM 1000
72 #define REL_TRUNCATE_FRACTION 16
81 #define VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL 20
82 #define VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL 50
83 #define VACUUM_TRUNCATE_LOCK_TIMEOUT 5000
89 #define BYPASS_THRESHOLD_PAGES 0.02
95 #define FAILSAFE_EVERY_PAGES \
96 ((BlockNumber) (((uint64) 4 * 1024 * 1024 * 1024) / BLCKSZ))
104 #define VACUUM_FSM_EVERY_PAGES \
105 ((BlockNumber) (((uint64) 8 * 1024 * 1024 * 1024) / BLCKSZ))
111 #define SKIP_PAGES_THRESHOLD ((BlockNumber) 32)
117 #define PREFETCH_SIZE ((BlockNumber) 32)
123 #define ParallelVacuumIsActive(vacrel) ((vacrel)->pvs != NULL)
233 bool *all_visible_according_to_vm);
237 bool sharelock,
Buffer vmbuffer);
240 Buffer vmbuffer,
bool all_visible_according_to_vm,
241 bool *has_lpdead_items);
244 bool *has_lpdead_items);
250 int num_offsets,
Buffer vmbuffer);
260 bool estimated_count,
265 bool *lock_waiter_detected);
316 char **indnames = NULL;
355 errcallback.
arg = vacrel;
364 if (instrument && vacrel->
nindexes > 0)
475 (
errmsg(
"aggressively vacuuming \"%s.%s.%s\"",
480 (
errmsg(
"vacuuming \"%s.%s.%s\"",
564 if (new_rel_allvisible > new_rel_pages)
565 new_rel_allvisible = new_rel_pages;
575 new_rel_allvisible, vacrel->
nindexes > 0,
577 &frozenxid_updated, &minmulti_updated,
false);
613 double read_rate = 0,
617 memset(&walusage, 0,
sizeof(
WalUsage));
628 msgfmt =
_(
"finished vacuuming \"%s.%s.%s\": index scans: %d\n");
639 msgfmt =
_(
"automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n");
641 msgfmt =
_(
"automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n");
646 msgfmt =
_(
"automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n");
648 msgfmt =
_(
"automatic vacuum of table \"%s.%s.%s\": index scans: %d\n");
659 orig_rel_pages == 0 ? 100.0 :
662 _(
"tuples: %lld removed, %lld remain, %lld are dead but not yet removable\n"),
668 _(
"tuples missed: %lld dead from %u pages not removed due to cleanup lock contention\n"),
674 _(
"removable cutoff: %u, which was %d XIDs old when operation ended\n"),
676 if (frozenxid_updated)
681 _(
"new relfrozenxid: %u, which is %d XIDs ahead of previous value\n"),
684 if (minmulti_updated)
689 _(
"new relminmxid: %u, which is %d MXIDs ahead of previous value\n"),
692 appendStringInfo(&
buf,
_(
"frozen: %u pages from table (%.2f%% of total) had %lld tuples frozen\n"),
694 orig_rel_pages == 0 ? 100.0 :
704 msgfmt =
_(
"%u pages from table (%.2f%% of total) had %lld dead item identifiers removed\n");
713 msgfmt =
_(
"%u pages from table (%.2f%% of total) have %lld dead item identifiers\n");
717 orig_rel_pages == 0 ? 100.0 :
728 _(
"index \"%s\": pages: %u in total, %u newly deleted, %u currently deleted, %u reusable\n"),
743 if (secs_dur > 0 || usecs_dur > 0)
745 read_rate = (double) BLCKSZ * PageMissOp / (1024 * 1024) /
746 (secs_dur + usecs_dur / 1000000.0);
747 write_rate = (double) BLCKSZ * PageDirtyOp / (1024 * 1024) /
748 (secs_dur + usecs_dur / 1000000.0);
751 read_rate, write_rate);
753 _(
"buffer usage: %lld hits, %lld misses, %lld dirtied\n"),
754 (
long long) PageHitOp,
755 (
long long) PageMissOp,
756 (
long long) PageDirtyOp);
758 _(
"WAL usage: %lld records, %lld full page images, %llu bytes\n"),
761 (
unsigned long long) walusage.
wal_bytes);
822 next_fsm_block_to_vacuum = 0;
823 bool all_visible_according_to_vm;
828 const int initprog_index[] = {
833 int64 initprog_val[3];
837 initprog_val[1] = rel_pages;
838 initprog_val[2] = dead_items_info->
max_bytes;
851 bool has_lpdead_items;
852 bool got_cleanup_lock =
false;
905 next_fsm_block_to_vacuum = blkno;
931 if (!got_cleanup_lock)
950 if (!got_cleanup_lock &&
960 got_cleanup_lock =
true;
976 if (got_cleanup_lock)
978 vmbuffer, all_visible_according_to_vm,
1002 || !has_lpdead_items)
1015 if (got_cleanup_lock && vacrel->
nindexes == 0 && has_lpdead_items &&
1020 next_fsm_block_to_vacuum = blkno;
1058 if (blkno > next_fsm_block_to_vacuum)
1089 bool *all_visible_according_to_vm)
1147 if (next_block < vacrel->next_unskippable_block)
1155 *all_visible_according_to_vm =
true;
1191 bool next_unskippable_allvis;
1193 *skipsallvis =
false;
1198 next_unskippable_block,
1199 &next_unskippable_vmbuffer);
1207 if (!next_unskippable_allvis)
1223 if (next_unskippable_block == rel_pages - 1)
1244 *skipsallvis =
true;
1247 next_unskippable_block++;
1413 bool all_visible_according_to_vm,
1414 bool *has_lpdead_items)
1418 int prune_options = 0;
1466 #ifdef USE_ASSERT_CHECKING
1471 bool debug_all_frozen;
1476 &debug_cutoff, &debug_all_frozen))
1526 if (!all_visible_according_to_vm && presult.
all_visible)
1565 elog(
WARNING,
"page is not marked all-visible but visibility map bit is set in relation \"%s\" page %u",
1587 elog(
WARNING,
"page containing LP_DEAD items is marked as all-visible in relation \"%s\" page %u",
1600 else if (all_visible_according_to_vm && presult.
all_visible &&
1654 bool *has_lpdead_items)
1660 recently_dead_tuples,
1674 recently_dead_tuples = 0;
1675 missed_dead_tuples = 0;
1703 deadoffsets[lpdead_items++] = offnum;
1710 &NoFreezePageRelfrozenXid,
1711 &NoFreezePageRelminMxid))
1764 missed_dead_tuples++;
1771 recently_dead_tuples++;
1780 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
1799 if (lpdead_items > 0)
1810 missed_dead_tuples += lpdead_items;
1813 else if (lpdead_items > 0)
1833 if (missed_dead_tuples > 0)
1841 *has_lpdead_items = (lpdead_items > 0);
1988 bool allindexes =
true;
1989 double old_live_tuples = vacrel->
rel->
rd_rel->reltuples;
1990 const int progress_start_index[] = {
1994 const int progress_end_index[] = {
1999 int64 progress_start_val[2];
2000 int64 progress_end_val[3];
2018 progress_start_val[1] = vacrel->
nindexes;
2077 progress_end_val[0] = 0;
2078 progress_end_val[1] = 0;
2134 blkno = iter_result->
blkno;
2135 vacrel->
blkno = blkno;
2174 (
errmsg(
"table \"%s\": removed %lld dead item identifiers in %u pages",
2213 for (
int i = 0;
i < num_offsets;
i++)
2222 unused[nunused++] = toff;
2276 vmbuffer, visibility_cutoff_xid, flags);
2304 const int progress_index[] = {
2308 int64 progress_val[2] = {0, 0};
2328 (
errmsg(
"bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans",
2331 errdetail(
"The table's relfrozenxid or relminmxid is too far in the past."),
2332 errhint(
"Consider increasing configuration parameter maintenance_work_mem or autovacuum_work_mem.\n"
2333 "You might also need to consider other ways for VACUUM to keep up with the allocation of transaction IDs.")));
2353 const int progress_start_index[] = {
2357 const int progress_end_index[] = {
2361 int64 progress_start_val[2];
2362 int64 progress_end_val[2] = {0, 0};
2372 progress_start_val[1] = vacrel->
nindexes;
2384 estimated_count, vacrel);
2423 ivinfo.
index = indrel;
2467 double reltuples,
bool estimated_count,
2473 ivinfo.
index = indrel;
2534 if (possibly_freeable > 0 &&
2550 bool lock_waiter_detected;
2573 lock_waiter_detected =
false;
2594 (
errmsg(
"\"%s\": stopping truncate due to conflicting lock request",
2602 WAIT_EVENT_VACUUM_TRUNCATE);
2612 if (new_rel_pages != orig_rel_pages)
2632 vacrel->
blkno = new_rel_pages;
2634 if (new_rel_pages >= orig_rel_pages)
2664 (
errmsg(
"table \"%s\": truncated %u to %u pages",
2666 orig_rel_pages, new_rel_pages)));
2667 orig_rel_pages = new_rel_pages;
2668 }
while (new_rel_pages > vacrel->
nonempty_pages && lock_waiter_detected);
2694 "prefetch size must be power of 2");
2712 if ((blkno % 32) == 0)
2718 elapsed = currenttime;
2726 (
errmsg(
"table \"%s\": suspending truncate due to conflicting lock request",
2729 *lock_waiter_detected =
true;
2732 starttime = currenttime;
2746 if (prefetchedUntil > blkno)
2752 for (pblkno = prefetchStart; pblkno <= blkno; pblkno++)
2757 prefetchedUntil = prefetchStart;
2845 (
errmsg(
"disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel",
2873 dead_items_info->
max_bytes = vac_work_mem * 1024L;
2956 bool all_visible =
true;
2963 offnum <= maxoff && all_visible;
2988 all_visible =
false;
2989 *all_frozen =
false;
3009 all_visible =
false;
3010 *all_frozen =
false;
3022 all_visible =
false;
3023 *all_frozen =
false;
3030 *visibility_cutoff_xid = xmin;
3033 if (all_visible && *all_frozen &&
3035 *all_frozen =
false;
3044 all_visible =
false;
3045 *all_frozen =
false;
3049 elog(
ERROR,
"unexpected HeapTupleSatisfiesVacuum result");
3072 for (
int idx = 0;
idx < nindexes;
idx++)
3103 switch (errinfo->
phase)
3109 errcontext(
"while scanning block %u offset %u of relation \"%s.%s\"",
3112 errcontext(
"while scanning block %u of relation \"%s.%s\"",
3116 errcontext(
"while scanning relation \"%s.%s\"",
3124 errcontext(
"while vacuuming block %u offset %u of relation \"%s.%s\"",
3127 errcontext(
"while vacuuming block %u of relation \"%s.%s\"",
3131 errcontext(
"while vacuuming relation \"%s.%s\"",
3136 errcontext(
"while vacuuming index \"%s\" of relation \"%s.%s\"",
3141 errcontext(
"while cleaning up index \"%s\" of relation \"%s.%s\"",
3147 errcontext(
"while truncating relation \"%s.%s\" to %u blocks",
3173 vacrel->
blkno = blkno;
3175 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
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
BlockNumber BufferGetBlockNumber(Buffer buffer)
PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBufferForCleanup(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
bool ConditionalLockBufferForCleanup(Buffer buffer)
#define BUFFER_LOCK_UNLOCK
#define BUFFER_LOCK_SHARE
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
#define BUFFER_LOCK_EXCLUSIVE
static bool BufferIsValid(Buffer bufnum)
Size PageGetHeapFreeSpace(Page page)
void PageTruncateLinePointerArray(Page page)
static bool PageIsEmpty(Page page)
static Item PageGetItem(Page page, ItemId itemId)
static void PageClearAllVisible(Page page)
#define SizeOfPageHeaderData
static void PageSetAllVisible(Page page)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static bool PageIsNew(Page page)
static bool PageIsAllVisible(Page page)
static XLogRecPtr PageGetLSN(Page page)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define Assert(condition)
TransactionId MultiXactId
#define StaticAssertStmt(condition, errmessage)
char * get_database_name(Oid dbid)
int errmsg_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
int errhint(const char *fmt,...)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start, BlockNumber end)
Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk)
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
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
#define HeapTupleHeaderGetXmin(tup)
#define HeapTupleHeaderXminCommitted(tup)
#define MaxHeapTuplesPerPage
#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)
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)
#define WL_EXIT_ON_PM_DEATH
void UnlockRelation(Relation relation, LOCKMODE lockmode)
bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode)
#define AccessExclusiveLock
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 MultiXactIdPrecedesOrEquals(MultiXactId multi1, MultiXactId multi2)
#define MultiXactIdIsValid(multi)
#define InvalidMultiXactId
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
const char * pg_rusage_show(const PGRUsage *ru0)
void pg_rusage_init(PGRUsage *ru0)
PgStat_Counter pgStatBlockReadTime
PgStat_Counter pgStatBlockWriteTime
void pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter livetuples, PgStat_Counter deadtuples)
#define qsort(a, b, c, d)
GlobalVisState * GlobalVisTestFor(Relation rel)
#define PROGRESS_VACUUM_PHASE_FINAL_CLEANUP
#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_NUM_INDEX_VACUUMS
#define PROGRESS_VACUUM_PHASE_VACUUM_HEAP
#define PROGRESS_VACUUM_MAX_DEAD_TUPLE_BYTES
#define PROGRESS_VACUUM_HEAP_BLKS_SCANNED
#define PROGRESS_VACUUM_PHASE_INDEX_CLEANUP
#define PROGRESS_VACUUM_PHASE_VACUUM_INDEX
#define PROGRESS_VACUUM_INDEXES_PROCESSED
#define PROGRESS_VACUUM_INDEXES_TOTAL
#define PROGRESS_VACUUM_HEAP_BLKS_VACUUMED
#define PROGRESS_VACUUM_PHASE_TRUNCATE
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)
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)
#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)
struct ErrorContextCallback * previous
void(* callback)(void *arg)
BlockNumber pages_deleted
BlockNumber pages_newly_deleted
BufferAccessStrategy strategy
ParallelVacuumState * pvs
VacDeadItemsInfo * dead_items_info
Buffer next_unskippable_vmbuffer
BlockNumber nonempty_pages
BlockNumber scanned_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 lpdead_item_pages
MultiXactId NewRelminMxid
struct VacuumCutoffs cutoffs
bool next_unskippable_allvis
TransactionId vm_conflict_horizon
OffsetNumber deadoffsets[MaxHeapTuplesPerPage]
TransactionId FreezeLimit
TransactionId relfrozenxid
MultiXactId MultiXactCutoff
VacOptValue index_cleanup
void TidStoreEndIterate(TidStoreIter *iter)
TidStoreIterResult * TidStoreIterateNext(TidStoreIter *iter)
void TidStoreDestroy(TidStore *ts)
TidStore * TidStoreCreateLocal(size_t max_bytes, bool insert_only)
TidStoreIter * TidStoreBeginIterate(TidStore *ts)
void TidStoreSetBlockOffsets(TidStore *ts, BlockNumber blkno, OffsetNumber *offsets, int num_offsets)
size_t TidStoreMemoryUsage(TidStore *ts)
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
static TransactionId ReadNextTransactionId(void)
#define InvalidTransactionId
#define TransactionIdIsValid(xid)
#define TransactionIdIsNormal(xid)
IndexBulkDeleteResult * vac_bulkdel_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat, TidStore *dead_items, VacDeadItemsInfo *dead_items_info)
void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel)
void vac_update_relstats(Relation relation, BlockNumber num_pages, double num_tuples, BlockNumber num_all_visible_pages, bool hasindex, TransactionId frozenxid, MultiXactId minmulti, bool *frozenxid_updated, bool *minmulti_updated, bool in_outer_xact)
void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
void vacuum_delay_point(void)
bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params, struct VacuumCutoffs *cutoffs)
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)
IndexBulkDeleteResult * vac_cleanup_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat)
@ VACOPTVALUE_UNSPECIFIED
#define VACOPT_DISABLE_PAGE_SKIPPING
static void dead_items_cleanup(LVRelState *vacrel)
static bool heap_page_is_all_visible(LVRelState *vacrel, Buffer buf, TransactionId *visibility_cutoff_xid, bool *all_frozen)
static void update_relstats_all_indexes(LVRelState *vacrel)
static void dead_items_add(LVRelState *vacrel, BlockNumber blkno, OffsetNumber *offsets, int num_offsets)
#define VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL
static void vacuum_error_callback(void *arg)
static void lazy_vacuum_heap_page(LVRelState *vacrel, BlockNumber blkno, Buffer buffer, OffsetNumber *offsets, int num_offsets, Buffer vmbuffer)
static void lazy_truncate_heap(LVRelState *vacrel)
static void lazy_vacuum(LVRelState *vacrel)
static void lazy_cleanup_all_indexes(LVRelState *vacrel)
static bool lazy_scan_noprune(LVRelState *vacrel, Buffer buf, BlockNumber blkno, Page page, bool *has_lpdead_items)
#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 bool heap_vac_scan_next_block(LVRelState *vacrel, BlockNumber *blkno, bool *all_visible_according_to_vm)
static void lazy_scan_prune(LVRelState *vacrel, Buffer buf, BlockNumber blkno, Page page, Buffer vmbuffer, bool all_visible_according_to_vm, bool *has_lpdead_items)
void heap_vacuum_rel(Relation rel, VacuumParams *params, BufferAccessStrategy bstrategy)
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)
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 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
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)
TidStore * parallel_vacuum_get_dead_items(ParallelVacuumState *pvs, VacDeadItemsInfo **dead_items_info_p)
void parallel_vacuum_end(ParallelVacuumState *pvs, IndexBulkDeleteResult **istats)
void visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, uint8 flags)
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)
void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen)
#define VM_ALL_FROZEN(r, b, v)
#define VISIBILITYMAP_VALID_BITS
#define VISIBILITYMAP_ALL_FROZEN
#define VISIBILITYMAP_ALL_VISIBLE
bool IsInParallelMode(void)
#define InvalidXLogRecPtr
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)