| From: | Bharath Rupireddy <bharath(dot)rupireddyforpostgres(at)gmail(dot)com> |
|---|---|
| To: | Kirill Reshke <reshkekirill(at)gmail(dot)com> |
| Cc: | Michael Paquier <michael(at)paquier(dot)xyz>, Jeff Davis <pgsql(at)j-davis(dot)com>, Jingtang Zhang <mrdrivingduck(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org, Nitin Jadhav <nitinjadhavpostgres(at)gmail(dot)com> |
| Subject: | Re: Use WALReadFromBuffers in more places |
| Date: | 2026-09-14 20:07:00 |
| Message-ID: | CALj2ACUMtx+3hd7mO8Gb5kewpvwQ9OLEPPSC1fC2r500k5_CaQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
On Wed, Sep 9, 2026 at 8:44 PM Bharath Rupireddy
<bharath(dot)rupireddyforpostgres(at)gmail(dot)com> wrote:
>
> Thanks a lot for benchmarking it. The subscriber (or for that matter
> any logical decoding consumer) that closely follows the publisher WAL
> gets the most out of it by avoiding disk read syscalls and IO. In
> other words, all the WAL is available in the WAL buffers for the
> readers before the walwriter's opportunistic page initialization zeros
> them out.
>
> > Code itself looks fine to me, don't see any major issues.
>
> Thanks for reviewing it.
I noticed a CF bot failure in 001_rep_changes.pl because the logical
walsender was reading all the WAL from WAL buffers, so the disk read
path was never hit. This caused the TAP test that expects at least one
disk read to time out. This reminds me of a missing piece in the
WALReadFromBuffers() journey, that is, reporting how often WAL is read
from WAL buffers. So far the physical walsender TAP test hasn't
complained, but in the 0001 patch I added support to report WAL buffer
hits using the existing IOOP_HIT operation and adjusted the physical
walsender test accordingly. Note that I couldn't add byte-level hit
tracking in 0001, which I plan to do separately. The added hit counter
for WAL is enough to know how often reads come from WAL buffers and
will fix the CF bot failure.
Another idea to resolve this is to just count reads from WAL buffers
into the existing reads and read_bytes, the same way WALRead() does,
and be done with it. This is simpler, though one can't distinguish or
know how often WAL buffers are hit and reading from WAL files is
avoided. One argument in favor of this approach is to just treat WAL
buffer hits like OS page cache hits, and since we don't count those in
pg_stat_io, that is okay. But I prefer using the hits operation unless
anyone thinks otherwise.
0002 through 0004 are unchanged, except that the logical walsender
test in 0002 now waits for the sum of reads and hits, since a read
from the WAL buffers is reported as a hit and not as a read.
attached WAL summarizer changes as the 0005 patch. I benchmarked how
it helps the WAL summarizer while reading WAL. I used
pg_logical_emit_message() to emit WAL and summarize_wal to let the WAL
summarizer read it back, and here are the results. With WAL direct IO
on, the patch reduces the summarizer's WAL reads from 604.7 MB to
233.0 MB per run, reducing the physical disk reads from 3.46 MB/s to
1.83 MB/s, with throughput unchanged (7,656 to 7,720 TPS). With WAL
direct IO off, the same reads are eliminated at the syscall level with
no throughput change, so it doesn't regress.
# build WAL direct IO WAL generated MB summarizer file read MB
buffer hits WAL-disk reads WAL-disk writes
1 HEAD on 601 604.7
0 3.46 MB/s 13.80 MB/s
2 PATCHED on 606 233.0
48,627 1.83 MB/s 13.90 MB/s
3 HEAD off 489 492.6
0 0 29.44 MB/s
4 PATCHED off 501 181.1
41,866 0 27.05 MB/s
Please find the attached v9 patches.
[1]
[17:19:24.455](0.020s) ok 8 - value replicated to subscriber without
replica identity index
[17:19:24.475](0.019s) ok 9 - check replicated changes for table
having no columns
[17:23:06.938](222.464s) # poll_query_until timed out executing this query:
# SELECT sum(reads) > 0
# FROM pg_catalog.pg_stat_io
# WHERE backend_type = 'walsender'
# AND object = 'wal'
# expecting this output:
# t
# last actual query output:
# f
# with stderr:
[17:23:06.939](0.001s) # die: Timed out while waiting for the
walsender to update its IO statistics at t/001_rep_changes.pl line
193.
[17:23:06.939](0.000s) 1..9
--
Bharath Rupireddy
Amazon Web Services: https://aws.amazon.com
| Attachment | Content-Type | Size |
|---|---|---|
| v9-0001-Add-statistics-for-WAL-reads-from-WAL-buffers-in-.patch | application/octet-stream | 6.8 KB |
| v9-0002-Use-WALReadFromBuffers-for-logical-replication-wa.patch | application/octet-stream | 5.3 KB |
| v9-0003-Use-WALReadFromBuffers-for-local-WAL-reads.patch | application/octet-stream | 3.6 KB |
| v9-0004-Test-reading-WAL-from-buffers-across-a-segment-bo.patch | application/octet-stream | 6.0 KB |
| v9-0005-Use-WALReadFromBuffers-for-the-WAL-summarizer.patch | application/octet-stream | 4.9 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Bharath Rupireddy | 2026-09-14 20:28:00 | Re: Report index currently being vacuumed in pg_stat_progress_vacuum |
| Previous Message | Robert Haas | 2026-09-14 19:59:42 | Re: Trying to break online checksums with LLMs |