Skip to content

fix: bind installer include mode to its migration transaction - #205

Draft
samo-agent wants to merge 2 commits into
NikolayS:release/2.0from
samo-agent:agent/fix-202-external-marker
Draft

fix: bind installer include mode to its migration transaction#205
samo-agent wants to merge 2 commits into
NikolayS:release/2.0from
samo-agent:agent/fix-202-external-marker

Conversation

@samo-agent

@samo-agent samo-agent commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Draft stacked #202 fix — do not merge

This isolates the follow-up delta on the held release/2.0 branch. It does not authorize merging #200, #204, or this PR, and it does not authorize tagging. Before the final release candidate, this fix must be folded into the candidate and the release-stamp commit recreated last so payload identity remains unambiguous.

Relates to #202.

Red reproduction

The previous held head ba96f7858c0827b8afaf031cd3f832de37db256a trusted the literal value of pg_ash.install_in_migration_transaction. Supplying it before connection startup bypassed both installer transaction boundaries:

Issue #202 external-marker v1.5 precondition: 1.5|1.5|11
Issue #202 external-marker v1.5 install_exit=3
Issue #202 external-marker v1.5 after failure: 2.0|2.0|11
ERROR: forced late installer failure under externally preset marker

The new regression supplies PGOPTIONS=-c pg_ash.install_in_migration_transaction=on before direct installer invocation. It covers both the immutable v1.5 payload and an empty database, forces a late failure at ash.summary(...), and compares identity, config data, config relation OID, schema, and survival of the blocker from a fresh connection.

Fix and rationale

A finite preflight cannot cover event triggers, dependency changes, concurrent DDL, vanished roles, permissions, cancellation, deadlock/timeout, storage/resource failures, or commit failure. The robust boundary remains one transaction around installer replay plus normalization.

The migration now stores its assigned transaction ID in the transaction-local internal setting. The installer accepts include mode only when that token matches pg_current_xact_id_if_assigned(); an ambient literal such as on has no matching assigned transaction and therefore fails closed into direct-installer transaction ownership. The installer computes that decision once and reuses it at the footer, so later SQL or an event trigger cannot change ownership by mutating the setting. The migration retains one final COMMIT; direct invocation retains its documented final COMMIT.

Green verification

Exact candidate: 38af9f2f9b462027a484bd42ae0c273ecfe32a28

PostgreSQL 14 full #202 suite: PASS
PostgreSQL 17 full #202 suite: PASS
PostgreSQL 19beta2 full #202 suite: PASS

external-marker v1.5: install_exit=3, after=1.5|1.5|11, rollback PASS
external-marker fresh: install_exit=3, after=<absent>|<absent>|<absent>, rollback PASS
custom-trigger: migration_exit=3, after=1.5|1.5|11, rollback PASS
dependent-view: migration_exit=3, after=1.5|1.5|11, rollback PASS
same-client transaction-marker rollback: PASS

PostgreSQL 17 release gate:
  fresh-install PASS
  upgrade-chain PASS
  features PASS
  degraded-no-cron PASS
  degraded-no-pgss PASS
  degraded-neither PASS
  cron-path PASS

17/17 test_release_stamp.py: PASS
7/7 test_ci_step_script.py: PASS
check_release_stamp.py --tag v2.0: PASS
git diff --check: PASS

No merge or tag has been performed.

Exercise a marker supplied through PGOPTIONS against both the immutable v1.5 payload and an empty database. A forced late DDL failure must leave version, config data and identity, and the ash schema exactly unchanged.
The installer previously trusted the literal internal GUC value, so an ambient PGOPTIONS setting could suppress both transaction boundaries. Store the migration's transaction ID as the local token, accept include mode only when it matches the currently assigned transaction, and cache that decision through the footer. Direct invocations now retain their transaction while the cumulative migration still owns one atomic installer-plus-normalization transaction.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant