Skip to content

Commit 3601f21

Browse files
lysusre-bot
authored andcommitted
tikv: fix wasted sleep and return error in last backoff (pingcap#11788) (pingcap#11806)
1 parent 571bfed commit 3601f21

File tree

2 files changed

+21
-14
lines changed

2 files changed

+21
-14
lines changed

store/tikv/backoff.go

+20-13
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ type Backoffer struct {
239239
errors []error
240240
types []backoffType
241241
vars *kv.Variables
242+
noop bool
242243
}
243244

244245
// txnStartKey is a key for transaction start_ts info in context.Context.
@@ -253,6 +254,11 @@ func NewBackoffer(ctx context.Context, maxSleep int) *Backoffer {
253254
}
254255
}
255256

257+
// NewNoopBackoff create a Backoffer do nothing just return error directly
258+
func NewNoopBackoff(ctx context.Context) *Backoffer {
259+
return &Backoffer{ctx: ctx, noop: true}
260+
}
261+
256262
// WithVars sets the kv.Variables to the Backoffer and return it.
257263
func (b *Backoffer) WithVars(vars *kv.Variables) *Backoffer {
258264
if vars != nil {
@@ -284,6 +290,20 @@ func (b *Backoffer) BackoffWithMaxSleep(typ backoffType, maxSleepMs int, err err
284290
default:
285291
}
286292

293+
b.types = append(b.types, typ)
294+
if b.noop || (b.maxSleep > 0 && b.totalSleep >= b.maxSleep) {
295+
errMsg := fmt.Sprintf("%s backoffer.maxSleep %dms is exceeded, errors:", typ.String(), b.maxSleep)
296+
for i, err := range b.errors {
297+
// Print only last 3 errors for non-DEBUG log levels.
298+
if log.GetLevel() == zapcore.DebugLevel || i >= len(b.errors)-3 {
299+
errMsg += "\n" + err.Error()
300+
}
301+
}
302+
logutil.Logger(context.Background()).Warn(errMsg)
303+
// Use the first backoff type to generate a MySQL error.
304+
return b.types[0].TError()
305+
}
306+
287307
backoffCounter, backoffDuration := typ.metric()
288308
backoffCounter.Inc()
289309
// Lazy initialize.
@@ -299,7 +319,6 @@ func (b *Backoffer) BackoffWithMaxSleep(typ backoffType, maxSleepMs int, err err
299319
realSleep := f(b.ctx, maxSleepMs)
300320
backoffDuration.Observe(float64(realSleep) / 1000)
301321
b.totalSleep += realSleep
302-
b.types = append(b.types, typ)
303322

304323
var startTs interface{}
305324
if ts := b.ctx.Value(txnStartKey); ts != nil {
@@ -313,18 +332,6 @@ func (b *Backoffer) BackoffWithMaxSleep(typ backoffType, maxSleepMs int, err err
313332
zap.Reflect("txnStartTS", startTs))
314333

315334
b.errors = append(b.errors, errors.Errorf("%s at %s", err.Error(), time.Now().Format(time.RFC3339Nano)))
316-
if b.maxSleep > 0 && b.totalSleep >= b.maxSleep {
317-
errMsg := fmt.Sprintf("%s backoffer.maxSleep %dms is exceeded, errors:", typ.String(), b.maxSleep)
318-
for i, err := range b.errors {
319-
// Print only last 3 errors for non-DEBUG log levels.
320-
if log.GetLevel() == zapcore.DebugLevel || i >= len(b.errors)-3 {
321-
errMsg += "\n" + err.Error()
322-
}
323-
}
324-
logutil.Logger(context.Background()).Warn(errMsg)
325-
// Use the first backoff type to generate a MySQL error.
326-
return b.types[0].TError()
327-
}
328335
return nil
329336
}
330337

store/tikv/region_request_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (s *testRegionRequestSuite) SetUpTest(c *C) {
4949
s.store, s.peer, s.region = mocktikv.BootstrapWithSingleStore(s.cluster)
5050
pdCli := &codecPDClient{mocktikv.NewPDClient(s.cluster)}
5151
s.cache = NewRegionCache(pdCli)
52-
s.bo = NewBackoffer(context.Background(), 1)
52+
s.bo = NewNoopBackoff(context.Background())
5353
s.mvccStore = mocktikv.MustNewMVCCStore()
5454
client := mocktikv.NewRPCClient(s.cluster, s.mvccStore)
5555
s.regionRequestSender = NewRegionRequestSender(s.cache, client)

0 commit comments

Comments
 (0)