You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
COMMIT PREPARED in the preparing session crashes the backend after a pgcolumnar write #1323
Found while writing #1304 option 5's two-phase arm. Reproduced on main at 024e737, PG16 assert build, with nothing of mine installed:
CREATETABLEtp (ts timestamptz, v int) USING pgcolumnar;
INSERT INTO tp SELECT now(), 1;
BEGIN;
INSERT INTO tp SELECT'2044-02-02'::timestamptz+ g * interval '2 s', g FROM generate_series(1, 2600) g;
PREPARE TRANSACTION 'x3';
COMMIT PREPARED 'x3'; -- same session: signal 11
COMMIT PREPARED from another session works. That's what parallel_copy does (the leader commits the loaders' prepared transactions), so nothing in the corpus has hit it.
Backtrace (gdb attached to the backend before COMMIT PREPARED):
#0 PgColumnarFlushAllPendingWrites () at src/columnar_write_state.c:3844
#1 pgcolumnar_xact_callback (event=...) at src/columnar_tableam.c:2669
#2 CallXactCallbacks (event=XACT_EVENT_PRE_COMMIT) at xact.c:3703
#3 CommitTransaction () at xact.c:2214
...
#7 exec_simple_query (query_string="COMMIT PREPARED 'x3'") at postgres.c:1303
Cause, as I read it:PgColumnarWriteStates and PgColumnarWriteContext live in a child of TopTransactionContext. PREPARE deletes that context, but the callback's PREPARE arm doesn't reset the two statics. Only the COMMIT/ABORT arms do, via PgColumnarDiscardAllPendingWrites, and PREPARE reaches neither. So the next transaction in the session, here the COMMIT PREPARED itself, walks a freed list at its PRE_COMMIT. The memo has a comment about exactly this for PREPARE ("PREPARE deletes TopTransactionContext without ever reaching the COMMIT/ABORT arms below"), but the write states weren't given the same treatment.
Likely fix: in the PREPARE arm, after the flush, discard the pending write states (and the delete vectors' equivalent if they share the shape). The arm: PREPARE then COMMIT PREPARED in one session, in both twins.
I'm not fixing it inside #1304 option 5. That PR's pytest twin commits from another session and says why.
Activity
test: a pgcolumnar write prepared and finished in one session (comman…
fix: let go of the pending writes and delete vectors at PREPARE (comm…
test: prepared_writes' pytest twin, registered, TESTS.md 98, CHANGELOG (
test: prepared_writes waits for the server before the index-scan prem…
test: prepared_writes enters the ledger, 11 checks, 6 dated by 3 muta…
test: a pgcolumnar write prepared and finished in one session (comman…
fix: let go of the pending writes and delete vectors at PREPARE (comm…
test: prepared_writes' pytest twin, registered, TESTS.md 98, CHANGELOG (
test: prepared_writes waits for the server before the index-scan prem…
test: prepared_writes enters the ledger, 11 checks, 6 dated by 3 muta…
Merge pull request #1324 from OffgridwithJD/fix/1323-prepare-write-st…