diff --git a/internal/client/client_interceptor.go b/internal/client/client_interceptor.go index 9e55a1038..e490d18ad 100644 --- a/internal/client/client_interceptor.go +++ b/internal/client/client_interceptor.go @@ -107,6 +107,12 @@ func buildResourceControlInterceptor( // Build the interceptor. interceptFn := func(next interceptor.RPCInterceptorFunc) interceptor.RPCInterceptorFunc { return func(target string, req *tikvrpc.Request) (*tikvrpc.Response, error) { + // bypass some internal requests and it's may influence user experience. For example, the + // request of `alter user password`, totally bypasses the resource control. it's not cost + // many resources, but it's may influence the user experience. + if reqInfo.Bypass() { + return next(target, req) + } consumption, penalty, err := resourceControlInterceptor.OnRequestWait(ctx, resourceGroupName, reqInfo) if err != nil { return nil, err diff --git a/internal/resourcecontrol/resource_control.go b/internal/resourcecontrol/resource_control.go index fb55d25fd..9aecac140 100644 --- a/internal/resourcecontrol/resource_control.go +++ b/internal/resourcecontrol/resource_control.go @@ -16,12 +16,14 @@ package resourcecontrol import ( "reflect" + "strings" "time" "github.com/pingcap/kvproto/pkg/coprocessor" "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/tikv/client-go/v2/internal/logutil" "github.com/tikv/client-go/v2/tikvrpc" + "github.com/tikv/client-go/v2/util" "go.uber.org/zap" ) @@ -34,6 +36,9 @@ type RequestInfo struct { writeBytes int64 storeID uint64 replicaNumber int64 + // bypass indicates whether the request should be bypassed. + // some internal request should be bypassed, such as Privilege request. + bypass bool } // MakeRequestInfo extracts the relevant information from a BatchRequest. @@ -43,6 +48,8 @@ func MakeRequestInfo(req *tikvrpc.Request) *RequestInfo { } var writeBytes int64 + var requestSource string + var bypass bool switch r := req.Req.(type) { case *kvrpcpb.PrewriteRequest: for _, m := range r.Mutations { @@ -52,12 +59,19 @@ func MakeRequestInfo(req *tikvrpc.Request) *RequestInfo { for _, l := range r.Secondaries { writeBytes += int64(len(l)) } + requestSource = r.GetContext().GetRequestSource() case *kvrpcpb.CommitRequest: for _, k := range r.Keys { writeBytes += int64(len(k)) } + requestSource = r.GetContext().GetRequestSource() } - return &RequestInfo{writeBytes: writeBytes, storeID: req.Context.Peer.StoreId, replicaNumber: req.ReplicaNumber} + if len(requestSource) > 0 { + if strings.Contains(requestSource, util.InternalRequest+"_"+util.InternalTxnOthers) { + bypass = true + } + } + return &RequestInfo{writeBytes: writeBytes, storeID: req.Context.Peer.StoreId, replicaNumber: req.ReplicaNumber, bypass: bypass} } // IsWrite returns whether the request is a write request. @@ -75,6 +89,11 @@ func (req *RequestInfo) ReplicaNumber() int64 { return req.replicaNumber } +// Bypass returns whether the request should be bypassed. +func (req *RequestInfo) Bypass() bool { + return req.bypass +} + func (req *RequestInfo) StoreID() uint64 { return req.storeID }