Re: Unexpected behavior after OOM errors

From: Michael Paquier <michael(at)paquier(dot)xyz>
To: Alexander Lakhin <exclusion(at)gmail(dot)com>
Cc: 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 07:49:49
Message-ID: alswHQQfAdmC7M4B@paquier.xyz
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, Jul 17, 2026 at 12:00:01PM +0300, Alexander Lakhin wrote:
> (Assuming the attached OOM injection patch applied.)
> 1) An issue in generate_partition_qual():
> --- a/src/backend/utils/cache/partcache.c
> +++ b/src/backend/utils/cache/partcache.c
> @@ -419,3 +419,5 @@ generate_partition_qual(Relation rel)
>          oldcxt = MemoryContextSwitchTo(rel->rd_partcheckcxt);
> +oom_prob = 0.1;
>          rel->rd_partcheck = copyObject(result);
> +oom_prob = 0;
>          MemoryContextSwitchTo(oldcxt);

This one is again an ordering problem: let's assign rd_partcheckcxt
and rd_partcheck once we are sure that all the allocations have
succeeded, so as we don't finish with a semi-allocated transient
state.

> 2) lookup_type_cache():
> --- a/src/backend/utils/cache/typcache.c
> +++ b/src/backend/utils/cache/typcache.c
> @@ -463,8 +463,10 @@ lookup_type_cache(Oid type_id, int flags)
>      in_progress_list[in_progress_offset] = type_id;
>
> +oom_prob = 0.1;
>      /* Try to look up an existing entry */
>      typentry = (TypeCacheEntry *) hash_search(TypeCacheHash,
>                                                &type_id,
>                                                HASH_FIND, NULL);
> +oom_prob = 0;
>
> triggers
> TRAP: failed Assert("cache->cc_tupdesc != NULL"), File:
> "catcache.c", Line: 1112, PID: 43932

This one is tricky. That's obviously due to the fact that we store a
type ID in the in_progress_list and on OOM we finish with a stale
entry in the list, no cleaned up. My first impression was: could we
delay the registration of the type ID in the in_progress_list? But
the answer to that is no; we want it from the point where we to the
lookups in the typcache hash table to protect from concurrent
invalidation. So I am not sure what to do here yet.

> 3) pgstat_prep_pending_entry() / pgstat_write_statsfiles():
> --- a/src/backend/utils/activity/pgstat.c
> +++ b/src/backend/utils/activity/pgstat.c
> @@ -1333,3 +1333,5 @@ pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *creat
>
> +oom_prob = 0.005;
>          entry_ref->pending = MemoryContextAllocZero(pgStatPendingContext, entrysize);
> +oom_prob = 0;
>          dlist_push_tail(&pgStatPending, &entry_ref->pending_node);
>
> triggers
> TRAP: failed Assert("!ps->dropped"), File: "pgstat.c", Line: 1730, PID: 844901
> maybe this Assert can be removed, because there is no corresponding

Yes, perhaps we should do that. I am not completely sure if this is
the best thing to do, though.

> 4) make_new_heap():
> --- a/src/backend/commands/repack.c
> +++ b/src/backend/commands/repack.c
> @@ -1255,3 +1255,5 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, Oid NewAccessMethod,
>       */
> +oom_prob = 0.01;
>      CommandCounterIncrement();
> +oom_prob = 0;
>
> triggers:
> TRAP: failed Assert("ItemIdIsNormal(lp)"), File: "heapam.c", Line: 2813, PID: 943626
> also:
> ERROR:  attempted to delete invisible tuple

I'll let Alvaro comment on this one. It deserves an open item.

For now, I have 1 out of 4, the partcache one. 25% is still better
than 0%. :p
--
Michael

Attachment Content-Type Size
partcache-oom.patch text/plain 1.6 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Thom Brown 2026-07-18 07:56:59 Re: [PATCH] Rename "getdatabaseencoding()" to "pg_database_encoding()", and document
Previous Message Denis Smirnov 2026-07-18 07:42:20 Re: Avoid unnecessary StringInfo allocation in tablesync COPY buffer