tidaldb/docs/planning/milestone-8/phase-10/task-06-skew-rolling-upgrade.md
jx12n 8a0950260f feat(m8p10): multi-process cluster mode — scatter-gather, reconcile relay, chaos/UAT suites
Splits monolithic cluster.rs into tidal-server/src/cluster/ modules. Adds redeliver-missed
relay, bounded HLC drift, lag tracking, and reconcile idempotence. Five new tier-3 test suites
(chaos, lifecycle, multiproc, region, routes, runbook) all green. Docs, CHANGELOG, and ROADMAP
updated with G4/G5/G6 known gaps.
2026-06-10 14:07:33 -06:00

71 lines
3.7 KiB
Markdown

# Task 06: Clock-skew and rolling-upgrade scenarios
## Delivers
The remaining two ROADMAP chaos scenarios, in the same `cluster_chaos.rs` suite (or a
sibling `cluster_lifecycle.rs` if size warrants — implementer's call, same feature gate):
HLC clock-skew with ±500ms across processes, and a 3-node rolling upgrade with a
continuously-written mixed-version window.
## Complexity: M
## Dependencies
Task 04 (harness restart/env hooks); task 01 (HLC offset, `TIDAL_HLC_SKEW_MS`).
## Technical Design
### Clock skew (`mp_clock_skew_reconciliation_stays_causal`)
Spawn 3 nodes with `TIDAL_HLC_SKEW_MS` = `+500`, `0`, `-500` (each process's HLC
genuinely runs skewed — the engine offset from task 01, no mocks). Scenario:
1. Seed + converge; signals replicate normally (decay timestamps are `Timestamp::now()`,
unaffected by HLC skew — assert decay parity 1e-6 still holds; this pins the scope of
the skew mechanism).
2. Divergence: hide a (user,item) on the skewed-BEHIND node, and (after partitioning it
via the task-05 proxy) hide a different pair on the skewed-AHEAD leader; heal.
3. `/cluster/reconcile` in BOTH directions; assert: both nodes converge to the identical
hard-negative state (LWW is deterministic despite 1s of relative skew — HLC `update()`
advances past remote timestamps, `max(wall, last_seen+1)`); repeated reconciles are
no-ops (stability ⇒ no timestamp oscillation); skewed-behind node's hides are not
lost (its register still wins where it is the only writer — hide semantics intact).
4. Assert reconcile responses stay < 100ms (skew must not break the perf envelope).
### Rolling upgrade (`mp_rolling_upgrade_no_loss_no_stall`)
ROADMAP mechanism: "simulate by restarting with different config." All nodes run
persistent `--data-dir`s.
1. Boot 3 nodes ("version N": env `TIDAL_VERSION_TAG=N` informational; config has
`write_workers: 2`).
2. Start a background writer: continuous `POST /signals` round-robin against ALL nodes
(forwarding finds the leader), tallying successes/failures.
3. Upgrade followers first, one at a time: SIGTERM (graceful), restart same data-dir with
"version N+1" (env tag + `write_workers: 4`), `wait_healthy`, `POST /cluster/heal` for
the restarted region (covers segments shipped while it was down its WAL recovery
plus heal close the gap), `wait_converged_all`.
4. Leader last: `POST /cluster/promote` to an already-upgraded follower, then restart the
old leader the same way the real rolling-upgrade choreography.
5. Stop the writer. Assert: zero write errors during the whole window (a request window
overlapping a node's restart may retry once forwarding to the CURRENT leader must
make every logical write eventually succeed; tally semantics defined in-test);
final convergence on all 3 (counts equal, decay parity 1e-6 restarted nodes
recovered their pre-restart state from WAL, no loss); lag returns to 0 (no stall);
leader is the promoted node.
Engine note: `replication::upgrade::RollingUpgradeCoordinator` exists from earlier M8
work the implementer reads it first and reuses/asserts through it where it fits the
server surface; if it is engine-internal version-gating only, note that in the test
header rather than forcing it in.
## Acceptance Criteria
- [ ] Skew test: processes genuinely run with ±500ms HLC offsets; reconciliation
deterministic and stable both directions; hides intact; decay unaffected;
reconcile < 100ms under skew
- [ ] Rolling upgrade: continuous writes across the full 3-node restart choreography
with zero lost logical writes, zero corruption (WAL recovery proven by post-restart
parity), zero replication stall, promote-before-leader-restart exercised
- [ ] Both suites green under `--features cluster-e2e`