From 2e547455062da050f437a5c9b52648a6e11e8e9b Mon Sep 17 00:00:00 2001
From: TatsuyaKawata <kawatatatsuya0913@gmail.com>
Date: Tue, 18 Nov 2025 23:45:24 +0900
Subject: [PATCH v2] 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 deb9a3dc0d1..577197917d8 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -355,6 +355,9 @@ typedef struct LVRelState
 	int64		recently_dead_tuples;	/* # dead, but not yet removable */
 	int64		missed_dead_tuples; /* # removable, but not removed */
 
+	/* Total memory usage tracking for dead_items */
+	Size		total_dead_items_bytes;
+
 	/* State maintained by heap_vac_scan_next_block() */
 	BlockNumber current_block;	/* last block returned */
 	BlockNumber next_unskippable_block; /* next unskippable block */
@@ -765,6 +768,7 @@ 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->vm_new_visible_pages = 0;
 	vacrel->vm_new_visible_frozen_pages = 0;
@@ -975,6 +979,7 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
 			int64		total_blks_hit;
 			int64		total_blks_read;
 			int64		total_blks_dirtied;
+			int			vac_work_mem;
 
 			TimestampDifference(starttime, endtime, &secs_dur, &usecs_dur);
 			memset(&walusage, 0, sizeof(WalUsage));
@@ -1154,6 +1159,18 @@ 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 */
+			vac_work_mem = AmAutoVacuumWorkerProcess() &&
+						autovacuum_work_mem != -1 ?
+						autovacuum_work_mem : maintenance_work_mem;
+
+			appendStringInfo(&buf,
+							_("total memory usage: %.2f MB of %.2f MB allowed\n"),
+							(double) vacrel->total_dead_items_bytes / (1024.0 * 1024.0),
+							(double) vac_work_mem / 1024.0
+							);
+
 			appendStringInfo(&buf, _("system usage: %s"), pg_rusage_show(&ru0));
 
 			ereport(verbose ? INFO : LOG,
@@ -2576,6 +2593,17 @@ lazy_vacuum(LVRelState *vacrel)
 		Assert(VacuumFailsafeActive);
 	}
 
+/*
+ * Add current memory usage to the running total before resetting.
+ * This tracks cumulative memory across all index vacuum cycles.
+ */
+	if (vacrel->dead_items != NULL)
+	{
+		Size		final_bytes = TidStoreMemoryUsage(vacrel->dead_items);
+
+		vacrel->total_dead_items_bytes += final_bytes;
+	}
+
 	/*
 	 * Forget the LP_DEAD items that we just vacuumed (or just decided to not
 	 * vacuum)
@@ -3553,6 +3581,7 @@ dead_items_alloc(LVRelState *vacrel, int nworkers)
 		{
 			vacrel->dead_items = parallel_vacuum_get_dead_items(vacrel->pvs,
 																&vacrel->dead_items_info);
+
 			return;
 		}
 	}
@@ -3598,6 +3627,7 @@ dead_items_add(LVRelState *vacrel, BlockNumber blkno, OffsetNumber *offsets,
 static void
 dead_items_reset(LVRelState *vacrel)
 {
+
 	if (ParallelVacuumIsActive(vacrel))
 	{
 		parallel_vacuum_reset_dead_items(vacrel->pvs);
-- 
2.34.1

