pg_recvlogical: Prevent flushed data from being re-sent after restarting replication

Fujii Masao <masao.fujii@gmail.com>

From: Fujii Masao <masao.fujii@gmail.com>
To: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2025-09-04T16:16:14Z
Lists: pgsql-hackers

Attachments

Hi,

When pg_recvlogical loses connection, it reconnects and restarts
replication unless
--no-loop option is used. I noticed that in this scenario, data that
has already been
flushed can be re-sent after restarting replication. This happens
because the replication
start position used when restarting replication is taken from the write position
in the last status update message, which may be older than the actual
position of
the last flushed data. As a result, some flushed data could exist newer than
the replication start position and be re-sent. Is this a bug?

To fix this issue, I'd like to propose the attached patch that fixes
this by ensuring
all written data is flushed to disk before restarting replication and by using
the last flushed position as the replication start point. This prevents already
flushed data from being re-sent.

Additionally, when the --no-loop option is used, I found that pg_recvlogical
could previously exit without flushing written data, risking data loss.
The attached patch fixes this issue by also ensuring that all data is flushed
to disk before exiting with --no-loop.

Thought?

Regards,


-- 
Fujii Masao

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. pg_recvlogical: remove unnecessary OutputFsync() return value checks.

  2. Add test for pg_recvlogical reconnection behavior.

  3. Add a new helper function wait_for_file() to Utils.pm.

  4. pg_recvlogical: Prevent flushed data from being re-sent.