adapter: remove ENABLE_CLUSTER_CONTROLLER and the legacy REFRESH scheduler - #38101
adapter: remove ENABLE_CLUSTER_CONTROLLER and the legacy REFRESH scheduler#38101aljoscha wants to merge 1 commit into
Conversation
…duler The cluster controller has been default-on since v26.29 and owns the replica set of every user managed cluster. The break-glass dyncfg kept two legacy paths reachable: the REFRESH scheduler in `cluster_scheduling.rs`, whose two entry points already returned before doing any work while the gate was on, and the legacy branches in the ALTER sequencer. Delete the gate and everything only it kept alive: the scheduler module, its coordinator plumbing (two messages, the timer, the select-loop tick, the `cluster_scheduling_decisions` state), the two scheduler metrics, the `cluster_check_scheduling_policies_interval` system var, and the `ReplicaCreateDropReason::ClusterScheduling` variant. The persisted audit vocabulary stays: `SchedulingDecisionsWithReasonsV2` and friends are written by the controller's on-refresh path too, and old events must remain decodable.
f283eea to
ed282e5
Compare
| # period. A zero value would therefore crash-loop environmentd on every boot, | ||
| # so it must be rejected at ALTER SYSTEM SET time. | ||
| simple conn=mz_system,user=mz_system | ||
| ALTER SYSTEM SET cluster_check_scheduling_policies_interval = '0s'; |
There was a problem hiding this comment.
hmm, does our new controller actually run on a similar interval to where we had this before? Now I'm curious.
|
Close, but slower, and the difference is absorbed by a knob that was always the real one. The old poll was The controller's interval is only a fallback cadence, Why the 2s doesn't worry me: the window decision is so the turn-on already leads the refresh by Worth saying explicitly: both numbers are the polling interval, not a bound on how long a refresh takes. Turning the cluster on is the cheap part. Happy to drop |
mtabebe
left a comment
There was a problem hiding this comment.
Change looks good for me. Thanks for updating all the comments too
|
tyty! 🙇♂️ you probably saw, and I don't want to hurry you, but there are some more cleanups left in this stack 😅 |
Part 1 of 3 of the design for removing the legacy cluster paths.
Stacked on #38078 (the design doc). Parts 2 and 3 stack on this one.
Why
The cluster controller has been default-on since v26.29 and owns the replica
set of every user managed cluster in production. It still lives behind the
break-glass dyncfg
ENABLE_CLUSTER_CONTROLLER, and that flag is the only thingkeeping the legacy REFRESH scheduler reachable: both of its entry points return
before doing any work while the gate is on, so it is a strict no-op in
production today.
Removing the gate means reverting to the legacy paths requires a binary
rollback. The gate has several releases of burn-in behind it, and the direct
reshape path (see part 3) remains as the operational escape hatch.
What lands
ENABLE_CLUSTER_CONTROLLERdyncfg: definition, registration, its fiveread sites, and the sqllogictest binary's force-on entry.
src/adapter/src/coord/cluster_scheduling.rswholesale:check_scheduling_policies,check_refresh_policy,handle_scheduling_decisions, and theSchedulingDecision/RefreshDecisiontypes.Message::CheckSchedulingPoliciesandMessage::SchedulingDecisionswith their handlers, the timer, theselect-loop tick, and the
cluster_scheduling_decisionsstate.mz_check_scheduling_policies_secondsandmz_handle_scheduling_decisions_seconds(and their rows in the generateddoc/user/data/metrics.yml).cluster_check_scheduling_policies_interval, whose soleconsumer was the timer.
ReplicaCreateDropReason::ClusterScheduling, constructed only by thescheduler.
The persisted audit vocabulary stays:
SchedulingDecisionsWithReasonsV2andfriends are written by the controller's on-refresh path too
(
refresh_window_decision_to_audit_log), and old events must remain decodableregardless.
Tests
test/sqllogictest/mz_cluster_schedules.slt: thecluster_check_scheduling_policies_intervalvalidation block goes with thevar.
test/testdrive/cluster-controller.td: thecc_handoff*legacy-handoffscenarios and the
cc_strandbreak-glass section are deleted (both aregate-off scenarios). The freeze-the-controller technique in the
unmanaged-conversion refusal block is replaced by cranking
cluster_controller_tick_intervalup. Part 3 adds a replacement forcc_strandthat exercises the direct cut-over escape hatch instead.test/pg-cdc/cluster-graceful-reconfiguration.td: the explicit legacyforeground section goes, the controller section stays.
misc/python/materialize/mzcompose/__init__.pypins the flag only forversions below v26.38, so mixed-version runs against older binaries still
exercise the same path.
parallel_workload/action.pydrops it from thedo-not-flip list, and the two launchdarkly-flag-consistency allowlist entries
go.