Search in sources :

Example 1 with TiBatchWriteException

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);
}
Also used : TiRegion(com.pingcap.tikv.region.TiRegion) GrpcException(com.pingcap.tikv.exception.GrpcException) ByteString(com.google.protobuf.ByteString) ClientRPCResult(com.pingcap.tikv.txn.type.ClientRPCResult) Metapb(org.tikv.kvproto.Metapb) TiBatchWriteException(com.pingcap.tikv.exception.TiBatchWriteException)

Example 2 with TiBatchWriteException

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)));
}
Also used : Kvrpcpb(org.tikv.kvproto.Kvrpcpb) TiRegion(com.pingcap.tikv.region.TiRegion) GrpcException(com.pingcap.tikv.exception.GrpcException) ByteString(com.google.protobuf.ByteString) ClientRPCResult(com.pingcap.tikv.txn.type.ClientRPCResult) TiBatchWriteException(com.pingcap.tikv.exception.TiBatchWriteException)

Example 3 with TiBatchWriteException

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);
        }
    }
}
Also used : ByteString(com.google.protobuf.ByteString) Kvrpcpb(org.tikv.kvproto.Kvrpcpb) ArrayList(java.util.ArrayList) TiBatchWriteException(com.pingcap.tikv.exception.TiBatchWriteException) LinkedHashMap(java.util.LinkedHashMap) TiRegion(com.pingcap.tikv.region.TiRegion) BatchKeys(com.pingcap.tikv.txn.type.BatchKeys) ArrayList(java.util.ArrayList) List(java.util.List) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 4 with TiBatchWriteException

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)));
}
Also used : ByteString(com.google.protobuf.ByteString) TiRegion(com.pingcap.tikv.region.TiRegion) ArrayList(java.util.ArrayList) GrpcException(com.pingcap.tikv.exception.GrpcException) ClientRPCResult(com.pingcap.tikv.txn.type.ClientRPCResult) TiBatchWriteException(com.pingcap.tikv.exception.TiBatchWriteException)

Example 5 with TiBatchWriteException

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);
    }
}
Also used : ByteString(com.google.protobuf.ByteString) ArrayList(java.util.ArrayList) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) ConcreteBackOffer(com.pingcap.tikv.util.ConcreteBackOffer) BackOffer(com.pingcap.tikv.util.BackOffer) ExecutionException(java.util.concurrent.ExecutionException) TiBatchWriteException(com.pingcap.tikv.exception.TiBatchWriteException)

Aggregations

ByteString (com.google.protobuf.ByteString)8 TiBatchWriteException (com.pingcap.tikv.exception.TiBatchWriteException)8 ClientRPCResult (com.pingcap.tikv.txn.type.ClientRPCResult)5 ArrayList (java.util.ArrayList)5 GrpcException (com.pingcap.tikv.exception.GrpcException)4 TiRegion (com.pingcap.tikv.region.TiRegion)4 BackOffer (com.pingcap.tikv.util.BackOffer)2 ConcreteBackOffer (com.pingcap.tikv.util.ConcreteBackOffer)2 ExecutionException (java.util.concurrent.ExecutionException)2 ExecutorCompletionService (java.util.concurrent.ExecutorCompletionService)2 Kvrpcpb (org.tikv.kvproto.Kvrpcpb)2 BatchKeys (com.pingcap.tikv.txn.type.BatchKeys)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Metapb (org.tikv.kvproto.Metapb)1