Re: Unexpected behavior after OOM errors

From: Michael Paquier <michael(at)paquier(dot)xyz>
To: Alex Masterov <amasterov(at)gmail(dot)com>
Cc: Alexander Lakhin <exclusion(at)gmail(dot)com>, Matthias van de Meent <boekewurm+postgres(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Unexpected behavior after OOM errors
Date: 2026-07-18 00:47:43
Message-ID: alrNLw6fYc_u7ZP9@paquier.xyz
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, Jul 17, 2026 at 04:15:15PM +0200, Alex Masterov wrote:
> The assertion in issue #3 (ent->entry_ref != NULL, pgstat_shmem.c) also has
> a separate trigger I'd like to report — a different code path that poisons
> the same hash in pgstat_get_entry_ref_cached().
> pgstat_get_entry_ref_cached() inserts a zero-filled hash slot — entry_ref
> == NULL — before allocating memory for it. If MemoryContextAlloc() fails
> with OOM it longjmps out, leaving the NULL slot permanently poisoned in
> pgStatEntryRefHash. The hash is backend-local and cross-transaction, so
> abort does not clean it up.
>
> Crash vectors:
> - Debug builds: backend exit hits Assert(ent->entry_ref != NULL) in
> pgstat_release_matching_entry_refs()
> - Release builds: any GC pass (DROP TABLE etc.) causes
> pgstat_gc_entry_refs() to unconditionally dereference the NULL → SIGSEGV
>
> This is the backend-local sibling of the shared/DSA-path issue fixed in
> 8191e0c16a. Present since 5891c7a8ed8 (2022); affects PG15, PG17, PG18, and
> master.

Yeah, I can buy this one. MemoryContextAlloc() would fail an longjmp
on OOM, so we'd better keep the backend data clean. Perhaps we should
just use the Extended() flavor to bypass the failure and do cleanup
actions.. Will look later.
--
Michael

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Lukas Fittl 2026-07-18 01:04:22 Re: pg_plan_advice: fix parsing underscore in numbers
Previous Message Nikolay Samokhvalov 2026-07-17 22:54:02 Raise default track_activity_query_size to 16kB (from 1kB, unchanged since 8.x)