From 73a32f78fdc74d342cbf9f2e617f2edbfa71c30e Mon Sep 17 00:00:00 2001 From: UndefinedSy Date: Fri, 5 Jul 2024 10:32:42 +0800 Subject: [PATCH] fix. raft follower will rollback itself when it misses a certain log if a leader fails to update its last_log_id_sent (maybe caused be follower fail or network issue), it will then try to send some duplicated logs in the next appendLog request. ``` commitId_: 99 | v local wal: |-------------------| req.append_entries: |----------------| ``` in this case, follower will do rollback even if the logs are the same. --- src/kvstore/raftex/RaftPart.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/kvstore/raftex/RaftPart.cpp b/src/kvstore/raftex/RaftPart.cpp index a4fb54f053e..b4293da6a2c 100644 --- a/src/kvstore/raftex/RaftPart.cpp +++ b/src/kvstore/raftex/RaftPart.cpp @@ -1731,8 +1731,10 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, TermID lastTerm = (numLogs == 0) ? req.get_last_log_term_sent() : req.get_log_str_list().back().get_log_term(); auto localWalIt = wal_->iterator(firstId, lastId); + bool hasConflict = false; for (size_t i = 0; i < numLogs && localWalIt->valid(); ++i, ++(*localWalIt), ++diffIndex) { if (localWalIt->logTerm() != req.get_log_str_list()[i].get_log_term()) { + hasConflict = true; break; } } @@ -1749,7 +1751,9 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req, // Found a difference at log of (firstId + diffIndex), all logs from (firstId + diffIndex) // could be truncated - wal_->rollbackToLog(firstId + diffIndex - 1); + if (hasConflict) { + wal_->rollbackToLog(firstId + diffIndex - 1); + } firstId = firstId + diffIndex; numLogs = numLogs - diffIndex; }