[PATCH] Halve peak memory allocation for toast_flatten_tuple

From: Pavel Borisov <pashkin(dot)elfe(at)gmail(dot)com>
To: Postgres hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: [PATCH] Halve peak memory allocation for toast_flatten_tuple
Date: 2026-09-21 16:26:19
Message-ID: CALT9ZEG8W0-xVCYQmxebYQ55fE-SJmKOTrBqgMbcVekhGNMaAw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi, hackers!

Existing code detoasts every external attribute into a Datum array,
then calls heap_fill_tuple on the complete set. So around 2x tuple
length memory is allocated (result tuple plus all detoasted values).
If I remember correctly, toasted tuples can be up to 1GB long, so
even before the length limit, tuple flattening can strain the local
backend's memory beyond the need.

Mainly this affects logical replication with REPLICA IDENTITY
FULL with tables with several large toasted columns: every
UPDATE/DELETE flattens the old tuple. The other callers -- catalog
cache loading and PL/pgSQL record assignment -- handle smaller tuples
where the difference is negligible.

In the patch attached I flatten TOASTed tuples with a two-stage approach:
- For each external attribute build a VARHDRSZ stub whose header
matches what detoast_external_attr will return (size and compression
tag). Pass the stubs through heap_fill_tuple_attr with skip_copy=true
so alignment and sizes are computed without copying data. attr_data[]
records the destination pointer for every non-null attribute.
- Detoast one attribute at a time into the pre-computed position, pfree
immediately.

Peak memory usage decreased from 2x tuple to 1x tuple plus one detoasted
value.

The extra per-attribute cost (one VARHDRSZ palloc/pfree for the
stub, toast pointer decode for compression detection) is negligible
compared the toast-fetch I/O that dominates every call.

Please look at the patch attached, reviews are always welcome!

Regards,
Pavel Borisov
Supabase

Attachment Content-Type Size
v1-0001-Halve-peak-memory-allocation-for-toast_flatten_tu.patch application/octet-stream 18.5 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Alexandre Felipe 2026-09-21 16:42:08 Re: aio: worker: Free SMGR objects when idle
Previous Message Greg Burd 2026-09-21 16:24:45 [PATCH] unrecognized win32 error 448 (ERROR_UNTRUSTED_MOUNT_POINT) breaks tablespaces on Win11 26200