-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accept any snapshot that allows replication #110
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1478,10 +1478,13 @@ func stepLeader(r *raft, m pb.Message) error { | |
switch { | ||
case pr.State == tracker.StateProbe: | ||
pr.BecomeReplicate() | ||
case pr.State == tracker.StateSnapshot && pr.Match >= pr.PendingSnapshot: | ||
// TODO(tbg): we should also enter this branch if a snapshot is | ||
// received that is below pr.PendingSnapshot but which makes it | ||
// possible to use the log again. | ||
case pr.State == tracker.StateSnapshot && pr.Match+1 >= r.raftLog.firstIndex(): | ||
// Note that we don't take into account PendingSnapshot to | ||
// enter this branch. No matter at which index a snapshot | ||
// was actually applied, as long as this allows catching up | ||
// the follower from the log, we will accept it. This gives | ||
// systems more flexibility in how they implement snapshots; | ||
// see the comments on PendingSnapshot. | ||
r.logger.Debugf("%x recovered from needing snapshot, resumed sending replication messages to %x [%s]", r.id, m.From, pr) | ||
// Transition back to replicating state via probing state | ||
// (which takes the snapshot into account). If we didn't | ||
|
@@ -1560,10 +1563,6 @@ func stepLeader(r *raft, m pb.Message) error { | |
if pr.State != tracker.StateSnapshot { | ||
return nil | ||
} | ||
// TODO(tbg): this code is very similar to the snapshot handling in | ||
// MsgAppResp above. In fact, the code there is more correct than the | ||
// code here and should likely be updated to match (or even better, the | ||
// logic pulled into a newly created Progress state machine handler). | ||
Comment on lines
-1563
to
-1566
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This TODO wasn't true, because the code is quite different (we don't check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, I think any better logic here is predicated on passing in the snapshot index. See cockroachdb/cockroach#87583.
Without the snapshot index being passed in, I don't think we can know the Match until we receive an MsgAppResp, so moving to StateProbe seems like the right thing to do until that happens. |
||
if !m.Reject { | ||
pr.BecomeProbe() | ||
r.logger.Debugf("%x snapshot succeeded, resumed sending replication messages to %x [%s]", r.id, m.From, pr) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logically, it can also be (maybe should?)
pr.Next >= r.raftLog.firstIndex()
.Next
is the next index to send. Indices betweenMatch+1
andNext-1
are in-flight (by invariant which we haven't formalized yet), so don't necessarily need to be present in the log.The
MaybeUpdate()
call 4 lines above should setNext
to be at leastMatch+1
, so this should be safe.Feel free to leave this for #124.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do it for #124. Semantically,
Match+1
seems better since that's where the leader's and follower's logs match, but they're equivalent here and I don't have a particularly strong opinion either way.