Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config, sysvar: map max-server-connections to max_connections #35453

Merged
merged 13 commits into from
Jun 23, 2022
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ var (
map[string]string{
"check-mb4-value-in-utf8": "tidb_check_mb4_value_in_utf8",
"enable-collect-execution-info": "tidb_enable_collect_execution_info",
"max-server-connections": "max_connections",
},
},
{
Expand Down Expand Up @@ -473,6 +474,7 @@ type Instance struct {
EnableCollectExecutionInfo bool `toml:"tidb_enable_collect_execution_info" json:"tidb_enable_collect_execution_info"`
PluginDir string `toml:"plugin_dir" json:"plugin_dir"`
PluginLoad string `toml:"plugin_load" json:"plugin_load"`
MaxConnections uint32 `toml:"max_connections" json:"max_connections"`
}

func (l *Log) getDisableTimestamp() bool {
Expand Down Expand Up @@ -824,6 +826,7 @@ var defaultConf = Config{
EnableCollectExecutionInfo: true,
PluginDir: "/data/deploy/plugin",
PluginLoad: "",
MaxConnections: 0,
},
Status: Status{
ReportStatus: true,
Expand Down
6 changes: 3 additions & 3 deletions config/config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ repair-mode = false
# In repair mode, repairing table which is not in repair list will get wrong database or wrong table error.
repair-table-list = []

# The maximum permitted number of simultaneous client connections. When the value is 0, the number of connections is unlimited.
max-server-connections = 0

# Whether new collations are enabled, as indicated by its name, this configuration entry take effect ONLY when a TiDB cluster bootstraps for the first time.
new_collations_enabled_on_first_bootstrap = true

Expand Down Expand Up @@ -465,3 +462,6 @@ tidb_slow_log_threshold = 300
# tidb_record_plan_in_slow_log is used to enable record query plan in slow log.
# 0 is disable. 1 is enable.
tidb_record_plan_in_slow_log = 1

# The maximum permitted number of simultaneous client connections. When the value is 0, the number of connections is unlimited.
max_connections = 0
15 changes: 9 additions & 6 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,6 @@ repair-mode = false
# In repair mode, repairing table which is not in repair list will get wrong database or wrong table error.
repair-table-list = []

# The maximum permitted number of simultaneous client connections. When the value is 0, the number of connections is unlimited.
max-server-connections = 0

# Whether new collations are enabled, as indicated by its name, this configuration entry take effect ONLY when a TiDB cluster bootstraps for the first time.
new_collations_enabled_on_first_bootstrap = true

Expand All @@ -309,6 +306,11 @@ deprecate-integer-display-length = false
# See https://dev.mysql.com/doc/refman/8.0/en/string-type-syntax.html for more details.
enable-enum-length-limit = true

[instance]

# The maximum permitted number of simultaneous client connections. When the value is 0, the number of connections is unlimited.
max_connections = 0

[log]
# Log level: debug, info, warn, error, fatal.
level = "info"
Expand Down Expand Up @@ -707,7 +709,7 @@ unrecognized-option-test = true
match, err := regexp.Match("(?:.|\n)*invalid configuration option(?:.|\n)*", []byte(err.Error()))
require.NoError(t, err)
require.True(t, match)
require.Equal(t, uint32(0), conf.MaxServerConnections)
require.Equal(t, uint32(0), conf.Instance.MaxConnections)

err = f.Truncate(0)
require.NoError(t, err)
Expand All @@ -722,7 +724,6 @@ delay-clean-table-lock = 5
split-region-max-num=10000
server-version = "test_version"
repair-mode = true
max-server-connections = 200
max-index-length = 3080
index-limit = 70
table-column-count-limit = 4000
Expand Down Expand Up @@ -768,6 +769,8 @@ grpc-keepalive-timeout = 10
grpc-concurrent-streams = 2048
grpc-initial-window-size = 10240
grpc-max-send-msg-size = 40960
[instance]
max_connections = 200
`)

require.NoError(t, err)
Expand Down Expand Up @@ -797,7 +800,7 @@ grpc-max-send-msg-size = 40960
require.Equal(t, uint64(10000), conf.SplitRegionMaxNum)
require.True(t, conf.RepairMode)
require.Equal(t, uint64(16), conf.TiKVClient.ResolveLockLiteThreshold)
require.Equal(t, uint32(200), conf.MaxServerConnections)
require.Equal(t, uint32(200), conf.Instance.MaxConnections)
require.Equal(t, []string{"tiflash"}, conf.IsolationRead.Engines)
require.Equal(t, 3080, conf.MaxIndexLength)
require.Equal(t, 70, conf.IndexLimit)
Expand Down
13 changes: 7 additions & 6 deletions executor/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -914,16 +914,17 @@ func TestValidateSetVar(t *testing.T) {
result.Check(testkit.Rows("SYSTEM"))

// The following cases test value out of range and illegal type when setting system variables.
// See https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html for more details.
// See https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html for more details.
tk.MustExec("set @@global.max_connections=100001")
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect max_connections value: '100001'"))
result = tk.MustQuery("select @@global.max_connections;")
result.Check(testkit.Rows("100000"))

// "max_connections == 0" means there is no limitation on the number of connections.
tk.MustExec("set @@global.max_connections=-1")
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect max_connections value: '-1'"))
result = tk.MustQuery("select @@global.max_connections;")
result.Check(testkit.Rows("1"))
result.Check(testkit.Rows("0"))

err = tk.ExecToErr("set @@global.max_connections='hello'")
require.True(t, terror.ErrorEqual(err, variable.ErrWrongTypeForVar))
Expand Down Expand Up @@ -970,7 +971,7 @@ func TestValidateSetVar(t *testing.T) {
tk.MustExec("set @@global.max_connections=-1")
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect max_connections value: '-1'"))
result = tk.MustQuery("select @@global.max_connections;")
result.Check(testkit.Rows("1"))
result.Check(testkit.Rows("0"))

err = tk.ExecToErr("set @@global.max_connections='hello'")
require.True(t, terror.ErrorEqual(err, variable.ErrWrongTypeForVar))
Expand Down Expand Up @@ -1226,15 +1227,15 @@ func TestSelectGlobalVar(t *testing.T) {
defer clean()
tk := testkit.NewTestKit(t, store)

tk.MustQuery("select @@global.max_connections;").Check(testkit.Rows("151"))
tk.MustQuery("select @@max_connections;").Check(testkit.Rows("151"))
tk.MustQuery("select @@global.max_connections;").Check(testkit.Rows("0"))
tk.MustQuery("select @@max_connections;").Check(testkit.Rows("0"))

tk.MustExec("set @@global.max_connections=100;")

tk.MustQuery("select @@global.max_connections;").Check(testkit.Rows("100"))
tk.MustQuery("select @@max_connections;").Check(testkit.Rows("100"))

tk.MustExec("set @@global.max_connections=151;")
tk.MustExec("set @@global.max_connections=0;")

// test for unknown variable.
err := tk.ExecToErr("select @@invalid")
Expand Down
4 changes: 2 additions & 2 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6212,11 +6212,11 @@ func TestGlobalCacheCorrectness(t *testing.T) {
defer clean()

tk := testkit.NewTestKit(t, store)
tk.MustQuery("SHOW VARIABLES LIKE 'max_connections'").Check(testkit.Rows("max_connections 151"))
tk.MustQuery("SHOW VARIABLES LIKE 'max_connections'").Check(testkit.Rows("max_connections 0"))
tk.MustExec("SET GLOBAL max_connections=1234")
tk.MustQuery("SHOW VARIABLES LIKE 'max_connections'").Check(testkit.Rows("max_connections 1234"))
// restore
tk.MustExec("SET GLOBAL max_connections=151")
tk.MustExec("SET GLOBAL max_connections=0")
}

func TestRedundantColumnResolve(t *testing.T) {
Expand Down
30 changes: 25 additions & 5 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ func NewServer(cfg *config.Config, driver IDriver) (*Server, error) {
rand.Seed(time.Now().UTC().UnixNano())

variable.RegisterStatistics(s)
variable.SetMaxConnections = s.SetMaxConnections

return s, nil
}
Expand Down Expand Up @@ -352,7 +353,7 @@ func setTxnScope() {
// Export config-related metrics
func (s *Server) reportConfig() {
metrics.ConfigStatus.WithLabelValues("token-limit").Set(float64(s.cfg.TokenLimit))
metrics.ConfigStatus.WithLabelValues("max-server-connections").Set(float64(s.cfg.MaxServerConnections))
metrics.ConfigStatus.WithLabelValues("max_connections").Set(float64(s.cfg.Instance.MaxConnections))
}

// Run runs the server.
Expand Down Expand Up @@ -605,18 +606,37 @@ func (cc *clientConn) connectInfo() *variable.ConnectionInfo {
}

func (s *Server) checkConnectionCount() error {
// When the value of MaxServerConnections is 0, the number of connections is unlimited.
if int(s.cfg.MaxServerConnections) == 0 {
// When the value of Instance.MaxConnections is 0, the number of connections is unlimited.
if int(s.cfg.Instance.MaxConnections) == 0 {
return nil
}

s.rwlock.RLock()
conns := len(s.clients)
s.rwlock.RUnlock()

if conns >= int(s.cfg.MaxServerConnections) {
if conns >= int(s.cfg.Instance.MaxConnections) {
logutil.BgLogger().Error("too many connections",
zap.Uint32("max connections", s.cfg.MaxServerConnections), zap.Error(errConCount))
zap.Uint32("max connections", s.cfg.Instance.MaxConnections), zap.Error(errConCount))
return errConCount
}
return nil
}

// SetMaxConnections checks and updates the value of max_connections.
func (s *Server) SetMaxConnections(newMaxConnections uint32) error {
// When the value of newMaxConnections is 0, the number of connections is unlimited.
if int(newMaxConnections) == 0 {
return nil
}

s.rwlock.RLock()
conns := len(s.clients)
s.rwlock.RUnlock()

if conns >= int(newMaxConnections) {
logutil.BgLogger().Error("Current connections number exceeds the setting value",
zap.Uint32("max connections", newMaxConnections), zap.Error(errConCount))
return errConCount
}
return nil
Expand Down
1 change: 0 additions & 1 deletion sessionctx/variable/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
// but changing them has no effect on behavior.

var noopSysVars = []*SysVar{
{Scope: ScopeGlobal, Name: MaxConnections, Value: "151", Type: TypeUnsigned, MinValue: 1, MaxValue: 100000},
// It is unsafe to pretend that any variation of "read only" is enabled when the server
// does not support it. It is possible that these features will be supported in future,
// but until then...
Expand Down
12 changes: 12 additions & 0 deletions sessionctx/variable/sysvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,18 @@ var defaultSysVars = []*SysVar{
{Scope: ScopeInstance, Name: PluginDir, Value: "/data/deploy/plugin", ReadOnly: true, GetGlobal: func(s *SessionVars) (string, error) {
return config.GetGlobalConfig().Instance.PluginDir, nil
}},
{Scope: ScopeInstance, Name: MaxConnections, Value: strconv.FormatUint(uint64(config.GetGlobalConfig().Instance.MaxConnections), 10), Type: TypeUnsigned, MinValue: 0, MaxValue: 100000, SetGlobal: func(s *SessionVars, val string) error {
newVal := uint32(TidbOptInt64(val, 0))
if SetMaxConnections != nil {
if err := SetMaxConnections(newVal); err != nil {
return err
}
}
config.GetGlobalConfig().Instance.MaxConnections = newVal
return nil
}, GetGlobal: func(s *SessionVars) (string, error) {
return strconv.FormatUint(uint64(config.GetGlobalConfig().Instance.MaxConnections), 10), nil
}},

/* The system variables below have GLOBAL scope */
{Scope: ScopeGlobal, Name: MaxPreparedStmtCount, Value: strconv.FormatInt(DefMaxPreparedStmtCount, 10), Type: TypeInt, MinValue: -1, MaxValue: 1048576},
Expand Down
2 changes: 2 additions & 0 deletions sessionctx/variable/tidb_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,4 +994,6 @@ var (
GetMemQuotaAnalyze func() int64 = nil
// SetStatsCacheCapacity is the func registered by domain to set statsCache memory quota.
SetStatsCacheCapacity atomic.Value
// SetMaxConnections is the func registered by derver to set the value of max_connections.
SetMaxConnections func(newMaxConnections uint32) error = nil
)
2 changes: 2 additions & 0 deletions tidb-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,8 @@ func setGlobalVars() {
cfg.Instance.CheckMb4ValueInUTF8.Store(cfg.CheckMb4ValueInUTF8.Load())
case "enable-collect-execution-info":
cfg.Instance.EnableCollectExecutionInfo = cfg.EnableCollectExecutionInfo
case "max-server-connections":
cfg.Instance.MaxConnections = cfg.MaxServerConnections
}
case "log":
switch oldName {
Expand Down