Skip to content

[DPE-7882] fix(logical-replication): match replication peers by identity across models (8/8) - #349

Draft
marceloneppel wants to merge 8 commits into
lr-6-restore-guardfrom
lr-7-uuid-identity
Draft

marceloneppel wants to merge 8 commits into
lr-6-restore-guardfrom
lr-7-uuid-identity

Conversation

@marceloneppel

@marceloneppel marceloneppel commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Issue

Eighth PR of the logical replication migration series (after #338). Completes the cross-model half of canonical/postgresql-operator#1085 and canonical/postgresql-k8s-operator#1052: the circular-replication guards and replication chains keyed on bare app names, which are only unique within one model — and Juju renames cross-model relation remotes per side (remote-<model-uuid> on the offering side, the consume alias on the consuming side). That got cross-model cases wrong in both directions:

  • a legitimate subscription between two same-named apps in different models was rejected with Circular replication detected (chain-membership false positive), and
  • genuine cross-model cycles slipped through undetected (name comparisons never matched the per-side renames).

Solution

Identity-based matching with a legacy fallback:

  • every relation side stamps its (model UUID, app name) identity into its own app-databag side (replication-identity) at the existing write points (process_offer, push_subscription_request, apply_updated_subscription_request),
  • replication chains carry model-uuid/app-name tokens (own token appended on build),
  • Bumps the library version to 16.3.16 for the charms to pin.
  • the direct-cycle check, the multi-hop chain-membership check and the subscriber same-app check all match by identity, falling back to bare app names when a peer side has not stamped yet (names remain exact within one model).

Validation

  • tox -e lint and tox -e unit green on this commit (4857 passed / 77 skipped).
  • Charm-side circular integration suite in the charm Multipass VM with this slice baked into the packed charm (dpe-7882-reinstate-logical-replication + zip-patched lib): 7/7 passed (test_deploy_clusters, test_setup_tables, test_bidirectional_same_table_blocked, test_bidirectional_different_tables_allowed, test_cleanup_ab_relations, test_multihop_circular_blocked, test_multihop_different_table_allowed).
  • Manual CMR end-to-end in the VM (two same-named postgresql apps in different models, offer/consume via data-integrators): the legitimate same-name cross-model subscription deployed, replicated a marker row in 26 s and stayed active (no false block); the mirrored request that closes the cycle was blocked with Circular replication detected.

Checklist

  • I have added or updated any relevant documentation.
  • I have cleaned any remaining cloud resources from my accounts.

@marceloneppel marceloneppel changed the title [DPE-7882] fix(logical-replication): match replication peers by identity across models (7/6) [DPE-7882] fix(logical-replication): match replication peers by identity across models (7/7) Oct 7, 2026
@marceloneppel
marceloneppel added this pull request to stack #343 October 7, 2026 21:01
@marceloneppel marceloneppel changed the title [DPE-7882] fix(logical-replication): match replication peers by identity across models (7/7) [DPE-7882] fix(logical-replication): match replication peers by identity across models (7/8) Oct 7, 2026
@marceloneppel
marceloneppel removed this pull request from stack #343 October 7, 2026 22:36
@marceloneppel
marceloneppel added this pull request to stack #351 October 7, 2026 22:40
@marceloneppel marceloneppel changed the title [DPE-7882] fix(logical-replication): match replication peers by identity across models (7/8) [DPE-7882] fix(logical-replication): match replication peers by identity across models (8/8) Oct 7, 2026
…models

App names are unique within one model only, and Juju renames cross-model
relation remotes per side (remote-<model-uuid> on the offering side), so
the circular-replication guards and chains keyed on bare app names got
cross-model cases wrong in both directions: a legitimate subscription
between two same-named apps in different models was rejected, while real
cross-model cycles slipped through undetected.

Every relation side now stamps its (model UUID, app name) identity into
its own app-databag side, replication chains carry model-uuid/app-name
tokens, and all comparison sites match by identity with a bare-name
fallback for peers on older library versions.

Validated: unit+lint green; charm-side circular integration suite 7/7 in
the charm Multipass VM with the slice baked into the packed charm; CMR
manual test end-to-end (same-name cross-model subscription replicates,
mirrored request blocked with 'Circular replication detected').
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant