fix(ha-term-safety): bug-828 partial — revive dead safe-commit-from-votes + advertise real durable tip
Clean failover was truncating committed jobs because the post-election safe-commit-from-votes computation was dead: vote_reply_dispatch decoded each granting voter's advertised peerLastLogLsn but discarded it, so ha_compute_safe _committed_lsn saw only the self-vote (the 'from 1 granted voters' fingerprint) and truncated to self_lsn. Part 1: vote_reply_dispatch now records the granting voter's (lsn,tag,grant) into ctx->votes[] via a record-only ha_record_vote_reply seam (no double-promotion; raft_on_vote_reply stays the sole production promotion driver) — so safe-commit reflects the true voted majority. Part 2: the candidate/voter advertise the real DURABLE (fsync'd) tip; persist_wal _write_replicated advances durable_lsn after its fail-loud inline fdatasync. Reviewer-verified SAFE (advertises only durable positions; safe-commit bounded by the durable majority, preserving more committed entries, never marking a non-majority-durable LSN safe). 177 unit tests; new test_ha_vote_gate + election tests green. PARTIAL: does NOT yet make the live clean-failover pass. A deeper slice of bug-828/795 remains — a catch-up'd standby still under-advertises its durable position in the live run (the documented architectural catch-up/durability gap), so a job-less node can still win and truncate. Tracked for a dedicated effort.
This commit is contained in:
parent
14c41cb298
commit
91b9a445f0
6 changed files with 313 additions and 20 deletions
|
|
@ -992,6 +992,29 @@ void handle_request_vote_reply(ha_state_t *ha,
|
|||
uint64_t peer_config_tag,
|
||||
uint64_t peer_lsn);
|
||||
|
||||
/*
|
||||
* ha_record_vote_reply: record-only vote-reply seam (bug-828).
|
||||
*
|
||||
* Records ctx->votes[peer_idx] (granted flag + peer_config_tag + peer_lsn) under
|
||||
* ctx->lock with the same idempotency guard as handle_request_vote_reply, and
|
||||
* updates the vote tally / freshest-responder tracking — but does NOT call
|
||||
* ha_elect_evaluate_and_signal (never posts ctx->done, never runs the legacy
|
||||
* promotion side-effects). The PRODUCTION vote_reply_dispatch path calls this so
|
||||
* the granting voter's advertised LSN reaches ha_compute_safe_committed_lsn via
|
||||
* ctx->votes[], while the raft library remains the sole production promotion
|
||||
* driver (raft_on_vote_reply → on_become_leader) — no double-promotion.
|
||||
*
|
||||
* peer_idx: 0-based index into ctx->votes[] (same convention as
|
||||
* handle_request_vote_reply; the absolute→local mapping is done by the caller).
|
||||
*/
|
||||
void ha_record_vote_reply(ha_state_t *ha,
|
||||
ha_elect_ctx_t *ctx,
|
||||
int peer_idx,
|
||||
uint64_t term,
|
||||
int vote_granted,
|
||||
uint64_t peer_config_tag,
|
||||
uint64_t peer_lsn);
|
||||
|
||||
/*
|
||||
* xce_probe_config_tag: single-RTT OP_probeConfigTag RPC to one peer.
|
||||
* Fills *tag_out with the peer's current config_tag on success.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue