Search in sources :

Example 1 with ScanResponse

use of org.tikv.kvproto.Kvrpcpb.ScanResponse in project client-java by tikv.

the class RegionStoreClient method scan.

public List<KvPair> scan(BackOffer backOffer, ByteString startKey, long version, boolean keyOnly) {
    boolean forWrite = false;
    while (true) {
        // we should refresh region
        region = regionManager.getRegionByKey(startKey, backOffer);
        Supplier<ScanRequest> request = () -> ScanRequest.newBuilder().setContext(makeContext(getResolvedLocks(version), this.storeType, backOffer.getSlowLog())).setStartKey(startKey).setVersion(version).setKeyOnly(keyOnly).setLimit(getConf().getScanBatchSize()).build();
        KVErrorHandler<ScanResponse> handler = new KVErrorHandler<>(regionManager, this, lockResolverClient, resp -> resp.hasRegionError() ? resp.getRegionError() : null, resp -> null, resolveLockResult -> addResolvedLocks(version, resolveLockResult.getResolvedLocks()), version, forWrite);
        ScanResponse resp = callWithRetry(backOffer, TikvGrpc.getKvScanMethod(), request, handler);
        if (isScanSuccess(backOffer, resp)) {
            return doScan(resp);
        }
    }
}
Also used : RawScanRequest(org.tikv.kvproto.Kvrpcpb.RawScanRequest) ScanRequest(org.tikv.kvproto.Kvrpcpb.ScanRequest) RawScanResponse(org.tikv.kvproto.Kvrpcpb.RawScanResponse) ScanResponse(org.tikv.kvproto.Kvrpcpb.ScanResponse) KVErrorHandler(org.tikv.common.operation.KVErrorHandler)

Example 2 with ScanResponse

use of org.tikv.kvproto.Kvrpcpb.ScanResponse in project tispark by pingcap.

the class KVErrorHandler method handleResponseError.

// Referenced from TiDB
// store/tikv/region_request.go - onRegionError
/**
 * @return true: client should retry
 */
