-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
kvserver: don't refuse to fwd lease proposals in some edge cases #58722
Conversation
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.
Reviewed 1 of 1 files at r1, 3 of 3 files at r2, 5 of 5 files at r3.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @andreimatei, @bdarnell, and @tbg)
pkg/kv/kvserver/replica_proposal_buf.go, line 163 at r3 (raw file):
leaderKnown bool leader roachpb.ReplicaID
Might as well give this a comment, mentioning the value of this field when !leaderKnown
.
pkg/kv/kvserver/replica_proposal_buf.go, line 168 at r3 (raw file):
// leaderIneligibleForLease is set if the leader is known, but its type of // replica prevents it from acquiring a lease. leaderIneligibleForLease bool
nit: Invert this condition to avoid the double-negative down below.
pkg/kv/kvserver/replica_proposal_buf.go, line 178 at r3 (raw file):
replicaID() roachpb.ReplicaID leaderStatusRLocked(raftGroup proposerRaft) leaderInfo
stray line?
pkg/kv/kvserver/replica_proposal_buf.go, line 446 at r3 (raw file):
buf := b.arr.asSlice()[:used] ents := make([]raftpb.Entry, 0, used) var leaderInfo leaderInfo
nit: move this down to where the other variable declarations use to live. No need to mix it up with these slices of entries.
pkg/kv/kvserver/replica_proposal_buf.go, line 501 at r3 (raw file):
// A special case is when the leader is known, but is ineligible to get the // lease. In that case, we have no choice but to continue with the proposal. if !leaderInfo.iAmTheLeader && p.Request.IsLeaseRequest() {
We may need to extend this check even more. In 91f58af, I noticed that we are rejecting lease extensions when we are the current leaseholder if we haven't yet grabbed raft leadership. That seems wrong.
No need to do anything here.
pkg/kv/kvserver/replica_proposal_buf.go, line 503 at r3 (raw file):
if !leaderInfo.iAmTheLeader && p.Request.IsLeaseRequest() { proposeAnyway := leaderInfo.leaderIneligibleForLease || b.testing.allowLeaseProposalWhenNotLeader if leaderInfo.leaderKnown && !proposeAnyway {
This grouping seems odd to me. We're saying leader known && (either leader eligible || not testing allow when not leader)
. So if leaderKnown && !leaderIneligibleForLease
, aren't we rejecting, regardless of the testing knob? I don't think that's the intention. I think we want to group the first two conditions together like:
leaderKnownAndEligible := ...
if leaderKnownAndEligible && !b.testing.allowLeaseProposalWhenNotLeader {
...
}
pkg/kv/kvserver/replica_proposal_buf.go, line 764 at r3 (raw file):
} func (rp *replicaProposer) leaderStatusRLocked(raftGroup proposerRaft) leaderInfo {
Keep this in order with the interface. Either pull this all the way up above destroyed()
(but don't do that) or shuffle the interface def. Ideally, this would go right above rejectProposalWithRedirectLocked
in the declaration and the definition.
pkg/kv/kvserver/replica_proposal_buf.go, line 775 at r3 (raw file):
if leaderKnown { // Figure out if the leader is eligible for getting a lease. Only VOTER_FULL // replicas are eligible.
This seems like the kind of comment that is going to rot. How should we avoid that?
pkg/kv/kvserver/replica_proposal_buf.go, line 785 at r3 (raw file):
leaderIneligibleForLease = false } else { err := batcheval.CheckCanReceiveLease(leaderRep, *rangeDesc)
nit: Seems like we should just pass the descriptor by pointer, since that's what every caller wants and that's generally how we interact with RangeDescriptors.
pkg/kv/kvserver/replica_proposal_buf_test.go, line 59 at r3 (raw file):
} func (t *testProposer) leaderStatusRLocked(raftGroup proposerRaft) leaderInfo {
Why define this method in such a random place? I know these kinds of comments seem like nits, but a few of these changes in a row and the entire structure of a piece of code falls apart and we're left with chaos! And then a month later, we'll decide that we need to rewrite everything because the code is jumbled and hard to read. And then we introduce a bug during the rewrite. And then data gets corrupted in an important deployment. And then a SpaceX satellite falls out of the sky. And then SpaceX goes bankrupt due to a lawsuit. And we never make it to Mars. Don't you want to go to Mars??
pkg/kv/kvserver/batcheval/cmd_lease.go, line 45 at r2 (raw file):
// If we decide to start using long-lived learners at some point, that math may change.
If we decide?
pkg/kv/kvserver/batcheval/cmd_lease.go, line 47 at r2 (raw file):
// point, that math may change. func checkCanReceiveLease( newLeaseholer roachpb.ReplicaDescriptor, rngDesc roachpb.RangeDescriptor,
Should rngDesc
be a pointer?
pkg/kv/kvserver/batcheval/cmd_lease.go, line 46 at r3 (raw file):
// out the edge cases. If we decide to start using long-lived learners at some // point, that math may change. func CheckCanReceiveLease(
Want to add a unit test around this here in pkg/kv/kvserver/batcheval/cmd_lease.go
?
383e6a8
to
230a2cc
Compare
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.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @andreimatei, @bdarnell, @nvanbenschoten, and @tbg)
pkg/kv/kvserver/replica_proposal_buf.go, line 163 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Might as well give this a comment, mentioning the value of this field when
!leaderKnown
.
done
pkg/kv/kvserver/replica_proposal_buf.go, line 178 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
stray line?
done
pkg/kv/kvserver/replica_proposal_buf.go, line 446 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
nit: move this down to where the other variable declarations use to live. No need to mix it up with these slices of entries.
done
pkg/kv/kvserver/replica_proposal_buf.go, line 503 at r3 (raw file):
So if leaderKnown && !leaderIneligibleForLease, aren't we rejecting, regardless of the testing knob? I don't think that's the intention.
This was, in fact, the intention. The testing knob is kinda crap, and is only used by one rando. I wanted to keep the scope of the knob as small as possible - i.e. only apply it in the most regular situation (when the leader is eligible). In particular, I don't want the knob to introduce the possibility of the deadlock.
WDYT
pkg/kv/kvserver/replica_proposal_buf.go, line 764 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Keep this in order with the interface. Either pull this all the way up above
destroyed()
(but don't do that) or shuffle the interface def. Ideally, this would go right aboverejectProposalWithRedirectLocked
in the declaration and the definition.
done
pkg/kv/kvserver/replica_proposal_buf.go, line 775 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
This seems like the kind of comment that is going to rot. How should we avoid that?
I've deleted it :P
pkg/kv/kvserver/replica_proposal_buf.go, line 785 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
nit: Seems like we should just pass the descriptor by pointer, since that's what every caller wants and that's generally how we interact with RangeDescriptors.
yeah... I had made it a value for symmetry with the ReplicaDescriptor
arg, where we do use values more. Changed.
pkg/kv/kvserver/replica_proposal_buf_test.go, line 59 at r3 (raw file):
Don't you want to go to Mars??
https://www.youtube.com/watch?v=KDXbl54HpQE
pkg/kv/kvserver/batcheval/cmd_lease.go, line 45 at r2 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
// If we decide to start using long-lived learners at some point, that math may change.
If we decide?
well I'm just moving a comment around
But yeah, I've deleted it. Cause we have decided, but the math is not changing (as far as learners go)
pkg/kv/kvserver/batcheval/cmd_lease.go, line 47 at r2 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Should
rngDesc
be a pointer?
done
pkg/kv/kvserver/batcheval/cmd_lease.go, line 46 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
Want to add a unit test around this here in
pkg/kv/kvserver/batcheval/cmd_lease.go
?
done
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.
though there are still a few minor tweaks to make in that inner condition to unravel it a little.
We should get more eyes on this too, since I assume we're planning for another backport attempt.
Reviewed 6 of 6 files at r6.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @andreimatei, @bdarnell, and @tbg)
pkg/kv/kvserver/replica_proposal_buf.go, line 168 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
nit: Invert this condition to avoid the double-negative down below.
I still think this would be an improvement.
pkg/kv/kvserver/replica_proposal_buf.go, line 503 at r3 (raw file):
Previously, andreimatei (Andrei Matei) wrote…
So if leaderKnown && !leaderIneligibleForLease, aren't we rejecting, regardless of the testing knob? I don't think that's the intention.
This was, in fact, the intention. The testing knob is kinda crap, and is only used by one rando. I wanted to keep the scope of the knob as small as possible - i.e. only apply it in the most regular situation (when the leader is eligible). In particular, I don't want the knob to introduce the possibility of the deadlock.
WDYT
I think this makes the knob super hard to reason about. I'd be in favor of broadening it to just disable this entire rejection mechanism. That's the effect it had before.
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.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @andreimatei, @bdarnell, and @tbg)
pkg/kv/kvserver/replica_proposal_buf_test.go, line 59 at r3 (raw file):
Previously, andreimatei (Andrei Matei) wrote…
Don't you want to go to Mars??
This assertion had become nonsensical in #9915f0d0f104aa918c94340e9e47129b90421999. It's from a time where the surrounding function was dealing with the local store only. Release note: None
230a2cc
to
e94acdd
Compare
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.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @andreimatei, @bdarnell, and @tbg)
pkg/kv/kvserver/replica_proposal_buf.go, line 168 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
I still think this would be an improvement.
done
pkg/kv/kvserver/replica_proposal_buf.go, line 503 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
I think this makes the knob super hard to reason about. I'd be in favor of broadening it to just disable this entire rejection mechanism. That's the effect it had before.
ok, done
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.
Reviewed 6 of 6 files at r9.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @bdarnell and @tbg)
pkg/kv/kvserver/replica_proposal_buf.go, line 501 at r3 (raw file):
Previously, nvanbenschoten (Nathan VanBenschoten) wrote…
We may need to extend this check even more. In 91f58af, I noticed that we are rejecting lease extensions when we are the current leaseholder if we haven't yet grabbed raft leadership. That seems wrong.
No need to do anything here.
By the way, this is now tracked in #59179.
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.
Reviewed 6 of 6 files at r7, 3 of 3 files at r8, 6 of 6 files at r9.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @andreimatei and @bdarnell)
pkg/kv/kvserver/batcheval/cmd_lease.go, line 51 at r9 (raw file):
wouldbeLeaseholer roachpb.ReplicaDescriptor, rngDesc *roachpb.RangeDescriptor, ) error { repDesc, ok := rngDesc.GetReplicaDescriptorByID(wouldbeLeaseholer.ReplicaID)
Leaseholder
Make checkCanReceiveLease() more nimble, anticipating broader use. Release note: None
This patch backpedals a little bit on the logic introduced in cockroachdb#55148. That patch said that, if a leader is known, every other replica refuses to propose a lease acquisition. Instead, the replica in question redirects whomever was triggering the lease acquisition to the leader, thinking that the leader should take the lease. That patch introduced a deadlock: some replicas refuse to take the lease because they are not VOTER_FULL (see CheckCanReceiveLease()). To fix the deadlock, this patch incorporates that check in the proposal buffer's decision about whether or not to reject a proposal: if the leader is believed to refuse to take the lease, then we again forward our own lease request. An edge case to the edge case is when the leader is not even part of the proposer's range descriptor. This can happen if the proposer is far behind. In this case, we assume that the leader is eligible. If it isn't, the deadlock will resolve once the proposer catches up. A future patch will relax the conditions under which a replica agrees to take the lease. VOTER_INCOMING replicas should take the lease. VOTER_DEMOTING are more controversial. Fixes cockroachdb#57798 Release note: None
e94acdd
to
a767cdd
Compare
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.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @bdarnell and @tbg)
pkg/kv/kvserver/batcheval/cmd_lease.go, line 51 at r9 (raw file):
Previously, tbg (Tobias Grieger) wrote…
Leaseholder
Done.
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.
bors r+
Reviewable status: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @bdarnell, @nvanbenschoten, and @tbg)
Build succeeded: |
Fixes cockroachdb#57342. This looks to have been the same thing as cockroachdb#57798, and was fixed by cockroachdb#58722. Release note: None
This patch backpedals a little bit on the logic introduced in #55148.
That patch said that, if a leader is known, every other replica refuses
to propose a lease acquisition. Instead, the replica in question
redirects whomever was triggering the lease acquisition to the leader,
thinking that the leader should take the lease.
That patch introduced a deadlock: some replicas refuse to take the lease
because they are not VOTER_FULL (see CheckCanReceiveLease()). To fix the
deadlock, this patch incorporates that check in the proposal buffer's
decision about whether or not to reject a proposal: if the leader is
believed to refuse to take the lease, then we again forward our own
lease request.
An edge case to the edge case is when the leader is not even part of the
proposer's range descriptor. This can happen if the proposer is far
behind. In this case, we assume that the leader is eligible. If it
isn't, the deadlock will resolve once the proposer catches up.
A future patch will relax the conditions under which a replica agrees to
take the lease. VOTER_INCOMING replicas should take the lease.
VOTER_DEMOTING are more controversial.
Fixes #57798
Release note: None