forked from lei.chen/myxce
fix(ha-commit-engine,persist): reserve WAL lsn 0 — first entry starts at lsn 1
Root cause (found via live 3-node E2E + a verification test): lsn was 0-based
(hdr.lsn = current_lsn++ from current_lsn=0), and 0 was overloaded as a
sentinel, causing three cold-start defects on a freshly-promoted leader:
- the first WAL entry (own-term promotion NOOP at lsn 0) was structurally
uncommittable: commit_advance_locked only stores when cand>cur and
committed_lsn starts at 0, so lsn 0 can never advance it;
- commit_set_writable_lsn(noop_lsn=0) set writable_lsn=0, which wait_done
reads as 'gate off' — the own-term safety gate was a no-op on the first leader;
- bug-543 (WAL hole): ha_stream_wal_to_standby filters hdr.lsn>standby_lsn;
a fresh empty standby reports standby_lsn=0 (ambiguous 'empty' vs 'has lsn 0'),
so lsn 0 failed 0>0 and was dropped -> non-contiguous standby WAL.
Fix: a fresh persist store initializes current_lsn=1, reserving lsn 0 as the
none/empty sentinel. The first real entry is lsn 1 -> committable (0->1),
writable_lsn=1 -> gate effective, and standby_lsn=0 unambiguously means 'empty'
so catch-up streams from the first entry with no hole. persist_recover is
data-driven (current_lsn=max(hdr.lsn+1)), so existing on-disk WALs and non-fresh
recovery are unaffected; the change only sets the base for brand-new stores.
No wire/capnp change.
Verification: test_coldstart_lsn0 drives the real commit engine + real streamer
and proves H1 (first entry commits 0->1), H3 (gate effective + blocks when
committed<writable), H4 (empty-standby catch-up is contiguous [1,2], control
standby_lsn=1 gets only [2]). Full controller suite green under ASAN. Tests that
relied on the lsn-0 base were shifted (several strengthened); commit.c /
config_repl.c / ha.c / wire format untouched.
Owning specs: ha-commit-engine / ha-wal-replication / persist. Follow-up:
sweep stale lsn-0 comments (repl.c:429-436, persist.c:1055-1075/1240-1243/1296).
This commit is contained in:
parent
c97c7632e9
commit
7519fa96dd
10 changed files with 480 additions and 31 deletions
|
|
@ -226,10 +226,12 @@ static void test_p3_wal_torn_write_after_checkpoint(void)
|
|||
|
||||
teardown_p3_persist(p);
|
||||
|
||||
/* Truncate to exactly 4 complete post-checkpoint entries (keep lsns 4..7,
|
||||
* drop lsn 8). The segment also holds pre-checkpoint entries 0..2 and
|
||||
* the checkpoint marker at lsn 3 — that is 4 entries × entry_size bytes
|
||||
* of header+payload before the post-checkpoint block.
|
||||
/* Truncate to exactly 4 complete post-checkpoint entries (keep lsns 5..8,
|
||||
* drop lsn 9). The segment also holds pre-checkpoint entries 1..3 and
|
||||
* the checkpoint marker at lsn 4 — that is 4 entries × entry_size bytes
|
||||
* of header+payload before the post-checkpoint block. (LSN 0 is reserved
|
||||
* as the empty sentinel, so the first real entry is lsn 1; the truncation
|
||||
* math below is purely offset/count-based and is unaffected by the base.)
|
||||
*
|
||||
* Pre-checkpoint entries: 3 × (hdr + 5) + 1 × (hdr + 0) checkpoint marker
|
||||
* Post-checkpoint entries: 5 × (hdr + 9); keep 4, drop 1.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue