fix: check kill signal against 0 (#1102)

* fix: check kill signal against 0, so that all kill signals will not be ignored.

Signed-off-by: ekexium <eke@fastmail.com>

* refactor: extract method checkKilled()

Signed-off-by: ekexium <eke@fastmail.com>

---------

Signed-off-by: ekexium <eke@fastmail.com>
Co-authored-by: cfzjywxk <lsswxrxr@163.com>
This commit is contained in:
ekexium 2024-01-10 15:48:27 +08:00 committed by GitHub
parent c8c29046e1
commit 057c479dd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 13 deletions

View File

@ -217,10 +217,9 @@ func (b *Backoffer) BackoffWithCfgAndMaxSleep(cfg *Config, maxSleepMs int, err e
atomic.AddInt64(&detail.BackoffCount, 1) atomic.AddInt64(&detail.BackoffCount, 1)
} }
if b.vars != nil && b.vars.Killed != nil { err2 := b.CheckKilled()
if atomic.LoadUint32(b.vars.Killed) == 1 { if err2 != nil {
return errors.WithStack(tikverr.ErrQueryInterrupted) return err2
}
} }
var startTs interface{} var startTs interface{}
@ -382,3 +381,17 @@ func (b *Backoffer) longestSleepCfg() (*Config, int) {
} }
return nil, 0 return nil, 0
} }
func (b *Backoffer) CheckKilled() error {
if b.vars != nil && b.vars.Killed != nil {
killed := atomic.LoadUint32(b.vars.Killed)
if killed != 0 {
logutil.BgLogger().Info(
"backoff stops because a killed signal is received",
zap.Uint32("signal", killed),
)
return errors.WithStack(tikverr.ErrQueryInterrupted)
}
}
return nil
}

View File

@ -2502,3 +2502,13 @@ func (s *testCommitterSuite) TestExtractKeyExistsErr() {
s.True(txn.GetMemBuffer().TryLock()) s.True(txn.GetMemBuffer().TryLock())
txn.GetMemBuffer().Unlock() txn.GetMemBuffer().Unlock()
} }
func (s *testCommitterSuite) TestKillSignal() {
txn := s.begin()
err := txn.Set([]byte("key"), []byte("value"))
s.Nil(err)
var killed uint32 = 2
txn.SetVars(kv.NewVariables(&killed))
err = txn.Commit(context.Background())
s.ErrorContains(err, "query interrupted")
}

View File

@ -217,23 +217,38 @@ func (b *Backoffer) BackoffWithCfgAndMaxSleep(cfg *Config, maxSleepMs int, err e
atomic.AddInt64(&detail.BackoffCount, 1) atomic.AddInt64(&detail.BackoffCount, 1)
} }
if b.vars != nil && b.vars.Killed != nil { err2 := b.checkKilled()
if atomic.LoadUint32(b.vars.Killed) == 1 { if err2 != nil {
return errors.WithStack(tikverr.ErrQueryInterrupted) return err2
}
} }
var startTs interface{} var startTs interface{}
if ts := b.ctx.Value(TxnStartKey); ts != nil { if ts := b.ctx.Value(TxnStartKey); ts != nil {
startTs = ts startTs = ts
} }
logutil.Logger(b.ctx).Debug("retry later", logutil.Logger(b.ctx).Debug(
"retry later",
zap.Error(err), zap.Error(err),
zap.Int("totalSleep", b.totalSleep), zap.Int("totalSleep", b.totalSleep),
zap.Int("excludedSleep", b.excludedSleep), zap.Int("excludedSleep", b.excludedSleep),
zap.Int("maxSleep", b.maxSleep), zap.Int("maxSleep", b.maxSleep),
zap.Stringer("type", cfg), zap.Stringer("type", cfg),
zap.Reflect("txnStartTS", startTs)) zap.Reflect("txnStartTS", startTs),
)
return nil
}
func (b *Backoffer) checkKilled() error {
if b.vars != nil && b.vars.Killed != nil {
killed := atomic.LoadUint32(b.vars.Killed)
if killed != 0 {
logutil.BgLogger().Info(
"backoff stops because a killed signal is received",
zap.Uint32("signal", killed),
)
return errors.WithStack(tikverr.ErrQueryInterrupted)
}
}
return nil return nil
} }

View File

@ -1477,9 +1477,8 @@ func (s *RegionRequestSender) SendReqCtx(
} }
// recheck whether the session/query is killed during the Next() // recheck whether the session/query is killed during the Next()
boVars := bo.GetVars() if err2 := bo.CheckKilled(); err2 != nil {
if boVars != nil && boVars.Killed != nil && atomic.LoadUint32(boVars.Killed) == 1 { return nil, nil, retryTimes, err2
return nil, nil, retryTimes, errors.WithStack(tikverr.ErrQueryInterrupted)
} }
if val, err := util.EvalFailpoint("mockRetrySendReqToRegion"); err == nil { if val, err := util.EvalFailpoint("mockRetrySendReqToRegion"); err == nil {
if val.(bool) { if val.(bool) {

View File

@ -44,6 +44,10 @@ type Variables struct {
// Pointer to SessionVars.Killed // Pointer to SessionVars.Killed
// Killed is a flag to indicate that this query is killed. // Killed is a flag to indicate that this query is killed.
// This is an enum value rather than a boolean. See sqlkiller.go
// in TiDB for its definition.
// When its value is 0, it's not killed
// When its value is not 0, it's killed, the value indicates concrete reason.
Killed *uint32 Killed *uint32
} }