From 8bfcac2621d3a5417fe02d9c778e02e61ea69804 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Fri, 18 Sep 2026 13:06:01 -0400
Subject: [PATCH 2/4] Avoid cleanup lock in recovery if only setting VM

1252a4ee286 folded visibility map updates into the XLOG_HEAP2_PRUNE_*
records emitted by heap_page_prune_and_freeze(), and passed the flag
requesting a cleanup lock on replay unconditionally. That is required
when the record removes or redirects line pointers, but not for a record
that only sets PD_ALL_VISIBLE and the VM bits. The former
XLOG_HEAP2_VISIBLE record was replayed under an ordinary exclusive lock.

This could be seen as a regression since cleanup locks require all pins
to be released and eventually cancels the query holding them. This could
lead to more conflicts on the standby.

Fix by requesting the cleanup lock only when the record actually prunes
or freezes.
---
 src/backend/access/heap/pruneheap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 5778ba49a05..2f23554dd90 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -1337,7 +1337,7 @@ heap_page_prune_and_freeze(PruneFreezeParams *params,
 									  do_set_vm ? prstate.vmbuffer : InvalidBuffer,
 									  do_set_vm ? prstate.new_vmbits : 0,
 									  conflict_xid,
-									  true, /* cleanup lock */
+									  do_prune || do_freeze,	/* cleanup lock */
 									  params->reason,
 									  prstate.frozen, prstate.nfrozen,
 									  prstate.redirected, prstate.nredirected,
-- 
2.43.0

