From 9462ae7eb645ffb79fd4b7f1c0bb7515ec2da3ba Mon Sep 17 00:00:00 2001 From: Ayush Tiwari Date: Sat, 10 Oct 2026 20:06:35 +0000 Subject: [PATCH v1] Clear walsender reader pointers after cleanup When logical streaming ends, FreeDecodingContext() frees the reader but xlogreader still points to it. Physical streaming leaves a reader in the replication command context that is reset on return. A subsequent error can therefore dereference a stale reader in WalSndErrorCleanup(). Free the physical reader explicitly and clear the global reader and decoding-context pointers when streaming finishes or error cleanup runs. Adjust the assertion after START_REPLICATION to expect no active reader. --- src/backend/replication/walsender.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 10bc3e0cae4..9bbc434544d 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -384,6 +384,9 @@ WalSndErrorCleanup(void) if (xlogreader != NULL && xlogreader->seg.ws_file >= 0) wal_segment_close(xlogreader); + xlogreader = NULL; + logical_decoding_ctx = NULL; + if (MyReplicationSlot != NULL) ReplicationSlotRelease(); @@ -1032,6 +1035,9 @@ StartReplication(StartReplicationCmd *cmd) Assert(streamingDoneSending && streamingDoneReceiving); } + XLogReaderFree(xlogreader); + xlogreader = NULL; + if (cmd->slotname) ReplicationSlotRelease(); @@ -1601,6 +1607,8 @@ StartLogicalReplication(StartReplicationCmd *cmd) WalSndLoop(XLogSendLogical); FreeDecodingContext(logical_decoding_ctx); + logical_decoding_ctx = NULL; + xlogreader = NULL; ReplicationSlotRelease(); replication_active = false; @@ -2295,7 +2303,7 @@ exec_replication_command(const char *cmd_string) /* dupe, but necessary per libpqrcv_endstreaming */ EndReplicationCommand(cmdtag); - Assert(xlogreader != NULL); + Assert(xlogreader == NULL && logical_decoding_ctx == NULL); break; } -- 2.43.0