From: | Dmitry Fomin <fomin(dot)list(at)gmail(dot)com> |
---|---|
To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
Subject: | Segfault in RI UPDATE CASCADE on partitioned tables with LIKE+ATTACH child (attnum drift) |
Date: | 2025-10-16 09:46:26 |
Message-ID: | 7DCE78D7-0520-4207-822B-92F60AEA14B4@gmail.com |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
Hello,
We’re seeing a backend segfault when an ON UPDATE CASCADE fires across partitions, if the destination partition was created via CREATE TABLE … LIKE + ATTACH (so its physical tuple descriptor differs from the parent due to dropped-column tombstones/attnum drift). Names/types match by inspection, but the crash occurs during tuple materialization in the RI trigger execution.
Minimal Reproducer (self-contained)
DROP SCHEMA IF EXISTS t CASCADE;
CREATE SCHEMA t;
-- Pipelines (partitioned)
CREATE TABLE t.pipelines (
partition_id int NOT NULL,
id bigint NOT NULL,
PRIMARY KEY (partition_id, id)
) PARTITION BY LIST (partition_id);
CREATE TABLE t.pipelines_102 PARTITION OF t.pipelines FOR VALUES IN (102);
CREATE TABLE t.pipelines_50 PARTITION OF t.pipelines FOR VALUES IN (50);
-- Stages (partitioned) with ON UPDATE CASCADE to pipelines.
-- Create a mid column and drop it to leave a tombstone gap in attnums.
CREATE TABLE t.stages (
partition_id int NOT NULL,
id bigint NOT NULL,
tmp_mid int, -- dropped below, leaves parent attnum gap
pipeline_id bigint NOT NULL,
name text,
status int,
PRIMARY KEY (partition_id, id),
FOREIGN KEY (partition_id, pipeline_id)
REFERENCES t.pipelines(partition_id, id)
ON UPDATE CASCADE ON DELETE CASCADE
) PARTITION BY LIST (partition_id);
CREATE TABLE t.stages_102 PARTITION OF t.stages FOR VALUES IN (102);
ALTER TABLE t.stages DROP COLUMN tmp_mid;
-- Miscreate destination stage partition via LIKE + ATTACH (no tombstone, different attnums).
CREATE TABLE t.stages_50_like (LIKE t.stages INCLUDING DEFAULTS);
ALTER TABLE t.stages ATTACH PARTITION t.stages_50_like FOR VALUES IN (50);
-- Builds (partitioned), cascades to both stages and pipelines.
CREATE TABLE t.builds (
partition_id int NOT NULL,
id bigint NOT NULL,
stage_id bigint NOT NULL,
commit_id bigint NOT NULL,
PRIMARY KEY (partition_id, id),
FOREIGN KEY (partition_id, stage_id)
REFERENCES t.stages(partition_id, id)
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (partition_id, commit_id)
REFERENCES t.pipelines(partition_id, id)
ON UPDATE CASCADE ON DELETE CASCADE
) PARTITION BY LIST (partition_id);
CREATE TABLE t.builds_102 PARTITION OF t.builds FOR VALUES IN (102);
CREATE TABLE t.builds_50 PARTITION OF t.builds FOR VALUES IN (50);
-- Seed rows in source partition 102.
INSERT INTO t.pipelines_102(partition_id, id) VALUES (102, 1);
INSERT INTO t.stages_102 (partition_id, id, pipeline_id, name, status)
VALUES (102, 10, 1, 's', 0);
INSERT INTO t.builds_102 (partition_id, id, stage_id, commit_id)
VALUES (102, 100, 10, 1);
-- Crash repro: cascaded UPDATE across partitions
UPDATE t.pipelines
SET partition_id = 50
WHERE partition_id = 102 AND id = 1;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
Postgres logs:
2025-10-16 09:23:08.535 UTC [18630] LOG: client backend (PID 18673) was terminated by signal 11: Segmentation fault
2025-10-16 09:23:08.535 UTC [18630] DETAIL: Failed process was running: UPDATE t.pipelines
SET partition_id = 50
WHERE partition_id = 102 AND id = 1;
Environment
PostgreSQL:
postgres=# SHOW server_version;
server_version
----------------
18.0
(1 row)
postgres=# SHOW server_version_num;
server_version_num
--------------------
180000
(1 row)
postgres=# SELECT version();
version
----------------------------------------------------------------------------------------------------------
PostgreSQL 18.0 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit
(1 row)
postgres=# SHOW shared_preload_libraries;
shared_preload_libraries
--------------------------
(1 row)
postgres=# SELECT extname, extversion FROM pg_extension ORDER BY 1;
extname | extversion
---------+------------
plpgsql | 1.0
(1 row)
OS/Kernel/Libc:
[root(at)postgres-source ~]# uname -a
Linux postgres-source 5.14.0-427.22.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jun 19 04:14:38 PDT 2024 x86_64 x86_64 x86_64 GNU/Linux
[root(at)postgres-source ~]# cat /etc/os-release
NAME="Oracle Linux Server"
VERSION="9.3"
ID="ol"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="9.3"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Oracle Linux Server 9.3"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:oracle:linux:9:3:server"
HOME_URL="https://linux.oracle.com/"
BUG_REPORT_URL="https://github.com/oracle/oracle-linux"
ORACLE_BUGZILLA_PRODUCT="Oracle Linux 9"
ORACLE_BUGZILLA_PRODUCT_VERSION=9.3
ORACLE_SUPPORT_PRODUCT="Oracle Linux"
ORACLE_SUPPORT_PRODUCT_VERSION=9.3
[root(at)postgres-source ~]# ldd --version
ldd (GNU libc) 2.34
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
Backrace in attachment
Issue is reproducible at least in Postgres 16, 17, 18
Please let me know if I need to provide some other information
—
BR Dmitry

From | Date | Subject | |
---|---|---|---|
Next Message | Jacob Champion | 2025-10-16 16:45:39 | Re: BUG #19089: Mounting Issue |
Previous Message | 崔紫玉 | 2025-10-16 07:30:10 | Re: BUG #19081: Inconsistent target rows seen by the UPDATE and INSERT statements within the same transaction |