Re: BUG #19556: Segmentation fault in test_decoding

From: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>
To: a(dot)kozhemyakin(at)postgrespro(dot)ru, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19556: Segmentation fault in test_decoding
Date: 2026-07-19 07:30:12
Message-ID: CAD21AoATTaDaODg2u+CrwLHfQX7_LThQqJ_6grAmRrHPbTdoRw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Fri, Jul 17, 2026 at 9:30 AM PG Bug reporting form
<noreply(at)postgresql(dot)org> wrote:
>
> The following bug has been logged on the website:
>
> Bug reference: 19556
> Logged by: Alexander Kozhemyakin
> Email address: a(dot)kozhemyakin(at)postgrespro(dot)ru
> PostgreSQL version: 19beta2
> Operating system: ubuntu 26.04
> Description:
>
> Hi,
>
> The following script causes the server to crash with a Segmentation fault.
>
> initdb -D data
> echo "
> max_prepared_transactions = '15'
> wal_level = logical " >> data/postgresql.auto.conf
> pg_ctl -D data -l logfile start
>
> psql <<EOF
> SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot',
> 'test_decoding', false, true);
> CREATE TABLE test (id int PRIMARY KEY, data text);
> INSERT INTO test VALUES (1, 'test data');
> BEGIN;
> SELECT * FROM test WHERE id = 1 FOR SHARE;
> PREPARE TRANSACTION 'p1';
> SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL,
> 'include-xids', '0', 'skip-empty-xacts', '1');
> EOF
>
>
> backtrace
> Program terminated with signal SIGSEGV, Segmentation fault.
> #0 0x0000749f6ee23f54 in pg_decode_prepare_txn (ctx=0x6344c3d7f3f0,
> txn=0x6344c3d7d320, prepare_lsn=24628632) at
> /pgpro/postgres/contrib/test_decoding/test_decoding.c:378
> 378 if (data->skip_empty_xacts && !txndata->xact_wrote_changes)
> (gdb) bt
> #0 0x0000749f6ee23f54 in pg_decode_prepare_txn (ctx=0x6344c3d7f3f0,
> txn=0x6344c3d7d320, prepare_lsn=24628632) at
> /pgpro/postgres/contrib/test_decoding/test_decoding.c:378
> #1 0x00006344a8e8293c in prepare_cb_wrapper (cache=<optimized out>,
> txn=<optimized out>, prepare_lsn=<optimized out>) at
> /pgpro/postgres/src/backend/replication/logical/logical.c:985
> #2 0x00006344a8e90c24 in ReorderBufferPrepare (rb=0x6344c3cd9e10,
> xid=xid(at)entry=745, gid=gid(at)entry=0x7ffcb3620ef4 "p1") at
> /pgpro/postgres/src/backend/replication/logical/reorderbuffer.c:2934
> #3 0x00006344a8e7fa26 in DecodePrepare (ctx=0x6344c3d7f3f0,
> buf=0x7ffcb3621030, parsed=0x7ffcb3620ea0) at
> /pgpro/postgres/src/backend/replication/logical/decode.c:815
> #4 xact_decode (ctx=0x6344c3d7f3f0, buf=0x7ffcb3621030) at
> /pgpro/postgres/src/backend/replication/logical/decode.c:347
> #5 0x00006344a8e7f223 in LogicalDecodingProcessRecord
> (ctx=ctx(at)entry=0x6344c3d7f3f0, record=0x6344c3d7f788) at
> /pgpro/postgres/src/backend/replication/logical/decode.c:116
> #6 0x00006344a8e8577b in pg_logical_slot_get_changes_guts
> (fcinfo=0x6344c3d83410, confirm=confirm(at)entry=true,
> binary=binary(at)entry=false) at
> /pgpro/postgres/src/backend/replication/logical/logicalfuncs.c:266
> #7 0x00006344a8e858f4 in pg_logical_slot_get_changes (fcinfo=<optimized
> out>) at /pgpro/postgres/src/backend/replication/logical/logicalfuncs.c:333
> #8 0x00006344a8d3666d in ExecMakeTableFunctionResult
> (setexpr=0x6344c3d5ffc8, econtext=0x6344c3d5fe18, argContext=<optimized
> out>, expectedDesc=0x6344c3d49868, randomAccess=false)
> at /pgpro/postgres/src/backend/executor/execSRF.c:234
> #9 0x00006344a8d4a14b in FunctionNext (node=node(at)entry=0x6344c3d5fc08) at
> /pgpro/postgres/src/backend/executor/nodeFunctionscan.c:94
> #10 0x00006344a8d36f4c in ExecScanFetch (node=<optimized out>,
> epqstate=<optimized out>, accessMtd=<optimized out>, recheckMtd=<optimized
> out>) at /pgpro/postgres/src/include/executor/execScan.h:126
> #11 ExecScanExtended (node=<optimized out>, accessMtd=0x6344a8d49e10
> <FunctionNext>, recheckMtd=0x6344a8d49e00 <FunctionRecheck>, epqstate=0x0,
> qual=0x0, projInfo=0x6344c3d49ea8)
> at /pgpro/postgres/src/include/executor/execScan.h:187
> #12 ExecScan (node=0x6344c3d5fc08, accessMtd=0x6344a8d49e10 <FunctionNext>,
> recheckMtd=0x6344a8d49e00 <FunctionRecheck>) at
> /pgpro/postgres/src/backend/executor/execScan.c:59
> #13 0x00006344a8d2c17b in ExecProcNode (node=0x6344c3d5fc08) at
> /pgpro/postgres/src/include/executor/executor.h:272
> #14 ExecutePlan (queryDesc=0x6344c3cd55d0, operation=CMD_SELECT,
> sendTuples=true, numberTuples=0, direction=<optimized out>,
> dest=0x6344c3d8b7b8) at /pgpro/postgres/src/backend/executor/execMain.c:1675
> #15 standard_ExecutorRun (queryDesc=0x6344c3cd55d0, direction=<optimized
> out>, count=0) at /pgpro/postgres/src/backend/executor/execMain.c:364
> #16 0x00006344a8f11478 in PortalRunSelect
> (portal=portal(at)entry=0x6344c3d018b0, forward=forward(at)entry=true, count=0,
> count(at)entry=9223372036854775807, dest=dest(at)entry=0x6344c3d8b7b8)
> at /pgpro/postgres/src/backend/tcop/pquery.c:920
> #17 0x00006344a8f12c5e in PortalRun (portal=portal(at)entry=0x6344c3d018b0,
> count=count(at)entry=9223372036854775807, isTopLevel=isTopLevel(at)entry=true,
> dest=dest(at)entry=0x6344c3d8b7b8, altdest=altdest(at)entry=0x6344c3d8b7b8,
> qc=qc(at)entry=0x7ffcb3621640) at
> /pgpro/postgres/src/backend/tcop/pquery.c:764
> #18 0x00006344a8f0e95e in exec_simple_query (query_string=0x6344c3c80f60
> "SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL,
> 'include-xids', '0', 'skip-empty-xacts', '1');")
> at /pgpro/postgres/src/backend/tcop/postgres.c:1271
> #19 0x00006344a8f103e5 in PostgresMain (dbname=<optimized out>,
> username=<optimized out>) at
> /pgpro/postgres/src/backend/tcop/postgres.c:4691
> #20 0x00006344a8f0aaa3 in BackendMain (startup_data=<optimized out>,
> startup_data_len=<optimized out>) at
> /pgpro/postgres/src/backend/tcop/backend_startup.c:107
> #21 0x00006344a8e6184f in postmaster_child_launch (child_type=<optimized
> out>, child_slot=1, startup_data=startup_data(at)entry=0x7ffcb3621aec "",
> startup_data_len=startup_data_len(at)entry=4,
> client_sock=client_sock(at)entry=0x7ffcb3621af0) at
> /pgpro/postgres/src/backend/postmaster/launch_backend.c:274
> #22 0x00006344a8e653ef in BackendStartup (client_sock=0x7ffcb3621af0) at
> /pgpro/postgres/src/backend/postmaster/postmaster.c:3519
> #23 ServerLoop () at
> /pgpro/postgres/src/backend/postmaster/postmaster.c:1688
> #24 0x00006344a8e66cbf in PostmasterMain (argc=argc(at)entry=3,
> argv=argv(at)entry=0x6344c3c7b440) at
> /pgpro/postgres/src/backend/postmaster/postmaster.c:1386
> #25 0x00006344a8b3b35e in main (argc=3, argv=0x6344c3c7b440) at
> /pgpro/postgres/src/backend/main/main.c:230
>

Thank you for the report!

> first bad commit 072ee847ad4c3fb52

Right. I've confirmed that this issue can happen PG18 or newer. In
ReorderBufferPrepare() it sends a prepare message if
ReorderBufferReplay() didn't send it, but ISTM missed the case where
the transaction is empty. I'll investigate the issue further and work
on it.

Regards,

--
Masahiko Sawada
Amazon Web Services: https://aws.amazon.com

In response to

Browse pgsql-bugs by date

  From Date Subject
Previous Message Matheus Alcantara 2026-07-18 18:33:26 Re: BUG #19553: Wrong results from nested LEFT JOINs over an empty subquery (regression since v16)