On Mon, 31 Aug 2026 at 08:45, Zhijie Hou (Fujitsu)
<[email protected]> wrote:
>
> Here is the updated patch which addressed all comments including 
> Kuroda-San's[1].

Thanks for the updated patch.
I found one case where the update fails with the following test:
CREATE TABLE t (id int PRIMARY KEY, a text, b text, c text);
ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL;
ALTER TABLE t ALTER COLUMN b SET STORAGE EXTERNAL;
ALTER TABLE t ALTER COLUMN c SET STORAGE EXTERNAL;

-- Create a row with more than 400MB of TOASTed data
INSERT INTO t VALUES (1, repeat('a', 400 * 1024 * 1024));

-- Add another 400 MB value to the row.
UPDATE t SET b = repeat('b', 400 * 1024 * 1024) WHERE id = 1;

-- Add another 400 MB value, bringing the total row data to ~1.2 GB.
UPDATE t SET c = repeat('c', 400 * 1024 * 1024) WHERE id = 1;

CREATE PUBLICATION p FOR TABLE t WHERE (id < 0);

UPDATE t SET id = 2 WHERE id = 1;
ERROR:  invalid memory alloc request size 1258291264

DROP PUBLICATION p;
-- Without the publication, the same update succeeds.
UPDATE t SET id = 2 WHERE id = 1;  -- succeeds

The failure appears to be caused by BuildOldKeyTuple. It inlines all
three TOASTed column values (a, b, and c) into a single tuple and then
passes the resulting tuple to heap_form_tuple(). Since each column is
approximately 400 MB, the resulting tuple requires roughly 1.2 GB of
memory. In this case, palloc0() attempts to allocate 1,258,291,264
bytes, which exceeds PostgreSQL's MaxAllocSize of 1,073,741,823 bytes,
resulting in the error.

Interestingly, the update succeeds after dropping the publication, so
this appears to be specific to the code path triggered by the
publication's row filter.

Regards,
Vignesh


Reply via email to