Currently, when pg_recvlogical exits due to SIGINT or SIGTERM, it can terminate after writing decoded output locally but before sending feedback that reflects the latest written position to the server. If pg_recvlogical is restarted after that, the server-side logical replication slot may still remain behind those already-written changes, and the same decoded data can be sent again.
Attached patch makes pg_recvlogical send final feedback once more during SIGINT/SIGTERM exit, before sending CopyDone. That gives the server one more chance to advance the slot far enough to avoid resending already-written data after pg_recvlogical is restarted.
Thanks for the patch!
The problem statement and solution makes sense to me.
I applied v1 and tried it locally. It builds cleanly and the new block in 030_pg_recvlogical.pl passes. As a sanity check I reverted just the prepareToTerminate() change and kept the test: the "does not duplicate decoded changes after signal shutdown" assertion then fails (the row is decoded twice
on the restart), so the test is clearly exercising the fix too. I don't see any
downside of having the fix attached.
One note is that this is still only a best-effort improvement. Depending on when SIGINT or SIGTERM arrives, pg_recvlogical may already have written decoded output that the server cannot yet safely treat as confirmed, so duplicate data can still be received after restart. In other words, this patch reduces the likelihood of duplicates, but does not guarantee that they will never happen.
Agreed that this is a best-effort improvement rather than a guarantee, and