From a42ebb4ea9847607106aa6a1f34b58882f6edc1e Mon Sep 17 00:00:00 2001 From: TatsuyaKawata Date: Thu, 20 Nov 2025 22:46:57 +0900 Subject: [PATCH v4] Add memory usage reporting to VACUUM VERBOSE --- src/backend/access/heap/vacuumlazy.c | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index deb9a3dc0d1..14f6f1ec1cf 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -347,6 +347,8 @@ typedef struct LVRelState /* Instrumentation counters */ int num_index_scans; + int num_dead_items_resets; /* # times dead_items was reset */ + Size total_dead_items_bytes; /* # total memory usage for dead_items */ /* Counters that follow are only for scanned_pages */ int64 tuples_deleted; /* # deleted from table */ int64 tuples_frozen; /* # newly frozen */ @@ -645,6 +647,7 @@ heap_vacuum_rel(Relation rel, const VacuumParams params, BufferUsage startbufferusage = pgBufferUsage; ErrorContextCallback errcallback; char **indnames = NULL; + Size dead_items_max_bytes; /* # save max_bytes before cleanup */ verbose = (params.options & VACOPT_VERBOSE) != 0; instrument = (verbose || (AmAutoVacuumWorkerProcess() && @@ -765,11 +768,14 @@ heap_vacuum_rel(Relation rel, const VacuumParams params, vacrel->live_tuples = 0; vacrel->recently_dead_tuples = 0; vacrel->missed_dead_tuples = 0; + vacrel->total_dead_items_bytes = 0; + vacrel->num_dead_items_resets = 0; vacrel->vm_new_visible_pages = 0; vacrel->vm_new_visible_frozen_pages = 0; vacrel->vm_new_frozen_pages = 0; + dead_items_max_bytes = 0; /* * Get cutoffs that determine which deleted tuples are considered DEAD, * not just RECENTLY_DEAD, and which XIDs/MXIDs to freeze. Then determine @@ -844,6 +850,12 @@ heap_vacuum_rel(Relation rel, const VacuumParams params, lazy_check_wraparound_failsafe(vacrel); dead_items_alloc(vacrel, params.nworkers); + /* + * Save max_bytes before cleanup, as dead_items_info may be freed in + * parallel mode during dead_items_cleanup(). + */ + dead_items_max_bytes = vacrel->dead_items_info->max_bytes; + /* * Call lazy_scan_heap to perform all required heap pruning, index * vacuuming, and heap vacuuming (plus related processing) @@ -1154,6 +1166,14 @@ heap_vacuum_rel(Relation rel, const VacuumParams params, walusage.wal_bytes, walusage.wal_fpi_bytes, walusage.wal_buffers_full); + /* + * Report memory usage for dead_items tracking. + */ + appendStringInfo(&buf, + _("memory usage: total %.2f MB used across %d index scan(s) (max mem space is limited %.2f MB at once)\n"), + (double) vacrel->total_dead_items_bytes / (1024.0 * 1024.0), + vacrel->num_dead_items_resets, + (double) dead_items_max_bytes / (1024.0 * 1024.0)); appendStringInfo(&buf, _("system usage: %s"), pg_rusage_show(&ru0)); ereport(verbose ? INFO : LOG, @@ -3598,6 +3618,15 @@ dead_items_add(LVRelState *vacrel, BlockNumber blkno, OffsetNumber *offsets, static void dead_items_reset(LVRelState *vacrel) { + /* Increment dead_items reset counter */ + vacrel->num_dead_items_resets++; + + /* Track total memory usage for dead_items */ + if (vacrel->dead_items != NULL) + { + vacrel->total_dead_items_bytes += TidStoreMemoryUsage(vacrel->dead_items); + } + if (ParallelVacuumIsActive(vacrel)) { parallel_vacuum_reset_dead_items(vacrel->pvs); -- 2.34.1