Skip to content

Add IN CLUSTER ... REPLICA ... syntax for materialized views#35235

Draft
antiguru wants to merge 6 commits intoMaterializeInc:mainfrom
antiguru:replica_targeted_objects
Draft

Add IN CLUSTER ... REPLICA ... syntax for materialized views#35235
antiguru wants to merge 6 commits intoMaterializeInc:mainfrom
antiguru:replica_targeted_objects

Conversation

@antiguru
Copy link
Member

Per-replica introspection needs materialized views that render only on a specific replica.
This adds IN CLUSTER <cluster> REPLICA <replica> syntax to CREATE MATERIALIZED VIEW, threading a target_replica through the compute controller, SQL parser, planner, catalog, and sequencer.

The first commit adds the target_replica field to DataflowDescription and the compute controller, including the send_to_collection_replicas helper that routes commands only to the replica hosting a targeted collection.

The second commit threads the field through the SQL layer: the parser accepts the new syntax, the planner resolves the replica name, the catalog stores it, and the sequencer sets it on the dataflow before shipping.
On bootstrap, target_replica is restored from the catalog.

The syntax is internal-only.
All existing callers pass None, so behavior is unchanged.

Tests added:

  • test/sqllogictest/materialized_view_replica_targeted.slt — parsing, error cases, round-trip, data correctness
  • test/testdrive/materialized-view-replica-targeted.td — introspection (hydration status, per-replica frontiers), replica drop/recreate, cluster restart

🤖 Generated with Claude Code

Add a `target_replica` field on `DataflowDescription` that pins a
dataflow to a specific replica. The controller ensures only the targeted
replica receives the dataflow and its related commands (`Schedule`,
`AllowWrites`, `AllowCompaction`).

The field defaults to `None` in `DataflowDescription::new()`, so all
existing callers retain broadcast behavior unchanged.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@github-actions
Copy link

Thanks for opening this PR! Here are a few tips to help make the review process smooth for everyone.

PR title guidelines

  • Use imperative mood: "Fix X" not "Fixed X" or "Fixes X"
  • Be specific: "Fix panic in catalog sync when controller restarts" not "Fix bug" or "Update catalog code"
  • Prefix with area if helpful: compute: , storage: , adapter: , sql:

Pre-merge checklist

  • The PR title is descriptive and will make sense in the git log.
  • This PR has adequate test coverage / QA involvement has been duly considered. (trigger-ci for additional test/nightly runs)
  • If this PR includes major user-facing behavior changes, I have pinged the relevant PM to schedule a changelog post.
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).

Thread a `target_replica` through the SQL layer so materialized views
can be pinned to a specific cluster replica. The parser accepts
`IN CLUSTER <cluster> REPLICA <replica>` on CREATE MATERIALIZED VIEW
statements. The planner resolves the replica name to a ReplicaId, the
catalog stores it, and the sequencer sets `DataflowDescription.target_replica`
before shipping the dataflow. On bootstrap, the field is restored from
the catalog entry.

The syntax is internal-only. All existing callers continue to pass
`None`, so behavior is unchanged.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@antiguru antiguru force-pushed the replica_targeted_objects branch from 37af36a to b86bc61 Compare February 26, 2026 20:34
antiguru and others added 2 commits February 27, 2026 10:33
The pretty-printer for `SHOW CREATE MATERIALIZED VIEW` was not
emitting the `REPLICA <name>` clause after `IN CLUSTER <name>`.
Also fix the error message expectation in the SLT test.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…dropped

When a replica is dropped, any materialized views that target it via
`IN CLUSTER ... REPLICA ...` are also dropped. Without this, the persist
shard's upper frontier stops advancing (no replica advances it), causing
reads to hang indefinitely.

The cascade is implemented in `ObjectsToDrop::add_item` for the
`ClusterReplica` case, which covers both `DROP CLUSTER REPLICA` and
`ALTER CLUSTER SET (REPLICATION FACTOR ...)` code paths.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Member Author

@antiguru antiguru left a comment

Choose a reason for hiding this comment

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

We need to ensure that replica-targeted objects can only be created by privileged users, i.e., mz_system for the moment.

* Restrict replica-targeted MV creation to internal users (mz_system).
  Non-internal users get "permission denied" error.
* Extract `ComputeCommand::target_replica()` method and use it in the
  rehydration filtering logic.
* Add comment explaining the target_replica existence check in
  `create_dataflow`.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Comment on lines 1149 to 1156
match &command {
ComputeCommand::Schedule(cid) if skipped_ids.contains(cid) => continue,
ComputeCommand::AllowCompaction { id: cid, .. } if skipped_ids.contains(cid) => {
continue;
}
ComputeCommand::AllowWrites(cid) if skipped_ids.contains(cid) => continue,
_ => {}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Please extract a collection_id function here.

@antiguru antiguru force-pushed the replica_targeted_objects branch 3 times, most recently from da3de8c to 969657d Compare February 27, 2026 14:36
The privilege check requires an internal user for creating
replica-targeted materialized views. Update both SLT and testdrive
tests to use mz_system connections for these statements.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@antiguru antiguru force-pushed the replica_targeted_objects branch from 969657d to 76f337d Compare February 27, 2026 15:24
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