@@ -375,12 +375,6 @@ type raft struct {
375
375
376
376
// the leader id
377
377
lead uint64
378
- // logSynced is true if this node's log is guaranteed to be a prefix of the
379
- // leader's log at this term. Always true for the leader. Always false for a
380
- // candidate. For a follower, this is true if the last entry term matches the
381
- // leader term, otherwise becomes true when the first MsgApp append from the
382
- // leader succeeds.
383
- logSynced bool
384
378
// leadTransferee is id of the leader transfer target when its value is not zero.
385
379
// Follow the procedure defined in raft thesis 3.10.
386
380
leadTransferee uint64
@@ -769,7 +763,6 @@ func (r *raft) reset(term uint64) {
769
763
r .Vote = None
770
764
}
771
765
r .lead = None
772
- r .logSynced = false
773
766
774
767
r .electionElapsed = 0
775
768
r .heartbeatElapsed = 0
@@ -873,10 +866,6 @@ func (r *raft) becomeFollower(term uint64, lead uint64) {
873
866
r .reset (term )
874
867
r .tick = r .tickElection
875
868
r .lead = lead
876
- // If the last entry term matches the leader term, the log is guaranteed to be
877
- // a prefix of the leader's log. Otherwise, we will establish this guarantee
878
- // later, on the first successful MsgApp.
879
- r .logSynced = r .raftLog .lastTerm () == term
880
869
r .state = StateFollower
881
870
r .logger .Infof ("%x became follower at term %d" , r .id , r .Term )
882
871
}
@@ -919,7 +908,6 @@ func (r *raft) becomeLeader() {
919
908
r .reset (r .Term )
920
909
r .tick = r .tickHeartbeat
921
910
r .lead = r .id
922
- r .logSynced = true // the leader's log is in sync with itself
923
911
r .state = StateLeader
924
912
// Followers enter replicate mode when they've been successfully probed
925
913
// (perhaps after having received a snapshot as a result). The leader is
@@ -947,6 +935,8 @@ func (r *raft) becomeLeader() {
947
935
// so the preceding log append does not count against the uncommitted log
948
936
// quota of the new leader. In other words, after the call to appendEntry,
949
937
// r.uncommittedSize is still 0.
938
+
939
+ r .raftLog .leaderTerm = r .Term // the leader's log is consistent with itself
950
940
r .logger .Infof ("%x became leader at term %d" , r .id , r .Term )
951
941
}
952
942
@@ -1747,7 +1737,7 @@ func (r *raft) handleAppendEntries(m pb.Message) {
1747
1737
return
1748
1738
}
1749
1739
if mlastIndex , ok := r .raftLog .maybeAppend (m .Index , m .LogTerm , m .Commit , m .Entries ... ); ok {
1750
- r .logSynced = true // from now on, the log is a prefix of the leader's log
1740
+ r .raftLog . leaderTerm = m . Term // the log is now consistent with the leader
1751
1741
r .send (pb.Message {To : m .From , Type : pb .MsgAppResp , Index : mlastIndex })
1752
1742
return
1753
1743
}
@@ -1787,10 +1777,10 @@ func (r *raft) handleHeartbeat(m pb.Message) {
1787
1777
// leader's log. Otherwise, entries at this index may mismatch.
1788
1778
//
1789
1779
// TODO(pav-kv): move this logic to r.raftLog, which is more appropriate for
1790
- // handling safety. The raftLog can use the logSynced flag for other safety
1791
- // checks. For example, unstable.truncateAndAppend currently may override a
1792
- // suffix of the log unconditionally, but it can only be done if !logSynced .
1793
- if r . logSynced {
1780
+ // handling safety. The raftLog can use leaderTerm for other safety checks.
1781
+ // For example, unstable.truncateAndAppend currently may override a suffix of
1782
+ // the log unconditionally, but it can only be done if m.Term > leaderTerm .
1783
+ if m . Term == r . raftLog . leaderTerm {
1794
1784
r .raftLog .commitTo (min (m .Commit , r .raftLog .lastIndex ()))
1795
1785
}
1796
1786
r .send (pb.Message {To : m .From , Type : pb .MsgHeartbeatResp , Context : m .Context })
@@ -1807,6 +1797,7 @@ func (r *raft) handleSnapshot(m pb.Message) {
1807
1797
if r .restore (s ) {
1808
1798
r .logger .Infof ("%x [commit: %d] restored snapshot [index: %d, term: %d]" ,
1809
1799
r .id , r .raftLog .committed , sindex , sterm )
1800
+ r .raftLog .leaderTerm = m .Term // the log is now consistent with the leader
1810
1801
r .send (pb.Message {To : m .From , Type : pb .MsgAppResp , Index : r .raftLog .lastIndex ()})
1811
1802
} else {
1812
1803
r .logger .Infof ("%x [commit: %d] ignored snapshot [index: %d, term: %d]" ,
0 commit comments