use of com.pingcap.tikv.exception.TiBatchWriteException in project tispark by pingcap.
the class TTLManager method sendTxnHeartBeat.
private void sendTxnHeartBeat(BackOffer bo, long ttl) {
Pair<TiRegion, Metapb.Store> pair = regionManager.getRegionStorePairByKey(primaryLock);
TiRegion tiRegion = pair.first;
Metapb.Store store = pair.second;
ClientRPCResult result = kvClient.txnHeartBeat(bo, primaryLock, startTS, ttl, tiRegion, store);
if (!result.isSuccess() && !result.isRetry()) {
throw new TiBatchWriteException("sendTxnHeartBeat error", result.getException());
}
if (result.isRetry()) {
try {
bo.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, new GrpcException(String.format("sendTxnHeartBeat failed, regionId=%s", tiRegion.getId()), result.getException()));
this.regionManager.invalidateStore(store.getId());
this.regionManager.invalidateRegion(tiRegion);
// re-split keys and commit again.
sendTxnHeartBeat(bo, ttl);
} catch (GrpcException e) {
String errorMsg = String.format("sendTxnHeartBeat error, regionId=%s, detail=%s", tiRegion.getId(), e.getMessage());
throw new TiBatchWriteException(errorMsg, e);
}
}
LOG.debug("sendTxnHeartBeat success key={} ttl={} success", LogDesensitization.hide(KeyUtils.formatBytes(primaryLock)), ttl);
}
use of com.pingcap.tikv.exception.TiBatchWriteException in project tispark by pingcap.
the class TwoPhaseCommitter method doPrewritePrimaryKeyWithRetry.
private void doPrewritePrimaryKeyWithRetry(BackOffer backOffer, ByteString key, ByteString value) throws TiBatchWriteException {
Pair<TiRegion, Metapb.Store> pair = this.regionManager.getRegionStorePairByKey(key, backOffer);
TiRegion tiRegion = pair.first;
Kvrpcpb.Mutation mutation;
if (!value.isEmpty()) {
mutation = Kvrpcpb.Mutation.newBuilder().setKey(key).setValue(value).setOp(Op.Put).build();
} else {
mutation = Kvrpcpb.Mutation.newBuilder().setKey(key).setOp(Op.Del).build();
}
List<Kvrpcpb.Mutation> mutationList = Collections.singletonList(mutation);
// send rpc request to tikv server
long lockTTL = getTxnLockTTL(this.startTs);
ClientRPCResult prewriteResult = this.kvClient.prewrite(backOffer, mutationList, key, lockTTL, this.startTs, tiRegion);
if (!prewriteResult.isSuccess() && !prewriteResult.isRetry()) {
throw new TiBatchWriteException("prewrite primary key error", prewriteResult.getException());
}
if (prewriteResult.isRetry()) {
try {
backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, new GrpcException(String.format("Txn prewrite primary key failed, regionId=%s", tiRegion.getId()), prewriteResult.getException()));
// re-split keys and commit again.
this.doPrewritePrimaryKeyWithRetry(backOffer, key, value);
} catch (GrpcException e) {
String errorMsg = String.format("Txn prewrite primary key error, re-split commit failed, regionId=%s, detail=%s", tiRegion.getId(), e.getMessage());
throw new TiBatchWriteException(errorMsg, e);
}
}
LOG.info("prewrite primary key {} successfully", LogDesensitization.hide(KeyUtils.formatBytes(key)));
}
use of com.pingcap.tikv.exception.TiBatchWriteException in project tispark by pingcap.
the class TwoPhaseCommitter method doPrewriteSecondaryKeysInBatchesWithRetry.
private void doPrewriteSecondaryKeysInBatchesWithRetry(BackOffer backOffer, ByteString primaryKey, List<ByteString> keys, List<ByteString> values, int size, int level) throws TiBatchWriteException {
if (keys == null || keys.isEmpty() || values == null || values.isEmpty() || size <= 0) {
// return success
return;
}
Map<ByteString, Kvrpcpb.Mutation> mutations = new LinkedHashMap<>();
for (int i = 0; i < size; i++) {
ByteString key = keys.get(i);
ByteString value = values.get(i);
Kvrpcpb.Mutation mutation;
if (!value.isEmpty()) {
mutation = Kvrpcpb.Mutation.newBuilder().setKey(key).setValue(value).setOp(Kvrpcpb.Op.Put).build();
} else {
// value can be null (table with one primary key integer column, data is encoded in key)
mutation = Kvrpcpb.Mutation.newBuilder().setKey(key).setOp(Kvrpcpb.Op.Del).build();
}
mutations.put(key, mutation);
}
// groups keys by region
Map<TiRegion, List<ByteString>> groupResult = groupKeysByRegion(this.regionManager, keys, backOffer);
List<BatchKeys> batchKeyList = new ArrayList<>();
for (Map.Entry<TiRegion, List<ByteString>> entry : groupResult.entrySet()) {
TiRegion tiRegion = entry.getKey();
this.appendBatchBySize(batchKeyList, tiRegion, entry.getValue(), true, mutations);
}
// For prewrite, stop sending other requests after receiving first error.
for (BatchKeys batchKeys : batchKeyList) {
TiRegion oldRegion = batchKeys.getRegion();
TiRegion currentRegion = this.regionManager.getRegionByKey(oldRegion.getStartKey(), backOffer);
if (oldRegion.equals(currentRegion)) {
doPrewriteSecondaryKeySingleBatchWithRetry(backOffer, primaryKey, batchKeys, mutations);
} else {
if (level > prewriteMaxRetryTimes) {
throw new TiBatchWriteException(String.format("> max retry number %s, oldRegion=%s, currentRegion=%s", prewriteMaxRetryTimes, oldRegion, currentRegion));
}
LOG.info(String.format("oldRegion=%s != currentRegion=%s, will re-fetch region info and retry", oldRegion, currentRegion));
retryPrewriteBatch(backOffer, primaryKey, batchKeys, mutations, level <= 0 ? 1 : level + 1);
}
}
}
use of com.pingcap.tikv.exception.TiBatchWriteException in project tispark by pingcap.
the class TwoPhaseCommitter method doCommitPrimaryKeyWithRetry.
private void doCommitPrimaryKeyWithRetry(BackOffer backOffer, ByteString key, long commitTs) throws TiBatchWriteException {
Pair<TiRegion, Metapb.Store> pair = this.regionManager.getRegionStorePairByKey(key, backOffer);
TiRegion tiRegion = pair.first;
List<ByteString> keys = new ArrayList<>();
keys.add(key);
// send rpc request to tikv server
ClientRPCResult commitResult = this.kvClient.commit(backOffer, keys, this.startTs, commitTs, tiRegion);
if (!commitResult.isSuccess()) {
if (!commitResult.isRetry()) {
throw new TiBatchWriteException("commit primary key error", commitResult.getException());
} else {
backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, new GrpcException(String.format("Txn commit primary key failed, regionId=%s", tiRegion.getId()), commitResult.getException()));
// re-split keys and commit again.
this.doCommitPrimaryKeyWithRetry(backOffer, key, commitTs);
}
}
LOG.info("commit primary key {} successfully", LogDesensitization.hide(KeyUtils.formatBytes(key)));
}
use of com.pingcap.tikv.exception.TiBatchWriteException in project tispark by pingcap.
the class TwoPhaseCommitter method doPrewriteSecondaryKeys.
private void doPrewriteSecondaryKeys(ByteString primaryKey, Iterator<Pair<ByteString, ByteString>> pairs, int maxBackOfferMS) throws TiBatchWriteException {
try {
int taskBufferSize = writeThreadPerTask * 2;
int totalSize = 0, cnt = 0;
Pair<ByteString, ByteString> pair;
ExecutorCompletionService<Void> completionService = new ExecutorCompletionService<>(executorService);
while (pairs.hasNext()) {
List<ByteString> keyBytes = new ArrayList<>(writeBufferSize);
List<ByteString> valueBytes = new ArrayList<>(writeBufferSize);
while (keyBytes.size() < writeBufferSize && pairs.hasNext()) {
pair = pairs.next();
keyBytes.add(pair.first);
valueBytes.add(pair.second);
}
int curSize = keyBytes.size();
cnt++;
if (cnt > taskBufferSize) {
// consume one task if reaches task limit
completionService.take().get();
}
BackOffer backOffer = ConcreteBackOffer.newCustomBackOff(maxBackOfferMS);
completionService.submit(() -> {
doPrewriteSecondaryKeysInBatchesWithRetry(backOffer, primaryKey, keyBytes, valueBytes, curSize, 0);
return null;
});
totalSize = totalSize + keyBytes.size();
}
for (int i = 0; i < Math.min(taskBufferSize, cnt); i++) {
completionService.take().get();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new TiBatchWriteException("Current thread interrupted.", e);
} catch (ExecutionException e) {
throw new TiBatchWriteException("Execution exception met.", e);
}
}
Aggregations