Files
seaweedfs/sw-block/design/wal-replication-v2-orchestrator.md
T
pingqiuandClaude Opus 4.6 edec7098e8 feat: add V2 protocol simulator and enginev2 sender/session prototype
Adds sw-block/ directory with:

- distsim: protocol correctness simulator (96 tests)
  - cluster model with epoch fencing, barrier semantics, commit modes
  - endpoint identity, control-plane flow, candidate eligibility
  - timeout events, timer races, same-tick ordering
  - session ownership tracking with ID-based stale fencing

- enginev2: standalone V2 sender/session implementation (63 tests)
  - per-replica Sender with identity-preserving reconciliation
  - RecoverySession with FSM phase transitions and session ID
  - execution APIs: BeginConnect, RecordHandshake, BeginCatchUp,
    RecordCatchUpProgress, CompleteSessionByID — all sender-authority-gated
  - recovery outcome branching: zero-gap, catch-up, needs-rebuild
  - assignment-intent orchestration with epoch fencing

- design docs: acceptance criteria, open questions, first-slice spec,
  protocol development process

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:38:27 -07:00

8.5 KiB

WAL Replication V2 Orchestrator

Date: 2026-03-26 Status: design proposal Purpose: define the volume-level orchestration model that sits above the per-replica WAL V2 FSM

Why This Document Exists

ReplicaFSM alone is not enough.

It can describe one replica relative to the current primary, but it cannot by itself model:

  • primary head continuing to advance
  • multiple replicas in different states
  • durability mode semantics
  • primary lease loss and epoch change
  • primary failover and replica promotion
  • fencing of old recovery sessions

So WAL V2 needs a second layer:

  • per-replica ReplicaFSM
  • volume-level Orchestrator

Scope

This document defines the volume-level logic only.

It does not define:

  • exact network protocol
  • exact master RPCs
  • exact storage backend internals

It assumes the per-replica state machine from:

  • wal-replication-v2-state-machine.md

Core Model

The orchestrator owns:

  1. current primary lineage
  • epoch
  • lease/authority state
  1. volume durability mode
  • best_effort
  • sync_all
  • sync_quorum
  1. moving primary progress
  • headLSN
  • checkpoint/snapshot anchors
  1. replica set
  • one ReplicaFSM per replica
  • per-replica role in the current volume topology
  1. volume-level admission decision
  • can writes proceed?
  • can sync requests complete?
  • must promotion/failover occur?

Two FSM Layers

Layer A: ReplicaFSM

Owns per-replica state such as:

  • Bootstrapping
  • InSync
  • Lagging
  • CatchingUp
  • PromotionHold
  • NeedsRebuild
  • Rebuilding
  • CatchUpAfterRebuild
  • Failed

Layer B: VolumeOrchestrator

Owns system-wide state such as:

  • current epoch
  • current primary identity
  • durability mode
  • set of required replicas
  • current headLSN
  • whether writes or promotions are allowed

The orchestrator does not replace ReplicaFSM. It drives it.

Volume State

The orchestrator should track at least:

type VolumeMode string

type PrimaryState string

const (
    PrimaryServing  PrimaryState = "Serving"
    PrimaryDraining PrimaryState = "Draining"
    PrimaryLost     PrimaryState = "Lost"
)

type VolumeModel struct {
    Epoch        uint64
    PrimaryID    string
    PrimaryState PrimaryState
    Mode         VolumeMode

    HeadLSN       uint64
    CheckpointLSN uint64

    RequiredReplicaIDs []string
    Replicas           map[string]*ReplicaFSM
}

This is a model shape, not a required production struct.

Orchestrator Responsibilities

1. Advance primary head

When primary commits a new write:

  • increment headLSN
  • enqueue/send to replica sender loops
  • evaluate whether the current mode still allows ACK

2. Evaluate sync eligibility

The orchestrator computes volume-level durability from replica states.

Derived rule:

  • only ReplicaFSM.IsSyncEligible() counts

3. Drive recovery entry

When a replica disconnects or falls behind:

  • feed disconnect/lag events into that replica FSM
  • decide whether to try catch-up or rebuild
  • acquire recovery reservation if required

4. Handle primary authority changes

When lease is lost or a new primary is chosen:

  • increment epoch
  • abort stale recovery sessions
  • reevaluate all replica relationships from the new primary's perspective

5. Drive promotion / failover

When current primary is lost:

  • choose promotion candidate
  • assign new epoch
  • move old primary to stale/lost
  • convert the promoted replica into the new serving primary
  • reclassify remaining replicas relative to the new primary

Required Volume-Level Events

The orchestrator should be able to simulate at least these events.

Write/progress events

  • WriteCommitted(lsn)
  • CheckpointAdvanced(lsn)
  • BarrierCompleted(replicaID, flushedLSN)

