From: PG Bug reporting form <noreply@postgresql.org>
To: pgsql-bugs@lists.postgresql.org
Cc: exclusion@gmail.com
Subject: BUG #17792: MERGE uses uninitialized pointer and crashes when target tuple is updated concurrently
Date: Tue, 14 Feb 2023 07:00:01 +0000
Message-ID: <17792-0f89452029662c36@postgresql.org> (raw)
The following bug has been logged on the website:
Bug reference: 17792
Logged by: Alexander Lakhin
Email address: exclusion@gmail.com
PostgreSQL version: 15.2
Operating system: Ubuntu 22.04
Description:
When executing the following queries with valgrind:
echo "
CREATE TABLE source (sid integer);
INSERT INTO source VALUES (1);
CREATE TABLE target (tid integer, tval integer);
INSERT INTO target VALUES (1, 1);
" | psql
for ((i=1;i<=50;i++)); do
echo "iteration $i"
echo "
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
UPDATE SET tval = 0;
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
UPDATE SET tval = 0;
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
UPDATE SET tval = 0;
" | psql &
echo "
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
DELETE;
INSERT INTO target VALUES (1, 1);
" | psql &
wait
grep '_suppression_' server.log && break
grep 'runtime error: ' server.log && break
done
I get:
...
iteration 15
MERGE 1
MERGE 1
MERGE 1
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
connection to server was lost
<insert_a_suppression_name_here>
server.log contains:
==00:00:00:28.417 799644== Conditional jump or move depends on uninitialised
value(s)
==00:00:00:28.417 799644== at 0x43C67B: ExecMergeMatched
(nodeModifyTable.c:2992)
==00:00:00:28.417 799644== by 0x43CCB4: ExecMerge
(nodeModifyTable.c:2750)
==00:00:00:28.417 799644== by 0x43D72B: ExecModifyTable
(nodeModifyTable.c:3867)
==00:00:00:28.417 799644== by 0x40E7F1: ExecProcNodeFirst
(execProcnode.c:464)
==00:00:00:28.417 799644== by 0x406E19: ExecProcNode (executor.h:259)
==00:00:00:28.417 799644== by 0x406E19: ExecutePlan (execMain.c:1636)
==00:00:00:28.417 799644== by 0x406FF9: standard_ExecutorRun
(execMain.c:363)
==00:00:00:28.417 799644== by 0x4070C5: ExecutorRun (execMain.c:307)
==00:00:00:28.417 799644== by 0x5C5465: ProcessQuery (pquery.c:160)
==00:00:00:28.417 799644== by 0x5C601A: PortalRunMulti (pquery.c:1277)
==00:00:00:28.417 799644== by 0x5C65F3: PortalRun (pquery.c:791)
==00:00:00:28.417 799644== by 0x5C27C3: exec_simple_query
(postgres.c:1250)
==00:00:00:28.417 799644== by 0x5C465D: PostgresMain (postgres.c:4593)
==00:00:00:28.417 799644== Uninitialised value was created by a stack
allocation
==00:00:00:28.417 799644== at 0x43D189: ExecModifyTable
(nodeModifyTable.c:3572)
==00:00:00:28.417 799644==
{
<insert_a_suppression_name_here>
...
==00:00:00:28.417 799644== Exit program on first error
(--exit-on-first-error=yes)
2023-02-14 08:43:28.826 MSK [799385] LOG: server process (PID 799644)
exited with exit code 1
2023-02-14 08:43:28.826 MSK [799385] DETAIL: Failed process was running:
MERGE INTO target t USING source AS s ON t.tid = s.sid WHEN MATCHED THEN
DELETE;
(With asan I get "nodeModifyTable.c:2992:11: runtime error: member access
within misaligned address 0x561fcdc53231 for type 'struct TupleTableSlot',
which requires 8 byte alignment", without valgrind/sanitizer just
SIGSEGV.)
At nodeModifyTable.c:2992 I see:
if (!TupIsNull(context->cpUpdateRetrySlot))
It looks like cpUpdateRetrySlot was not initialized on the context creation
in ExecModifyTable(), and ExecCrossPartitionUpdate(), where it could get a
value, just not called for this case.
Observed since the MERGE introduction (7103ebb7a).
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: noreply@postgresql.org, pgsql-bugs@lists.postgresql.org, exclusion@gmail.com
Subject: Re: BUG #17792: MERGE uses uninitialized pointer and crashes when target tuple is updated concurrently
In-Reply-To: <17792-0f89452029662c36@postgresql.org>
* 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