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

From Andres Freund
Subject Re: eliminate xl_heap_visible to reduce WAL (and eventually set VM on-access)
Date
Msg-id 7clovcjtacv6peujpfaimeynrkcd4anp6ohbdd3ncgtjo67anb@ylcccepdiuz2
Whole thread Raw
In response to Re: eliminate xl_heap_visible to reduce WAL (and eventually set VM on-access)  (Alexey Makhmutov <a.makhmutov@postgrespro.ru>)
Responses Re: eliminate xl_heap_visible to reduce WAL (and eventually set VM on-access)
List pgsql-hackers
Hi,

On 2026-04-06 17:30:51 +0300, Alexey Makhmutov wrote:
> Sorry for the late note for the already committed patch, but I have a
> question on the last part of the 'heap_xlog_prune_freeze' function related
> to the FSM update (it was committed in add323d -'Eliminate
> XLOG_HEAP2_VISIBLE from vacuum phase III').

FWIW, I don't think it's ever too late to look at commits, and certainly not
when it's a commit from the same release.


> Currently it contains the following logic:
>     
> ...
> Size    freespace = 0;
> ...
> if (BufferIsValid(buffer))
> {
>     if ((xlrec.flags & (XLHP_HAS_REDIRECTIONS |
>                         XLHP_HAS_DEAD_ITEMS |
>                         XLHP_HAS_NOW_UNUSED_ITEMS)) ||
>         (vmflags & VISIBILITYMAP_VALID_BITS))
>         freespace = PageGetHeapFreeSpace(BufferGetPage(buffer));
> ...
>     UnlockReleaseBuffer(buffer);
> }
> ...
> if (freespace > 0)
>     XLogRecordPageWithFreeSpace(rlocator, blkno, freespace);
> ...
>         
> My question is about the last check ('freespace > 0') - do we really want to
> call 'XLogRecordPageWithFreeSpace' only if 'freespace' is greater than 0? As
> I understand, the zero value is a perfectly valid output of the
> 'PageGetHeapFreeSpace' call (i.e. page has no space or no free line items
> while we mark all rows as frozen/visible), but with the current
> implementation we will skip FSM update in such case.

I don't have a strong opinion on this, but I think it's pretty defensible to
record only when there's free space. The whole goal of updating the FSM during
recovery is to make sure that free space can be found fairly quickly after
promotion (it's also beneficial in some crash recovery cases, but not that
much).

If the page filled up during an insert / update / delete, we will have updated
the FSM with that information at that point:

    /*
     * If the page is running low on free space, update the FSM as well.
     * Arbitrarily, our definition of "low" is less than 20%. We can't do much
     * better than that without knowing the fill-factor for the table.
     *
     * XXX: Don't do this if the page was restored from full page image. We
     * don't bother to update the FSM in that case, it doesn't need to be
     * totally accurate anyway.
     */
    if (action == BLK_NEEDS_REDO && freespace < BLCKSZ / 5)
        XLogRecordPageWithFreeSpace(target_locator, blkno, freespace);


The reason to update the FSM after something pruning / vacuuming related is
that there now might be *more* space available than before, it shouldn't
shrink.

Obviously the FSM is not crashsafe, so updating it with 0 during replay could
avoid some unnecessary page reads after a promotion. But I'm not sure that
that's particularly worth optimizing for.


With all that said, I'm somewhat doubtful that freespace > 0 filters out a
meaningful amount of freespace updates, it's rare for pages to be that full.

Greetings,

Andres Freund



pgsql-hackers by date:

Previous
From: "David G. Johnston"
Date:
Subject: Re: PG 19 release notes and authors
Next
From: John Naylor
Date:
Subject: Re: PG 19 release notes and authors