SERIES.txt -- UNDO/FLUX v3, rebased onto current origin/master
================================================================

Rebase target : origin/master = 72b916a20db4417cb3e825ab747236b154fdabd7 (2026-10-11)
Merge-base    : e5d25959cf8761c7dbdd7cfbb91338e94a40e8e2
Series        : 20 posted commits (v3), 563 files changed, +133280 / -259
Patches       : patches/0001..0020 (git format-patch, dependency order)
Bundle        : v3.bundle   (git bundle of origin/master..v3; the 20 commits
                 sit directly on 72b916a20db; a 21st local-only "dev" commit is
                 excluded from the posted series and from the bundle's range)
git-am proof  : all 20 apply onto a fresh origin/master checkout, diff --check
                 clean, AM-EXIT=0.

The 0009-0018 commits are heap-neutral preparatory changes to the table-AM,
executor, trigger, EvalPlanQual, logical-replication, VACUUM and pg_visibility
interfaces; each is a no-op for heap and for any AM that does not opt in, and
all are ordered before 0019 (FLUX), which is the first commit that uses them.

Patches
-------

0001  Add a cluster-wide UNDO engine with records in the WAL stream
      The UNDO substrate: records live in the common WAL stream; crash recovery
      reverts loser transactions' structural changes through a recovery pass.
      Changes since v2: 6 items (unused AM prepare hook removed; headerscheck
      skips undormgrlist.h; recovery-model docs made accurate; buffer content
      locks released before inline abort UNDO; failed-abort WAL-hold claim
      corrected; UNDO docs promoted to a chapter).

0002  Add transactional filesystem operations (FILEOPS) backed by UNDO
      WAL resource manager (RM_FILEOPS_ID) making structural filesystem
      mutations crash-safe and rollback-safe; AtPrepare path for 2PC.
      Changes since v2: report apply failures as failures; remove obsolete UNDO
      file cleanup. Tests: drop logical_revert_naptime in 063/061; show a crash
      right after commit loses deferred ops.

0003  Route filesystem mutations through FILEOPS
      Wire in-tree DDL/storage callers (CREATE/DROP DATABASE, TABLESPACE,
      copydir) through the FILEOPS API.  (No "Changes since v2" block.)

0004  Add per-backend UNDO logs
      Per-backend UNDO logs and the undo apply/discard workers; the engine FLUX
      table/index UNDO reverts crash losers from, after the database opens.
      Changes since v2: 38 items (2PC rollback chains; subxact undo dispatch;
      non-permanent/temp undo handling; 3-page record spanning; FPIs on undo
      pages; snapshot-limited recovery start; project formatting + pgperltidy).

0005  Add the ATM, sLog, and logical revert worker
      The aborted-transaction map, the on-demand sLog row-lock store, and the
      logical revert worker.
      Changes since v2: 24 items + 3 tests (retention report; inline UNDO always
      for non-index; new-database dir removed on abort/crash; roll back
      in-flight UNDO preceding the checkpoint; prepared row locks restored
      without clobbering owners; "a cluster that never uses UNDO costs what
      master does").

0006  nbtree: mark aborted index inserts dead via UNDO
      Changes since v2: 22 items + 2 tests (flush index UNDO before commit
      record; newest-first apply in crash recovery; CLR redo consistency-checked;
      index UNDO applied inline only).

0007  hash: mark aborted index inserts dead via UNDO
      Changes since v2: 14 items + 1 test (restore UNDO abort ordering; persist
      FILEOPS ownership for deferred crash losers; dead-tuples hint on hash
      rollback; PANIC only when an inverse cannot be made durable).

0008  nbtree: support in-place delete-marking for stable-TID UPDATE
      Changes since v2: 11 items + 1 test (uniqueness check asks the AM about a
      delete-marked entry; atomic delete-mark of a full leaf via replace split;
      amcheck handles delete-marked entries; tombstone trailer room).

0009  tableam: let an AM declare that UPDATE keeps a row's TID    [prep]
0010  executor: keep the pre-update row of an in-place UPDATE     [prep]
0011  EvalPlanQual: fetch an in-place AM's reference rows with the query
      snapshot                                                    [prep]
0012  AFTER triggers: queue an in-place AM's row images with the event  [prep]
0013  logical replication: pre-check unique keys an in-place UPDATE changes [prep]
0014  tableam: SO_RETURN_DELETED, and update_deleted detection for any AM [prep]
0015  tableam: let a block AM's size estimate use its own default fillfactor [prep]
0016  tableam: let REPACK (CONCURRENTLY) accept any AM whose changes are
      decoded                                                     [prep]
      (adds TableAmRoutine.am_logical_decoding; REPACK tests it instead of
       naming heap.)
0017  vacuum: add parallel_vacuum_set_index_stats() and a bulkdel injection
      point                                                       [prep]
0018  pg_visibility: refuse tables of other table AMs in the tuple checks [prep]
      (0009-0018 have no "Changes since v2" block except 0016; they are the new
       heap-neutral interface preparation split out of the FLUX commit.)

0019  Add the FLUX in-place-MVCC table access method
      In-place MVCC table AM: a row keeps its TID; heap-shaped xmin/xmax/cid in
      the header; older versions from the per-backend UNDO log; row locks in the
      shared on-demand sLog, never on the tuple.
      Changes since v2: 60+ items (invisible aborted writers; idempotent UNDO
      keyed on version; helping; TOAST supersede; VACUUM reclaims aborted-INSERT
      rows and truncates the whole empty tail; tombstone-removal horizon
      reasoning; scan slots own a copy under a writer-excluding lock; VACUUM
      never moves a live row; row locks not held per-row until commit;
      user_catalog_table refused; project formatting + pgperltidy).

0020  Benchmarks: HEAP vs FLUX
      Benchmark scaffolding comparing heap and FLUX. (No "Changes since v2".)

Changes since v2 (series-level)
-------------------------------
 - RECNO dropped from the series; the benchmark commit is trimmed to heap vs
   FLUX.
 - The three v2 review reports (patch-split mistakes; CREATE DATABASE crash
   leaving the directory; a filesystem error PANICking in a critical section)
   are fixed; see the cover letter.
 - The "constant time recovery / CTR" framing and the O(1) claims are dropped;
   the README states the real recovery model.
 - Rebased from the v2 base onto current origin/master (72b916a20db), 99
   upstream commits of churn resolved; 4 merge conflicts, all in test-list /
   docs files (recovery test 058/059 renumbered to 062/063 around upstream's
   new 058/059; repack.sgml restructure; test_decoding + injection_points spec
   lists), no code-logic conflicts.
 - Full release gate green on the rebased tip (see cover-letter status block).

Conflict resolutions (rebase onto origin/master)
-------------------------------------------------
 1. src/test/recovery/meson.build (0002): upstream took test numbers 058/059 for
    058_shutdown_crash_restart.pl and 059_remote_apply_status_interval.pl; our
    058_fileops_recovery.pl / 059_fileops_2pc.pl renumbered to 062/063 (files
    renamed, README and 061's comment cross-references updated). 060/061 kept.
 2. src/test/recovery/meson.build (0004): keep both sides -> 062,063,071 in order.
 3. doc/src/sgml/ref/repack.sgml (0016): upstream restructured the CONCURRENTLY
    exclusions into a nested <itemizedlist> keeping the old "access method is not
    heap" wording; our one-item wording change ("does not support logical
    decoding of its changes") re-applied to upstream's structure.
 4. contrib/test_decoding/Makefile + src/test/modules/injection_points/meson.build
    (0019): keep upstream's SLOT_CREATION_TST block / injection_points_isolation
    variable, append our flux_outofplace regress and our 8 new isolation specs
    (6 flux_* + repack_other_table + vacuum_progress).
