From 856b5c4bbfcec5078a7bdba77e56fe1f82407bf6 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 15 Jul 2026 17:09:27 +0000 Subject: [PATCH v20 1/2] Introduce LVScanData for lazy heap scan state Group the per-scan counters and trackers that lazy heap scan accumulates into a new struct, LVScanData, pointed to by LVRelState. These are the values built up while scanning the heap, such as page and tuple counts, the oldest extant XID/MXID trackers, the skipped-all-visible flag, and so on. The upcoming parallel heap vacuum will use this. There, each worker scans a disjoint set of blocks and accumulates its own copy of these values. When the scan finishes the leader has to combine them, summing the counters, taking the oldest XID/MXID across workers, and OR-ing the skipped-all-visible flags. Grouping exactly these fields into one struct gives the leader a single, copyable unit to gather from each worker, instead of reaching into each worker's whole LVRelState, most of which is not per-worker scan output at all. No functional change. Author: Masahiko Sawada Author: Bharath Rupireddy Reviewed-by: Amit Kapila Reviewed-by: Hayato Kuroda Reviewed-by: Peter Smith Reviewed-by: Tomas Vondra Reviewed-by: Dilip Kumar Reviewed-by: Melanie Plageman Discussion: https://postgr.es/m/CAD21AoAEfCNv-GgaDheDJ+s-p_Lv1H24AiJeNoPGCmZNSwL1YA@mail.gmail.com --- src/backend/access/heap/vacuumlazy.c | 291 +++++++++++++-------------- src/tools/pgindent/typedefs.list | 1 + 2 files changed, 145 insertions(+), 147 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 39395aed0d5..affd7221c74 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -249,6 +249,55 @@ typedef enum */ #define EAGER_SCAN_REGION_SIZE 4096 +/* + * Data and counters updated during lazy heap scan. + */ +typedef struct LVScanData +{ + BlockNumber scanned_pages; /* # pages examined (not skipped via VM) */ + + /* + * Count of all-visible blocks eagerly scanned (for logging only). This + * does not include skippable blocks scanned due to SKIP_PAGES_THRESHOLD. + */ + BlockNumber eager_scanned_pages; + + BlockNumber removed_pages; /* # pages removed by relation truncation */ + BlockNumber new_frozen_tuple_pages; /* # pages with newly frozen tuples */ + + /* # pages newly set all-visible in the VM */ + BlockNumber new_all_visible_pages; + + /* + * # pages newly set all-visible and all-frozen in the VM. This is a + * subset of new_all_visible_pages. That is, new_all_visible_pages + * includes all pages set all-visible, but + * new_all_visible_all_frozen_pages includes only those which were also + * set all-frozen. + */ + BlockNumber new_all_visible_all_frozen_pages; + + /* # all-visible pages newly set all-frozen in the VM */ + BlockNumber new_all_frozen_pages; + + BlockNumber lpdead_item_pages; /* # pages with LP_DEAD items */ + BlockNumber missed_dead_pages; /* # pages with missed dead tuples */ + BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */ + + /* Counters that follow are only for scanned_pages */ + int64 tuples_deleted; /* # deleted from table */ + int64 tuples_frozen; /* # newly frozen */ + int64 lpdead_items; /* # deleted from indexes */ + int64 live_tuples; /* # live tuples remaining */ + int64 recently_dead_tuples; /* # dead, but not yet removable */ + int64 missed_dead_tuples; /* # removable, but not removed */ + + /* Tracks oldest extant XID/MXID for setting relfrozenxid/relminmxid. */ + TransactionId NewRelfrozenXid; + MultiXactId NewRelminMxid; + bool skippedallvis; +} LVScanData; + typedef struct LVRelState { /* Target heap relation and its indexes */ @@ -275,10 +324,6 @@ typedef struct LVRelState /* VACUUM operation's cutoffs for freezing and pruning */ struct VacuumCutoffs cutoffs; GlobalVisState *vistest; - /* Tracks oldest extant XID/MXID for setting relfrozenxid/relminmxid */ - TransactionId NewRelfrozenXid; - MultiXactId NewRelminMxid; - bool skippedallvis; /* Error reporting state */ char *dbname; @@ -304,35 +349,9 @@ typedef struct LVRelState VacDeadItemsInfo *dead_items_info; BlockNumber rel_pages; /* total number of pages */ - BlockNumber scanned_pages; /* # pages examined (not skipped via VM) */ - - /* - * Count of all-visible blocks eagerly scanned (for logging only). This - * does not include skippable blocks scanned due to SKIP_PAGES_THRESHOLD. - */ - BlockNumber eager_scanned_pages; - - BlockNumber removed_pages; /* # pages removed by relation truncation */ - BlockNumber new_frozen_tuple_pages; /* # pages with newly frozen tuples */ - - /* # pages newly set all-visible in the VM */ - BlockNumber new_all_visible_pages; - - /* - * # pages newly set all-visible and all-frozen in the VM. This is a - * subset of new_all_visible_pages. That is, new_all_visible_pages - * includes all pages set all-visible, but - * new_all_visible_all_frozen_pages includes only those which were also - * set all-frozen. - */ - BlockNumber new_all_visible_all_frozen_pages; - /* # all-visible pages newly set all-frozen in the VM */ - BlockNumber new_all_frozen_pages; - - BlockNumber lpdead_item_pages; /* # pages with LP_DEAD items */ - BlockNumber missed_dead_pages; /* # pages with missed dead tuples */ - BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */ + /* Data and counters updated during lazy heap scan */ + LVScanData *heap_scan_data; /* Statistics output by us, for table */ double new_rel_tuples; /* new estimated total # of tuples */ @@ -351,14 +370,6 @@ typedef struct LVRelState */ PVWorkerUsage worker_usage; - /* Counters that follow are only for scanned_pages */ - int64 tuples_deleted; /* # deleted from table */ - int64 tuples_frozen; /* # newly frozen */ - int64 lpdead_items; /* # deleted from indexes */ - int64 live_tuples; /* # live tuples remaining */ - int64 recently_dead_tuples; /* # dead, but not yet removable */ - int64 missed_dead_tuples; /* # removable, but not removed */ - /* State maintained by heap_vac_scan_next_block() */ BlockNumber current_block; /* last block returned */ BlockNumber next_unskippable_block; /* next unskippable block */ @@ -747,15 +758,8 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, Assert(params->index_cleanup == VACOPTVALUE_AUTO); } - /* Initialize page counters explicitly (be tidy) */ - vacrel->scanned_pages = 0; - vacrel->eager_scanned_pages = 0; - vacrel->removed_pages = 0; - vacrel->new_frozen_tuple_pages = 0; - vacrel->lpdead_item_pages = 0; - vacrel->missed_dead_pages = 0; - vacrel->nonempty_pages = 0; - /* dead_items_alloc allocates vacrel->dead_items later on */ + /* All counters start at zero; a few fields are initialized below */ + vacrel->heap_scan_data = palloc0(sizeof(LVScanData)); /* Allocate/initialize output statistics state */ vacrel->new_rel_tuples = 0; @@ -767,22 +771,14 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, vacrel->num_index_scans = 0; vacrel->num_dead_items_resets = 0; vacrel->total_dead_items_bytes = 0; - vacrel->tuples_deleted = 0; - vacrel->tuples_frozen = 0; - vacrel->lpdead_items = 0; - vacrel->live_tuples = 0; - vacrel->recently_dead_tuples = 0; - vacrel->missed_dead_tuples = 0; - - vacrel->new_all_visible_pages = 0; - vacrel->new_all_visible_all_frozen_pages = 0; - vacrel->new_all_frozen_pages = 0; vacrel->worker_usage.vacuum.nlaunched = 0; vacrel->worker_usage.vacuum.nplanned = 0; vacrel->worker_usage.cleanup.nlaunched = 0; vacrel->worker_usage.cleanup.nplanned = 0; + /* dead_items_alloc allocates vacrel->dead_items later on */ + /* * Get cutoffs that determine which deleted tuples are considered DEAD, * not just RECENTLY_DEAD, and which XIDs/MXIDs to freeze. Then determine @@ -804,15 +800,15 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, vacrel->vistest = GlobalVisTestFor(rel); /* Initialize state used to track oldest extant XID/MXID */ - vacrel->NewRelfrozenXid = vacrel->cutoffs.OldestXmin; - vacrel->NewRelminMxid = vacrel->cutoffs.OldestMxact; + vacrel->heap_scan_data->NewRelfrozenXid = vacrel->cutoffs.OldestXmin; + vacrel->heap_scan_data->NewRelminMxid = vacrel->cutoffs.OldestMxact; /* * Initialize state related to tracking all-visible page skipping. This is * very important to determine whether or not it is safe to advance the * relfrozenxid/relminmxid. */ - vacrel->skippedallvis = false; + vacrel->heap_scan_data->skippedallvis = false; skipwithvm = true; if (params->options & VACOPT_DISABLE_PAGE_SKIPPING) { @@ -925,15 +921,15 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, * value >= FreezeLimit, and relminmxid to a value >= MultiXactCutoff. * Non-aggressive VACUUMs may advance them by any amount, or not at all. */ - Assert(vacrel->NewRelfrozenXid == vacrel->cutoffs.OldestXmin || + Assert(vacrel->heap_scan_data->NewRelfrozenXid == vacrel->cutoffs.OldestXmin || TransactionIdPrecedesOrEquals(vacrel->aggressive ? vacrel->cutoffs.FreezeLimit : vacrel->cutoffs.relfrozenxid, - vacrel->NewRelfrozenXid)); - Assert(vacrel->NewRelminMxid == vacrel->cutoffs.OldestMxact || + vacrel->heap_scan_data->NewRelfrozenXid)); + Assert(vacrel->heap_scan_data->NewRelminMxid == vacrel->cutoffs.OldestMxact || MultiXactIdPrecedesOrEquals(vacrel->aggressive ? vacrel->cutoffs.MultiXactCutoff : vacrel->cutoffs.relminmxid, - vacrel->NewRelminMxid)); - if (vacrel->skippedallvis) + vacrel->heap_scan_data->NewRelminMxid)); + if (vacrel->heap_scan_data->skippedallvis) { /* * Must keep original relfrozenxid in a non-aggressive VACUUM that @@ -941,8 +937,8 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, * values will have missed unfrozen XIDs from the pages we skipped. */ Assert(!vacrel->aggressive); - vacrel->NewRelfrozenXid = InvalidTransactionId; - vacrel->NewRelminMxid = InvalidMultiXactId; + vacrel->heap_scan_data->NewRelfrozenXid = InvalidTransactionId; + vacrel->heap_scan_data->NewRelminMxid = InvalidMultiXactId; } /* @@ -972,7 +968,8 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, vac_update_relstats(rel, new_rel_pages, vacrel->new_live_tuples, new_rel_allvisible, new_rel_allfrozen, vacrel->nindexes > 0, - vacrel->NewRelfrozenXid, vacrel->NewRelminMxid, + vacrel->heap_scan_data->NewRelfrozenXid, + vacrel->heap_scan_data->NewRelminMxid, &frozenxid_updated, &minmulti_updated, false); /* @@ -987,8 +984,8 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, */ pgstat_report_vacuum(rel, Max(vacrel->new_live_tuples, 0), - vacrel->recently_dead_tuples + - vacrel->missed_dead_tuples, + vacrel->heap_scan_data->recently_dead_tuples + + vacrel->heap_scan_data->missed_dead_tuples, starttime); pgstat_progress_end_command(); @@ -1062,23 +1059,23 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, vacrel->relname, vacrel->num_index_scans); appendStringInfo(&buf, _("pages: %u removed, %u remain, %u scanned (%.2f%% of total), %u eagerly scanned\n"), - vacrel->removed_pages, + vacrel->heap_scan_data->removed_pages, new_rel_pages, - vacrel->scanned_pages, + vacrel->heap_scan_data->scanned_pages, orig_rel_pages == 0 ? 100.0 : - 100.0 * vacrel->scanned_pages / + 100.0 * vacrel->heap_scan_data->scanned_pages / orig_rel_pages, - vacrel->eager_scanned_pages); + vacrel->heap_scan_data->eager_scanned_pages); appendStringInfo(&buf, _("tuples: %" PRId64 " removed, %" PRId64 " remain, %" PRId64 " are dead but not yet removable\n"), - vacrel->tuples_deleted, + vacrel->heap_scan_data->tuples_deleted, (int64) vacrel->new_rel_tuples, - vacrel->recently_dead_tuples); - if (vacrel->missed_dead_tuples > 0) + vacrel->heap_scan_data->recently_dead_tuples); + if (vacrel->heap_scan_data->missed_dead_tuples > 0) appendStringInfo(&buf, _("tuples missed: %" PRId64 " dead from %u pages not removed due to cleanup lock contention\n"), - vacrel->missed_dead_tuples, - vacrel->missed_dead_pages); + vacrel->heap_scan_data->missed_dead_tuples, + vacrel->heap_scan_data->missed_dead_pages); diff = (int32) (ReadNextTransactionId() - vacrel->cutoffs.OldestXmin); appendStringInfo(&buf, @@ -1086,33 +1083,33 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, vacrel->cutoffs.OldestXmin, diff); if (frozenxid_updated) { - diff = (int32) (vacrel->NewRelfrozenXid - + diff = (int32) (vacrel->heap_scan_data->NewRelfrozenXid - vacrel->cutoffs.relfrozenxid); appendStringInfo(&buf, _("new relfrozenxid: %u, which is %d XIDs ahead of previous value\n"), - vacrel->NewRelfrozenXid, diff); + vacrel->heap_scan_data->NewRelfrozenXid, diff); } if (minmulti_updated) { - diff = (int32) (vacrel->NewRelminMxid - + diff = (int32) (vacrel->heap_scan_data->NewRelminMxid - vacrel->cutoffs.relminmxid); appendStringInfo(&buf, _("new relminmxid: %u, which is %d MXIDs ahead of previous value\n"), - vacrel->NewRelminMxid, diff); + vacrel->heap_scan_data->NewRelminMxid, diff); } appendStringInfo(&buf, _("frozen: %u pages from table (%.2f%% of total) had %" PRId64 " tuples frozen\n"), - vacrel->new_frozen_tuple_pages, + vacrel->heap_scan_data->new_frozen_tuple_pages, orig_rel_pages == 0 ? 100.0 : - 100.0 * vacrel->new_frozen_tuple_pages / + 100.0 * vacrel->heap_scan_data->new_frozen_tuple_pages / orig_rel_pages, - vacrel->tuples_frozen); + vacrel->heap_scan_data->tuples_frozen); appendStringInfo(&buf, _("visibility map: %u pages set all-visible, %u pages set all-frozen (%u were all-visible)\n"), - vacrel->new_all_visible_pages, - vacrel->new_all_visible_all_frozen_pages + - vacrel->new_all_frozen_pages, - vacrel->new_all_frozen_pages); + vacrel->heap_scan_data->new_all_visible_pages, + vacrel->heap_scan_data->new_all_visible_all_frozen_pages + + vacrel->heap_scan_data->new_all_frozen_pages, + vacrel->heap_scan_data->new_all_frozen_pages); if (vacrel->do_index_vacuuming) { if (vacrel->nindexes == 0 || vacrel->num_index_scans == 0) @@ -1132,10 +1129,10 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, msgfmt = _("%u pages from table (%.2f%% of total) have %" PRId64 " dead item identifiers\n"); } appendStringInfo(&buf, msgfmt, - vacrel->lpdead_item_pages, + vacrel->heap_scan_data->lpdead_item_pages, orig_rel_pages == 0 ? 100.0 : - 100.0 * vacrel->lpdead_item_pages / orig_rel_pages, - vacrel->lpdead_items); + 100.0 * vacrel->heap_scan_data->lpdead_item_pages / orig_rel_pages, + vacrel->heap_scan_data->lpdead_items); if (vacrel->worker_usage.vacuum.nplanned > 0) appendStringInfo(&buf, @@ -1340,8 +1337,8 @@ lazy_scan_heap(LVRelState *vacrel) * one-pass strategy, and the two-pass strategy with the index_cleanup * param set to 'off'. */ - if (vacrel->scanned_pages > 0 && - vacrel->scanned_pages % FAILSAFE_EVERY_PAGES == 0) + if (vacrel->heap_scan_data->scanned_pages > 0 && + vacrel->heap_scan_data->scanned_pages % FAILSAFE_EVERY_PAGES == 0) lazy_check_wraparound_failsafe(vacrel); /* @@ -1396,9 +1393,9 @@ lazy_scan_heap(LVRelState *vacrel) page = BufferGetPage(buf); blkno = BufferGetBlockNumber(buf); - vacrel->scanned_pages++; + vacrel->heap_scan_data->scanned_pages++; if (was_eager_scanned) - vacrel->eager_scanned_pages++; + vacrel->heap_scan_data->eager_scanned_pages++; /* Report as block scanned, update error traceback information */ pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno); @@ -1583,16 +1580,16 @@ lazy_scan_heap(LVRelState *vacrel) /* now we can compute the new value for pg_class.reltuples */ vacrel->new_live_tuples = vac_estimate_reltuples(vacrel->rel, rel_pages, - vacrel->scanned_pages, - vacrel->live_tuples); + vacrel->heap_scan_data->scanned_pages, + vacrel->heap_scan_data->live_tuples); /* * Also compute the total number of surviving heap entries. In the * (unlikely) scenario that new_live_tuples is -1, take it as zero. */ vacrel->new_rel_tuples = - Max(vacrel->new_live_tuples, 0) + vacrel->recently_dead_tuples + - vacrel->missed_dead_tuples; + Max(vacrel->new_live_tuples, 0) + vacrel->heap_scan_data->recently_dead_tuples + + vacrel->heap_scan_data->missed_dead_tuples; read_stream_end(stream); @@ -1639,7 +1636,7 @@ lazy_scan_heap(LVRelState *vacrel) * callback_private_data contains a reference to the LVRelState, passed to the * read stream API during stream setup. The LVRelState is an in/out parameter * here (locally named `vacrel`). Vacuum options and information about the - * relation are read from it. vacrel->skippedallvis is set if we skip a block + * relation are read from it. vacrel->heap_scan_data->skippedallvis is set if we skip a block * that's all-visible but not all-frozen (to ensure that we don't update * relfrozenxid in that case). vacrel also holds information about the next * unskippable block -- as bookkeeping for this function. @@ -1700,7 +1697,7 @@ heap_vac_scan_next_block(ReadStream *stream, { next_block = vacrel->next_unskippable_block; if (skipsallvis) - vacrel->skippedallvis = true; + vacrel->heap_scan_data->skippedallvis = true; } } @@ -1979,8 +1976,8 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno, LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); /* Count the newly all-frozen pages for logging */ - vacrel->new_all_visible_pages++; - vacrel->new_all_visible_all_frozen_pages++; + vacrel->heap_scan_data->new_all_visible_pages++; + vacrel->heap_scan_data->new_all_visible_all_frozen_pages++; } freespace = PageGetHeapFreeSpace(page); @@ -2071,10 +2068,10 @@ lazy_scan_prune(LVRelState *vacrel, heap_page_prune_and_freeze(¶ms, &presult, &vacrel->offnum, - &vacrel->NewRelfrozenXid, &vacrel->NewRelminMxid); + &vacrel->heap_scan_data->NewRelfrozenXid, &vacrel->heap_scan_data->NewRelminMxid); - Assert(MultiXactIdIsValid(vacrel->NewRelminMxid)); - Assert(TransactionIdIsValid(vacrel->NewRelfrozenXid)); + Assert(MultiXactIdIsValid(vacrel->heap_scan_data->NewRelminMxid)); + Assert(TransactionIdIsValid(vacrel->heap_scan_data->NewRelfrozenXid)); if (presult.nfrozen > 0) { @@ -2084,7 +2081,7 @@ lazy_scan_prune(LVRelState *vacrel, * frozen tuples (don't confuse that with pages newly set all-frozen * in VM). */ - vacrel->new_frozen_tuple_pages++; + vacrel->heap_scan_data->new_frozen_tuple_pages++; } /* @@ -2092,7 +2089,7 @@ lazy_scan_prune(LVRelState *vacrel, */ if (presult.lpdead_items > 0) { - vacrel->lpdead_item_pages++; + vacrel->heap_scan_data->lpdead_item_pages++; /* * deadoffsets are collected incrementally in @@ -2108,25 +2105,25 @@ lazy_scan_prune(LVRelState *vacrel, /* Finally, add page-local counts to whole-VACUUM counts */ if (presult.newly_all_visible) - vacrel->new_all_visible_pages++; + vacrel->heap_scan_data->new_all_visible_pages++; if (presult.newly_all_visible_frozen) - vacrel->new_all_visible_all_frozen_pages++; + vacrel->heap_scan_data->new_all_visible_all_frozen_pages++; if (presult.newly_all_frozen) - vacrel->new_all_frozen_pages++; + vacrel->heap_scan_data->new_all_frozen_pages++; /* Capture if the page was newly set frozen */ *vm_page_frozen = presult.newly_all_visible_frozen || presult.newly_all_frozen; - vacrel->tuples_deleted += presult.ndeleted; - vacrel->tuples_frozen += presult.nfrozen; - vacrel->lpdead_items += presult.lpdead_items; - vacrel->live_tuples += presult.live_tuples; - vacrel->recently_dead_tuples += presult.recently_dead_tuples; + vacrel->heap_scan_data->tuples_deleted += presult.ndeleted; + vacrel->heap_scan_data->tuples_frozen += presult.nfrozen; + vacrel->heap_scan_data->lpdead_items += presult.lpdead_items; + vacrel->heap_scan_data->live_tuples += presult.live_tuples; + vacrel->heap_scan_data->recently_dead_tuples += presult.recently_dead_tuples; /* Can't truncate this page */ if (presult.hastup) - vacrel->nonempty_pages = blkno + 1; + vacrel->heap_scan_data->nonempty_pages = blkno + 1; /* Did we find LP_DEAD items? */ *has_lpdead_items = (presult.lpdead_items > 0); @@ -2169,8 +2166,8 @@ lazy_scan_noprune(LVRelState *vacrel, missed_dead_tuples; bool hastup; HeapTupleHeader tupleheader; - TransactionId NoFreezePageRelfrozenXid = vacrel->NewRelfrozenXid; - MultiXactId NoFreezePageRelminMxid = vacrel->NewRelminMxid; + TransactionId NoFreezePageRelfrozenXid = vacrel->heap_scan_data->NewRelfrozenXid; + MultiXactId NoFreezePageRelminMxid = vacrel->heap_scan_data->NewRelminMxid; OffsetNumber deadoffsets[MaxHeapTuplesPerPage]; Assert(BufferGetBlockNumber(buf) == blkno); @@ -2297,8 +2294,8 @@ lazy_scan_noprune(LVRelState *vacrel, * this particular page until the next VACUUM. Remember its details now. * (lazy_scan_prune expects a clean slate, so we have to do this last.) */ - vacrel->NewRelfrozenXid = NoFreezePageRelfrozenXid; - vacrel->NewRelminMxid = NoFreezePageRelminMxid; + vacrel->heap_scan_data->NewRelfrozenXid = NoFreezePageRelfrozenXid; + vacrel->heap_scan_data->NewRelminMxid = NoFreezePageRelminMxid; /* Save any LP_DEAD items found on the page in dead_items */ if (vacrel->nindexes == 0) @@ -2325,25 +2322,25 @@ lazy_scan_noprune(LVRelState *vacrel, * indexes will be deleted during index vacuuming (and then marked * LP_UNUSED in the heap) */ - vacrel->lpdead_item_pages++; + vacrel->heap_scan_data->lpdead_item_pages++; dead_items_add(vacrel, blkno, deadoffsets, lpdead_items); - vacrel->lpdead_items += lpdead_items; + vacrel->heap_scan_data->lpdead_items += lpdead_items; } /* * Finally, add relevant page-local counts to whole-VACUUM counts */ - vacrel->live_tuples += live_tuples; - vacrel->recently_dead_tuples += recently_dead_tuples; - vacrel->missed_dead_tuples += missed_dead_tuples; + vacrel->heap_scan_data->live_tuples += live_tuples; + vacrel->heap_scan_data->recently_dead_tuples += recently_dead_tuples; + vacrel->heap_scan_data->missed_dead_tuples += missed_dead_tuples; if (missed_dead_tuples > 0) - vacrel->missed_dead_pages++; + vacrel->heap_scan_data->missed_dead_pages++; /* Can't truncate this page */ if (hastup) - vacrel->nonempty_pages = blkno + 1; + vacrel->heap_scan_data->nonempty_pages = blkno + 1; /* Did we find LP_DEAD items? */ *has_lpdead_items = (lpdead_items > 0); @@ -2372,7 +2369,7 @@ lazy_vacuum(LVRelState *vacrel) /* Should not end up here with no indexes */ Assert(vacrel->nindexes > 0); - Assert(vacrel->lpdead_item_pages > 0); + Assert(vacrel->heap_scan_data->lpdead_item_pages > 0); if (!vacrel->do_index_vacuuming) { @@ -2406,7 +2403,7 @@ lazy_vacuum(LVRelState *vacrel) BlockNumber threshold; Assert(vacrel->num_index_scans == 0); - Assert(vacrel->lpdead_items == vacrel->dead_items_info->num_items); + Assert(vacrel->heap_scan_data->lpdead_items == vacrel->dead_items_info->num_items); Assert(vacrel->do_index_vacuuming); Assert(vacrel->do_index_cleanup); @@ -2433,7 +2430,7 @@ lazy_vacuum(LVRelState *vacrel) * cases then this may need to be reconsidered. */ threshold = (double) vacrel->rel_pages * BYPASS_THRESHOLD_PAGES; - bypass = (vacrel->lpdead_item_pages < threshold && + bypass = (vacrel->heap_scan_data->lpdead_item_pages < threshold && TidStoreMemoryUsage(vacrel->dead_items) < 32 * 1024 * 1024); } @@ -2572,7 +2569,7 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) * place). */ Assert(vacrel->num_index_scans > 0 || - vacrel->dead_items_info->num_items == vacrel->lpdead_items); + vacrel->dead_items_info->num_items == vacrel->heap_scan_data->lpdead_items); Assert(allindexes || VacuumFailsafeActive); /* @@ -2734,8 +2731,8 @@ lazy_vacuum_heap_rel(LVRelState *vacrel) * the second heap pass. No more, no less. */ Assert(vacrel->num_index_scans > 1 || - (vacrel->dead_items_info->num_items == vacrel->lpdead_items && - vacuumed_pages == vacrel->lpdead_item_pages)); + (vacrel->dead_items_info->num_items == vacrel->heap_scan_data->lpdead_items && + vacuumed_pages == vacrel->heap_scan_data->lpdead_item_pages)); ereport(DEBUG2, (errmsg("table \"%s\": removed %" PRId64 " dead item identifiers in %u pages", @@ -2865,9 +2862,9 @@ lazy_vacuum_heap_page(LVRelState *vacrel, BlockNumber blkno, Buffer buffer, { /* Count the newly set VM page for logging */ LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK); - vacrel->new_all_visible_pages++; + vacrel->heap_scan_data->new_all_visible_pages++; if (all_frozen) - vacrel->new_all_visible_all_frozen_pages++; + vacrel->heap_scan_data->new_all_visible_all_frozen_pages++; } /* Revert to the previous phase information for error traceback */ @@ -2944,7 +2941,7 @@ static void lazy_cleanup_all_indexes(LVRelState *vacrel) { double reltuples = vacrel->new_rel_tuples; - bool estimated_count = vacrel->scanned_pages < vacrel->rel_pages; + bool estimated_count = vacrel->heap_scan_data->scanned_pages < vacrel->rel_pages; const int progress_start_index[] = { PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_INDEXES_TOTAL @@ -3126,7 +3123,7 @@ should_attempt_truncation(LVRelState *vacrel) if (!vacrel->do_rel_truncate || VacuumFailsafeActive) return false; - possibly_freeable = vacrel->rel_pages - vacrel->nonempty_pages; + possibly_freeable = vacrel->rel_pages - vacrel->heap_scan_data->nonempty_pages; if (possibly_freeable > 0 && (possibly_freeable >= REL_TRUNCATE_MINIMUM || possibly_freeable >= vacrel->rel_pages / REL_TRUNCATE_FRACTION)) @@ -3152,7 +3149,7 @@ lazy_truncate_heap(LVRelState *vacrel) /* Update error traceback information one last time */ update_vacuum_error_info(vacrel, NULL, VACUUM_ERRCB_PHASE_TRUNCATE, - vacrel->nonempty_pages, InvalidOffsetNumber); + vacrel->heap_scan_data->nonempty_pages, InvalidOffsetNumber); /* * Loop until no more truncating can be done. @@ -3253,7 +3250,7 @@ lazy_truncate_heap(LVRelState *vacrel) * without also touching reltuples, since the tuple count wasn't * changed by the truncation. */ - vacrel->removed_pages += orig_rel_pages - new_rel_pages; + vacrel->heap_scan_data->removed_pages += orig_rel_pages - new_rel_pages; vacrel->rel_pages = new_rel_pages; ereport(vacrel->verbose ? INFO : DEBUG2, @@ -3261,7 +3258,7 @@ lazy_truncate_heap(LVRelState *vacrel) vacrel->relname, orig_rel_pages, new_rel_pages))); orig_rel_pages = new_rel_pages; - } while (new_rel_pages > vacrel->nonempty_pages && lock_waiter_detected); + } while (new_rel_pages > vacrel->heap_scan_data->nonempty_pages && lock_waiter_detected); } /* @@ -3290,7 +3287,7 @@ count_nondeletable_pages(LVRelState *vacrel, bool *lock_waiter_detected) */ blkno = vacrel->rel_pages; prefetchedUntil = InvalidBlockNumber; - while (blkno > vacrel->nonempty_pages) + while (blkno > vacrel->heap_scan_data->nonempty_pages) { Buffer buf; Page page; @@ -3402,7 +3399,7 @@ count_nondeletable_pages(LVRelState *vacrel, bool *lock_waiter_detected) * pages still are; we need not bother to look at the last known-nonempty * page. */ - return vacrel->nonempty_pages; + return vacrel->heap_scan_data->nonempty_pages; } /* diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 56c1f997f88..223dfc80417 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -1611,6 +1611,7 @@ LSEG LUID LVRelState LVSavedErrInfo +LVScanData LWLock LWLockHandle LWLockMode -- 2.47.3