Skip to content

compute: drop the duplicated instants from the hydration times relation [closed: not worth the churn] - #38427

Closed
antiguru wants to merge 1 commit into
claude/hydration-visibility-compute-js1ycmfrom
claude/hydration-times-slim-js1ycm
Closed

compute: drop the duplicated instants from the hydration times relation [closed: not worth the churn]#38427
antiguru wants to merge 1 commit into
claude/hydration-visibility-compute-js1ycmfrom
claude/hydration-times-slim-js1ycm

Conversation

@antiguru

@antiguru antiguru commented Aug 24, 2026

Copy link
Copy Markdown
Member

Closed, not deferred. The duplication this removes is real but internal, and removing it makes the relation worse to read.

mz_compute_hydration_times_per_worker carries time_ns, a duration whose origin is the export's creation. Dropping installed_at moves that origin into a different relation, so the relation no longer explains its own duration: interpreting it means either a join against the lifecycle log or the non-obvious hydrated_at - time_ns. Before, the instants and the duration cross-checked each other inside one row, which is what let the ordering invariant be asserted locally.

Against that, the duplication costs two Duration fields per export per worker and a few lines of packing, and is invisible to consumers. The removal gives no consumer a capability it did not have. Meanwhile it churns a downstream consumer that is being built against these relations right now.

"Remove the duplication" was the right instinct about an internal wart. The wart turns out to be cheaper than the surgery.

What survives from this PR: the reasoning about why hydrated_at cannot be pivoted from the lifecycle log's hydrated — the first is the durability reading, taken when the reported output frontier passes the as-of, and the second is the dataflow-progress reading. Since mz_compute_hydration_statuses.hydrated is time_ns IS NOT NULL and feeds blue-green readiness, redefining it would have readiness cut over before the output is durable. That is now recorded as a frozen commitment in the design doc's "What the timestamps promise, and what they do not", along with the rest of the consumer-facing compatibility contract.

If this is ever revisited, the smaller and more defensible cut is to drop only started_at, keeping installed_at so time_ns's origin stays in the row.

@linear-code

linear-code Bot commented Aug 24, 2026

Copy link
Copy Markdown

CPU-226

@antiguru
antiguru force-pushed the claude/hydration-times-slim-js1ycm branch from dfce91f to 504223d Compare August 24, 2026 12:13
`installed_at` and `started_at` were maintained twice, in this relation and in
`mz_compute_lifecycle_events_per_worker`, from the same handlers and the same
event times, with the `installed_at <= started_at` invariant enforced in both
representations. Keep them in one place: the lifecycle log's `installed` and
`started` events.

`time_ns` and `hydrated_at` stay. They are not duplicates of anything, because
`hydrated_at` is the durability reading, taken when the reported output frontier
passes the as-of. That frontier is the meet of the write and compute frontiers, so
for a collection that sinks to persist it moves only once the output is durable,
while for an index, which produces its output by writing its own trace, it
coincides with computation. One column meant two things depending on the object.

The lifecycle log answers that by using separate terms rather than redefining the
column: its `hydrated` is always the dataflow-progress reading and its `written`
is always the durability one, neither depending on the object type. Pivoting the
log's `hydrated` into `hydrated_at` would therefore not be a refactor but a
redefinition, and since `mz_compute_hydration_statuses.hydrated` is `time_ns IS
NOT NULL` and feeds the blue-green readiness query, it would have readiness cut
over on the earlier compute reading, before the output is durable. Comments at
both relations record which reading each term carries.

`handle_hydration_start` no longer writes to the hydration-time output, since
nothing it changes is packed there any more; its retract-and-reinsert pair would
have been a no-op. `started_at` survives as internal state only, to guard the
handler and to back-fill `started` in `handle_hydration`.

`test/testdrive/hydration-timestamps.td` moves its stage scenarios to the
lifecycle relation and keeps the duration assertions here, so it now tests that
the two relations agree rather than that one of them is self-consistent. The
`time_ns` cross-check joins them on `(export_id, worker_id)`, both being per
worker.

No new migration step: the index key `(export_id, worker_id)` is unchanged, and
the `mz_indexes` fingerprint move is covered by the existing replacement step at
this dev version.

Part of CPU-226

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZVCMBSLdxzGus78ZKWhZz
@antiguru
antiguru force-pushed the claude/hydration-times-slim-js1ycm branch from 504223d to 950ab39 Compare August 24, 2026 13:02
@antiguru antiguru changed the title compute: drop the duplicated instants from the hydration times relation compute: drop the duplicated instants from the hydration times relation [closed: not worth the churn] Aug 24, 2026
@antiguru antiguru closed this Aug 24, 2026
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.

2 participants