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

streamingccl: use correct bounds for range key SSTs #112903

Merged
merged 1 commit into from
Oct 25, 2023

Conversation

stevendanna
Copy link
Collaborator

Previously, we were erroneously calling Next() on the end key of our SST even though the end key already represented an exclusive bounds.

This Next() meant that the bounds of our SSTs were slightly incorrect. In most cases, this was harmless, but in the case of a range boundary that aligned directly with the actual bounds of the SST, it could result in us attempting to split an SST into 2 with the RHS ending up empty.

Here, we fix that and also make our SST splitting a bit more robust to bad input. It now errors if the LHS or RHS ends up empty despite a split key inside the given bounds. It also handles split keys outside of the bounds. Neither of these things should happen unless our contract with other parts of the system changes.

Fixes #112846

Release note (bug fix): Fix a bug that could prevent phyiscal replication from advancing in the face of some range deletion operations.

@stevendanna stevendanna requested a review from a team as a code owner October 23, 2023 20:13
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Comment on lines +1001 to +1008
// Special case: The split key less than the start key.
if splitKey.Compare(start) < 0 {
return nil, &rangeKeySST{start: start, end: end, data: data}, nil
}

// Special case: The split key is greater or equal to the
// exclusive end key.
if end.Compare(splitKey) <= 0 {
return &rangeKeySST{start: start, end: end, data: data}, nil, nil
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I could be convinced that these should just also return errors since they really should not happen.

Copy link
Collaborator

Choose a reason for hiding this comment

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

why don't you think this could happen? I think the RangeKeyMismatchError docstring suggests that any part of the rangekey sst we want to ingest could be in a different range-- I think that leaves open the possibility that the whole rangekey sst is in a different range.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I was just not thinking this through when I wrote this. I think what I had in my mind is that if the whole SST was in a different range, then why did we ever send it to the wrong range. But, perhaps our entire SST is on one side of a split we don't know about yet. So, I'll leave these cases and remove the errant comment.

Thanks!

Copy link
Collaborator

@msbutler msbutler left a comment

Choose a reason for hiding this comment

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

LGTM and nice tests! Just had one clarifying question.

Comment on lines +1001 to +1008
// Special case: The split key less than the start key.
if splitKey.Compare(start) < 0 {
return nil, &rangeKeySST{start: start, end: end, data: data}, nil
}

// Special case: The split key is greater or equal to the
// exclusive end key.
if end.Compare(splitKey) <= 0 {
return &rangeKeySST{start: start, end: end, data: data}, nil, nil
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

why don't you think this could happen? I think the RangeKeyMismatchError docstring suggests that any part of the rangekey sst we want to ingest could be in a different range-- I think that leaves open the possibility that the whole rangekey sst is in a different range.

@@ -956,7 +958,18 @@ func (r *rangeKeyBatcher) flush(ctx context.Context, toFlush mvccRangeKeyValues)
if err != nil {
return err
}
work = append([]*rangeKeySST{left, right}, work...)

// The second two cases really should not be possible unless we've
Copy link
Collaborator

Choose a reason for hiding this comment

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

again, curious why you think the second and third cases aren't really possible.

Previously, we were erroneously calling Next() on the end key of our
SST even though the end key already represented an exclusive bounds.

This Next() meant that the bounds of our SSTs were slightly
incorrect. In most cases, this was harmless, but in the case of a
range boundary that aligned directly with the _actual_ bounds of the
SST, it could result in us attempting to split an SST into 2 with the
RHS ending up empty.

Here, we fix that and also make our SST splitting a bit more robust to
bad input. It now errors if the LHS or RHS ends up empty despite a
split key inside the given bounds. It also handles split keys outside
of the bounds. Neither of these things should happen unless our
contract with other parts of the system changes.

Fixes cockroachdb#112846

Release note (bug fix): Fix a bug that could prevent phyiscal
replication from advancing in the face of some range deletion
operations.
@stevendanna stevendanna added backport-23.2.x Flags PRs that need to be backported to 23.2. backport-23.1.x Flags PRs that need to be backported to 23.1 labels Oct 25, 2023
@stevendanna
Copy link
Collaborator Author

bors r=msbutler

@craig
Copy link
Contributor

craig bot commented Oct 25, 2023

Build succeeded:

@craig craig bot merged commit 54bd405 into cockroachdb:master Oct 25, 2023
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-23.1.x Flags PRs that need to be backported to 23.1 backport-23.2.x Flags PRs that need to be backported to 23.2.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

streamingccl: range key splitting can produce incorrect SST
3 participants