mirror of https://github.com/tikv/client-go.git
add retry limit for excluded backoff type to avoid infinite retry (#1002)
* add retry limit for excluded backoff type to avoid infinite retry Signed-off-by: cfzjywxk <lsswxrxr@163.com> * change log Signed-off-by: cfzjywxk <lsswxrxr@163.com> --------- Signed-off-by: cfzjywxk <lsswxrxr@163.com>
This commit is contained in:
parent
2eaf68e0cd
commit
888cbb283e
|
|
@ -143,7 +143,13 @@ func (b *Backoffer) BackoffWithCfgAndMaxSleep(cfg *Config, maxSleepMs int, err e
|
|||
if b.noop {
|
||||
return err
|
||||
}
|
||||
if b.maxSleep > 0 && (b.totalSleep-b.excludedSleep) >= b.maxSleep {
|
||||
maxBackoffTimeExceeded := (b.totalSleep - b.excludedSleep) >= b.maxSleep
|
||||
maxExcludedTimeExceeded := false
|
||||
if maxLimit, ok := isSleepExcluded[cfg.name]; ok {
|
||||
maxExcludedTimeExceeded = b.excludedSleep >= maxLimit && b.excludedSleep >= b.maxSleep
|
||||
}
|
||||
maxTimeExceeded := maxBackoffTimeExceeded || maxExcludedTimeExceeded
|
||||
if b.maxSleep > 0 && maxTimeExceeded {
|
||||
longestSleepCfg, longestSleepTime := b.longestSleepCfg()
|
||||
errMsg := fmt.Sprintf("%s backoffer.maxSleep %dms is exceeded, errors:", cfg.String(), b.maxSleep)
|
||||
for i, err := range b.errors {
|
||||
|
|
@ -163,7 +169,8 @@ func (b *Backoffer) BackoffWithCfgAndMaxSleep(cfg *Config, maxSleepMs int, err e
|
|||
backoffDetail.WriteString(":")
|
||||
backoffDetail.WriteString(strconv.Itoa(times))
|
||||
}
|
||||
errMsg += fmt.Sprintf("\ntotal-backoff-times: %v, backoff-detail: %v", totalTimes, backoffDetail.String())
|
||||
errMsg += fmt.Sprintf("\ntotal-backoff-times: %v, backoff-detail: %v, maxBackoffTimeExceeded: %v, maxExcludedTimeExceeded: %v",
|
||||
totalTimes, backoffDetail.String(), maxBackoffTimeExceeded, maxExcludedTimeExceeded)
|
||||
returnedErr := err
|
||||
if longestSleepCfg != nil {
|
||||
errMsg += fmt.Sprintf("\nlongest sleep type: %s, time: %dms", longestSleepCfg.String(), longestSleepTime)
|
||||
|
|
|
|||
|
|
@ -98,3 +98,15 @@ func TestBackoffDeepCopy(t *testing.T) {
|
|||
assert.ErrorIs(t, err, BoMaxDataNotReady.err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackoffWithMaxExcludedExceed(t *testing.T) {
|
||||
setBackoffExcluded(BoTiKVServerBusy.name, 1)
|
||||
b := NewBackofferWithVars(context.TODO(), 1, nil)
|
||||
err := b.Backoff(BoTiKVServerBusy, errors.New("server is busy"))
|
||||
assert.Nil(t, err)
|
||||
|
||||
// As the total excluded sleep is greater than the max limited value, error should be returned.
|
||||
err = b.Backoff(BoTiKVServerBusy, errors.New("server is busy"))
|
||||
assert.NotNil(t, err)
|
||||
assert.Greater(t, b.excludedSleep, b.maxSleep)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,11 +130,18 @@ var (
|
|||
BoTxnLockFast = NewConfig(txnLockFastName, &metrics.BackoffHistogramLockFast, NewBackoffFnCfg(2, 3000, EqualJitter), tikverr.ErrResolveLockTimeout)
|
||||
)
|
||||
|
||||
var isSleepExcluded = map[string]struct{}{
|
||||
BoTiKVServerBusy.name: {},
|
||||
var isSleepExcluded = map[string]int{
|
||||
BoTiKVServerBusy.name: 600000, // The max excluded limit is 10min.
|
||||
// add BoTiFlashServerBusy if appropriate
|
||||
}
|
||||
|
||||
// setBackoffExcluded is used for test only.
|
||||
func setBackoffExcluded(name string, maxVal int) {
|
||||
if _, ok := isSleepExcluded[name]; ok {
|
||||
isSleepExcluded[name] = maxVal
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// NoJitter makes the backoff sequence strict exponential.
|
||||
NoJitter = 1 + iota
|
||||
|
|
|
|||
Loading…
Reference in New Issue