Replica health events

  • ReplicaDisconnected(replicaID)
  • ReplicaReconnect(replicaID, flushedLSN)
  • ReplicaReservationLost(replicaID)
  • ReplicaCatchupTimeout(replicaID)
  • ReplicaRebuildTooSlow(replicaID)

Topology/control events

  • PrimaryLeaseLost()
  • EpochChanged(newEpoch)
  • PromoteReplica(replicaID)
  • ReplicaAssigned(replicaID)
  • ReplicaRemoved(replicaID)

Mode Semantics

best_effort

Rules:

  • ACK after primary local durability
  • replicas may be Lagging, CatchingUp, NeedsRebuild, or Rebuilding
  • background recovery continues

Volume implication:

  • primary can keep serving while replicas recover

sync_all

Rules:

  • ACK only when all required replicas are InSync and durable through target LSN
  • bounded retry only
  • no silent downgrade

Volume implication:

  • one lagging required replica can block sync completion
  • orchestrator may fail requests, not silently reinterpret policy

sync_quorum

Rules:

  • ACK when quorum of required nodes are durable through target LSN
  • lagging replicas may recover in background as long as quorum remains

Volume implication:

  • orchestrator must count eligible replicas, not just healthy sockets

Primary-Head Simulation Rules

The orchestrator must explicitly model that the primary keeps moving.

Rule 1: head moves independently of replica recovery

A replica entering CatchingUp does not freeze headLSN.

Rule 2: each recovery attempt uses explicit targets

For a replica in recovery, orchestrator chooses:

  • catchupTargetLSN = H0
  • or snapshotCpLSN = C and replay target H0

Rule 3: promotion is explicit

A replica is not restored to InSync just because it reaches H0.

It must still pass:

  • barrier confirmation
  • PromotionHold

Failover / Promotion Model

The orchestrator must be able to simulate:

  1. old primary loses lease
  2. old primary is fenced by epoch change
  3. one replica is promoted
  4. promoted replica becomes new primary under a higher epoch
  5. all old recovery sessions from the old primary are invalidated
  6. remaining replicas are reevaluated relative to the new primary's head and retained history

Important consequence:

  • failover is not a ReplicaFSM transition only
  • it is a volume-level re-rooting of all replica relationships

Suggested Promotion Rules

Promotion candidate should prefer:

  1. highest valid durable progress
  2. current epoch-consistent history
  3. healthiest replica among tied candidates

After promotion:

  • PrimaryID changes
  • Epoch increments
  • all replica reservations from the previous primary are void
  • all non-primary replicas must renegotiate recovery against the new primary

Multi-Replica Examples

Example 1: sync_all

  • replica A = InSync
  • replica B = Lagging
  • replica C = InSync

If A and B are required replicas in RF=3 sync_all:

  • writes needing sync durability fail or wait
  • even though one replica is still healthy

Example 2: sync_quorum

  • replica A = InSync
  • replica B = CatchingUp
  • replica C = InSync

If quorum is 2:

  • volume can continue serving sync requests
  • B recovers in background

Example 3: failover

  • old primary lost
  • replica A promoted
  • replica B was previously CatchingUp under old epoch

After promotion:

  • B's old session is aborted
  • B re-enters evaluation against A's history

What The Tiny Prototype Should Simulate

The V2 prototype should be able to drive at least these scenarios:

  1. steady state keep-up
  • primary head advances
  • all required replicas remain InSync
  1. short outage
  • one replica disconnects
  • primary keeps writing
  • reconnect succeeds within recoverable window
  • replica returns via PromotionHold
  1. long outage
  • one replica disconnects too long
  • recoverability expires
  • replica goes NeedsRebuild
  • rebuild and trailing replay complete
  1. tail chasing
  • replica catch-up speed is below primary ingest speed
  • orchestrator chooses fail, throttle, or rebuild path depending on mode
  1. failover
  • primary lease lost
  • new epoch assigned
  • replica promoted
  • old recovery sessions fenced
  1. mixed-state quorum
  • different replicas in different states
  • orchestrator computes correct sync_all / sync_quorum result

Relationship To WAL V1

WAL V1 already contains pieces of this logic, but they are scattered across:

  • shipper state
  • barrier code
  • retention code
  • assignment/promotion code
  • rebuild code
  • heartbeat/master logic

V2 should separate these into:

  • per-replica recovery FSM
  • volume-level orchestrator

Bottom Line

The next step after ReplicaFSM is not Smart WAL.

The next step is the volume-level orchestrator model.

Why:

  • primary keeps moving
  • durability mode is volume-scoped
  • failover/promotion is volume-scoped
  • replica recovery must be evaluated in the context of the whole volume

So V2 needs:

  • ReplicaFSM for one replica
  • VolumeOrchestrator for the moving multi-replica system