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

Retry for range exceed error #2774

Merged
merged 8 commits into from
Mar 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.pingcap.tikv.operation.SchemaInfer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
Expand Down Expand Up @@ -212,6 +213,7 @@ private SelectResponse process(RegionTask regionTask) {

// In case of one region task spilt into several others, we ues a queue to properly handle all
// the remaining tasks.
int retryCount = 0;
while (!remainTasks.isEmpty()) {
RegionTask task = remainTasks.poll();
if (task == null) {
Expand Down Expand Up @@ -267,9 +269,7 @@ private SelectResponse process(RegionTask regionTask) {
logger.info(
String.format(
"start coprocess request to %s in region %d with timeout %s",
task.getHost(),
region.getId(),
client.getTimeout()));
task.getHost(), region.getId(), client.getTimeout()));

Collection<RegionTask> tasks =
client.coprocess(backOffer, dagRequest, ranges, responseQueue, startTs);
Expand All @@ -284,6 +284,37 @@ private SelectResponse process(RegionTask regionTask) {
+ remainTasks.size()
+ " tasks not executed due to",
e);

// We guess range may exceed bound in corner case. Since it is
// hard to find the root cause, we just log it and retry once here.
// We use client-java's splitRangeByRegion method to avoid exceed bound issue. It seems this
// method can split range correctly.
if (e.getMessage().contains("Request range exceeds bound")) {
String regionSt = Arrays.toString(region.getStartKey().toByteArray());
String regionEd = Arrays.toString(region.getEndKey().toByteArray());
Long storeId = store == null ? 0 : store.getId();
logger.warn(
String.format(
"region task failed. host:%s region:%s, store: %d. region start key: %s, region end key: %s",
task.getHost(), region.getId(), storeId, regionSt, regionEd));
logger.warn("start to print range");
for (Coprocessor.KeyRange range : ranges) {
logger.warn(
"Sending DAG request with range "
+ Arrays.toString(range.getStart().toByteArray())
+ " to "
+ Arrays.toString(range.getEnd().toByteArray()));
}
if (retryCount < 1) {
retryCount++;
remainTasks.addAll(
RangeSplitter.newSplitter(clientSession.getTiKVSession().getRegionManager())
.splitRangeByRegion(ranges, storeType));
logger.info(
"Re-splitting region task and retry once. Task count: " + remainTasks.size());
continue;
}
}
// Rethrow to upper levels
throw new RegionTaskException("Handle region task failed:", e);
}
Expand Down