Dear Hackers,
I'd like to discuss a problem with replication slots's restart LSN. Physical
slots are saved to disk at the beginning of checkpoint. At the end of
checkpoint, old WAL segments are recycled or removed from disk, if they are not
kept by slot's restart_lsn values.
If an existing physical slot is advanced in the middle of checkpoint execution,
WAL segments, which are related to saved on disk restart LSN may be removed. It
is because the calculation of the replication slot miminal LSN is occured at
the end of checkpoint, prior to old WAL segments removal. If to hard stop
(pg_stl -m immediate) the postgres instance right after checkpoint and to
restart it, the slot's restart_lsn may point to the removed WAL segment. I
believe, such behaviour is not good.
The doc [0] describes that restart_lsn may be set to the some past value after
reload. There is a discussion [1] on pghackers where such behaviour is
discussed. The main reason of not flushing physical slots on advancing is a
performance reason. I'm ok with such behaviour, except of that the
corresponding WAL segments should not be removed.
I propose to keep WAL segments by saved on disk (flushed) restart_lsn of slots.
Add a new field restart_lsn_flushed into ReplicationSlot structure. Copy
restart_lsn to restart_lsn_flushed in SaveSlotToPath. It doesn't change the
format of storing the slot contents on disk. I attached a patch. It is not yet
complete, but demonstate a way to solve the problem.
I reproduced the problem by the following way:
* Add some delay in CheckPointBuffers (pg_usleep) to emulate long checkpoint
execution. * Execute checkpoint and pg_replication_slot_advance right after
starting of the checkpoint from another connection. * Hard restart the server
right after checkpoint completion. * After restart slot's restart_lsn may point
to removed WAL segment.
The proposed patch fixes it.
[0] https://www.postgresql.org/docs/current/logicaldecoding-explanation.html
[1]
https://www.postgresql.org/message-id/flat/059cc53a-8b14-653a-a24d-5f867503b0ee%40postgrespro.ru