Skip to content
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

raft: forbid direct voter removal without demotion #131445

Merged

Conversation

nvanbenschoten
Copy link
Member

Informs #129796.
Informs #125355.

This commit is a natural continuation of 7f37eaa (from 5 years ago). The commit made it so that the replicateQueue would never issue a ChangeReplicas request that removed a voter replica. Instead, the replicate queue would always demote the voter replica to a learner replica first.

This commit makes it so that raft will no longer allow direct voter removal in a proposed configuration change. Instead, it requires the voter (who may be the leader) to first be demoted to a learner. This prevents abuse and strengthens the guarantee that we will never perform such unsafe configuration changes.

Release note: None

@nvanbenschoten nvanbenschoten requested a review from a team as a code owner September 26, 2024 17:36
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Member

@tbg tbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions, mostly due to me needing some help to page this back in. Will leave unapproved due to this and your open TODO in the last commit.

Is the argument for why adding an assertion when switching configs is safe that "we haven't done voter removals in 5 years and so nobody will have a direct voter removal sitting in their raft log and getting applied when the new binary boots up"?

Also, I'm doubting that understand the DisableConfChangeValidation comment entirely. This part:

These checks are generally sensible (cannot leave a joint
// config unless in a joint config, et cetera) but they have false positives
// because the active configuration may not be the most recent
// configuration.

Yet, we call ValidateProp on the leader and the first thing it does is make sure we've applied all previous config changes. Which means the only way the visible config isn't the right one to compare with is that the instance isn't actually the leader any more and the caller has seen a newer config already. In this case, we basically need to make sure the config never makes it into the committed log - or at least need to make sure it applies as a no-op (i.e. apply-time validation vs propose-time). I feel like there was more to this than I can reconstruct now. I seem to remember a case in which conf changes were discarded erroneously, and this somehow impacted availability.

Assuming you have a good grasp on this flag, could you touch up the comment here to that effect? If you're similarly unsure I can dig up some dirt. @pav-kv this also seems up your alley.

I also can't help but think how silly it is that we don't have a sequence number in the config and do first a validation of consecutive sequence number and then can authoritatively run sanity checks on the transition. This might be worth filing an issue for? I doubt we want to tackle it directly now.

@nvanbenschoten nvanbenschoten force-pushed the nvanbenschoten/dontAllowVoterRemoval branch from f0c9ee9 to 9b7a345 Compare October 7, 2024 23:11
@nvanbenschoten
Copy link
Member Author

Will leave unapproved due to this and your open TODO in the last commit.

This TODO is now addressed. PTAL!

Is the argument for why adding an assertion when switching configs is safe that "we haven't done voter removals in 5 years and so nobody will have a direct voter removal sitting in their raft log and getting applied when the new binary boots up"?

Essentially, yes. It seems exceedingly unlikely that such an unapplied config change would survive across 5 years of biannual upgrades where every upgrade requires a rolling restart. We have also flushed the raft log on each range at least once during this period with the lock table migration.

I would be ok with changing it to an log.Error instead of a log.Panic in prod to be extra safe, but I don't think that's needed. And note that in the case where this does fire, it will only fire once on the leader. Some other replica will then step up and complete the config change.

I seem to remember a case in which conf changes were discarded erroneously, and this somehow impacted availability.

Yes, that's correct, see the discussion on d8d274b, which talks about what was going wrong. Note that this PR is moving some of this code, but it isn't actually changing any of it. I'm happy if we start pulling on some of this again, but it would be better if that happens outside of the critical path of leader leases.

This commit extracts a confchange.ValidateProp function, which is called
from `stepLeader` when handling a ConfChange MsgProp. Extracting will
let us more easily test the validation logic.

Epic: None
Release note: None
Informs cockroachdb#129796.
Informs cockroachdb#125355.

This commit is a natural continuation of 7f37eaa (from 5 years ago). The commit
made it so that the replicateQueue would never issue a ChangeReplicas request
that removed a voter replica. Instead, the replicate queue would always demote
the voter replica to a learner replica first.

This commit makes it so that raft will no longer allow direct voter removal in a
proposed configuration change. Instead, it requires the voter (who may be the
leader) to first be demoted to a learner. This prevents abuse and strengthens
the guarantee that we will never perform such unsafe configuration changes.

Release note: None
Informs cockroachdb#129796.
Informs cockroachdb#125355.

Perform the same assertion as we have in pkg/raft, but for cases where
DisableConfChangeValidation is set to true.

Release note: None
@nvanbenschoten nvanbenschoten force-pushed the nvanbenschoten/dontAllowVoterRemoval branch from b7f63f1 to 686d59d Compare October 14, 2024 18:43
Copy link
Member

@tbg tbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 5 of 5 files at r1, 7 of 7 files at r2, 2 of 2 files at r3, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @nvanbenschoten)

@nvanbenschoten
Copy link
Member Author

TFTR!

bors r+

@craig craig bot merged commit aa722b5 into cockroachdb:master Oct 15, 2024
23 checks passed
@nvanbenschoten nvanbenschoten deleted the nvanbenschoten/dontAllowVoterRemoval branch October 16, 2024 03:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants