v15-0014-Set-empty-pages-all-visible-in-XLOG_HEAP2_PRUNE_.patch
text/x-patch
Filename: v15-0014-Set-empty-pages-all-visible-in-XLOG_HEAP2_PRUNE_.patch
Type: text/x-patch
Part: 13
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v15-0014
Subject: Set empty pages all-visible in XLOG_HEAP2_PRUNE_VACUUM_SCAN record
| File | + | − |
|---|---|---|
| src/backend/access/heap/vacuumlazy.c | 35 | 21 |
From b0242b98434d61bcaff239a5731f3d1e65f310f6 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 17 Sep 2025 16:04:18 -0400
Subject: [PATCH v15 14/23] Set empty pages all-visible in
XLOG_HEAP2_PRUNE_VACUUM_SCAN record
As part of a project to eliminate XLOG_HEAP2_VISIBLE records, eliminate
their usage in phase I vacuum of empty pages.
---
src/backend/access/heap/vacuumlazy.c | 56 +++++++++++++++++-----------
1 file changed, 35 insertions(+), 21 deletions(-)
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 539e5267574..e8721761392 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1882,11 +1882,22 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno,
*/
if (!PageIsAllVisible(page))
{
+ bool set_pd_all_vis = true;
+
+ /* Lock vmbuffer before entering critical section */
+ LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE);
+
START_CRIT_SECTION();
PageSetAllVisible(page);
MarkBufferDirty(buf);
+ visibilitymap_set_vmbits(blkno,
+ vmbuffer,
+ VISIBILITYMAP_ALL_VISIBLE |
+ VISIBILITYMAP_ALL_FROZEN,
+ RelationGetRelationName(vacrel->rel));
+
if (RelationNeedsWAL(vacrel->rel))
{
/*
@@ -1897,34 +1908,37 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno,
* all-visible and find that the page isn't initialized, which
* will cause a PANIC. To prevent that, check whether the page
* has been previously WAL-logged, and if not, do that now.
- *
- * Otherwise, just emit WAL for setting PD_ALL_VISIBLE on the
- * heap page. Doing this in a separate record from setting the
- * VM allows us to omit the heap page from the VM WAL chain.
*/
if (PageGetLSN(page) == InvalidXLogRecPtr)
+ {
log_newpage_buffer(buf, true);
- else
- log_heap_prune_and_freeze(vacrel->rel, buf,
- InvalidBuffer,
- 0,
- InvalidTransactionId, /* conflict xid */
- false, /* cleanup lock */
- true, /* set_pd_all_vis */
- PRUNE_VACUUM_SCAN, /* reason */
- NULL, 0,
- NULL, 0,
- NULL, 0,
- NULL, 0);
+ set_pd_all_vis = false;
+ }
+
+ /*
+ * Emit WAL for setting PD_ALL_VISIBLE on the heap page and
+ * setting the VM. If we emitted a new page record for the
+ * page above, setting PD_ALL_VISIBLE will already have been
+ * included in that record.
+ */
+ log_heap_prune_and_freeze(vacrel->rel, buf,
+ vmbuffer,
+ VISIBILITYMAP_ALL_VISIBLE |
+ VISIBILITYMAP_ALL_FROZEN,
+ InvalidTransactionId, /* conflict xid */
+ false, /* cleanup lock */
+ set_pd_all_vis,
+ PRUNE_VACUUM_SCAN, /* reason */
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ NULL, 0);
}
- visibilitymap_set(vacrel->rel, blkno,
- InvalidXLogRecPtr,
- vmbuffer, InvalidTransactionId,
- VISIBILITYMAP_ALL_VISIBLE |
- VISIBILITYMAP_ALL_FROZEN);
END_CRIT_SECTION();
+ LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK);
+
/* Count the newly all-frozen pages for logging */
vacrel->vm_new_visible_pages++;
vacrel->vm_new_visible_frozen_pages++;
--
2.43.0