use of com.pingcap.tikv.region.TiRegion in project tispark by pingcap.
the class LockResolverClientV4 method resolveRegionLocks.
/**
* resolveRegionLocks is essentially the same as resolveLock, but we resolve all keys in the same
* region at the same time.
*/
private boolean resolveRegionLocks(BackOffer bo, Lock lock, TiRegion tiRegion, List<ByteString> keys, TxnStatus status) {
RegionStoreClient regionStoreClient = clientBuilder.build(tiRegion);
Supplier<Kvrpcpb.ResolveLockRequest> factory = () -> Kvrpcpb.ResolveLockRequest.newBuilder().setContext(tiRegion.getContext()).setStartVersion(lock.getTxnID()).setCommitVersion(status.getCommitTS()).addAllKeys(keys).build();
KVErrorHandler<Kvrpcpb.ResolveLockResponse> handler = new KVErrorHandler<>(regionManager, regionStoreClient, regionStoreClient.lockResolverClient, resp -> null, resp -> null, resolveLockResult -> null, 0L, false);
Kvrpcpb.ResolveLockResponse resp = regionStoreClient.callWithRetry(bo, TikvGrpc.getKvResolveLockMethod(), factory, handler);
if (resp == null || resp.hasRegionError()) {
logger.error("getKvResolveLockMethod failed without a cause");
regionManager.onRequestFail(tiRegion);
bo.doBackOff(BoRegionMiss, new TiClientInternalException("getKvResolveLockMethod failed without a cause"));
logger.debug(String.format("resolveRegionLocks region error, regrouping lock=%s region=%d", lock, tiRegion.getId()));
// Regroup locks.
Map<TiRegion, List<ByteString>> groupResult = groupKeysByRegion(this.regionManager, keys, bo);
for (Map.Entry<TiRegion, List<ByteString>> entry : groupResult.entrySet()) {
TiRegion region = entry.getKey();
resolveRegionLocks(bo, lock, region, entry.getValue(), status);
}
} else if (resp.hasError()) {
logger.error(String.format("unexpected resolveLock err: %s, lock: %s", resp.getError(), lock));
throw new KeyException(resp.getError());
}
return true;
}
use of com.pingcap.tikv.region.TiRegion in project tispark by pingcap.
the class RangeSplitter method groupByAndSortHandlesByRegionId.
/**
* Group by a list of handles by the handles' region, handles will be sorted.
*
* @param tableId Table id used for the handle
* @param handles Handle list
* @return <Region, HandleList> map
*/
public Map<Pair<TiRegion, Metapb.Store>, List<Handle>> groupByAndSortHandlesByRegionId(long tableId, List<Handle> handles) {
TLongObjectHashMap<List<Handle>> regionHandles = new TLongObjectHashMap<>();
TLongObjectHashMap<Pair<TiRegion, Metapb.Store>> idToRegionStorePair = new TLongObjectHashMap<>();
Map<Pair<TiRegion, Metapb.Store>, List<Handle>> result = new HashMap<>();
handles.sort(Handle::compare);
byte[] endKey = null;
TiRegion curRegion = null;
List<Handle> handlesInCurRegion = new ArrayList<>();
for (Handle curHandle : handles) {
RowKey key = RowKey.toRowKey(tableId, curHandle);
if (endKey == null || (endKey.length != 0 && FastByteComparisons.compareTo(key.getBytes(), endKey) >= 0)) {
if (curRegion != null) {
regionHandles.put(curRegion.getId(), handlesInCurRegion);
handlesInCurRegion = new ArrayList<>();
}
Pair<TiRegion, Metapb.Store> regionStorePair = regionManager.getRegionStorePairByKey(ByteString.copyFrom(key.getBytes()));
curRegion = regionStorePair.first;
idToRegionStorePair.put(curRegion.getId(), regionStorePair);
endKey = curRegion.getEndKey().toByteArray();
}
handlesInCurRegion.add(curHandle);
}
if (!handlesInCurRegion.isEmpty()) {
regionHandles.put(curRegion.getId(), handlesInCurRegion);
}
regionHandles.forEachEntry((k, v) -> {
Pair<TiRegion, Metapb.Store> regionStorePair = idToRegionStorePair.get(k);
result.put(regionStorePair, v);
return true;
});
return result;
}
use of com.pingcap.tikv.region.TiRegion in project tispark by pingcap.
the class RangeSplitter method splitRangeByRegion.
/**
* Split key ranges into corresponding region tasks and group by their region id
*
* @param keyRanges List of key ranges
* @param storeType Store type, null or TiKV for TiKV(leader), otherwise TiFlash(learner)
* @return List of RegionTask, each task corresponds to a different region.
*/
public List<RegionTask> splitRangeByRegion(List<KeyRange> keyRanges, TiStoreType storeType) {
if (keyRanges == null || keyRanges.size() == 0) {
return ImmutableList.of();
}
int i = 0;
KeyRange range = keyRanges.get(i++);
// region id to keyRange list
Map<Long, List<KeyRange>> idToRange = new HashMap<>();
Map<Long, Pair<TiRegion, Metapb.Store>> idToRegion = new HashMap<>();
while (true) {
Pair<TiRegion, Metapb.Store> regionStorePair = null;
BackOffer bo = ConcreteBackOffer.newGetBackOff();
while (regionStorePair == null) {
try {
regionStorePair = regionManager.getRegionStorePairByKey(range.getStart(), storeType, bo);
if (regionStorePair == null) {
throw new NullPointerException("fail to get region/store pair by key " + formatByteString(range.getStart()));
}
} catch (Exception e) {
LOG.warn("getRegionStorePairByKey error", e);
bo.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, e);
}
}
TiRegion region = regionStorePair.first;
idToRegion.putIfAbsent(region.getId(), regionStorePair);
// Both keys are at right hand side and then always not -INF
if (toRawKey(range.getEnd()).compareTo(toRawKey(region.getEndKey())) > 0) {
// current region does not cover current end key
KeyRange cutRange = KeyRange.newBuilder().setStart(range.getStart()).setEnd(region.getEndKey()).build();
List<KeyRange> ranges = idToRange.computeIfAbsent(region.getId(), k -> new ArrayList<>());
ranges.add(cutRange);
// cut new remaining for current range
range = KeyRange.newBuilder().setStart(region.getEndKey()).setEnd(range.getEnd()).build();
} else {
// current range covered by region
List<KeyRange> ranges = idToRange.computeIfAbsent(region.getId(), k -> new ArrayList<>());
ranges.add(range);
if (i >= keyRanges.size()) {
break;
}
range = keyRanges.get(i++);
}
}
ImmutableList.Builder<RegionTask> resultBuilder = ImmutableList.builder();
idToRange.forEach((k, v) -> {
Pair<TiRegion, Metapb.Store> regionStorePair = idToRegion.get(k);
resultBuilder.add(new RegionTask(regionStorePair.first, regionStorePair.second, v));
});
return resultBuilder.build();
}
use of com.pingcap.tikv.region.TiRegion in project tispark by pingcap.
the class MockServerTest method setUp.
@Before
@Override
public void setUp() throws IOException {
super.setUp();
Metapb.Region r = Metapb.Region.newBuilder().setRegionEpoch(Metapb.RegionEpoch.newBuilder().setConfVer(1).setVersion(2)).setId(233).setStartKey(ByteString.EMPTY).setEndKey(ByteString.EMPTY).addPeers(Metapb.Peer.newBuilder().setId(11).setStoreId(13)).build();
region = new TiRegion(r, r.getPeers(0), session.getConf().getIsolationLevel(), session.getConf().getCommandPriority());
pdServer.addGetRegionResp(Pdpb.GetRegionResponse.newBuilder().setRegion(r).build());
server = new KVMockServer();
port = server.start(region);
}
use of com.pingcap.tikv.region.TiRegion in project tispark by pingcap.
the class PDClientTest method testGetRegionByKeyAsync.
@Test
public void testGetRegionByKeyAsync() throws Exception {
byte[] startKey = new byte[] { 1, 0, 2, 4 };
byte[] endKey = new byte[] { 1, 0, 2, 5 };
int confVer = 1026;
int ver = 1027;
pdServer.addGetRegionResp(GrpcUtils.makeGetRegionResponse(pdServer.getClusterId(), GrpcUtils.makeRegion(1, encodeKey(startKey), encodeKey(endKey), GrpcUtils.makeRegionEpoch(confVer, ver), GrpcUtils.makePeer(1, 10), GrpcUtils.makePeer(2, 20))));
try (PDClient client = session.getPDClient()) {
TiRegion r = client.getRegionByKeyAsync(defaultBackOff(), ByteString.EMPTY).get();
assertEquals(r.getStartKey(), ByteString.copyFrom(startKey));
assertEquals(r.getEndKey(), ByteString.copyFrom(endKey));
assertEquals(r.getRegionEpoch().getConfVer(), confVer);
assertEquals(r.getRegionEpoch().getVersion(), ver);
assertEquals(r.getLeader().getId(), 1);
assertEquals(r.getLeader().getStoreId(), 10);
}
}
Aggregations