Re: Avoid streaming zero-filled WAL switch padding

From: Sehrope Sarkuni <sehrope(at)jackdb(dot)com>
To: Andrey Borodin <x4mmm(at)yandex-team(dot)ru>
Cc: pgsql-hackers mailing list <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Avoid streaming zero-filled WAL switch padding
Date: 2026-09-09 19:52:35
Message-ID: CAH7T-arGctyS6a651hG_da3bVYhU1MRaHOG-Jhi5AwX0U4h5_Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Sun, Sep 6, 2026 at 8:49 AM Andrey Borodin <x4mmm(at)yandex-team(dot)ru> wrote:
> On Sat, Sep 5, 2026, Sehrope Sarkuni wrote:
> > I think this needs an opt-in from the client. Something like a
> > START_REPLICATION option or at least a protocol guard.
>
> I agree. v2 adds a SKIP_WAL_PADDING option to physical
> START_REPLICATION. Existing clients continue to receive ordinary WALData
> messages, and built-in clients request the new format only from PG20 servers.
>
> The receiver no longer truncates and extends the segment. A segment newly
> created by walreceiver is already zero-filled according to wal_init_zero. For
> an existing or recycled segment, walreceiver writes the zeros locally with
> the normal wait-event and pg_stat_io accounting. This also removes the
> short-file crash window. New uncompressed pg_receivewal output is already
> pre-padded. Resumed, compressed, and tar output generate the zeros locally.
>
> I also added the missing Meson registration and used
> pg_memory_is_all_zeros(). As a compatibility check, I connected a pre-patch
> PG20 pg_receivewal to the patched server and compared the resulting switched
> segment byte for byte.

Looks good. v2 addresses everything from my first pass and it all looks
right to me.

Tested on 798bdcae89d. Builds clean, recovery suite passes, and a
pre-patch pg_receivewal against the patched server gets plain WALData
and byte-identical segments. With the patch on a standby the wire
traffic drops from 16 MiB to ~125 kB.

I'm not particularly familiar with the replication command grammar,
so other eyes on the START_REPLICATION option parsing would be good,
but it looks fine and behaves correctly in all the tests.

A few small things:

1. The test no longer proves the 'z' path was taken. An old client
produces the same bytes, so the compare passes either way. The
attached patch resets pg_stat_io on the standby before the switch
and checks the walreceiver wrote less than wal_segment_size: 248 kB
here vs exactly 16 MB unpatched. It restarts the standby first to
flush the counters, since the walreceiver only reports them on its
status timer. Byte counts also avoid the Windows skip a sparse-file
check would need.

2. The pg_stat_activity check runs right after $standby->start, before
the walreceiver has necessarily connected. That should use
poll_query_until(...).

3. recvFileIsNew is reset in XLogWalRcvClose but not at the
end-of-timeline close in WalReceiverMain.

See attached for a patch atop your v2 to address 1-3. The 0001 is your
v2 patch rebased and the additions are in 0002. Nothing special for the
rebase either (the patch is identical).

CI run for the modified tests shows it ran on Windows and passed there
as well:

https://github.com/sehrope/postgres/actions/runs/34376945257/job/102552798366#step:14:94

Regards,
-- Sehrope Sarkuni
Founder & CEO | JackDB, Inc. | https://www.jackdb.com/

Attachment Content-Type Size
v3-0001-Avoid-streaming-zero-filled-WAL-switch-padding.patch text/x-patch 32.5 KB
v3-0002-Fix-up-test-races-and-reset-recvFileIsNew-on-ever.patch text/x-patch 3.5 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Dmitry Fomin 2026-09-09 20:05:13 Re: [PATCH v1 0/7] Wait event timing and tracing instrumentation
Previous Message Robert Haas 2026-09-09 19:45:41 Re: Revert RI fast-path batching from REL_19_STABLE