From 98031ca80021a4f8871828e18c7f31ed9ce8489f Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Thu, 5 May 2022 11:43:16 -0700 Subject: [PATCH 1/9] chnages done --- config/config.go | 9 +-------- config/config.toml.example | 2 +- config/config_test.go | 23 ----------------------- executor/seqtest/seq_executor_test.go | 6 +++--- kv/kv.go | 5 ++++- server/server_test.go | 6 +++--- session/session.go | 2 +- sessionctx/variable/sysvar.go | 6 ++++++ sessionctx/variable/tidb_vars.go | 4 ++++ store/driver/txn/txn_driver.go | 2 +- tidb-server/main.go | 1 - 11 files changed, 24 insertions(+), 42 deletions(-) diff --git a/config/config.go b/config/config.go index 9bd27332c470e..d2737e82ddfd9 100644 --- a/config/config.go +++ b/config/config.go @@ -44,8 +44,6 @@ const ( MaxLogFileSize = 4096 // MB // DefTxnEntrySizeLimit is the default value of TxnEntrySizeLimit. DefTxnEntrySizeLimit = 6 * 1024 * 1024 - // DefTxnTotalSizeLimit is the default value of TxnTxnTotalSizeLimit. - DefTxnTotalSizeLimit = 100 * 1024 * 1024 // DefMaxIndexLength is the maximum index length(in bytes). This value is consistent with MySQL. DefMaxIndexLength = 3072 // DefMaxOfMaxIndexLength is the maximum index length(in bytes) for TiDB v3.0.7 and previous version. @@ -588,7 +586,6 @@ type Performance struct { ForcePriority string `toml:"force-priority" json:"force-priority"` BindInfoLease string `toml:"bind-info-lease" json:"bind-info-lease"` TxnEntrySizeLimit uint64 `toml:"txn-entry-size-limit" json:"txn-entry-size-limit"` - TxnTotalSizeLimit uint64 `toml:"txn-total-size-limit" json:"txn-total-size-limit"` TCPKeepAlive bool `toml:"tcp-keep-alive" json:"tcp-keep-alive"` TCPNoDelay bool `toml:"tcp-no-delay" json:"tcp-no-delay"` CrossJoin bool `toml:"cross-join" json:"cross-join"` @@ -816,7 +813,6 @@ var defaultConf = Config{ ForcePriority: "NO_PRIORITY", BindInfoLease: "3s", TxnEntrySizeLimit: DefTxnEntrySizeLimit, - TxnTotalSizeLimit: DefTxnTotalSizeLimit, DistinctAggPushDown: false, ProjectionPushDown: false, CommitterConcurrency: defTiKVCfg.CommitterConcurrency, @@ -930,6 +926,7 @@ var deprecatedConfig = map[string]struct{}{ "stmt-summary.history-size": {}, "mem-quota-query": {}, "query-log-max-len": {}, + "txn-total-size-limit": {}, } func isAllDeprecatedConfigItems(items []string) bool { @@ -1099,10 +1096,6 @@ func (c *Config) Valid() error { return err } - if c.Performance.TxnTotalSizeLimit > 1<<40 { - return fmt.Errorf("txn-total-size-limit should be less than %d", 1<<40) - } - if c.Instance.MemoryUsageAlarmRatio > 1 || c.Instance.MemoryUsageAlarmRatio < 0 { return fmt.Errorf("tidb_memory_usage_alarm_ratio in [Instance] must be greater than or equal to 0 and less than or equal to 1") } diff --git a/config/config.toml.example b/config/config.toml.example index 486d011467787..f0d6267fd079a 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -400,7 +400,7 @@ capacity-mb = 1000.0 [binlog] # enable to write binlog. # NOTE: If binlog is enabled with Kafka (e.g. arbiter cluster), -# txn-total-size-limit should be less than 1073741824(1G) because this is the maximum size that can be handled by Kafka. +# tidb_txn_total_size_limit should be less than 1073741824(1G) because this is the maximum size that can be handled by Kafka. enable = false # WriteTimeout specifies how long it will wait for writing binlog to pump. diff --git a/config/config_test.go b/config/config_test.go index 175466b0e6136..6d425b41e8163 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -173,7 +173,6 @@ func TestConfig(t *testing.T) { conf.Binlog.Enable = true conf.Binlog.IgnoreError = true conf.Binlog.Strategy = "hash" - conf.Performance.TxnTotalSizeLimit = 1000 conf.TiKVClient.CommitTimeout = "10s" conf.TiKVClient.RegionCacheTTL = 600 conf.Instance.EnableSlowLog.Store(logutil.DefaultTiDBEnableSlowLog) @@ -221,8 +220,6 @@ deprecate-integer-display-length = true enable-enum-length-limit = false stores-refresh-interval = 30 enable-forwarding = true -[performance] -txn-total-size-limit=2000 tcp-no-delay = false [tikv-client] commit-timeout="41s" @@ -268,7 +265,6 @@ grpc-max-send-msg-size = 40960 require.Equal(t, "hash", conf.Binlog.Strategy) // Test that the value will be overwritten by the config file. - require.Equal(t, uint64(2000), conf.Performance.TxnTotalSizeLimit) require.True(t, conf.AlterPrimaryKey) require.False(t, conf.Performance.TCPNoDelay) @@ -492,25 +488,6 @@ func TestOOMActionValid(t *testing.T) { } } -func TestTxnTotalSizeLimitValid(t *testing.T) { - conf := NewConfig() - tests := []struct { - limit uint64 - valid bool - }{ - {4 << 10, true}, - {10 << 30, true}, - {10<<30 + 1, true}, - {1 << 40, true}, - {1<<40 + 1, false}, - } - - for _, tt := range tests { - conf.Performance.TxnTotalSizeLimit = tt.limit - require.Equal(t, tt.valid, conf.Valid() == nil) - } -} - func TestPreparePlanCacheValid(t *testing.T) { conf := NewConfig() tests := map[PreparedPlanCache]bool{ diff --git a/executor/seqtest/seq_executor_test.go b/executor/seqtest/seq_executor_test.go index 8db34810f99ee..1f1096b879b09 100644 --- a/executor/seqtest/seq_executor_test.go +++ b/executor/seqtest/seq_executor_test.go @@ -936,12 +936,12 @@ func TestBatchInsertDelete(t *testing.T) { store, clean := testkit.CreateMockStore(t) defer clean() - originLimit := atomic.LoadUint64(&kv.TxnTotalSizeLimit) + originLimit := kv.TxnTotalSizeLimit.Load() defer func() { - atomic.StoreUint64(&kv.TxnTotalSizeLimit, originLimit) + kv.TxnTotalSizeLimit.Store(originLimit) }() // Set the limitation to a small value, make it easier to reach the limitation. - atomic.StoreUint64(&kv.TxnTotalSizeLimit, 5500) + kv.TxnTotalSizeLimit.Store(5500) tk := testkit.NewTestKit(t, store) tk.MustExec("use test") diff --git a/kv/kv.go b/kv/kv.go index 58aecb5195891..fc8613944de7a 100644 --- a/kv/kv.go +++ b/kv/kv.go @@ -32,6 +32,7 @@ import ( "github.com/tikv/client-go/v2/tikv" "github.com/tikv/client-go/v2/tikvrpc" pd "github.com/tikv/pd/client" + "go.uber.org/atomic" ) // UnCommitIndexKVFlag uses to indicate the index key/value is no need to commit. @@ -48,7 +49,9 @@ var ( // TxnEntrySizeLimit is limit of single entry size (len(key) + len(value)). TxnEntrySizeLimit uint64 = config.DefTxnEntrySizeLimit // TxnTotalSizeLimit is limit of the sum of all entry size. - TxnTotalSizeLimit uint64 = config.DefTxnTotalSizeLimit + //TxnTotalSizeLimit uint64 = //DefTiDBTxnTotalSizeLimit + + TxnTotalSizeLimit = atomic.NewUint64(100 * 1024 * 1024) ) // Getter is the interface for the Get method. diff --git a/server/server_test.go b/server/server_test.go index afd53f547d7df..87c70fac4c725 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -869,10 +869,10 @@ func (cli *testServerClient) runTestLoadData(t *testing.T, server *Server) { "xxx row5_col1 - row5_col3") require.NoError(t, err) - originalTxnTotalSizeLimit := kv.TxnTotalSizeLimit + originalTxnTotalSizeLimit := kv.TxnTotalSizeLimit.Load() // If the MemBuffer can't be committed once in each batch, it will return an error like "transaction is too large". - kv.TxnTotalSizeLimit = 10240 - defer func() { kv.TxnTotalSizeLimit = originalTxnTotalSizeLimit }() + kv.TxnTotalSizeLimit.Store(10240) + defer kv.TxnTotalSizeLimit.Store(originalTxnTotalSizeLimit) // support ClientLocalFiles capability cli.runTestsOnNewDB(t, func(config *mysql.Config) { diff --git a/session/session.go b/session/session.go index 5d584d9257f4a..b4c58166c9fd8 100644 --- a/session/session.go +++ b/session/session.go @@ -873,7 +873,7 @@ func (s *session) doCommitWithRetry(ctx context.Context) error { zap.String("txn", s.txn.GoString())) // Transactions will retry 2 ~ commitRetryLimit times. // We make larger transactions retry less times to prevent cluster resource outage. - txnSizeRate := float64(txnSize) / float64(kv.TxnTotalSizeLimit) + txnSizeRate := float64(txnSize) / float64(kv.TxnTotalSizeLimit.Load()) maxRetryCount := commitRetryLimit - int64(float64(commitRetryLimit-1)*txnSizeRate) err = s.retry(ctx, uint(maxRetryCount)) } else if !errIsNoisy(err) { diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 851161e359acb..d3f48687f94c8 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -410,6 +410,12 @@ var defaultSysVars = []*SysVar{ }}, /* The system variables below have GLOBAL scope */ + {Scope: ScopeGlobal, Name: TiDBTxnTotalSizeLimit, Value: strconv.FormatInt(DefTiDBTxnTotalSizeLimit, 10), Type: TypeInt, MaxValue: 1099511627776, GetGlobal: func(sv *SessionVars) (string, error) { + return strconv.FormatUint(kv.TxnTotalSizeLimit.Load(), 10), nil + }, SetGlobal: func(s *SessionVars, val string) error { + kv.TxnTotalSizeLimit.Store(uint64(TidbOptInt64(val, DefTiDBTxnTotalSizeLimit))) + return nil + }}, {Scope: ScopeGlobal, Name: MaxPreparedStmtCount, Value: strconv.FormatInt(DefMaxPreparedStmtCount, 10), Type: TypeInt, MinValue: -1, MaxValue: 1048576}, {Scope: ScopeGlobal, Name: InitConnect, Value: ""}, /* TiDB specific variables */ diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index 795904c3d52c1..a39b05913d980 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -638,6 +638,8 @@ const ( // TiDB vars that have only global scope const ( + // TiDBTxnTotalSizeLimit is the size limit of a single transaction + TiDBTxnTotalSizeLimit = "tidb_txn_total_size_limit" // TiDBGCEnable turns garbage collection on or OFF TiDBGCEnable = "tidb_gc_enable" // TiDBGCRunInterval sets the interval that GC runs @@ -841,6 +843,7 @@ const ( DefMaxAllowedPacket uint64 = 67108864 DefTiDBMemQuotaQuery = 1073741824 // 1GB DefTiDBQueryLogMaxLen = 4096 + DefTiDBTxnTotalSizeLimit = 100 * 1024 * 1024 ) // Process global variables. @@ -877,4 +880,5 @@ var ( StatsLoadPseudoTimeout = atomic.NewBool(DefTiDBStatsLoadPseudoTimeout) MemQuotaBindingCache = atomic.NewInt64(DefTiDBMemQuotaBindingCache) GCMaxWaitTime = atomic.NewInt64(DefTiDBGCMaxWaitTime) + TxnTotalSizeLimit uint64 = DefTiDBTxnTotalSizeLimit ) diff --git a/store/driver/txn/txn_driver.go b/store/driver/txn/txn_driver.go index 196db69f6e419..d658508b7744f 100644 --- a/store/driver/txn/txn_driver.go +++ b/store/driver/txn/txn_driver.go @@ -49,7 +49,7 @@ func NewTiKVTxn(txn *tikv.KVTxn) kv.Transaction { txn.SetKVFilter(TiDBKVFilter{}) entryLimit := atomic.LoadUint64(&kv.TxnEntrySizeLimit) - totalLimit := atomic.LoadUint64(&kv.TxnTotalSizeLimit) + totalLimit := kv.TxnTotalSizeLimit.Load() txn.GetUnionStore().SetEntrySizeLimit(entryLimit, totalLimit) return &tikvTxn{txn, make(map[int64]*model.TableInfo), nil} diff --git a/tidb-server/main.go b/tidb-server/main.go index 89819191c1aad..c5a2c85ab5b97 100644 --- a/tidb-server/main.go +++ b/tidb-server/main.go @@ -614,7 +614,6 @@ func setGlobalVars() { } plannercore.AllowCartesianProduct.Store(cfg.Performance.CrossJoin) privileges.SkipWithGrant = cfg.Security.SkipGrantTable - kv.TxnTotalSizeLimit = cfg.Performance.TxnTotalSizeLimit if cfg.Performance.TxnEntrySizeLimit > 120*1024*1024 { log.Fatal("cannot set txn entry size limit larger than 120M") } From 68b258415fc17d181c6c328d2301e4d9cfb2b438 Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Fri, 6 May 2022 15:11:21 -0700 Subject: [PATCH 2/9] *: move config file option tidb_txn_total_size_limit to sysvar --- sessionctx/variable/sysvar.go | 2 +- sessionctx/variable/sysvar_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 4ff84fd61218d..1a769cf683474 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -410,7 +410,7 @@ var defaultSysVars = []*SysVar{ }}, /* The system variables below have GLOBAL scope */ - {Scope: ScopeGlobal, Name: TiDBTxnTotalSizeLimit, Value: strconv.FormatInt(DefTiDBTxnTotalSizeLimit, 10), Type: TypeInt, MaxValue: 1099511627776, GetGlobal: func(sv *SessionVars) (string, error) { + {Scope: ScopeGlobal, Name: TiDBTxnTotalSizeLimit, Value: strconv.FormatInt(DefTiDBTxnTotalSizeLimit, 10), Type: TypeInt, MinValue: 10485760, MaxValue: 1099511627776, GetGlobal: func(sv *SessionVars) (string, error) { return strconv.FormatUint(kv.TxnTotalSizeLimit.Load(), 10), nil }, SetGlobal: func(s *SessionVars, val string) error { kv.TxnTotalSizeLimit.Store(uint64(TidbOptInt64(val, DefTiDBTxnTotalSizeLimit))) diff --git a/sessionctx/variable/sysvar_test.go b/sessionctx/variable/sysvar_test.go index 41488411d2e70..d105ee366d9f2 100644 --- a/sessionctx/variable/sysvar_test.go +++ b/sessionctx/variable/sysvar_test.go @@ -968,3 +968,29 @@ func TestTiDBQueryLogMaxLen(t *testing.T) { require.Equal(t, val, fmt.Sprintf("%d", expected)) require.NoError(t, err) } + +func TestTiDBTxnTotalSizeLimit(t *testing.T) { + sv := GetSysVar(TiDBTxnTotalSizeLimit) + vars := NewSessionVars() + + newVal := 10485760 + val, err := sv.Validate(vars, fmt.Sprintf("%d", newVal), ScopeGlobal) + require.Equal(t, "10485760", val) + require.NoError(t, err) + + // out of range + newVal = 1099511627777 + expected := 1099511627776 + val, err = sv.Validate(vars, fmt.Sprintf("%d", newVal), ScopeGlobal) + // expected to truncate + require.Equal(t, fmt.Sprintf("%d", expected), val) + require.NoError(t, err) + + // min value out of range + newVal = 1024 + expected = 10485760 + val, err = sv.Validate(vars, fmt.Sprintf("%d", newVal), ScopeGlobal) + // expected to set to min value + require.Equal(t, fmt.Sprintf("%d", expected), val) + require.Error(t, err) +} From b30e3066dd19583b648417808e86474d298ed5c4 Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Sat, 7 May 2022 00:45:10 -0700 Subject: [PATCH 3/9] txn entry size limit changes done --- config/config.go | 5 +---- config/config.toml.example | 4 ++-- kv/kv.go | 7 ++----- planner/core/planbuilder.go | 2 +- sessionctx/variable/sysvar.go | 6 ++++++ sessionctx/variable/sysvar_test.go | 27 ++++++++++++++++++++++++++- sessionctx/variable/tidb_vars.go | 4 ++++ store/driver/txn/txn_driver.go | 3 +-- tidb-server/main.go | 5 ----- 9 files changed, 43 insertions(+), 20 deletions(-) diff --git a/config/config.go b/config/config.go index d2737e82ddfd9..22639c2d87970 100644 --- a/config/config.go +++ b/config/config.go @@ -42,8 +42,6 @@ import ( // Config number limitations const ( MaxLogFileSize = 4096 // MB - // DefTxnEntrySizeLimit is the default value of TxnEntrySizeLimit. - DefTxnEntrySizeLimit = 6 * 1024 * 1024 // DefMaxIndexLength is the maximum index length(in bytes). This value is consistent with MySQL. DefMaxIndexLength = 3072 // DefMaxOfMaxIndexLength is the maximum index length(in bytes) for TiDB v3.0.7 and previous version. @@ -585,7 +583,6 @@ type Performance struct { PseudoEstimateRatio float64 `toml:"pseudo-estimate-ratio" json:"pseudo-estimate-ratio"` ForcePriority string `toml:"force-priority" json:"force-priority"` BindInfoLease string `toml:"bind-info-lease" json:"bind-info-lease"` - TxnEntrySizeLimit uint64 `toml:"txn-entry-size-limit" json:"txn-entry-size-limit"` TCPKeepAlive bool `toml:"tcp-keep-alive" json:"tcp-keep-alive"` TCPNoDelay bool `toml:"tcp-no-delay" json:"tcp-no-delay"` CrossJoin bool `toml:"cross-join" json:"cross-join"` @@ -812,7 +809,6 @@ var defaultConf = Config{ PseudoEstimateRatio: 0.8, ForcePriority: "NO_PRIORITY", BindInfoLease: "3s", - TxnEntrySizeLimit: DefTxnEntrySizeLimit, DistinctAggPushDown: false, ProjectionPushDown: false, CommitterConcurrency: defTiKVCfg.CommitterConcurrency, @@ -927,6 +923,7 @@ var deprecatedConfig = map[string]struct{}{ "mem-quota-query": {}, "query-log-max-len": {}, "txn-total-size-limit": {}, + "txn-entry-size-limit": {}, } func isAllDeprecatedConfigItems(items []string) bool { diff --git a/config/config.toml.example b/config/config.toml.example index f0d6267fd079a..52690f5f23a45 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -259,11 +259,11 @@ distinct-agg-push-down = false # NOTE: If binlog is enabled with Kafka (e.g. arbiter cluster), # this value should be less than 1073741824(1G) because this is the maximum size that can be handled by Kafka. # If binlog is disabled or binlog is enabled without Kafka, this value should be less than 1099511627776(1T). -txn-total-size-limit = 104857600 +tidb_txn_total_size_limit = 104857600 # The limitation of the size in byte for each entry in one transaction. # NOTE: Increasing this limit may cause performance problems. -txn-entry-size-limit = 6291456 +tidb_txn_entry_size_limit = 6291456 # The max number of running concurrency two phase committer request for an SQL. committer-concurrency = 128 diff --git a/kv/kv.go b/kv/kv.go index fc8613944de7a..d611e66f6f249 100644 --- a/kv/kv.go +++ b/kv/kv.go @@ -23,7 +23,6 @@ import ( deadlockpb "github.com/pingcap/kvproto/pkg/deadlock" "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/kvproto/pkg/metapb" - "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/util/memory" "github.com/pingcap/tidb/util/trxevents" @@ -47,11 +46,9 @@ const UnCommitIndexKVFlag byte = '1' // Those limits is enforced to make sure the transaction can be well handled by TiKV. var ( // TxnEntrySizeLimit is limit of single entry size (len(key) + len(value)). - TxnEntrySizeLimit uint64 = config.DefTxnEntrySizeLimit + TxnEntrySizeLimit = atomic.NewUint64(6 * 1024 * 1024) //DefTiDBTxnEntrySizeLimit // TxnTotalSizeLimit is limit of the sum of all entry size. - //TxnTotalSizeLimit uint64 = //DefTiDBTxnTotalSizeLimit - - TxnTotalSizeLimit = atomic.NewUint64(100 * 1024 * 1024) + TxnTotalSizeLimit = atomic.NewUint64(100 * 1024 * 1024) //DefTiDBTxnTotalSizeLimit ) // Getter is the interface for the Get method. diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index f2005a20c40be..9d6663e604604 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -2520,7 +2520,7 @@ func (b *PlanBuilder) buildAnalyzeAllIndex(as *ast.AnalyzeTableStmt, opts map[as } // CMSketchSizeLimit indicates the size limit of CMSketch. -var CMSketchSizeLimit = kv.TxnEntrySizeLimit / binary.MaxVarintLen32 +var CMSketchSizeLimit = kv.TxnEntrySizeLimit.Load() / binary.MaxVarintLen32 var analyzeOptionLimit = map[ast.AnalyzeOptionType]uint64{ ast.AnalyzeOptNumBuckets: 1024, diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 1a769cf683474..02ac14f18d7ea 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -410,6 +410,12 @@ var defaultSysVars = []*SysVar{ }}, /* The system variables below have GLOBAL scope */ + {Scope: ScopeGlobal, Name: TiDBTxnEntrySizeLimit, Value: strconv.FormatInt(DefTiDBTxnEntrySizeLimit, 10), Type: TypeInt, MinValue: 10485760, MaxValue: 125829120, GetGlobal: func(sv *SessionVars) (string, error) { + return strconv.FormatUint(kv.TxnEntrySizeLimit.Load(), 10), nil + }, SetGlobal: func(s *SessionVars, val string) error { + kv.TxnEntrySizeLimit.Store(uint64(TidbOptInt64(val, DefTiDBTxnEntrySizeLimit))) + return nil + }}, {Scope: ScopeGlobal, Name: TiDBTxnTotalSizeLimit, Value: strconv.FormatInt(DefTiDBTxnTotalSizeLimit, 10), Type: TypeInt, MinValue: 10485760, MaxValue: 1099511627776, GetGlobal: func(sv *SessionVars) (string, error) { return strconv.FormatUint(kv.TxnTotalSizeLimit.Load(), 10), nil }, SetGlobal: func(s *SessionVars, val string) error { diff --git a/sessionctx/variable/sysvar_test.go b/sessionctx/variable/sysvar_test.go index d105ee366d9f2..4a7cd6887bbeb 100644 --- a/sessionctx/variable/sysvar_test.go +++ b/sessionctx/variable/sysvar_test.go @@ -992,5 +992,30 @@ func TestTiDBTxnTotalSizeLimit(t *testing.T) { val, err = sv.Validate(vars, fmt.Sprintf("%d", newVal), ScopeGlobal) // expected to set to min value require.Equal(t, fmt.Sprintf("%d", expected), val) - require.Error(t, err) + require.NoError(t, err) +} +func TestTiDBTxnEntrySizeLimit(t *testing.T) { + sv := GetSysVar(TiDBTxnEntrySizeLimit) + vars := NewSessionVars() + + newVal := 10485760 + val, err := sv.Validate(vars, fmt.Sprintf("%d", newVal), ScopeGlobal) + require.Equal(t, "10485760", val) + require.NoError(t, err) + + // Max Value out of range + newVal = 125829121 + expected := 125829120 + val, err = sv.Validate(vars, fmt.Sprintf("%d", newVal), ScopeGlobal) + // expected to truncate + require.Equal(t, fmt.Sprintf("%d", expected), val) + require.NoError(t, err) + + // min value out of range + newVal = 1024 + expected = 10485760 + val, err = sv.Validate(vars, fmt.Sprintf("%d", newVal), ScopeGlobal) + // expected to set to min value + require.Equal(t, fmt.Sprintf("%d", expected), val) + require.NoError(t, err) } diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index a39b05913d980..d5367bf226530 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -638,6 +638,8 @@ const ( // TiDB vars that have only global scope const ( + // TiDBTxnEntrySizeLimit is the size limit of a single row of data in TiDB + TiDBTxnEntrySizeLimit = "tidb_txn_entry_size_limit" // TiDBTxnTotalSizeLimit is the size limit of a single transaction TiDBTxnTotalSizeLimit = "tidb_txn_total_size_limit" // TiDBGCEnable turns garbage collection on or OFF @@ -844,6 +846,7 @@ const ( DefTiDBMemQuotaQuery = 1073741824 // 1GB DefTiDBQueryLogMaxLen = 4096 DefTiDBTxnTotalSizeLimit = 100 * 1024 * 1024 + DefTiDBTxnEntrySizeLimit = 6 * 1024 * 1024 ) // Process global variables. @@ -881,4 +884,5 @@ var ( MemQuotaBindingCache = atomic.NewInt64(DefTiDBMemQuotaBindingCache) GCMaxWaitTime = atomic.NewInt64(DefTiDBGCMaxWaitTime) TxnTotalSizeLimit uint64 = DefTiDBTxnTotalSizeLimit + TxnEntrySizeLimit uint64 = DefTiDBTxnEntrySizeLimit ) diff --git a/store/driver/txn/txn_driver.go b/store/driver/txn/txn_driver.go index d658508b7744f..ace6cca0e6a46 100644 --- a/store/driver/txn/txn_driver.go +++ b/store/driver/txn/txn_driver.go @@ -16,7 +16,6 @@ package txn import ( "context" - "sync/atomic" "github.com/opentracing/opentracing-go" "github.com/pingcap/errors" @@ -48,7 +47,7 @@ type tikvTxn struct { func NewTiKVTxn(txn *tikv.KVTxn) kv.Transaction { txn.SetKVFilter(TiDBKVFilter{}) - entryLimit := atomic.LoadUint64(&kv.TxnEntrySizeLimit) + entryLimit := kv.TxnEntrySizeLimit.Load() totalLimit := kv.TxnTotalSizeLimit.Load() txn.GetUnionStore().SetEntrySizeLimit(entryLimit, totalLimit) diff --git a/tidb-server/main.go b/tidb-server/main.go index c5a2c85ab5b97..d71efeffcb9bd 100644 --- a/tidb-server/main.go +++ b/tidb-server/main.go @@ -614,11 +614,6 @@ func setGlobalVars() { } plannercore.AllowCartesianProduct.Store(cfg.Performance.CrossJoin) privileges.SkipWithGrant = cfg.Security.SkipGrantTable - if cfg.Performance.TxnEntrySizeLimit > 120*1024*1024 { - log.Fatal("cannot set txn entry size limit larger than 120M") - } - kv.TxnEntrySizeLimit = cfg.Performance.TxnEntrySizeLimit - priority := mysql.Str2Priority(cfg.Instance.ForcePriority) variable.ForcePriority = int32(priority) From 055181694750fde043aac04f2894a2fe75fcc2ec Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Thu, 12 May 2022 11:40:37 -0700 Subject: [PATCH 4/9] Default value change --- sessionctx/variable/tidb_vars.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index e7e55b95fae88..b1fdc58005b02 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -857,7 +857,7 @@ const ( MaxTiDBStatsCacheMemQuota = 1024 * 1024 * 1024 * 1024 // 1TB DefTiDBQueryLogMaxLen = 4096 DefTiDBTxnTotalSizeLimit = 100 * 1024 * 1024 - DefTiDBTxnEntrySizeLimit = 10485760 + DefTiDBTxnEntrySizeLimit = 6 * 1024 * 1024 DefTiDBBatchDMLIgnoreError = false DefTiDBMemQuotaAnalyze = -1 ) From 069cd6e81b7d7fe28179e9ecf1f16c899a6301c5 Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Thu, 12 May 2022 13:06:13 -0700 Subject: [PATCH 5/9] default value set in end of the function --- executor/seqtest/seq_executor_test.go | 1 + server/server_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/executor/seqtest/seq_executor_test.go b/executor/seqtest/seq_executor_test.go index 8e874754986f7..6662afb49d135 100644 --- a/executor/seqtest/seq_executor_test.go +++ b/executor/seqtest/seq_executor_test.go @@ -938,6 +938,7 @@ func TestBatchInsertDelete(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("set global tidb_txn_total_size_limit = 5500") + defer tk.MustExec("set global tidb_txn_total_size_limit = default") tk.MustExec("drop table if exists batch_insert") tk.MustExec("create table batch_insert (c int)") tk.MustExec("drop table if exists batch_insert_on_duplicate") diff --git a/server/server_test.go b/server/server_test.go index f406d586f686b..d25e5139053e3 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -874,6 +874,7 @@ func (cli *testServerClient) runTestLoadData(t *testing.T, server *Server) { }, "LoadData", func(dbt *testkit.DBTestKit) { // If the MemBuffer can't be committed once in each batch, it will return an error like "transaction is too large". dbt.MustExec("set global tidb_txn_total_size_limit = 10240") + defer dbt.MustExec("set global tidb_txn_total_size_limit = default") dbt.MustExec("set @@tidb_dml_batch_size = 3") dbt.MustExec("create table test (a varchar(255), b varchar(255) default 'default value', c int not null auto_increment, primary key(c))") dbt.MustExec("create view v1 as select 1") From 997a08c4b8fdb4082981017578f05a2ecb033b6d Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Thu, 12 May 2022 15:41:34 -0700 Subject: [PATCH 6/9] Changes done --- config/config_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/config/config_test.go b/config/config_test.go index 6d425b41e8163..89e92c4ee1ed9 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -220,6 +220,7 @@ deprecate-integer-display-length = true enable-enum-length-limit = false stores-refresh-interval = 30 enable-forwarding = true +[performance] tcp-no-delay = false [tikv-client] commit-timeout="41s" From 2c208f52495f1efe9a2a1fd026aa73d4809ed26f Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Mon, 16 May 2022 12:52:30 -0700 Subject: [PATCH 7/9] Changes done for upgrade --- config/config.go | 10 ++++++++-- session/bootstrap.go | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/config/config.go b/config/config.go index 6ab1da37d2111..d944726a0ef28 100644 --- a/config/config.go +++ b/config/config.go @@ -611,6 +611,12 @@ type Performance struct { StatsLoadConcurrency uint `toml:"stats-load-concurrency" json:"stats-load-concurrency"` StatsLoadQueueSize uint `toml:"stats-load-queue-size" json:"stats-load-queue-size"` EnableStatsCacheMemQuota bool `toml:"enable-stats-cache-mem-quota" json:"enable-stats-cache-mem-quota"` + // The following items are deprecated. We need to keep them here temporarily + // to support the upgrade process. They can be removed in future. + + // TxnEntrySizeLimit and TxnTotalSizeLimit , unused since bootstrap v91 + TxnEntrySizeLimit uint64 `toml:"txn-entry-size-limit" json:"txn-entry-size-limit"` + TxnTotalSizeLimit uint64 `toml:"txn-total-size-limit" json:"txn-total-size-limit"` } // PlanCache is the PlanCache section of the config. @@ -936,8 +942,8 @@ var deprecatedConfig = map[string]struct{}{ "enable-batch-dml": {}, // use tidb_enable_batch_dml "mem-quota-query": {}, "query-log-max-len": {}, - "performance.txn-total-size-limit": {}, - "performance.txn-entry-size-limit": {}, + "performance.txn-total-size-limit": {}, // use tidb_txn_total_size_limit + "performance.txn-entry-size-limit": {}, // use tidb_txn_entry_size_limit "performance.committer-concurrency": {}, } diff --git a/session/bootstrap.go b/session/bootstrap.go index 37d98a7155874..263a933f582cc 100644 --- a/session/bootstrap.go +++ b/session/bootstrap.go @@ -617,6 +617,8 @@ const ( version89 = 89 // version90 converts enable-batch-dml to a sysvar version90 = 90 + // version91 converts txn-total-size-limit and txn-entry-size-limit to a sysvar + version91 = 91 ) // currentBootstrapVersion is defined as a variable, so we can modify its value for testing. @@ -715,6 +717,7 @@ var ( upgradeToVer88, upgradeToVer89, upgradeToVer90, + upgradeToVer91, } ) @@ -1847,6 +1850,15 @@ func upgradeToVer90(s Session, ver int64) { valStr := variable.BoolToOnOff(config.GetGlobalConfig().EnableBatchDML) importConfigOption(s, "enable-batch-dml", variable.TiDBEnableBatchDML, valStr) } +func upgradeToVer91(s Session, ver int64) { + if ver >= version91 { + return + } + valStr := strconv.FormatUint(uint64(config.GetGlobalConfig().Performance.TxnEntrySizeLimit), 10) + importConfigOption(s, "txn-entry-size-limit", variable.TiDBTxnEntrySizeLimit, valStr) + vStr := strconv.FormatUint(uint64(config.GetGlobalConfig().Performance.TxnTotalSizeLimit), 10) + importConfigOption(s, "txn-total-size-limit", variable.TiDBTxnTotalSizeLimit, vStr) +} func writeOOMAction(s Session) { comment := "oom-action is `log` by default in v3.0.x, `cancel` by default in v4.0.11+" From 54ecf182910b7d71d23e7772e2c00676edea7028 Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Mon, 16 May 2022 15:18:00 -0700 Subject: [PATCH 8/9] Changes done for upgrade --- session/bootstrap.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/session/bootstrap.go b/session/bootstrap.go index 263a933f582cc..0603199078b09 100644 --- a/session/bootstrap.go +++ b/session/bootstrap.go @@ -1854,10 +1854,10 @@ func upgradeToVer91(s Session, ver int64) { if ver >= version91 { return } - valStr := strconv.FormatUint(uint64(config.GetGlobalConfig().Performance.TxnEntrySizeLimit), 10) + valStr := strconv.FormatUint(config.GetGlobalConfig().Performance.TxnEntrySizeLimit, 10) importConfigOption(s, "txn-entry-size-limit", variable.TiDBTxnEntrySizeLimit, valStr) - vStr := strconv.FormatUint(uint64(config.GetGlobalConfig().Performance.TxnTotalSizeLimit), 10) - importConfigOption(s, "txn-total-size-limit", variable.TiDBTxnTotalSizeLimit, vStr) + valStr = strconv.FormatUint(config.GetGlobalConfig().Performance.TxnTotalSizeLimit, 10) + importConfigOption(s, "txn-total-size-limit", variable.TiDBTxnTotalSizeLimit, valStr) } func writeOOMAction(s Session) { From c31e31568d9add4e435074bba6360286a1b29c2f Mon Sep 17 00:00:00 2001 From: alkaagr81 Date: Mon, 16 May 2022 15:38:16 -0700 Subject: [PATCH 9/9] Changes done --- session/bootstrap.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/session/bootstrap.go b/session/bootstrap.go index 0603199078b09..1f80ab1d90c36 100644 --- a/session/bootstrap.go +++ b/session/bootstrap.go @@ -1854,9 +1854,9 @@ func upgradeToVer91(s Session, ver int64) { if ver >= version91 { return } - valStr := strconv.FormatUint(config.GetGlobalConfig().Performance.TxnEntrySizeLimit, 10) + valStr := fmt.Sprint(config.GetGlobalConfig().Performance.TxnEntrySizeLimit) importConfigOption(s, "txn-entry-size-limit", variable.TiDBTxnEntrySizeLimit, valStr) - valStr = strconv.FormatUint(config.GetGlobalConfig().Performance.TxnTotalSizeLimit, 10) + valStr = fmt.Sprint(config.GetGlobalConfig().Performance.TxnTotalSizeLimit) importConfigOption(s, "txn-total-size-limit", variable.TiDBTxnTotalSizeLimit, valStr) }