From 265830febb6e22b92dc181b97d773b0ab1b2e338 Mon Sep 17 00:00:00 2001 From: Atsushi Torikoshi Date: Wed, 15 Jul 2026 18:34:21 +0900 Subject: [PATCH v2] Fix LSN of logical decoding message Report startptr, rather than endptr, as the LSN of a decoded logical message. The logical replication protocol documentation describes this field as the LSN of the logical decoding message, but the current implementation reports the end of its WAL record. This distinction matters to logical decoding consumers. A consumer typically records the LSN up to which decoded output has been successfully processed and uses it as the restart point after a crash or other failure. PostgreSQL reports startptr when decoding DML records, but reports endptr only for decoding pg_logical_emit_message(). Consumers that handle logical messages in the same way as other decoded records can therefore store an LSN past the message it has just processed and restart from that later position after a failure, potentially resulting in data loss. The regression test is adjusted accordingly. The test emits only a single non-transactional logical message, which is decoded with xid = 0, so filtering on xid = 0 is sufficient to identify the message without matching its LSN. --- src/backend/replication/logical/decode.c | 2 +- src/test/subscription/t/020_messages.pl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index c944be4ac83..09efc15e454 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -668,7 +668,7 @@ logicalmsg_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) if (!message->transactional) snapshot = SnapBuildGetOrBuildSnapshot(builder); - ReorderBufferQueueMessage(ctx->reorder, xid, snapshot, buf->endptr, + ReorderBufferQueueMessage(ctx->reorder, xid, snapshot, buf->origptr, message->transactional, message->message, /* first part of message is * prefix */ diff --git a/src/test/subscription/t/020_messages.pl b/src/test/subscription/t/020_messages.pl index ac518849156..bdedd5ff812 100644 --- a/src/test/subscription/t/020_messages.pl +++ b/src/test/subscription/t/020_messages.pl @@ -94,7 +94,7 @@ is($result, qq(), $node_publisher->safe_psql('postgres', "INSERT INTO tab_test VALUES (1)"); -my $message_lsn = $node_publisher->safe_psql('postgres', +$node_publisher->safe_psql('postgres', "SELECT pg_logical_emit_message(false, 'pgoutput', 'a non-transactional message')" ); @@ -107,7 +107,7 @@ $result = $node_publisher->safe_psql( 'proto_version', '1', 'publication_names', 'tap_pub', 'messages', 'true') - WHERE lsn = '$message_lsn' AND xid = 0 + WHERE xid = 0 )); is($result, qq(77|0), 'non-transactional message on slot is M'); -- 2.48.1