From d774b80288042d9a31cbc6477c2f0151f1c9dc2e Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Wed, 17 Sep 2025 18:11:49 -0400 Subject: [PATCH v14 11/24] Log setting empty pages PD_ALL_VISIBLE with XLOG_HEAP2_VACUUM_SCAN Though not a big win for this particular case, if we use the XLOG_HEAP2_VACUUM_SCAN record to log setting PD_ALL_VISIBLE on the heap page we can omit the heap page from the WAL chain when setting the visibility map. A follow-on commit will actually remove the heap page from the VM set WAL chain. --- src/backend/access/heap/vacuumlazy.c | 43 +++++++++++++++++++--------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 9bfcd67a61b..c016f8f7c25 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -1879,23 +1879,38 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno, { START_CRIT_SECTION(); - /* mark buffer dirty before writing a WAL record */ + PageSetAllVisible(page); MarkBufferDirty(buf); - /* - * It's possible that another backend has extended the heap, - * initialized the page, and then failed to WAL-log the page due - * to an ERROR. Since heap extension is not WAL-logged, recovery - * might try to replay our record setting the page 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. - */ - if (RelationNeedsWAL(vacrel->rel) && - PageGetLSN(page) == InvalidXLogRecPtr) - log_newpage_buffer(buf, true); + if (RelationNeedsWAL(vacrel->rel)) + { + /* + * It's possible that another backend has extended the heap, + * initialized the page, and then failed to WAL-log the page + * due to an ERROR. Since heap extension is not WAL-logged, + * recovery might try to replay our record setting the page + * 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, + InvalidTransactionId, /* conflict xid */ + false, /* cleanup lock */ + true, /* set_pd_all_vis */ + PRUNE_VACUUM_SCAN, /* reason */ + NULL, 0, + NULL, 0, + NULL, 0, + NULL, 0); + } - PageSetAllVisible(page); visibilitymap_set(vacrel->rel, blkno, buf, InvalidXLogRecPtr, vmbuffer, InvalidTransactionId, -- 2.43.0