feat(ha-repl-hardening): audit safe commit point and snapshot transfer tests (tasks 6.3, 6.4)

6.3: Fix single-node bug — ha_compute_safe_committed_lsn now returns
self_lsn instead of 0 for n_peers=0 (prevents WAL truncation on
single-node re-election). Add self_lsn/self_tag to ha_elect_ctx_t,
populated unconditionally in ha_start_election_async. All 3 test
scenarios pass under ASAN.

6.4: Add test_snapshot_recv_128kb_two_chunks (128KB snapshot in
2x64KB chunks, verifies size and applied_lsn); 4 other test cases
already existed from tasks 3.5c/3.5d. All ASAN-clean.
This commit is contained in:
Rongsong Shen 2026-06-05 06:21:00 +00:00
parent d41cfc5813
commit 345d51dd61
5 changed files with 160 additions and 23 deletions

View file

@ -108,6 +108,11 @@ typedef struct {
* cluster_init_phase2(c) and arm the committing timeout watchdog.
* NULL in unit tests (c=NULL bypasses phase2 and watchdog arming). */
cluster_t *c;
/* Task 6.3: candidate's own LSN/tag, stored unconditionally so that
* ha_compute_safe_committed_lsn can use them even for single-node elections
* where votes[] is empty (n_peers=0). */
uint64_t self_lsn; /* Candidate's own WAL LSN at election start */
uint64_t self_tag; /* Candidate's own config_tag at election start */
ha_vote_entry_t votes[]; /* C99 flexible array: n_peers-1 entries */
} ha_elect_ctx_t;
@ -297,9 +302,11 @@ void ha_nop_reply_state_report(ha_state_t *ha, myconf_t *myconf,
* Collects LSNs from all granted voters (self + peers with vote_granted=1),
* sorts descending, and returns the majority-threshold element.
*
* single-node (n_peers=0): outputs 0 for both fields (no vote data available).
* single-node (n_peers=0): returns ctx->self_lsn and ctx->self_tag directly —
* self is the only majority; returning 0 would truncate all WAL on re-election.
*
* Requirements: 2.3 (ha-repl-hardening spec)
* Task 6.3: single-node fix (self_lsn/self_tag fields added to ha_elect_ctx_t)
*/
void ha_compute_safe_committed_lsn(ha_elect_ctx_t *ctx,
uint64_t *safe_lsn_out,