From: Andrey Lepikhov <a.lepikhov@postgrespro.ru>
To: PostgreSQL mailing lists <pgsql-bugs@lists.postgresql.org>
Cc: Heikki Linnakangas <hlinnaka@iki.fi>
Subject: SEGFAULT on a concurrent UPDATE of mix of local and foreign partitions
Date: Fri, 6 Aug 2021 10:34:30 +0500
Message-ID: <cb2b808d-cbaa-4772-76ee-c8809bafcf3d@postgrespro.ru> (raw)
Hi,
Postgres SEGFAULT'ed on the UPDATE of mix of local and foreign partitions.
Initialization - see t.sql
For replaying this segfault just execute in parallel:
UPDATE test SET x = x - 1;
The problem was introduced by commit 1375422.
ExecUpdate has found a concurrently updated tuples and starts subplan
evaluation. This operation creates new EState for EPQState and sets
es_result_relations in NULL value. Next, ExecInitNode(subplan) is
launched and underlying ExecInitForeignScan tries to access to an
element of es_result_relations. This causes SEGFAULT.
I studied this problem shortly. I think, EPQState can use
es_result_relations of a parent EState. Patch in attachment fixes this.
check-world passed clearly.
--
regards,
Andrey Lepikhov
Postgres Professional
From ab067bdeb6de84db80504d2fb05da4385fa02ebc Mon Sep 17 00:00:00 2001
From: "Andrey V. Lepikhov" <a.lepikhov@postgrespro.ru>
Date: Fri, 6 Aug 2021 10:11:52 +0500
Subject: [PATCH] Share es_result_relations of parent EState in EPQState
because FDW direct-modify nodes expect it available.
---
src/backend/executor/execMain.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.cindex b3ce4bae53..a030fec86a 100644--- a/src/backend/executor/execMain.c+++ b/src/backend/executor/execMain.c@@ -2714,10 +2714,12 @@ EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
rcestate->es_output_cid = parentestate->es_output_cid;
/*
- * ResultRelInfos needed by subplans are initialized from scratch when the- * subplans themselves are initialized.+ * Share the parent's copy of ResultRelInfos needed by subplans.+ * We must do this before initializing the subplan, because direct-modify+ * FDWs expect their ResultRelInfos to be available.
*/
- rcestate->es_result_relations = NULL;+ rcestate->es_result_relations = parentestate->es_result_relations;+
/* es_trig_target_relations must NOT be copied */
rcestate->es_top_eflags = parentestate->es_top_eflags;
rcestate->es_instrument = parentestate->es_instrument;
--
2.31.1
* frame #0: 0x000000010a21df66 postgres`ExecInitForeignScan(node=0x00007f8e6b823ba8, estate=0x00007f8e6d809b20, eflags=0) at nodeForeignscan.c:230:30
frame #1: 0x000000010a1fc3c3 postgres`ExecInitNode(node=0x00007f8e6b823ba8, estate=0x00007f8e6d809b20, eflags=0) at execProcnode.c:284:27
frame #2: 0x000000010a218265 postgres`ExecInitAppend(node=0x00007f8e6b80e150, estate=0x00007f8e6d809b20, eflags=0) at nodeAppend.c:232:27
frame #3: 0x000000010a1fc193 postgres`ExecInitNode(node=0x00007f8e6b80e150, estate=0x00007f8e6d809b20, eflags=0) at execProcnode.c:181:27
frame #4: 0x000000010a1f4be1 postgres`EvalPlanQualStart(epqstate=0x00007f8e6b817490, planTree=0x00007f8e6b80e150) at execMain.c:2817:31
frame #5: 0x000000010a1f399f postgres`EvalPlanQualBegin(epqstate=0x00007f8e6b817490) at execMain.c:2630:3
frame #6: 0x000000010a1f38de postgres`EvalPlanQual(epqstate=0x00007f8e6b817490, relation=0x00007f8e6b59e160, rti=2, inputslot=0x00007f8e6b830688) at execMain.c:2370:2
frame #7: 0x000000010a24085c postgres`ExecUpdate(mtstate=0x00007f8e6b8173a8, resultRelInfo=0x00007f8e6b8175c0, tupleid=0x00007ffee5d76858, oldtuple=0x0000000000000000, slot=0x00007f8e6b82f9f0, planSlot=0x00007f8e6b8194f0, epqstate=0x00007f8e6b817490, estate=0x00007f8e6b817120, canSetTag=true) at nodeModifyTable.c:1861:18
frame #8: 0x000000010a23e964 postgres`ExecModifyTable(pstate=0x00007f8e6b8173a8) at nodeModifyTable.c:2592:12
frame #9: 0x000000010a1fc8c2 postgres`ExecProcNodeFirst(node=0x00007f8e6b8173a8) at execProcnode.c:463:9
frame #10: 0x000000010a1f4762 postgres`ExecProcNode(node=0x00007f8e6b8173a8) at executor.h:257:9
frame #11: 0x000000010a1efe01 postgres`ExecutePlan(estate=0x00007f8e6b817120, planstate=0x00007f8e6b8173a8, use_parallel_mode=false, operation=CMD_UPDATE, sendTuples=false, numberTuples=0, direction=ForwardScanDirection, dest=0x00007f8e6b8240d0, execute_once=true) at execMain.c:1551:10
frame #12: 0x000000010a1efcd0 postgres`standard_ExecutorRun(queryDesc=0x00007f8e6b815b20, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:361:3
frame #13: 0x000000010a1efa61 postgres`ExecutorRun(queryDesc=0x00007f8e6b815b20, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:305:3
frame #14: 0x000000010a4aff59 postgres`ProcessQuery(plan=0x00007f8e6b824038, sourceText="UPDATE test SET x = x - 1;", params=0x0000000000000000, queryEnv=0x0000000000000000, dest=0x00007f8e6b8240d0, qc=0x00007ffee5d76d30) at pquery.c:160:2
frame #15: 0x000000010a4aede3 postgres`PortalRunMulti(portal=0x00007f8e6e036120, isTopLevel=true, setHoldSnapshot=false, dest=0x00007f8e6b8240d0, altdest=0x00007f8e6b8240d0, qc=0x00007ffee5d76d30) at pquery.c:1266:5
frame #16: 0x000000010a4ae3a8 postgres`PortalRun(portal=0x00007f8e6e036120, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x00007f8e6b8240d0, altdest=0x00007f8e6b8240d0, qc=0x00007ffee5d76d30) at pquery.c:786:5
frame #17: 0x000000010a4a9393 postgres`exec_simple_query(query_string="UPDATE test SET x = x - 1;") at postgres.c:1214:10
Attachments:
[text/plain] 0001-Share-es_result_relations-of-parent-EState-in-EPQSta.patch (1.3K, ../cb2b808d-cbaa-4772-76ee-c8809bafcf3d@postgrespro.ru/2-0001-Share-es_result_relations-of-parent-EState-in-EPQSta.patch)
download | inline diff:
From ab067bdeb6de84db80504d2fb05da4385fa02ebc Mon Sep 17 00:00:00 2001
From: "Andrey V. Lepikhov" <a.lepikhov@postgrespro.ru>
Date: Fri, 6 Aug 2021 10:11:52 +0500
Subject: [PATCH] Share es_result_relations of parent EState in EPQState
because FDW direct-modify nodes expect it available.
---
src/backend/executor/execMain.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.cindex b3ce4bae53..a030fec86a 100644--- a/src/backend/executor/execMain.c+++ b/src/backend/executor/execMain.c@@ -2714,10 +2714,12 @@ EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
rcestate->es_output_cid = parentestate->es_output_cid;
/*
- * ResultRelInfos needed by subplans are initialized from scratch when the- * subplans themselves are initialized.+ * Share the parent's copy of ResultRelInfos needed by subplans.+ * We must do this before initializing the subplan, because direct-modify+ * FDWs expect their ResultRelInfos to be available.
*/
- rcestate->es_result_relations = NULL;+ rcestate->es_result_relations = parentestate->es_result_relations;+
/* es_trig_target_relations must NOT be copied */
rcestate->es_top_eflags = parentestate->es_top_eflags;
rcestate->es_instrument = parentestate->es_instrument;
--
2.31.1
[application/sql] t.sql (552B, ../cb2b808d-cbaa-4772-76ee-c8809bafcf3d@postgrespro.ru/3-t.sql)
download
[text/plain] backtrace.txt (3.0K, ../cb2b808d-cbaa-4772-76ee-c8809bafcf3d@postgrespro.ru/4-backtrace.txt)
download | inline:
* frame #0: 0x000000010a21df66 postgres`ExecInitForeignScan(node=0x00007f8e6b823ba8, estate=0x00007f8e6d809b20, eflags=0) at nodeForeignscan.c:230:30
frame #1: 0x000000010a1fc3c3 postgres`ExecInitNode(node=0x00007f8e6b823ba8, estate=0x00007f8e6d809b20, eflags=0) at execProcnode.c:284:27
frame #2: 0x000000010a218265 postgres`ExecInitAppend(node=0x00007f8e6b80e150, estate=0x00007f8e6d809b20, eflags=0) at nodeAppend.c:232:27
frame #3: 0x000000010a1fc193 postgres`ExecInitNode(node=0x00007f8e6b80e150, estate=0x00007f8e6d809b20, eflags=0) at execProcnode.c:181:27
frame #4: 0x000000010a1f4be1 postgres`EvalPlanQualStart(epqstate=0x00007f8e6b817490, planTree=0x00007f8e6b80e150) at execMain.c:2817:31
frame #5: 0x000000010a1f399f postgres`EvalPlanQualBegin(epqstate=0x00007f8e6b817490) at execMain.c:2630:3
frame #6: 0x000000010a1f38de postgres`EvalPlanQual(epqstate=0x00007f8e6b817490, relation=0x00007f8e6b59e160, rti=2, inputslot=0x00007f8e6b830688) at execMain.c:2370:2
frame #7: 0x000000010a24085c postgres`ExecUpdate(mtstate=0x00007f8e6b8173a8, resultRelInfo=0x00007f8e6b8175c0, tupleid=0x00007ffee5d76858, oldtuple=0x0000000000000000, slot=0x00007f8e6b82f9f0, planSlot=0x00007f8e6b8194f0, epqstate=0x00007f8e6b817490, estate=0x00007f8e6b817120, canSetTag=true) at nodeModifyTable.c:1861:18
frame #8: 0x000000010a23e964 postgres`ExecModifyTable(pstate=0x00007f8e6b8173a8) at nodeModifyTable.c:2592:12
frame #9: 0x000000010a1fc8c2 postgres`ExecProcNodeFirst(node=0x00007f8e6b8173a8) at execProcnode.c:463:9
frame #10: 0x000000010a1f4762 postgres`ExecProcNode(node=0x00007f8e6b8173a8) at executor.h:257:9
frame #11: 0x000000010a1efe01 postgres`ExecutePlan(estate=0x00007f8e6b817120, planstate=0x00007f8e6b8173a8, use_parallel_mode=false, operation=CMD_UPDATE, sendTuples=false, numberTuples=0, direction=ForwardScanDirection, dest=0x00007f8e6b8240d0, execute_once=true) at execMain.c:1551:10
frame #12: 0x000000010a1efcd0 postgres`standard_ExecutorRun(queryDesc=0x00007f8e6b815b20, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:361:3
frame #13: 0x000000010a1efa61 postgres`ExecutorRun(queryDesc=0x00007f8e6b815b20, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:305:3
frame #14: 0x000000010a4aff59 postgres`ProcessQuery(plan=0x00007f8e6b824038, sourceText="UPDATE test SET x = x - 1;", params=0x0000000000000000, queryEnv=0x0000000000000000, dest=0x00007f8e6b8240d0, qc=0x00007ffee5d76d30) at pquery.c:160:2
frame #15: 0x000000010a4aede3 postgres`PortalRunMulti(portal=0x00007f8e6e036120, isTopLevel=true, setHoldSnapshot=false, dest=0x00007f8e6b8240d0, altdest=0x00007f8e6b8240d0, qc=0x00007ffee5d76d30) at pquery.c:1266:5
frame #16: 0x000000010a4ae3a8 postgres`PortalRun(portal=0x00007f8e6e036120, count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x00007f8e6b8240d0, altdest=0x00007f8e6b8240d0, qc=0x00007ffee5d76d30) at pquery.c:786:5
frame #17: 0x000000010a4a9393 postgres`exec_simple_query(query_string="UPDATE test SET x = x - 1;") at postgres.c:1214:10
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: a.lepikhov@postgrespro.ru, pgsql-bugs@lists.postgresql.org, hlinnaka@iki.fi
Subject: Re: SEGFAULT on a concurrent UPDATE of mix of local and foreign partitions
In-Reply-To: <cb2b808d-cbaa-4772-76ee-c8809bafcf3d@postgrespro.ru>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox