Fix possibility of self-deadlock in ResolveRecoveryConflictWithBufferPin().
authorAndres Freund <[email protected]>
Tue, 3 May 2022 01:25:00 +0000 (18:25 -0700)
committerAndres Freund <[email protected]>
Tue, 3 May 2022 01:30:38 +0000 (18:30 -0700)
commitcbc47ad7ef6051a58cc954c28db44034e7e542be
tree71686bcc6af4ccd8c4a77d7a859728fd7cc4710c
parente8a0cf9b20a12d9cb7687a1363cdeb261ef16472
Fix possibility of self-deadlock in ResolveRecoveryConflictWithBufferPin().

The tests added in 9f8a050f68d failed nearly reliably on FreeBSD in CI, and
occasionally on the buildfarm. That turns out to be caused not by a bug in the
test, but by a longstanding bug in recovery conflict handling.

The standby timeout handler, used by ResolveRecoveryConflictWithBufferPin(),
executed SendRecoveryConflictWithBufferPin() inside a signal handler. A bad
idea, because the deadlock timeout handler (or a spurious latch set) could
have interrupted ProcWaitForSignal(). If unlucky that could cause a
self-deadlock on ProcArrayLock, if the deadlock check is in
SendRecoveryConflictWithBufferPin()->CancelDBBackends().

To fix, set a flag in StandbyTimeoutHandler(), and check the flag in
ResolveRecoveryConflictWithBufferPin().

Subsequently the recovery conflict tests will be backpatched.

Discussion: https://postgr.es/m/20220413002626[email protected]
Backpatch: 10-
src/backend/storage/ipc/standby.c