postgres.git / summary / log / commit / refs
commit 512d3e8919b649d36a6f246c657c8b8df7536e8a
Author: Melanie Plageman <melanieplageman@gmail.com>
Date: Sat Sep 12 00:37:53 2026 +0000
Make on-access pruning pin visibility map before locking heap page
b46e1e54d078 pinned the VM after acquiring a cleanup lock on the heap
page when on-access pruning. This was not correct, as pinning the VM may
require I/O. Pin the VM before acquiring the lock. This could mean
occasional unneeded pinning when the buffer is under contention, but
that should be rare.
Reported-by: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAAKRu_aR6e2mNVo-DNHDUfBE5i0cbE4%3Du%3D_Qi9%2Bv573qiGtBig%40mail.gmail.com
Backpatch-through: 19
src/backend/access/heap/pruneheap.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 29f4722b02d..54c69b69346 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -325,6 +325,14 @@ heap_page_prune_opt(Relation relation, Buffer buffer, Buffer *vmbuffer,
bool record_free_space = false;
Size freespace = 0;
+ /*
+ * Pin the VM page before taking the heap cleanup lock. This may
+ * occasionally lead to an unnecessary pin when the buffer is
+ * contended, but the same VM page covers many heap pages, so there is
+ * a good chance for the work to be reusable.
+ */
+ visibilitymap_pin(relation, BufferGetBlockNumber(buffer), vmbuffer);
+
/* OK, try to get exclusive buffer lock */
if (!ConditionalLockBufferForCleanup(buffer))
return;
@@ -340,9 +348,6 @@ heap_page_prune_opt(Relation relation, Buffer buffer, Buffer *vmbuffer,
PruneFreezeResult presult;
PruneFreezeParams params;
- visibilitymap_pin(relation, BufferGetBlockNumber(buffer),
- vmbuffer);
-
params.relation = relation;
params.buffer = buffer;
params.vmbuffer = *vmbuffer;
[parent: ce420353fab9]