Skip to content

Commit

Permalink
r/consensus: do not update heartbeat timestamp with prevote request
Browse files Browse the repository at this point in the history
When a voter receives vote request and it votes for the candidate it
updates the last heartbeat timeout. If this happens during the prevote
phase and in a deployment with even number of locks it may lead to
temporary live lock and not being able to elect the leader.

Fixes: redpanda-data#11657

Signed-off-by: Michal Maslanka <michal@redpanda.com>
  • Loading branch information
mmaslankaprv committed Jul 4, 2023
1 parent 7d68e46 commit 995c775
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/v/raft/consensus.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,7 @@ ss::future<vote_reply> consensus::do_vote(vote_request r) {
auto last_log_index = lstats.dirty_offset;
_probe->vote_request();
auto last_entry_term = get_last_entry_term(lstats);
bool term_changed = false;
vlog(_ctxlog.trace, "Received vote request: {}", r);

if (unlikely(is_request_target_node_invalid("vote", r))) {
Expand Down Expand Up @@ -1728,6 +1729,7 @@ ss::future<vote_reply> consensus::do_vote(vote_request r) {
reply.term = r.term;
_term = r.term;
_voted_for = {};
term_changed = true;
do_step_down("voter_term_greater");
if (_leader_id) {
_leader_id = std::nullopt;
Expand Down Expand Up @@ -1767,8 +1769,11 @@ ss::future<vote_reply> consensus::do_vote(vote_request r) {
} else {
reply.granted = (r.node_id == _voted_for);
}

if (reply.granted) {
/**
* Only update last heartbeat value, indicating existence of a leader if a
* term change i.e. a node is not processing prevote_request.
*/
if (reply.granted && term_changed) {
_hbeat = clock_type::now();
}

Expand Down

0 comments on commit 995c775

Please sign in to comment.