@Override
public boolean handleResponseError(BackOffer backOffer, RespT resp) {
    if (resp == null) {
        String msg = String.format("Request Failed with unknown reason for region region [%s]", recv.getRegion());
        logger.warn(msg);
        return handleRequestError(backOffer, new GrpcException(msg));
    }
    // Region error handling logic
    Errorpb.Error error = getRegionError(resp);
    if (error != null) {
        if (error.hasNotLeader()) {
            // this error is reported from raftstore:
            // peer of current request is not leader, the following might be its causes:
            // 1. cache is outdated, region has changed its leader, can be solved by re-fetching from PD
            // 2. leader of current region is missing, need to wait and then fetch region info from PD
            long newStoreId = error.getNotLeader().getLeader().getStoreId();
            boolean retry;
            // update Leader here
            logger.warn(String.format("NotLeader Error with region id %d and store id %d, new store id %d", recv.getRegion().getId(), recv.getRegion().getLeader().getStoreId(), newStoreId));
            BackOffFunction.BackOffFuncType backOffFuncType;
            // since issuing store = NO_LEADER_STORE_ID requests to pd will definitely fail.
            if (newStoreId != NO_LEADER_STORE_ID) {
                // If update leader fails, we need to fetch new region info from pd,
                // and re-split key range for new region. Setting retry to false will
                // stop retry and enter handleCopResponse logic, which would use RegionMiss
                // backOff strategy to wait, fetch new region and re-split key range.
                // onNotLeader is only needed when updateLeader succeeds, thus switch
                // to a new store address.
                TiRegion newRegion = this.regionManager.updateLeader(recv.getRegion(), newStoreId);
                retry = newRegion != null && recv.onNotLeader(this.regionManager.getStoreById(newStoreId), newRegion);
                if (!retry) {
                    notifyRegionStoreCacheInvalidate(recv.getRegion(), CacheInvalidateEvent.CacheType.LEADER);
                }
                backOffFuncType = BackOffFunction.BackOffFuncType.BoUpdateLeader;
            } else {
                logger.info(String.format("Received zero store id, from region %d try next time", recv.getRegion().getId()));
                backOffFuncType = BackOffFunction.BackOffFuncType.BoRegionMiss;
                retry = false;
            }
            if (!retry) {
                this.regionManager.invalidateRegion(recv.getRegion());
            }
            backOffer.doBackOff(backOffFuncType, new GrpcException(error.toString()));
            return retry;
        } else if (error.hasStoreNotMatch()) {
            // this error is reported from raftstore:
            // store_id requested at the moment is inconsistent with that expected
            // Solution:re-fetch from PD
            long storeId = recv.getRegion().getLeader().getStoreId();
            long actualStoreId = error.getStoreNotMatch().getActualStoreId();
            logger.warn(String.format("Store Not Match happened with region id %d, store id %d, actual store id %d", recv.getRegion().getId(), storeId, actualStoreId));
            invalidateRegionStoreCache(recv.getRegion());
            recv.onStoreNotMatch(this.regionManager.getStoreById(storeId));
            // throwing it out.
            return false;
        } else if (error.hasEpochNotMatch()) {
            // this error is reported from raftstore:
            // region has outdated version,please try later.
            logger.warn(String.format("Stale Epoch encountered for region [%s]", recv.getRegion()));
            this.regionManager.onRegionStale(recv.getRegion());
            notifyRegionCacheInvalidate(recv.getRegion());
            return false;
        } else if (error.hasServerIsBusy()) {
            // this error is reported from kv:
            // will occur when write pressure is high. Please try later.
            logger.warn(String.format("Server is busy for region [%s], reason: %s", recv.getRegion(), error.getServerIsBusy().getReason()));
            backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoServerBusy, new StatusRuntimeException(Status.fromCode(Status.Code.UNAVAILABLE).withDescription(error.toString())));
            backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, new GrpcException(error.getMessage()));
            return true;
        } else if (error.hasRegionNotFound()) {
            backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, new GrpcException(error.getMessage()));
            this.regionManager.onRegionStale(recv.getRegion());
            notifyRegionCacheInvalidate(recv.getRegion());
            return false;
        } else if (error.hasStaleCommand()) {
            // this error is reported from raftstore:
            // command outdated, please try later
            logger.warn(String.format("Stale command for region [%s]", recv.getRegion()));
            backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, new GrpcException(error.getMessage()));
            return true;
        } else if (error.hasRaftEntryTooLarge()) {
            logger.warn(String.format("Raft too large for region [%s]", recv.getRegion()));
            throw new StatusRuntimeException(Status.fromCode(Status.Code.UNAVAILABLE).withDescription(error.toString()));
        } else if (error.hasKeyNotInRegion()) {
            // this error is reported from raftstore:
            // key requested is not in current region
            // should not happen here.
            ByteString invalidKey = error.getKeyNotInRegion().getKey();
            logger.error(String.format("Key not in region [%s] for key [%s], this error should not happen here.", recv.getRegion(), KeyUtils.formatBytesUTF8(invalidKey)));
            throw new StatusRuntimeException(Status.UNKNOWN.withDescription(error.toString()));
        }
        logger.warn(String.format("Unknown error %s for region [%s]", error, recv.getRegion()));
        // For other errors, we only drop cache here.
        // Upper level may split this task.
        invalidateRegionStoreCache(recv.getRegion());
        // retry if raft proposal is dropped, it indicates the store is in the middle of transition
        if (error.getMessage().contains("Raft ProposalDropped") || error.getMessage().contains("is missing")) {
            backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, new GrpcException(error.getMessage()));
            return true;
        }
    }
    boolean retry = false;
    if (resp instanceof ScanResponse) {
        List<KvPair> kvPairs = ((ScanResponse) resp).getPairsList();
        List<Lock> locks = new ArrayList<>();
        for (KvPair kvPair : kvPairs) {
            if (kvPair.hasError()) {
                Lock lock = AbstractLockResolverClient.extractLockFromKeyErr(kvPair.getError());
                locks.add(lock);
            }
        }
        if (!locks.isEmpty()) {
            try {
                resolveLocks(backOffer, locks);
                retry = true;
            } catch (KeyException e) {
                logger.warn("Unable to handle KeyExceptions other than LockException", e);
            }
        }
    } else {
        // Key error handling logic
        Kvrpcpb.KeyError keyError = getKeyError.apply(resp);
        if (keyError != null) {
            try {
                Lock lock = AbstractLockResolverClient.extractLockFromKeyErr(keyError);
                resolveLock(backOffer, lock);
                retry = true;
            } catch (KeyException e) {
                logger.warn("Unable to handle KeyExceptions other than LockException", e);
            }
        }
    }
    return retry;
}
Also used : KvPair(org.tikv.kvproto.Kvrpcpb.KvPair) ByteString(com.google.protobuf.ByteString) Kvrpcpb(org.tikv.kvproto.Kvrpcpb) ScanResponse(org.tikv.kvproto.Kvrpcpb.ScanResponse) ArrayList(java.util.ArrayList) BackOffFunction(com.pingcap.tikv.util.BackOffFunction) ByteString(com.google.protobuf.ByteString) Errorpb(org.tikv.kvproto.Errorpb) KeyException(com.pingcap.tikv.exception.KeyException) Lock(com.pingcap.tikv.txn.Lock) TiRegion(com.pingcap.tikv.region.TiRegion) GrpcException(com.pingcap.tikv.exception.GrpcException) StatusRuntimeException(io.grpc.StatusRuntimeException)

