myxce/src
Rongsong Shen 007bf0c403 fix(ha-repl-hardening): snapshot fallback off-by-one — empty standby must stream, not snapshot
After reserve-lsn-0 (oldest retained WAL entry = lsn 1 on a fresh cluster), a
freshly-joined empty standby (applied_lsn=0) hit the snapshot-fallback branch
'standby_lsn < oldest_wal_lsn' (0 < 1) and was sent a non-existent snapshot
instead of streaming — so the own-term NOOP (lsn 1) never replicated, committed_lsn
stayed 0, the own-term gate (writable_lsn=1) stayed closed, and standbys kept
empty WALs. Live evidence:
  ha_dispatch_repl_action_for_standby: standby[0] lsn=0 < oldest_wal_lsn=1 -> requesting snapshot transfer

The snapshot fallback should fire only when the standby's NEXT-needed entry
(standby_lsn+1) has been GC'd below the oldest retained entry. Fix the boundary
to 'standby_lsn + 1 < oldest_wal_lsn' in ha_evaluate_repl_action (and the parallel
dead repl_needs_snapshot predicate). An empty standby (next-needed=1, oldest=1)
now STREAMs lsn 1 -> acks -> committed_lsn 0->1 -> own-term gate opens -> standbys
receive the WAL. Snapshot still fires for genuinely GC'd-behind standbys
(standby_lsn+1 < oldest). No underflow (oldest=0 -> 1<0 false). Pre-reserve-lsn-0
this off-by-one was masked by oldest_wal_lsn=0 (0<0 false).

TDD: test_empty_standby_fresh_cluster_streams_not_snapshot (RED->GREEN);
snapshot + heartbeat pins strengthened to assert SEND_SNAPSHOT only for genuinely
GC'd standbys and STREAM_WAL at the empty/boundary case. Full controller suite
green under ASAN; commit engine / streamer / apply path / wire untouched.
2026-06-14 12:10:40 +00:00
..
autoscaler support shared libxce(for api server) 2026-01-19 11:02:49 +08:00
controller fix(ha-repl-hardening): snapshot fallback off-by-one — empty standby must stream, not snapshot 2026-06-14 12:10:40 +00:00
docs docs(ha-single-leader-role): sync steering + contributor docs to three-state model + own-term gate (task 6.1) 2026-06-13 14:58:55 +00:00
frontend chore: baseline snapshot — prior-session work + ha-consistency-invariants spec family 2026-06-11 13:21:50 +00:00
include test(ha-convergence-recovery): RED egress-filter tests + submit_lsn field + dataex decls (task 1.1) 2026-06-14 01:40:22 +00:00
lib feat(ha-single-leader-role): remove CTRL_PRIMARY_COMMITTING enum + remaining decls — compiler-enforced (task 5.2) 2026-06-13 14:41:42 +00:00
nixSupport Merge Go frontend (apiserver + xcecli) into meson build 2026-04-14 11:23:18 +08:00
scheduler chore: baseline snapshot — prior-session work + ha-consistency-invariants spec family 2026-06-11 13:21:50 +00:00
schema feat(ha-wal-replication): standby WAL ACK reply (tasks 3.1-3.3) 2026-06-10 09:14:25 +00:00
tools fix(ha): election-safety hardening — vote gates, restored-vote term, freshness source 2026-06-10 01:25:39 +00:00
worker enhance xce-build skill 2026-05-30 08:13:59 +08:00
build chore: checkpoint all prior work for clean state 2026-06-04 13:04:16 +00:00
flake.lock docs: mark Phase 6 complete in phase6-scheduler-integration-plan 2026-04-30 07:17:32 +00:00
flake.nix save works 2026-03-04 18:18:53 +08:00
meson.build Merge Go frontend (apiserver + xcecli) into meson build 2026-04-14 11:23:18 +08:00
meson.options Merge Go frontend (apiserver + xcecli) into meson build 2026-04-14 11:23:18 +08:00