Skip to content

Commit 94b16c1

Browse files
coocoodzimulala
authored andcommitted
session: add a global/session variable 'tidb_disable_txn_auto_retry' (#6877)
1 parent 06a0bf5 commit 94b16c1

File tree

6 files changed

+61
-3
lines changed

6 files changed

+61
-3
lines changed

session/session.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,16 @@ func (s *session) doCommitWithRetry(ctx context.Context) error {
333333
}
334334
err := s.doCommit(ctx)
335335
if err != nil {
336+
commitRetryLimit := globalCommitRetryLimit
337+
if s.sessionVars.DisableTxnAutoRetry && !s.sessionVars.InRestrictedSQL {
338+
// Do not retry non-autocommit transactions.
339+
// For autocommit single statement transactions, the history count is always 1.
340+
// For explicit transactions, the statement count is more than 1.
341+
history := GetHistory(s)
342+
if history.Count() > 1 {
343+
commitRetryLimit = 0
344+
}
345+
}
336346
// Don't retry in BatchInsert mode. As a counter-example, insert into t1 select * from t2,
337347
// BatchInsert already commit the first batch 1000 rows, then it commit 1000-2000 and retry the statement,
338348
// Finally t1 will have more data than t2, with no errors return to user!
@@ -1269,7 +1279,8 @@ const loadCommonGlobalVarsSQL = "select HIGH_PRIORITY * from mysql.global_variab
12691279
variable.TiDBIndexLookupJoinConcurrency + quoteCommaQuote +
12701280
variable.TiDBIndexSerialScanConcurrency + quoteCommaQuote +
12711281
variable.TiDBHashJoinConcurrency + quoteCommaQuote +
1272-
variable.TiDBDistSQLScanConcurrency + "')"
1282+
variable.TiDBDistSQLScanConcurrency + quoteCommaQuote +
1283+
variable.TiDBDisableTxnAutoRetry + "')"
12731284

12741285
// loadCommonGlobalVariablesIfNeeded loads and applies commonly used global variables for the session.
12751286
func (s *session) loadCommonGlobalVariablesIfNeeded() error {

session/session_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,3 +2008,40 @@ func (s *testSessionSuite) TestDBUserNameLength(c *C) {
20082008
tk.MustExec(`grant all privileges on test.* to 'abcddfjakldfjaldddds'@'%' identified by ''`)
20092009
tk.MustExec(`grant all privileges on test.t to 'abcddfjakldfjaldddds'@'%' identified by ''`)
20102010
}
2011+
2012+
func (s *testSessionSuite) TestDisableTxnAutoRetry(c *C) {
2013+
tk1 := testkit.NewTestKitWithInit(c, s.store)
2014+
tk2 := testkit.NewTestKitWithInit(c, s.store)
2015+
tk1.MustExec("create table no_retry (id int)")
2016+
tk1.MustExec("insert into no_retry values (1)")
2017+
tk1.MustExec("set @@tidb_disable_txn_auto_retry = 1")
2018+
2019+
tk1.MustExec("begin")
2020+
tk1.MustExec("update no_retry set id = 2")
2021+
2022+
tk2.MustExec("begin")
2023+
tk2.MustExec("update no_retry set id = 3")
2024+
tk2.MustExec("commit")
2025+
2026+
// No auto retry because tidb_disable_txn_auto_retry is set to 1.
2027+
_, err := tk1.Se.Execute(context.Background(), "commit")
2028+
c.Assert(err, NotNil)
2029+
2030+
// session 1 starts a transaction early.
2031+
// execute a select statement to clear retry history.
2032+
tk1.MustExec("select 1")
2033+
tk1.Se.NewTxn()
2034+
// session 2 update the value.
2035+
tk2.MustExec("update no_retry set id = 4")
2036+
// Autocommit update will retry, so it would not fail.
2037+
tk1.MustExec("update no_retry set id = 5")
2038+
2039+
// RestrictedSQL should retry.
2040+
tk1.Se.GetSessionVars().InRestrictedSQL = true
2041+
tk1.MustExec("begin")
2042+
2043+
tk2.MustExec("update no_retry set id = 6")
2044+
2045+
tk1.MustExec("update no_retry set id = 7")
2046+
tk1.MustExec("commit")
2047+
}

session/tidb.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ var (
108108
statsLease = 3 * time.Second
109109

110110
// The maximum number of retries to recover from retryable errors.
111-
commitRetryLimit uint = 10
111+
globalCommitRetryLimit uint = 10
112112
)
113113

114114
// SetSchemaLease changes the default schema lease time for DDL.
@@ -129,7 +129,7 @@ func SetStatsLease(lease time.Duration) {
129129
// reinstated by retry, including network interruption, transaction conflicts, and
130130
// so on.
131131
func SetCommitRetryLimit(limit uint) {
132-
commitRetryLimit = limit
132+
globalCommitRetryLimit = limit
133133
}
134134

135135
// Parse parses a query string to raw ast.StmtNode.

sessionctx/variable/session.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ type SessionVars struct {
327327
EnableStreaming bool
328328

329329
writeStmtBufs WriteStmtBufs
330+
331+
DisableTxnAutoRetry bool
330332
}
331333

332334
// NewSessionVars creates a session vars object.
@@ -362,6 +364,7 @@ func NewSessionVars() *SessionVars {
362364
MemQuotaIndexLookupJoin: DefTiDBMemQuotaIndexLookupJoin,
363365
MemQuotaNestedLoopApply: DefTiDBMemQuotaNestedLoopApply,
364366
OptimizerSelectivityLevel: DefTiDBOptimizerSelectivityLevel,
367+
DisableTxnAutoRetry: DefTiDBDisableTxnAutoRetry,
365368
}
366369
var enableStreaming string
367370
if config.GetGlobalConfig().EnableStreaming {
@@ -562,6 +565,8 @@ func (s *SessionVars) SetSystemVar(name string, val string) error {
562565
s.EnableStreaming = TiDBOptOn(val)
563566
case TiDBOptimizerSelectivityLevel:
564567
s.OptimizerSelectivityLevel = tidbOptPositiveInt32(val, DefTiDBOptimizerSelectivityLevel)
568+
case TiDBDisableTxnAutoRetry:
569+
s.DisableTxnAutoRetry = TiDBOptOn(val)
565570
}
566571
s.systems[name] = val
567572
return nil

sessionctx/variable/sysvar.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ var defaultSysVars = []*SysVar{
637637
{ScopeSession, TxnIsolationOneShot, ""},
638638
{ScopeGlobal | ScopeSession, TiDBHashJoinConcurrency, strconv.Itoa(DefTiDBHashJoinConcurrency)},
639639
{ScopeSession, TiDBOptimizerSelectivityLevel, strconv.Itoa(DefTiDBOptimizerSelectivityLevel)},
640+
{ScopeGlobal | ScopeSession, TiDBDisableTxnAutoRetry, boolToIntStr(DefTiDBDisableTxnAutoRetry)},
640641
/* The following variable is defined as session scope but is actually server scope. */
641642
{ScopeSession, TiDBGeneralLog, strconv.Itoa(DefTiDBGeneralLog)},
642643
{ScopeSession, TiDBConfig, ""},

sessionctx/variable/tidb_vars.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ const (
150150
// tidb_hash_join_concurrency is used for hash join executor.
151151
// The hash join outer executor starts multiple concurrent join workers to probe the hash table.
152152
TiDBHashJoinConcurrency = "tidb_hash_join_concurrency"
153+
154+
// tidb_disable_txn_auto_retry disables transaction auto retry.
155+
TiDBDisableTxnAutoRetry = "tidb_disable_txn_auto_retry"
153156
)
154157

155158
// Default TiDB system variable values.
@@ -181,6 +184,7 @@ const (
181184
DefTiDBGeneralLog = 0
182185
DefTiDBHashJoinConcurrency = 5
183186
DefTiDBOptimizerSelectivityLevel = 0
187+
DefTiDBDisableTxnAutoRetry = false
184188
)
185189

186190
// Process global variables.

0 commit comments

Comments
 (0)