From 25561f4ae4fac4202a8d3a23a5bb5c051d0d9ec1 Mon Sep 17 00:00:00 2001 From: Neil Twigg Date: Tue, 8 Oct 2024 12:42:34 +0100 Subject: [PATCH] NRG: Do not revert term on truncate WAL Signed-off-by: Neil Twigg Co-authored-by: Maurice van Veen --- server/raft.go | 2 +- server/raft_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/server/raft.go b/server/raft.go index 0ae8d1183f0..dedc4be5956 100644 --- a/server/raft.go +++ b/server/raft.go @@ -3215,7 +3215,7 @@ func (n *raft) truncateWAL(term, index uint64) { } } // Set after we know we have truncated properly. - n.term, n.pterm, n.pindex = term, term, index + n.pterm, n.pindex = term, index } // Reset our WAL. This is equivalent to truncating all data from the log. diff --git a/server/raft_test.go b/server/raft_test.go index c810d189a79..4fef89d27fb 100644 --- a/server/raft_test.go +++ b/server/raft_test.go @@ -1007,3 +1007,44 @@ func TestNRGWALEntryWithoutQuorumMustTruncate(t *testing.T) { return nil }) } + +func TestNRGTermNoDecreaseAfterWALReset(t *testing.T) { + c := createJetStreamClusterExplicit(t, "R3S", 3) + defer c.shutdown() + + rg := c.createRaftGroup("TEST", 3, newStateAdder) + rg.waitOnLeader() + + l := rg.leader().node().(*raft) + l.Lock() + l.term = 20 + l.Unlock() + + esm := encodeStreamMsgAllowCompress("foo", "_INBOX.foo", nil, nil, 0, 0, true) + entries := []*Entry{newEntry(EntryNormal, esm)} + l.Lock() + ae := l.buildAppendEntry(entries) + l.Unlock() + + for _, f := range rg { + if f.node().ID() != l.ID() { + fn := f.node().(*raft) + fn.processAppendEntry(ae, fn.aesub) + require_Equal(t, fn.term, 20) // Follower's term gets upped as expected. + } + } + + // Lower the term, simulating the followers receiving a message from an old term/leader. + ae.term = 3 + for _, f := range rg { + if f.node().ID() != l.ID() { + fn := f.node().(*raft) + fn.processAppendEntry(ae, fn.aesub) + require_Equal(t, fn.term, 20) // Follower should reject and the term stays the same. + + fn.resetWAL() + fn.processAppendEntry(ae, fn.aesub) + require_Equal(t, fn.term, 20) // Follower should reject again, even after reset, term stays the same. + } + } +}