Skip to content

Conversation

@teskje
Copy link
Contributor

@teskje teskje commented Jan 15, 2026

This commit implements a piece of missing sequencing logic for ALTER MATERIALIZED VIEW ... APPLY REPLACEMENT ...: Before cutting over to the new dataflow we need to make sure that the old one has caught up to the new one. Otherwise the new one would start writing by appending an empty batch to bridge the gap, which could cause consistency violations.

The strategy chosen here is the same as what we already do for ALTER SINK. We split the sequencing into a prepare and a finish step. In the prepare step, we install a watch set that waits for the target MV's dataflow to catch up. When the watch set completes, we run the finish step which applies the replacement.

To ensure the waiting doesn't block all concurrent DDL, we need to exempt the ALTER MV sequencing from the global DDL lock. In the finish step we have to make sure that the replacement plan we're going to apply is still valid, i.e., neither the target nor the replacement has been dropped in the meantime.

Motivation

  • This PR fixes a recognized bug.

Fixes https://github.com/MaterializeInc/database-issues/issues/9980

(Kind of... It's expected behavior, so this provides a useful error instead of really fixing anything.)

  • This PR adds a known-desirable feature.

Closes https://github.com/MaterializeInc/database-issues/issues/9944

Tips for reviewer

Checklist

  • This PR has adequate test coverage / QA involvement has been duly considered. (trigger-ci for additional test/nightly runs)
  • 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).
  • If this PR includes major user-facing behavior changes, I have pinged the relevant PM to schedule a changelog post.

The previous apply update sorting logic assumed that ID order equals
dependency order for "derived items". That's not correct anymore: An
altered materialized view can depend on items with greater catalog IDs.

To ensure Materialize doesn't panic during startup when trying to parse
such altered materialized views, this commit changes the item update
sorting to use a topological sort for derived items instead.
The topological sorting in apply was using an inefficient quadratic
algorithm. That was fine when we were only sorting connection items but
is not fine anymore now that all most catalog items need to be sorted
topologically.

This commit changes the topo sort implementation to use Kahn's algorithm
(https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm),
which does the job in time linear in the number of items and dependency
edges.
This commit implements a piece of missing sequencing logic for `ALTER
MATERIALIZED VIEW ... APPLY REPLACEMENT ...`: Before cutting over to the
new dataflow we need to make sure that the old one has caught up to the
new one. Otherwise the new one would start writing by appending an empty
batch to bridge the gap, which could cause consistency violations.

The strategy chosen here is the same as what we already do for `ALTER
SINK`. We split the sequencing into a prepare and a finish step. In the
prepare step, we install a watch set that waits for the target MV's
dataflow to catch up. When the watch set completes, we run the finish
step which applies the replacement.

To ensure the waiting doesn't block all concurrent DDL, we need to
exempt the ALTER MV sequencing from the global DDL lock. In the finish
step we have to make sure that the replacement plan we're going to apply
is still valid, i.e., neither the target nor the replacement has been
dropped in the meantime.
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