You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2022/08/30 12:28:13 UTC

[couchdb] branch raft_storemodule updated: don't perform MPrevLogIndex lookup before MPrevLogIndex =< LastIndex check

This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch raft_storemodule
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/raft_storemodule by this push:
     new 09531cfe8 don't perform MPrevLogIndex lookup before MPrevLogIndex =< LastIndex check
09531cfe8 is described below

commit 09531cfe84711d1c8f72a882253b98c3452fee3f
Author: Robert Newson <rn...@apache.org>
AuthorDate: Tue Aug 30 13:24:24 2022 +0100

    don't perform MPrevLogIndex lookup before MPrevLogIndex =< LastIndex check
    
    This caused a slow follower to crash as MPrevLogIndex would not exist in
    its log
---
 src/couch/src/couch_raft.erl | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/couch/src/couch_raft.erl b/src/couch/src/couch_raft.erl
index 98fb6f926..b862d055b 100644
--- a/src/couch/src/couch_raft.erl
+++ b/src/couch/src/couch_raft.erl
@@ -152,8 +152,7 @@ handle_event(cast, #{type := 'AppendEntriesRequest', term := Term} = Msg, State,
         store_module := StoreModule
     } = Data,
     {LastIndex, _LastTerm} = StoreModule:last(Data),
-    {NthTerm, _} = StoreModule:lookup(MPrevLogIndex, Data),
-    LogOk = MPrevLogIndex == 0 orelse (MPrevLogIndex > 0 andalso MPrevLogIndex =< LastIndex andalso MPrevLogTerm == NthTerm),
+    LogOk = MPrevLogIndex == 0 orelse (MPrevLogIndex > 0 andalso MPrevLogIndex =< LastIndex andalso MPrevLogTerm == nthterm(MPrevLogIndex, Data)),
     if
         Term < CurrentTerm orelse (Term == CurrentTerm andalso State == follower andalso not LogOk) ->
             Reply = #{
@@ -370,6 +369,18 @@ state_timeout(leader) ->
 peers(Cohort) ->
     Cohort -- [node()].
 
+
+nthterm(N, Data) ->
+    #{
+        store_module := StoreModule
+    } = Data,
+    case StoreModule:lookup(N, Data) of
+        not_found ->
+            not_found;
+        {Term, _Value} ->
+            Term
+        end.
+
 persist({next_state, _NextState, NewData, _Actions} = HandleEventResult) ->
     persist(NewData, HandleEventResult);
 persist({keep_state, NewData, _Actions} = HandleEventResult) ->