Re: Inval reliability, especially for inplace updates

Noah Misch <noah@leadboat.com>

From: Noah Misch <noah@leadboat.com>
To: Mark Dilger <mark.dilger@enterprisedb.com>
Cc: Nitin Motiani <nitinmotiani@google.com>, Andres Freund <andres@anarazel.de>, pgsql-hackers@postgresql.org
Date: 2026-01-21T17:47:20Z
Lists: pgsql-hackers
On Wed, Jan 21, 2026 at 08:59:51AM -0800, Mark Dilger wrote:
> On Wed, Oct 23, 2024 at 7:54 PM Noah Misch <noah@leadboat.com> wrote:
> > I'm attaching the branch-specific patches for that and for the main fix.
> > Other notes from back-patching:
> >
> > - All branches change the ABI of PrepareToInvalidateCacheTuple(), a
> > function
> >   catcache.c exports for the benefit of inval.c.  No PGXN extension calls
> >   that, and I can't think of a use case in extensions.
> 
> Unfortunately, I can think of four.

Those are non-PGXN extensions, right?

Based on your experience, I probably should encourage packagers to do an early
check of the packages they build, especially if they build tableam modules not
found in PGXN.  How do you see it?

> I have four Table Access Methods that
> I now need to fork to be compatible with 18.0 and 18.1 on the one hand, and
> 18.2 onward on the other.

For what it's worth, the ABI break you quoted is the v14-v17 break, not the
v18 break:

- v18.2 (06b030e) is changing the CacheInvalidateHeapTupleInplace() ABI
- v14-v17 (e.g. 2e58802) is changing the PrepareToInvalidateCacheTuple() ABI

> I'm sorry I didn't follow this thread before it got pushed.
> 
> Is there a reason for doing this change in back branches?  The thread is
> pretty long, and I'm struggling to find a security or stability
> justification for the ABI break, but perhaps there is one.

Chiefly, the fix prevents data loss that arose via losing a relhasindex,
relfrozenxid, or datfrozenxid update.  (The log message of 0f69bed says
"another backend's DDL could then update the row without incorporating the
inplace update".)  For an example, see where that commit edits
src/test/isolation/expected/inplace-inval.out.



Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Update .abi-compliance-history for PrepareToInvalidateCacheTuple().

  2. Assert lack of hazardous buffer locks before possible catalog read.

  3. For inplace update, send nontransactional invalidations.

  4. Update .abi-compliance-history for CacheInvalidateHeapTupleInplace().

  5. Revisit cosmetics of "For inplace update, send nontransactional invalidations."

  6. Correct comments of "Fix data loss at inplace update after heap_update()".

  7. Move I/O before the index_update_stats() buffer lock region.

  8. Revert "For inplace update, send nontransactional invalidations."

  9. Revert "WAL-log inplace update before revealing it to other sessions."

  10. Fix inplace update buffer self-deadlock.

  11. Remove duplicate words in comments

  12. At end of recovery, reset all sinval-managed caches.

  13. Fix data loss at inplace update after heap_update().

  14. Remove comment about xl_heap_inplace "AT END OF STRUCT".

  15. Reduce memory consumption for pending invalidation messages.

  16. Add support for streaming to built-in logical replication.

  17. WAL Log invalidations at command end with wal_level=logical.

  18. Introduce logical decoding.

  19. Rename and document some invalidation routines to make it clearer that