Skip to content

Commit

Permalink
storage: ignore non-live probing follower during log truncation
Browse files Browse the repository at this point in the history
In the previous code, a follower in probing status which was not
recently active (i.e. a dead node) would permanently suppress
log truncations unless the Raft log was above threshold size (but the
size tracks only what the current leaseholder has written, i.e., it
can undercount dramatically). As a result, snapshots to other nodes
would get blocked if the log was in fact large (>16mb), leading to
ranges which effectively couldn't change their set of members.

Release note (bug fix): Prevent a problem that would cause the Raft log
to grow very large which in turn could prevent replication changes.
  • Loading branch information
tbg committed Feb 1, 2019
1 parent 4cd3f56 commit 6f3a0cf
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions pkg/storage/raft_log_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,12 @@ func computeTruncateDecision(input truncateDecisionInput) truncateDecision {
decision.ChosenVia = truncatableIndexChosenViaQuorumIndex

for _, progress := range input.RaftStatus.Progress {
if !progress.RecentActive {
// Make no exceptions for followers who haven't contacted
// us within a reasonable period of time.
continue
}

// Generally we truncate to the quorum commit index when the log becomes
// too large, but we make an exception for live followers which are
// being probed (i.e. the leader doesn't know how far they've caught
Expand All @@ -340,10 +346,11 @@ func computeTruncateDecision(input truncateDecisionInput) truncateDecision {
// ranges will be split many times over, resulting in a flurry of
// snapshots with overlapping bounds that put significant stress on the
// Raft snapshot queue.
probing := (progress.RecentActive && progress.State == raft.ProgressStateProbe)
if probing && decision.NewFirstIndex > decision.Input.FirstIndex {
decision.NewFirstIndex = decision.Input.FirstIndex
decision.ChosenVia = truncatableIndexChosenViaProbingFollower
if progress.State == raft.ProgressStateProbe {
if decision.NewFirstIndex > decision.Input.FirstIndex {
decision.NewFirstIndex = decision.Input.FirstIndex
decision.ChosenVia = truncatableIndexChosenViaProbingFollower
}
} else if !input.LogTooLarge() && decision.NewFirstIndex > progress.Match {
decision.NewFirstIndex = progress.Match
decision.ChosenVia = truncatableIndexChosenViaFollowers
Expand Down

0 comments on commit 6f3a0cf

Please sign in to comment.