feat(raft): safe log compaction with snapshot metadata
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled

- lastSnapshotIndex/Term bound the compacted prefix; lastLogIndex/Term
  and AppendEntries prevLog checks respect the snapshot base
- compactLog drops entries only through min(matchIndex, lastApplied) on
  the leader so lagging peers can still catch up via AppendEntries
- Persist snapshot fields in raft_state.bin; BARADB_RAFT_LOG_MAX_ENTRIES
- Fix commit-index scan to use findLogEntryByIndex (works after compact)
This commit is contained in:
2026-07-30 21:35:41 +03:00
parent 9df8316305
commit 53704e1036
6 changed files with 146 additions and 21 deletions
+35
View File
@@ -2706,6 +2706,41 @@ suite "Raft SQL Write Path":
check res.keyValuePairs.len == 1
check res.keyValuePairs[0][1].len == 0
test "compactLog discards applied prefix and preserves lastSnapshot base":
var n = newRaftNode("n1", @[], raftPort = 29120)
n.logMaxEntries = 8
n.becomeLeader()
# Single-node: simulate applied entries then compact.
for i in 1 .. 20:
let e = n.appendLog("put", cast[seq[byte]]("k" & $i & "\x00v"))
check e.index == uint64(i)
n.commitIndex = e.index
n.lastApplied = e.index
n.compactLog()
check n.log.len <= n.logMaxEntries
check n.lastSnapshotIndex > 0
check n.lastLogIndex == 20
let e21 = n.appendLog("put", cast[seq[byte]]("k21\x00v"))
check e21.index == 21
n.commitIndex = 21
n.lastApplied = 21
n.compactLog()
check n.lastLogIndex == 21
test "leader compactLog never discards past a lagging peer matchIndex":
var n = newRaftNode("n1", @["n2"], raftPort = 29121)
n.logMaxEntries = 5
n.becomeLeader()
n.matchIndex["n2"] = 0 # peer never caught up
for i in 1 .. 15:
discard n.appendLog("put", cast[seq[byte]]("x"))
n.commitIndex = uint64(i)
n.lastApplied = uint64(i)
n.compactLog()
# With matchIndex[n2]=0, through=0 — no compaction past snapshot 0
check n.lastSnapshotIndex == 0
check n.log.len == 15
test "appendDdlToRaft fails when node is not leader":
var n = newRaftNode("n1", @["n2"], raftPort = 29113)
let (ok, err) = waitFor appendDdlToRaft(n,