// lesson: commitment-and-safety
Commitment and Safety
An entry is committed once it is safe to apply to the state machine — Raft
then guarantees it will survive any future leader change. The leader tracks,
for every follower, matchIndex: the highest log index known to be replicated
on that server. Figure 2's "Rules for Servers, Leaders" gives the commit rule:
If there exists an N such that
N > commitIndex, a majority ofmatchIndex[i] ≥ N, andlog[N].term == currentTerm: setcommitIndex = N(§5.3, §5.4).
Two of those clauses are obvious — pick something new (N > commitIndex) that
a majority stores. The third clause, log[N].term == currentTerm, is the
subtle heart of Raft's safety argument.
Why majority replication is not enough (§5.4.2, Figure 8)
Figure 8 of the paper walks through the trap on a five-server cluster, S1–S5. In (a), S1 — leader in term 2 — appends an entry at index 2 but replicates it to only one other server (S2) before crashing: a minority. In (b), S5 wins the next election (term 3, with votes from S3, S4, and itself) and writes a different entry at index 2. S5 crashes too; in (c), S1 restarts and wins election again, this time as leader of term 4 — but it has not accepted any new client command yet, so its log still ends at index 2 with the same old term-2 entry. Coming to power, S1 just resumes normal replication (§5.3): retrying AppendEntries against S3 until the consistency check passes backfills that same old, already-existing entry onto S3 too. Nobody asked for that specifically; it falls out of the ordinary log-repair mechanism a new leader always runs. Now S1's old term-2 entry at index 2 sits on a majority of the cluster (S1, S2, and S3) — but nobody ever committed it. May a leader now count those replicas and consider index 2 committed? No. In (d), S5 — whose log still ends in term 3, higher than S1/S2/S3's term-2 last entry, so it looks "up-to-date" by §5.4.1 even though it is missing S1's index-2 entry entirely — wins a later election from S2, S3, and S4, and overwrites index 2 with its own term-3 entry. If counting replicas had been enough to call index 2 committed back in (c), this would be a lost write: the one unforgivable sin of a consensus algorithm.
The fix: a leader only ever commits by counting replicas for entries from its own current term. Old-term entries are never committed directly. They get committed indirectly: the moment a current-term entry at a later index commits, the Log Matching Property guarantees every earlier entry in that log — including the old-term stragglers — is committed with it.
So in the healthy case the sequence is: leader appends in its own term,
replicates, counts a majority, advances commitIndex past everything. In the
Figure 8 case the old entry simply waits for the new leader to commit its first
own-term entry (real implementations append a no-op at the start of a term for
exactly this reason).
Counting the leader itself
The leader is a member of the majority too. In this challenge we sidestep the
bookkeeping by passing a matchIndex slice with one element per server in
the cluster, leader included (the leader's own element is simply
len(log)). A majority means strictly more than half of that slice.
› Advance the Commit Index
30 ptsImplement AdvanceCommit. Given the cluster's matchIndex (one element per
server, leader included), the leader's log, currentTerm, and the current
commitIndex, return the new commit index: the largest N with
commitIndex < N <= len(log),matchIndex[i] >= Nfor a strict majority of servers, andlog[N-1].Term == currentTerm(remember: Raft indexNlives atlog[N-1]).
If no such N exists, return commitIndex unchanged. The function is pure —
no mutation, no side effects.
Log in to submit a solution and earn points.