From c7247ea196239894c44bfff35eba7cbb9aa1aac0 Mon Sep 17 00:00:00 2001 From: Chee Wooson Date: Mon, 28 Sep 2026 17:31:24 +0800 Subject: [PATCH v3 1/3] Wait for updaters still in progress when checking multixact conflicts An aborted updater can still be present in ProcArray after its abort is recorded in pg_xact. Skipping its conflict at that point lets callers proceed without the transaction-completion guarantee they expect; it can also make a later expansion try to add a second updater. Ignore an updater only after it is no longer running and has no commit record. Conflicting requests now wait until the abort window closes. The same rule also recognizes crash leftovers that can never commit. --- src/backend/access/heap/heapam.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 4207f0e0e08..17503e2fd1b 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -7863,8 +7863,14 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, if (ISUPDATE_from_mxstatus(members[i].status)) { - /* ignore aborted updaters */ - if (TransactionIdDidAbort(memxid)) + /* + * Ignore updaters that can no longer commit: not running, + * and no commit record can appear afterwards, since only + * the transaction itself could write one. This covers + * aborted updaters as well as crash leftovers. + */ + if (!TransactionIdIsInProgress(memxid) && + !TransactionIdDidCommit(memxid)) continue; } else @@ -7876,10 +7882,10 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, /* * Whatever remains are either live lockers that conflict with our - * wanted lock, and updaters that are not aborted. Those conflict - * with what we want. Set up to return true, but keep going to - * look for the current transaction among the multixact members, - * if needed. + * wanted lock, and updaters that are still running or committed. + * Those conflict with what we want. Set up to return true, but + * keep going to look for the current transaction among the multixact + * members, if needed. */ result = true; } -- 2.43.0