Fix lost wakeups in physical WAL senders
Physical WAL senders could sleep even when flushed WAL was waiting to
be sent, delaying replication and synchronous commits until another
event woke them. In the reported case, commits stalled for about ten
seconds, until the standby sent its next periodic status report.
Commit
bc971f4025c changed WAL sender wakeups to use condition
variables, which notify only senders already on the waitlist.
However, XLogSendPhysical() checks the flush position before
WalSndWait() joins the waitlist. If WAL is flushed between these two
steps, the wakeup can be missed, leaving the sender asleep despite
having more WAL to send.
Fix this by rechecking the flush position after joining the waitlist
and returning to the send loop if more WAL is available. For cascading
senders, also check for promotion or a timeline change, which require
the sender to revisit the current timeline even if the flush position
has not advanced.
Backpatch to v16, where commit
bc971f4025c introduced the
condition-variable wakeup mechanism.
Author: Alex Speller <alex@alexspeller.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/mvx5bs7q.
33b99c32-67d8-4373-8611-
7a8250fb2fd3@we.are.superhuman.com
Backpatch-through: 16