Hi Sawada-san, Thank you for your additional feedback on v4!
>We can initialize dead_items_max_bytes when declared. Thank you. I fixed it as you mentioned. >Does it need to check if vacrel->dead_items is non-NULL? Thank you. I fixed it as you mentioned. >I think we should not use "index scans" since the number doesn't >actually represent the number of index scans performed. How about >something like: > >memory usage: 1.02 MB in total, with dead-item storage reset 15 times >(limit was 0.06 MB) > >Also when it comes to the plural, we can use errmsg_plural() instead. Thank you. I fixed the message as you mentioned. Also, I found that ngettext() with appendStringInfo() is a standard pattern in the PostgreSQL codebase (e.g., src/backend/catalog/pg_shdepend.c, src/backend/catalog/dependency.c), so I use ngettext() in this code. If it's good to use errmsg_plural(), I can restructure the code to use errmsg_plural(). Best regards, Tatsuya Kawata
From b288449035f2d35bf393fbd93ea7c98d71ea1aaf Mon Sep 17 00:00:00 2001 From: TatsuyaKawata <[email protected]> Date: Sat, 22 Nov 2025 01:19:33 +0900 Subject: [PATCH v5] Add memory usage reporting to VACUUM VERBOSE --- src/backend/access/heap/vacuumlazy.c | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 65bb0568a86..826db728418 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 = 0; /* # save max_bytes before cleanup */ verbose = (params.options & VACOPT_VERBOSE) != 0; instrument = (verbose || (AmAutoVacuumWorkerProcess() && @@ -765,6 +768,8 @@ 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; @@ -844,6 +849,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 +1165,19 @@ 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. + * Note: num_dead_items_resets includes the final reset that occurs + * at the end of vacuum, so the count represents all resets including + * the last one. + */ + appendStringInfo(&buf, + ngettext("memory usage: %.2f MB in total, with dead-item storage reset %d time (limit was %.2f MB)\n", + "memory usage: %.2f MB in total, with dead-item storage reset %d times (limit was %.2f MB)\n", + vacrel->num_dead_items_resets), + (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, @@ -3603,6 +3627,12 @@ 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 */ + vacrel->total_dead_items_bytes += TidStoreMemoryUsage(vacrel->dead_items); + if (ParallelVacuumIsActive(vacrel)) { parallel_vacuum_reset_dead_items(vacrel->pvs); -- 2.34.1
