Hi,

I noticed that in lazy_scan_heap(), when there are no indexes on the
table being vacuumed, we don't release the lock on the heap page buffer
before vacuuming the freespace map. Other call sites of
FreeSpaceMapVacuumRange() hold no such lock. It seems like a waste to
hold a lock we don't need.

ISTM the fix (attached) is just to move down the call to
FreeSpaceMapVacuumRange() to after we've released the lock and recorded
the space we just freed.

- Melanie
From 27e459b357085993a35126fe55ec73eb73ae2e87 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplage...@gmail.com>
Date: Mon, 13 Nov 2023 16:39:25 -0500
Subject: [PATCH v1] Release lock on heap buffer before vacuuming FSM

When there are no indexes on a table, we vacuum each heap block after
pruning it and then update the freespace map. Periodically, we also
vacuum the freespace map. This was done while unnecessarily holding a
lock on the heap page. Move down the call to FreeSpaceMapVacuumRange()
so that we have already recorded any newly freed space and released the
lock on the heap page.
---
 src/backend/access/heap/vacuumlazy.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 6985d299b2..8b729828ce 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1046,18 +1046,6 @@ lazy_scan_heap(LVRelState *vacrel)
 				/* Forget the LP_DEAD items that we just vacuumed */
 				dead_items->num_items = 0;
 
-				/*
-				 * Periodically perform FSM vacuuming to make newly-freed
-				 * space visible on upper FSM pages.  Note we have not yet
-				 * performed FSM processing for blkno.
-				 */
-				if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
-				{
-					FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
-											blkno);
-					next_fsm_block_to_vacuum = blkno;
-				}
-
 				/*
 				 * Now perform FSM processing for blkno, and move on to next
 				 * page.
@@ -1071,6 +1059,18 @@ lazy_scan_heap(LVRelState *vacrel)
 
 				UnlockReleaseBuffer(buf);
 				RecordPageWithFreeSpace(vacrel->rel, blkno, freespace);
+
+				/*
+				 * Periodically perform FSM vacuuming to make newly-freed
+				 * space visible on upper FSM pages.
+				 */
+				if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES)
+				{
+					FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum,
+											blkno);
+					next_fsm_block_to_vacuum = blkno;
+				}
+
 				continue;
 			}
 
-- 
2.37.2

Reply via email to