Example 3 with ScanResponse

use of org.tikv.kvproto.Kvrpcpb.ScanResponse in project tispark by pingcap.

the class RegionStoreClient method scan.

public List<KvPair> scan(BackOffer backOffer, ByteString startKey, int limit, long version, boolean keyOnly) {
    boolean forWrite = false;
    while (true) {
        Supplier<ScanRequest> request = () -> ScanRequest.newBuilder().setContext(region.getContext(getResolvedLocks(version))).setStartKey(startKey).setVersion(version).setKeyOnly(keyOnly).setLimit(limit).build();
        KVErrorHandler<ScanResponse> handler = new KVErrorHandler<>(regionManager, this, lockResolverClient, resp -> resp.hasRegionError() ? resp.getRegionError() : null, resp -> null, resolveLockResult -> addResolvedLocks(version, resolveLockResult.getResolvedLocks()), version, forWrite);
        ScanResponse resp = callWithRetry(backOffer, TikvGrpc.getKvScanMethod(), request, handler);
        if (isScanSuccess(backOffer, resp)) {
            return doScan(resp);
        }
        // we should refresh region
        region = regionManager.getRegionByKey(startKey);
    }
}
Also used : ScanRequest(org.tikv.kvproto.Kvrpcpb.ScanRequest) RawScanRequest(org.tikv.kvproto.Kvrpcpb.RawScanRequest) ScanResponse(org.tikv.kvproto.Kvrpcpb.ScanResponse) RawScanResponse(org.tikv.kvproto.Kvrpcpb.RawScanResponse) KVErrorHandler(com.pingcap.tikv.operation.KVErrorHandler)

Aggregations

ScanResponse (org.tikv.kvproto.Kvrpcpb.ScanResponse)3 RawScanRequest (org.tikv.kvproto.Kvrpcpb.RawScanRequest)2 RawScanResponse (org.tikv.kvproto.Kvrpcpb.RawScanResponse)2 ScanRequest (org.tikv.kvproto.Kvrpcpb.ScanRequest)2 ByteString (com.google.protobuf.ByteString)1 GrpcException (com.pingcap.tikv.exception.GrpcException)1 KeyException (com.pingcap.tikv.exception.KeyException)1 KVErrorHandler (com.pingcap.tikv.operation.KVErrorHandler)1 TiRegion (com.pingcap.tikv.region.TiRegion)1 Lock (com.pingcap.tikv.txn.Lock)1 BackOffFunction (com.pingcap.tikv.util.BackOffFunction)1 StatusRuntimeException (io.grpc.StatusRuntimeException)1 ArrayList (java.util.ArrayList)1 KVErrorHandler (org.tikv.common.operation.KVErrorHandler)1 Errorpb (org.tikv.kvproto.Errorpb)1 Kvrpcpb (org.tikv.kvproto.Kvrpcpb)1 KvPair (org.tikv.kvproto.Kvrpcpb.KvPair)1