From 4db8d692aa24b348c8ff8c4a342466b65bdfdb97 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 Oct 2026 17:01:22 +0500 Subject: [PATCH] Do not reject WAL buffer reads after segment recycling XLogSendPhysical() calls CheckXLogRemoved() even when the entire requested range was copied by WALReadFromBuffers(). If the corresponding segment has been removed from pg_wal, this rejects data already available in the output buffer and terminates streaming unnecessarily. WALReadFromBuffers() verifies each page's identity before and after copying it. The removal check is needed only for data read from disk, where the segment might have been recycled during the read. Skip it when no call to WALRead() was needed. --- src/backend/replication/walsender.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 9f21c7c8dfe..b1748ed7223 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -3638,9 +3638,16 @@ retry: &errinfo)) WALReadRaiseError(&errinfo); - /* See logical_read_xlog_page(). */ - XLByteToSeg(startptr, segno, xlogreader->segcxt.ws_segsize); - CheckXLogRemoved(segno, xlogreader->seg.ws_tli); + /* + * Check that the segment read from disk was not recycled while we were + * reading it. See logical_read_xlog_page(). WALReadFromBuffers() validates + * its own reads, which need not have corresponding files in pg_wal. + */ + if (nbytes > 0) + { + XLByteToSeg(startptr, segno, xlogreader->segcxt.ws_segsize); + CheckXLogRemoved(segno, xlogreader->seg.ws_tli); + } /* * During recovery, the currently-open WAL file might be replaced with the base-commit: 126976a8ffcfa47f40d3df09243ebf4606001912 -- 2.50.1 (Apple Git-155)