Hi Heikki,
I verified your patch against the scenario from my duplicate report [1],
on a 19rc1 --enable-cassert build:
- the minimal SQL repro from my report (SELECT ... FOR NO KEY UPDATE,
subtransaction UPDATE, ROLLBACK TO + RELEASE SAVEPOINT, then a
TOAST-sized UPDATE in the top transaction) now passes; on the
unpatched build it trips Assert("HEAP_XMAX_IS_LOCKED_ONLY(
infomask_lock_old_tuple)");
- the real-world case where I originally hit this also passes: the
pg_task extension retries its bookkeeping UPDATE in the top
transaction after RollbackAndReleaseCurrentSubTransaction(), and
that update goes through exactly this heap_update() temp-lock
codepath (the task table update shows up in the log with the
expected lock-only infomask, no TRAP);
- with temporary elog() instrumentation at the assert site I confirmed
the multixid now comes back pruned: the aborted updating member is
removed, a fresh multixid is created, and the infomask has
HEAP_XMAX_LOCK_ONLY set — where the unpatched code returned the
original multixid unchanged (infomask without LOCK_ONLY).
The combocid regression test from the patch passes too. So the patch
fixes my case as well — thanks for picking this up!
[1]
https://www.postgresql.org/message-id/CAPgh2mJhTo2yq_vLrT6OZPn54hDxJpDVu=9l7ay_m5qognf...@mail.gmail.com
--
Georgy Shelkovy