commit d0a862d09016b2c02811821644688cee2c33089d Author: Alexey Masterov Date: Wed May 6 11:01:31 2026 +0200 xact: Prevent assertion failure in re-entrant AbortTransaction calls When an error occurs during AbortTransaction() after ProcArrayEndTransaction() has cleared MyProc->xid, subsequent abort attempts could pass a valid latestXid to ProcArrayEndTransaction() while proc->xid is already invalid, triggering Assert(TransactionIdIsValid(proc->xid)). Avoid this by checking MyProc->xid validity before calling RecordTransactionAbort() and only passing a valid latestXid when appropriate. diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 48bc90c9673..c7819d7d9d4 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -2979,7 +2979,20 @@ AbortTransaction(void) * record. */ if (!is_parallel_worker) - latestXid = RecordTransactionAbort(false); + { + /* + * Re-entrant abort: if another ERROR is raised during AbortTransaction() + * after ProcArrayEndTransaction() cleared our advertised XID, local + * transaction state can still report an XID until CleanupTransaction(). + * Do not run RecordTransactionAbort again (duplicate WAL/clog) and do + * not pass a valid latestXid to ProcArrayEndTransaction with proc->xid + * already cleared. + */ + if (TransactionIdIsValid(MyProc->xid)) + latestXid = RecordTransactionAbort(false); + else + latestXid = InvalidTransactionId; + } else { latestXid = InvalidTransactionId;