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

region cache: check if the pd returned regions covers the ranges #1377

Merged
merged 11 commits into from
Jul 3, 2024

Conversation

you06
Copy link
Contributor

@you06 you06 commented Jul 2, 2024

close #1376

Either len(regionsInfo) == 0 or gaps inside regionsInfo are valid cases, we should handle it. Unless we may suffer correctness issue if we read from regions with gap.

This PR adds the checks if regions can fully cover the given ranges in scanRegions and batchScanRegions. Since this is a rare case, I think we can just simply retry all the ranges if there are gaps.

you06 added 3 commits July 2, 2024 16:21
Signed-off-by: you06 <you1474600@gmail.com>
Signed-off-by: you06 <you1474600@gmail.com>
Signed-off-by: you06 <you1474600@gmail.com>
you06 added 3 commits July 3, 2024 14:43
Signed-off-by: you06 <you1474600@gmail.com>
Signed-off-by: you06 <you1474600@gmail.com>
Signed-off-by: you06 <you1474600@gmail.com>
Comment on lines 2157 to 2162
backoffErr = errors.Errorf("PD returned no region, limit: %d", limit)
continue
}
if regionsHaveGap([]pd.KeyRange{{StartKey: startKey, EndKey: endKey}}, regionsInfo, limit) {
backoffErr = errors.Errorf("PD returned regions have gaps, limit: %d", limit)
continue
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this an improvement for the original scan interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this should be picked back to earlier versions, which fixes the gap correctness issue for tiflash coprocessor.

// regionsHaveGap checks if the loaded regions can fully cover the key ranges.
// If there are any gaps between the regions, it returns true, then the requests might be retried.
// TODO: remove this function after PD client supports gap detection and handling it.
func regionsHaveGap(ranges []pd.KeyRange, regionsInfo []*pd.Region, limit int) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

The name seems not able to cover the actual usages which is more complex

Signed-off-by: you06 <you1474600@gmail.com>
internal/locate/region_cache.go Show resolved Hide resolved
internal/locate/region_cache.go Show resolved Hide resolved
if len(checkKey) == 0 {
return false
} else if len(ranges[checkIdx].EndKey) == 0 {
return true
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible the end key of the last region is also empty, should the true be returned in this case?

Copy link
Contributor

@MyonKeminta MyonKeminta Jul 3, 2024

Choose a reason for hiding this comment

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

This is the else branch of if len(checkKey) == 0, so here the checkKey is not empty, meaning that the returned regions didn't cover up to the very end.
Wait, checkKey looks never be assigned with an empty end_key as the function would immediately return at line 2257. The only possibility that it's empty must be an empty start_key which comes from the first range to check.
Then does it work when the ranges to check is ["", "b") and the regions is ["", "a")?
cc @you06

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, sorry, it still looks fine.
But I suggest adding some test cases where there are only one requested range and only one region in the result, and the range is half unbounded (empty startKey + non-empty endKey and non-empty startKey + empty endKey).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Half unbounded cases added.

if r.Meta == nil {
return true
}
if len(r.Meta.StartKey) != 0 && bytes.Compare(r.Meta.StartKey, checkKey) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

The left half of the condition seems unnecessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch.

return false
}
checkKey = r.Meta.EndKey
for len(ranges[checkIdx].EndKey) > 0 && bytes.Compare(checkKey, ranges[checkIdx].EndKey) >= 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not very familiar with the usage of it. Is the ranges here guaranteed to be already sorted by their start key?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the input ranges are sorted and cannot be overlapped.

@MyonKeminta MyonKeminta changed the title region ceche: check if the pd returned regions covers the ranges region cache: check if the pd returned regions covers the ranges Jul 3, 2024
you06 added 2 commits July 3, 2024 17:05
Signed-off-by: you06 <you1474600@gmail.com>
Signed-off-by: you06 <you1474600@gmail.com>
Signed-off-by: you06 <you1474600@gmail.com>
@cfzjywxk cfzjywxk merged commit d73cc1e into tikv:master Jul 3, 2024
10 checks passed
you06 added a commit to you06/client-go that referenced this pull request Jul 8, 2024
Signed-off-by: you06 <you1474600@gmail.com>
you06 added a commit to you06/client-go that referenced this pull request Jul 8, 2024
Signed-off-by: you06 <you1474600@gmail.com>
you06 added a commit to you06/client-go that referenced this pull request Jul 8, 2024
Signed-off-by: you06 <you1474600@gmail.com>
cfzjywxk pushed a commit that referenced this pull request Jul 10, 2024
…) (#1379)

* cherry pick #1377 to tidb-8.1

Signed-off-by: you06 <you1474600@gmail.com>

* run ci test in tidb-8.1

Signed-off-by: you06 <you1474600@gmail.com>

* lint

Signed-off-by: you06 <you1474600@gmail.com>

* rename function

Signed-off-by: you06 <you1474600@gmail.com>

* warn when no leader regions missing

Signed-off-by: you06 <you1474600@gmail.com>

---------

Signed-off-by: you06 <you1474600@gmail.com>
cfzjywxk pushed a commit that referenced this pull request Jul 10, 2024
…) (#1380)

* cherry pick #1377 to tidb-7.1

Signed-off-by: you06 <you1474600@gmail.com>

* lint

Signed-off-by: you06 <you1474600@gmail.com>

* rename function

Signed-off-by: you06 <you1474600@gmail.com>

* warn when no leader regions missing

Signed-off-by: you06 <you1474600@gmail.com>

---------

Signed-off-by: you06 <you1474600@gmail.com>
cfzjywxk pushed a commit that referenced this pull request Jul 10, 2024
…) (#1381)

* cherry pick #1377 to tidb-7.5

Signed-off-by: you06 <you1474600@gmail.com>

* run ci test in tidb-7.5

Signed-off-by: you06 <you1474600@gmail.com>

* lint

Signed-off-by: you06 <you1474600@gmail.com>

* fix import

Signed-off-by: you06 <you1474600@gmail.com>

* rename function

Signed-off-by: you06 <you1474600@gmail.com>

* warn when no leader regions missing

Signed-off-by: you06 <you1474600@gmail.com>

---------

Signed-off-by: you06 <you1474600@gmail.com>
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.

Need to check result of ScanRegions and BatchScanRegions
6 participants