Files
greptimedb/src/meta-client
Weny Xu 5523cf3874 feat(meta): track per-node scheduling state and fence region placement (#9884)
feat: track per-node scheduling state and fence region placement

Add a cluster-wide, persistent "can this node receive new regions" flag and
make every metasrv placement path respect it. This is the fence half of
`ADMIN drain_node`; the drain procedure, gRPC entry and region evacuation land
separately.

State layout
- New namespace `__node_scheduling/{datanode,flownode}/{node_id}` holding
  `{"schedulable": false}`. A missing key means schedulable, so undrain is a
  delete and no stale `schedulable: true` records are left behind.
- `NodeSchedulingKey`/`NodeSchedulingValue` mirror the existing KV conventions
  (`NodeInfoKey`'s `{role, node_id}` shape, `LeaseValue`'s `*Value` suffix).
  The role is part of the prefix, so extending to flownodes needs no key change.
- `NodeSchedulingManager` writes with `put_if_not_exists`/`compare_and_put`, so
  concurrent marks change the state exactly once, and reads a single prefix
  range per placement decision (DDL/failover only, not per query).

Placement
- `NodeInfo` gains `#[serde(skip)] schedulable: Option<bool>` plus
  `is_schedulable()`; `None` (unresolved) counts as schedulable, and the field
  never reaches heartbeat bytes, so the wire/in-memory format is unchanged.
- `SchedulingAwarePeerDiscovery` stamps the flag on `active_datanodes`. It is
  additive (never hides nodes) because failover still needs the full active set
  to compute its exclusion list.
- All three built-in selectors now fetch candidates through
  `selector::common::active_schedulable_datanodes`; `RegionSupervisor` adds
  unschedulable datanodes to `exclude_peer_ids` for both selector variants.

Enforcing the single fence
- `MetaPeerClient` no longer implements `PeerDiscovery`; its discovery methods
  are inherent, and `DatabaseOperator` (frontends only) takes the concrete
  client. `SchedulingAwarePeerDiscovery`, built once in `MetasrvBuilder`, is
  therefore the only way to obtain a `PeerDiscoveryRef`, so bypassing the fence
  is a compile error rather than a silent misplacement.

Compatibility
- New key namespace only; `NodeInfo` serialization is byte-identical, so old
  metasrv nodes and persisted heartbeats keep working. The flag itself is stored
  in the durable KV, so a follower metasrv sees marks written by the leader.

Verification
- `cargo nextest run -p meta-srv node_scheduling` (13), `selector` (12),
  `supervisor` (14), `-p common-meta cluster` (9), `-p meta-client` (36),
  `-p standalone` (compiles, no tests).
- `cargo clippy -p meta-srv -p common-meta -p meta-client -p standalone
  --all-targets -- -D warnings`, `cargo fmt --all -- --check`.

Signed-off-by: WenyXu <wenymedia@gmail.com>
2026-10-23 06:46:56 +00:00
..