Skip to content

Commit f88f720

Browse files
committed
Fix race condition at backend exit when deleting element in syncrep queue
When a backend exits, it gets deleted from the syncrep queue if present. The queue was checked without SyncRepLock taken in exclusive mode, so it would have been possible for a backend to remove itself after a WAL sender already did the job. Fix this issue based on a suggestion from Fujii Masao, by first checking the queue without the lock. Then, if the backend is present in the queue, take the lock and perform an additional lookup check before doing the element deletion. Author: Dongming Liu Reviewed-by: Kyotaro Horiguchi, Fujii Masao, Michael Paquier Discussion: https://postgr.es/m/a0806273-8bbb-43b3-bbe1-c45a58f6ae21.lingce.ldm@alibaba-inc.com Backpatch-through: 9.4
1 parent ddcc582 commit f88f720

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/backend/replication/syncrep.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,18 @@ SyncRepCancelWait(void)
319319
void
320320
SyncRepCleanupAtProcExit(void)
321321
{
322+
/*
323+
* First check if we are removed from the queue without the lock to not
324+
* slow down backend exit.
325+
*/
322326
if (!SHMQueueIsDetached(&(MyProc->syncRepLinks)))
323327
{
324328
LWLockAcquire(SyncRepLock, LW_EXCLUSIVE);
325-
SHMQueueDelete(&(MyProc->syncRepLinks));
329+
330+
/* maybe we have just been removed, so recheck */
331+
if (!SHMQueueIsDetached(&(MyProc->syncRepLinks)))
332+
SHMQueueDelete(&(MyProc->syncRepLinks));
333+
326334
LWLockRelease(SyncRepLock);
327335
}
328336
}

0 commit comments

Comments
 (0)