Hi, On Wed, Sep 9, 2026 at 8:44 PM Bharath Rupireddy <[email protected]> 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
v9-0001-Add-statistics-for-WAL-reads-from-WAL-buffers-in-.patch
Description: Binary data
v9-0002-Use-WALReadFromBuffers-for-logical-replication-wa.patch
Description: Binary data
v9-0003-Use-WALReadFromBuffers-for-local-WAL-reads.patch
Description: Binary data
v9-0004-Test-reading-WAL-from-buffers-across-a-segment-bo.patch
Description: Binary data
v9-0005-Use-WALReadFromBuffers-for-the-WAL-summarizer.patch
Description: Binary data
