From d18e72af178a25cef1d4095de6eb13684e8c987f Mon Sep 17 00:00:00 2001 From: Anthonin Bonnefoy Date: Tue, 25 Jun 2024 15:54:55 +0200 Subject: Fix possible overflow of pg_stat DSA's refcnt During backend initialisation, pgStat DSA is attached using dsa_attach_in_place with a NULL segment. The NULL segment means that there's no callback to release the DSA when the process exits. pgstat_detach_shmem only calls dsa_detach which, as mentioned in the function's comment, doesn't include releasing and thus doesn't decrement the reference count of pgStat DSA. Thus, every time a backend is created (new connection or new parallel worker), pgStat DSA's refcnt is increased and never decreased. It will eventually overflow and eventually reach 0, triggering the "could not attach to dynamic shared area" error on all newly created backends. When this state is reached, the only way to recover is to restart the instance to reset the counter. This patch fixes the issue by releasing pgStat DSA with dsa_release_in_place during pgStat shutdown to decrement refcnt. --- src/backend/utils/activity/pgstat_shmem.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c index fb79c5e771..51008e9998 100644 --- a/src/backend/utils/activity/pgstat_shmem.c +++ b/src/backend/utils/activity/pgstat_shmem.c @@ -246,6 +246,13 @@ pgstat_detach_shmem(void) pgStatLocal.shared_hash = NULL; dsa_detach(pgStatLocal.dsa); + + /* + * Detach doesn't decrement dsa's refcnt and since no segment was provided + * when attaching to the dsa, no cleanup callbacks are registered. We need + * to manually release dsa to correctly decrement dsa's refcnt + */ + dsa_release_in_place(pgStatLocal.shmem->raw_dsa_area); pgStatLocal.dsa = NULL; } -- 2.39.3 (Apple Git-146)