| From: | Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com> |
|---|---|
| To: | exclusion(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19482: Recursive QueueFKConstraintValidation() lacks stack depth check |
| Date: | 2026-05-17 14:44:24 |
| Message-ID: | CAJTYsWX5zQQozsqR-i1JQjDpw=d7mPhafD2qanCo3sH6BguTPA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Hi,
On Sun, 17 May 2026 at 18:01, PG Bug reporting form <noreply(at)postgresql(dot)org>
wrote:
> The following bug has been logged on the website:
>
> Bug reference: 19482
> Logged by: Alexander Lakhin
> Email address: exclusion(at)gmail(dot)com
> PostgreSQL version: 18.4
> Operating system: Ubuntu 24.04
> Description:
>
> The following script:
> echo "
> CREATE TABLE tp0 (a int, PRIMARY KEY (a)) PARTITION BY RANGE(a);
> ALTER TABLE tp0 ADD CONSTRAINT fk FOREIGN KEY (a) REFERENCES tp0 NOT VALID;
> " | psql
>
> for ((i=1;i<=48000;i++)); do # may take 2-3 hours
> echo "CREATE TABLE tp$i PARTITION OF tp$(( $i - 1 ))
> FOR VALUES FROM ($i) TO (1000000) PARTITION BY RANGE (a);";
> done | psql > psql.log
>
> echo "
> ALTER TABLE tp0 VALIDATE CONSTRAINT fk;
> " | psql
>
> leads to:
> 2026-05-16 12:35:43.258 EEST|law|regression|6a083a6f.34aa38|LOG:
> statement:
> ALTER TABLE tp0 VALIDATE CONSTRAINT fk;
> 2026-05-16 12:35:56.104 EEST|||6a07f1d1.32a4c7|LOG: client backend (PID
> 3451448) was terminated by signal 11: Segmentation fault
> 2026-05-16 12:35:56.104 EEST|||6a07f1d1.32a4c7|DETAIL: Failed process was
> running: ALTER TABLE tp0 VALIDATE CONSTRAINT fk;
>
> Core was generated by `postgres: law regression 127.0.0.1(48420) ALTER
> TABLE
> '.
> Program terminated with signal SIGSEGV, Segmentation fault.
> #0 0x00005e57e8d06ae9 in hash_initial_lookup (hashp=0x5e580f378e10,
> hashvalue=795799848, bucketptr=0x7ffe0c940090) at dynahash.c:1767
> 1767 bucket = calc_bucket(hctl, hashvalue);
> (gdb) (gdb) (gdb) (gdb) #0 0x00005e57e8d06ae9 in hash_initial_lookup
> (hashp=0x5e580f378e10, hashvalue=795799848, bucketptr=0x7ffe0c940090) at
> dynahash.c:1767
> #1 0x00005e57e8d0545c in hash_search_with_hash_value
> (hashp=0x5e580f378e10,
> keyPtr=0x7ffe0c94010c, hashvalue=795799848, action=HASH_FIND, foundPtr=0x0)
> at dynahash.c:1010
> #2 0x00005e57e8d0538a in hash_search (hashp=0x5e580f378e10,
> keyPtr=0x7ffe0c94010c, action=HASH_FIND, foundPtr=0x0) at dynahash.c:961
> #3 0x00005e57e8a7c224 in GetPrivateRefCountEntry (buffer=125,
> do_move=true)
> at bufmgr.c:381
> #4 0x00005e57e8a8051a in PinBuffer (buf=0x762990250980, strategy=0x0) at
> bufmgr.c:3085
> ...
> #20 0x00005e57e8ce0a15 in CheckNNConstraintFetch (relation=0x762989504168)
> at relcache.c:4619
> #21 0x00005e57e8cd9b66 in RelationBuildTupleDesc (relation=0x762989504168)
> at relcache.c:701
> #22 0x00005e57e8cdaa23 in RelationBuildDesc (targetRelId=464701,
> insertIt=true) at relcache.c:1204
> #23 0x00005e57e8cdc5cb in RelationIdGetRelation (relationId=464701) at
> relcache.c:2142
> #24 0x00005e57e84d14d2 in relation_open (relationId=464701, lockmode=4) at
> relation.c:58
> #25 0x00005e57e85a16c8 in table_open (relationId=464701, lockmode=4) at
> table.c:44
> #26 0x00005e57e877c41b in QueueFKConstraintValidation
> (wqueue=0x7ffe0d13d128, conrel=0x76299e17b6d0, fkrel=0x7629895039e8,
> pkrelid=16385,
> contuple=0x5e5850492148, lockmode=4) at tablecmds.c:13080
> #27 0x00005e57e877c450 in QueueFKConstraintValidation
> (wqueue=0x7ffe0d13d128, conrel=0x76299e17b6d0, fkrel=0x762989503268,
> pkrelid=16385,
> contuple=0x5e5850491c98, lockmode=4) at tablecmds.c:13086
> #28 0x00005e57e877c450 in QueueFKConstraintValidation
> (wqueue=0x7ffe0d13d128, conrel=0x76299e17b6d0, fkrel=0x762989502ae8,
> pkrelid=16385,
> contuple=0x5e58504917e8, lockmode=4) at tablecmds.c:13086
> ...
> #37383 0x00005e57e877c450 in QueueFKConstraintValidation
> (wqueue=0x7ffe0d13d128, conrel=0x76299e17b6d0, fkrel=0x76299dd9b218,
> pkrelid=16385,
> contuple=0x5e580f357b98, lockmode=4) at tablecmds.c:13086
> #37384 0x00005e57e877c450 in QueueFKConstraintValidation
> (wqueue=0x7ffe0d13d128, conrel=0x76299e17b6d0, fkrel=0x76299dd98358,
> pkrelid=16385,
> contuple=0x5e580f35d628, lockmode=4) at tablecmds.c:13086
> #37385 0x00005e57e877c025 in ATExecValidateConstraint
> (wqueue=0x7ffe0d13d128, rel=0x76299dd98358, constrName=0x5e580f3554d8 "fk",
> recurse=true,
> recursing=false, lockmode=4) at tablecmds.c:12966
> #37386 0x00005e57e876acde in ATExecCmd (wqueue=0x7ffe0d13d128,
> tab=0x5e580f354fc8, cmd=0x5e580f355488, lockmode=4, cur_pass=AT_PASS_MISC,
> context=0x7ffe0d13d320) at tablecmds.c:5497
> #37387 0x00005e57e876a347 in ATRewriteCatalogs (wqueue=0x7ffe0d13d128,
> lockmode=4, context=0x7ffe0d13d320) at tablecmds.c:5334
> #37388 0x00005e57e876968c in ATController (parsetree=0x5e580f32aa88,
> rel=0x76299dd98358, cmds=0x5e580f32aa38, recurse=true, lockmode=4,
> context=0x7ffe0d13d320)
> at tablecmds.c:4889
> #37389 0x00005e57e876929d in AlterTable (stmt=0x5e580f32aa88, lockmode=4,
> context=0x7ffe0d13d320) at tablecmds.c:4544
> #37390 0x00005e57e8ae8380 in ProcessUtilitySlow (pstate=0x5e580f354470,
> pstmt=0x5e580f32ab38,
> queryString=0x5e580f329f60 "ALTER TABLE tp0 VALIDATE CONSTRAINT fk;",
> context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0,
> dest=0x5e580f32aef8,
> qc=0x7ffe0d13d980) at utility.c:1321
>
> Reproduced on REL_18_STABLE, starting from b663b9436, and on master.
>
>
Thanks for the report and the bisected commit.
QueueFKConstraintValidation() recurses through the partition hierarchy
without a stack-depth check, which is the usual reason for SIGSEGV
crashes like the one in your stack trace. Other recursive helpers in
tablecmds.c (and elsewhere in the backend) call check_stack_depth() at
function entry so that we raise a controlled "stack depth limit
exceeded" error instead.
The attached patch does the same here. With max_stack_depth reduced
to 100kB, a scaled-down repro (2000 nested partitions) reproduces the
crash on master and produces the following clean error with the patch:
ALTER TABLE tp0 VALIDATE CONSTRAINT fk;
ERROR: stack depth limit exceeded
HINT: Increase the configuration parameter "max_stack_depth"
(currently 100kB), ...
Thoughts?
Regards,
Ayush
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Add-stack-depth-check-to-QueueFKConstraintValidat.patch | application/octet-stream | 1.7 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Álvaro Herrera | 2026-05-17 20:21:15 | Re: BUG #19462: MERGE on partitioned table with INSERT DEFAULT VALUES fails with "unknown action in MERGE WHEN clau |
| Previous Message | Noah Misch | 2026-05-17 01:40:54 | Re: [PATCH] Replace debug-only Asserts with runtime checks in logical replication apply worker |