Skip to content

initial commit for multidb - #7862

Open
YasenT wants to merge 4 commits into
pulp:mainfrom
YasenT:multidb-implementation
Open

initial commit for multidb#7862
YasenT wants to merge 4 commits into
pulp:mainfrom
YasenT:multidb-implementation

Conversation

@YasenT

@YasenT YasenT commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Initial PR for the multidb implementation. To test github actions. etc

@YasenT

YasenT commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@YasenT

YasenT commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@gerrod3 What do you think? Can I get a review?

@YasenT
YasenT marked this pull request as ready for review July 24, 2026 10:30

@gerrod3 gerrod3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 1 of reviews. This is honestly quite unreviewable in its current state. The AI comments are a nightmare and make references to docs and comments I don't have access to. The commits are not logically structured either. I would probably have ordered them something like:

  1. The initial adding of the database-alias and db-router
  2. Fixing management commands and other models (GenericReleation)
  3. Adding the database domain migration command
  4. CI work and tests

I would like to set expectations now that this will require major changes and many iterations before we are close to a state that might be mergeable.

Comment thread pulpcore/app/db_router.py Outdated
Comment thread pulpcore/app/settings.py
Comment on lines +318 to +323
CROSS_PLANE_RECONCILIATION_GRACE_MINUTES = 60

# KI-11: how long, in days, a confirmed-orphaned cross-plane row is kept (logged/alerted on every
# sweep) before the reconciliation sweep deletes it outright. 0 disables purging entirely --
# orphans are only ever logged, never deleted, which is the safe default.
CROSS_PLANE_RECONCILIATION_PURGE_AFTER_DAYS = 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need these two different settings?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one makes sure we don't "flag" objects in "flight" as orphans. For example in the case of a migration of an active domain to a new DB, we need some grace period before we start flagging as orphans

And than how regularly we purge is a different setting, the 2x can be very different values. Multiple days vs multiple hours. Makes sense to be 2 phased in a way.

Comment thread pulpcore/app/settings.py Outdated
Comment thread pulpcore/app/queryset.py Outdated
_DOMAIN_WALK_MAX_DEPTH = 2


def _resolve_domain_id(value, _depth=0, _seen=None):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this? Yeah it's probably the safest way to get the domain of the object, but I would expect that get_domain would always return the correct domain that the object is in. Maybe it doesn't matter since creating GenericRelationships typically never happen in a hot path

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see it more as a protection for the future, just playing safe.

Comment thread pulpcore/app/domain_sync.py Outdated
@dralley

dralley commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Rebase this please

@YasenT
YasenT force-pushed the multidb-implementation branch from ed36dcc to 2ad60ec Compare August 10, 2026 10:20
@YasenT

YasenT commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Rebase this please

rebased. tests re-running, had to fix few things, seems okay for now

@YasenT
YasenT force-pushed the multidb-implementation branch from 35804e0 to 6c71cca Compare August 13, 2026 19:08
@YasenT
YasenT requested a review from gerrod3 August 19, 2026 09:49
@YasenT
YasenT force-pushed the multidb-implementation branch from 6c71cca to dd289cb Compare September 1, 2026 17:21
YasenT and others added 4 commits September 1, 2026 19:26
…ting

Introduce the core routing infrastructure needed to split a Pulp
instance's domains across multiple database aliases: a `database_alias`
(and `moving`) field on `Domain`, a `PulpDomainRouter` that pins
control-plane models to `default` and routes data-plane models to their
owning domain's alias (via instance hints or the domain ContextVar), and
a `CrossDBQuerySetMixin` to safely materialize subqueries that would
otherwise span two databases.

Also add the supporting ContextVar/util helpers (`with_migration_alias`,
`domain_db`, `for_each_domain`, and a `get_domain_pk()` alias fix) used
by later commits, and the app-startup guards needed for `migrate` and
its existing post_migrate hooks to behave correctly once more than one
database alias is configured.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ting

Update existing management commands (datarepair, datarepair-2327,
remove-plugin, repository-size, rotate-db-key, dump-publications-to-fs,
handle-artifact-checksums, analyze-publication) to iterate per-domain and
query the correct database alias instead of assuming a single database.

Fix GenericForeignKey/GenericRelation handling across database
boundaries: resolve the transitive domain for content_object targets
that don't carry their own pulp_domain field (e.g. RepositoryVersion),
add a content_object_domain column to CreatedResource/ExportedResource/
UserRole/GroupRole to record which alias the referenced object actually
lives on, and clean up UserRole/GroupRole rows when their cross-plane
target is deleted (Django's native GenericRelation cascade can't follow
a relation across two different databases).

Also fix ProfileArtifact's cross-plane artifact lookup in the task
profiling viewset, and materialize a couple of querysets in
role_util.py that would otherwise become invalid cross-database
subqueries.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add pulpcore-manager migrate-all/migrate for orchestrating Django
migrations across every configured database alias in the right order.

Add move-domain/cleanup-moved-domain for relocating a domain's
data-plane rows from one alias to another: begin with a read-only
cutover, copy and verify the data, then complete the cutover and
delete the stale copy left behind on the source alias.

Add sync-domains/domain-size for keeping Domain metadata replicated to
satellite aliases and reporting on a domain's footprint, and
reconcile-cross-plane-references for sweeping up orphaned cross-plane
references left behind by these operations.

This is supported by MigrationStatus/DomainMove bookkeeping models,
Domain row replication to satellites (domain_sync.py), advisory locks
so only one orchestrator/mover runs at a time, per-alias connectivity
and migration-completeness reporting on the /status/ endpoint, worker
gating so tasks are deferred while a domain's data is mid-move or its
alias is unreachable, and a degraded API response for the same cases.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a "multi_db" CI matrix leg that spins up a second Postgres service
container and runs the unit test suite against it with PulpDomainRouter
registered.

Add unit tests covering the router itself, Domain
replication/reconciliation, domain move/cleanup, cross-plane reference
reconciliation, and the DomainMiddleware/task changes from the
preceding commits.

Also fix flakiness in test_cancel_task_group by retrying task-group
cancellation on a transient 409 instead of failing outright.

Co-authored-by: Cursor <cursoragent@cursor.com>
@YasenT
YasenT force-pushed the multidb-implementation branch from dd289cb to 124b368 Compare September 1, 2026 17:27
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.

3 participants