Re: eliminate xl_heap_visible to reduce WAL (and eventually set VM on-access) - Mailing list pgsql-hackers

From Melanie Plageman
Subject Re: eliminate xl_heap_visible to reduce WAL (and eventually set VM on-access)
Date
Msg-id CAAKRu_a02pu7U2S0qPZ5L+oWb2m2Zp965sOKCCLnKUAKNo-hfg@mail.gmail.com
Whole thread
In response to Re: eliminate xl_heap_visible to reduce WAL (and eventually set VM on-access)  (Tomas Vondra <tomas@vondra.me>)
List pgsql-hackers
On Fri, Sep 11, 2026 at 1:24 PM Melanie Plageman
<melanieplageman@gmail.com> wrote:
>
> On Thu, Sep 10, 2026 at 3:25 PM Melanie Plageman
> <melanieplageman@gmail.com> wrote:
>
> Here is a patch for this. While writing it, I realized I do not
> understand why we don't update the FSM when restoring an FPI --
> especially for COPY FREEZE. The FSM won't be up-to-date after
> promotion for those pages and vacuum won't scan them so they'll remain
> that way forever. Obviously not something to change in backbranches,
> but it strikes me as odd that we do that in any cases -- but
> especially for COPY FREEZE.

Correcting myself here: pre-19 COPY FREEZE relied on
XLOG_HEAP2_VISIBLE records to update the FSM when the heap pages in
the XLOG_HEAP2_MULTI_INSERT had heap page FPIs. But my question
remains, what is the point of skipping FSM updates when there is a
heap page FPI?

On another note, an LLM found a bug in the commit in this series that
set pd_prune_xid for multi-inserts. I set pd_prune_xid as long as the
page wasn't being set all-frozen, but you can insert frozen tuples
into a page when you are not then setting it all-frozen. In that case,
you do not want to set pd_prune_xid. The worst that can happen is a
spurious round of pruning for the page, but it's best to avoid this
(and it wasn't the intent). Inserting a frozen tuple should not set a
prune hint. Patch attached. Simple repro below:

CREATE EXTENSION pageinspect;
CREATE EXTENSION pg_visibility;
BEGIN;
CREATE TABLE t (id integer);
COPY t FROM PROGRAM 'seq 1 3000' FREEZE;
COMMIT;
SELECT g AS blkno, (page_header(get_raw_page('t', g))).prune_xid,
vm.all_visible, vm.all_frozen FROM generate_series( 0,
pg_relation_size('t') / current_setting('block_size')::integer - 1) AS
g JOIN pg_visibility_map('t') AS vm ON vm.blkno = g ORDER BY g;

- Melanie

Attachment

pgsql-hackers by date:

Previous
From: Haibo Yan
Date:
Subject: Re: Init connection time grows quadratically
Next
From: Melanie Plageman
Date:
Subject: Re: WAL_LOG CREATE DATABASE strategy broken for non-standard page layouts