From 9d19be16040ca409e31a81b2c86f2d23d3651e18 Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Thu, 16 Jun 2022 17:21:45 +0800 Subject: [PATCH 1/6] config, sysvar: map `max-server-connections` to `max_connections` --- config/config.go | 3 +++ config/config.toml.example | 6 +++--- config/config_test.go | 15 +++++++++------ server/server.go | 30 +++++++++++++++++++++++++----- sessionctx/variable/noop.go | 1 - sessionctx/variable/sysvar.go | 10 ++++++++++ sessionctx/variable/tidb_vars.go | 2 ++ tidb-server/main.go | 2 ++ 8 files changed, 54 insertions(+), 15 deletions(-) diff --git a/config/config.go b/config/config.go index a701b1501bf15..4c3b2d5c7b764 100644 --- a/config/config.go +++ b/config/config.go @@ -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", }, }, { @@ -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 { @@ -824,6 +826,7 @@ var defaultConf = Config{ EnableCollectExecutionInfo: true, PluginDir: "/data/deploy/plugin", PluginLoad: "", + MaxConnections: 0, }, Status: Status{ ReportStatus: true, diff --git a/config/config.toml.example b/config/config.toml.example index e23f390e23efb..2e5eaaff24b38 100644 --- a/config/config.toml.example +++ b/config/config.toml.example @@ -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 @@ -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 diff --git a/config/config_test.go b/config/config_test.go index 391bd874d3942..2e044062bd4e8 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -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 @@ -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" @@ -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) @@ -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 @@ -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) @@ -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) diff --git a/server/server.go b/server/server.go index 90b4a7e27101b..86f49884d4ab1 100644 --- a/server/server.go +++ b/server/server.go @@ -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 } @@ -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. @@ -605,8 +606,8 @@ 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 } @@ -614,9 +615,28 @@ func (s *Server) checkConnectionCount() error { 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 diff --git a/sessionctx/variable/noop.go b/sessionctx/variable/noop.go index 4f2cdac1aa690..6eb70beabfc99 100644 --- a/sessionctx/variable/noop.go +++ b/sessionctx/variable/noop.go @@ -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... diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 06e206c98ab8a..9506bdb0c4223 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -415,6 +415,16 @@ 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: math.MaxUint32, SetGlobal: func(s *SessionVars, val string) error { + newVal := uint32(TidbOptInt64(val, 0)) + 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}, diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index 64c1916292c73..c2e9356d7d8d2 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -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 ) diff --git a/tidb-server/main.go b/tidb-server/main.go index 40dd3cacfd5a1..10c3245eccdf8 100644 --- a/tidb-server/main.go +++ b/tidb-server/main.go @@ -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 { From 67ff2ad09494f52debe10194ad6f5891a9b35fff Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Thu, 16 Jun 2022 20:58:19 +0800 Subject: [PATCH 2/6] Fix UT fails. --- executor/set_test.go | 13 +++++++------ expression/integration_test.go | 4 ++-- sessionctx/variable/sysvar.go | 8 +++++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/executor/set_test.go b/executor/set_test.go index 4f0151b6d2129..1a9acb0e6e989 100644 --- a/executor/set_test.go +++ b/executor/set_test.go @@ -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)) @@ -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)) @@ -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") diff --git a/expression/integration_test.go b/expression/integration_test.go index 53be8080bb6fd..5b8d81a8a36a5 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -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) { diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index 9506bdb0c4223..fd870e912c8d6 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -415,10 +415,12 @@ 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: math.MaxUint32, SetGlobal: func(s *SessionVars, val string) error { + {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 err := SetMaxConnections(newVal); err != nil { - return err + if SetMaxConnections != nil { + if err := SetMaxConnections(newVal); err != nil { + return err + } } config.GetGlobalConfig().Instance.MaxConnections = newVal return nil From 1015d5350fbfe63eb129c2b05664484b9f647e32 Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Thu, 16 Jun 2022 23:44:38 +0800 Subject: [PATCH 3/6] Fix --- server/server.go | 2 +- sessionctx/variable/tidb_vars.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/server.go b/server/server.go index 86f49884d4ab1..e4a009f7f1937 100644 --- a/server/server.go +++ b/server/server.go @@ -634,7 +634,7 @@ func (s *Server) SetMaxConnections(newMaxConnections uint32) error { conns := len(s.clients) s.rwlock.RUnlock() - if conns >= int(newMaxConnections) { + if conns > int(newMaxConnections) { logutil.BgLogger().Error("Current connections number exceeds the setting value", zap.Uint32("max connections", newMaxConnections), zap.Error(errConCount)) return errConCount diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index c2e9356d7d8d2..657e88d161398 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -994,6 +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 is the func registered by server to set the value of max_connections. SetMaxConnections func(newMaxConnections uint32) error = nil ) From 8a0a06dac9d397cfa337f7c2e1a388412d082b2b Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Mon, 20 Jun 2022 20:11:47 +0800 Subject: [PATCH 4/6] Change error information --- server/server.go | 27 +++++---------------------- sessionctx/variable/sysvar.go | 8 +------- sessionctx/variable/tidb_vars.go | 2 -- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/server/server.go b/server/server.go index e4a009f7f1937..aa5a5f744d38b 100644 --- a/server/server.go +++ b/server/server.go @@ -302,7 +302,6 @@ 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 } @@ -515,11 +514,14 @@ func (s *Server) onConn(conn *clientConn) { }) terror.Log(err) } - if errors.Cause(err) == io.EOF { + switch errors.Cause(err) { + case io.EOF: // `EOF` means the connection is closed normally, we do not treat it as a noticeable error and log it in 'DEBUG' level. logutil.BgLogger().With(zap.Uint64("conn", conn.connectionID)). Debug("EOF", zap.String("remote addr", conn.bufReadConn.RemoteAddr().String())) - } else { + case errConCount: + _ = conn.writeError(ctx, err) + default: metrics.HandShakeErrorCounter.Inc() logutil.BgLogger().With(zap.Uint64("conn", conn.connectionID)). Warn("Server.onConn handshake", zap.Error(err), @@ -623,25 +625,6 @@ func (s *Server) checkConnectionCount() error { 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 -} - // ShowProcessList implements the SessionManager interface. func (s *Server) ShowProcessList() map[uint64]*util.ProcessInfo { rs := make(map[uint64]*util.ProcessInfo) diff --git a/sessionctx/variable/sysvar.go b/sessionctx/variable/sysvar.go index fd870e912c8d6..01879fde2943c 100644 --- a/sessionctx/variable/sysvar.go +++ b/sessionctx/variable/sysvar.go @@ -416,13 +416,7 @@ var defaultSysVars = []*SysVar{ 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 + config.GetGlobalConfig().Instance.MaxConnections = uint32(TidbOptInt64(val, 0)) return nil }, GetGlobal: func(s *SessionVars) (string, error) { return strconv.FormatUint(uint64(config.GetGlobalConfig().Instance.MaxConnections), 10), nil diff --git a/sessionctx/variable/tidb_vars.go b/sessionctx/variable/tidb_vars.go index 657e88d161398..64c1916292c73 100644 --- a/sessionctx/variable/tidb_vars.go +++ b/sessionctx/variable/tidb_vars.go @@ -994,6 +994,4 @@ 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 server to set the value of max_connections. - SetMaxConnections func(newMaxConnections uint32) error = nil ) From 50017824b288d00d7704062691cb8843ef292d9f Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Wed, 22 Jun 2022 16:00:39 +0800 Subject: [PATCH 5/6] Add error handlinr in server.go --- server/server.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/server.go b/server/server.go index aa5a5f744d38b..b657b2ef9a81e 100644 --- a/server/server.go +++ b/server/server.go @@ -47,7 +47,6 @@ import ( "time" "unsafe" - "github.com/blacktear23/go-proxyprotocol" "github.com/pingcap/errors" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain" @@ -520,7 +519,11 @@ func (s *Server) onConn(conn *clientConn) { logutil.BgLogger().With(zap.Uint64("conn", conn.connectionID)). Debug("EOF", zap.String("remote addr", conn.bufReadConn.RemoteAddr().String())) case errConCount: - _ = conn.writeError(ctx, err) + if err := conn.writeError(ctx, err); err != nil { + logutil.BgLogger().With(zap.Uint64("conn", conn.connectionID)). + Warn("error in writing errConCount", zap.Error(err), + zap.String("remote addr", conn.bufReadConn.RemoteAddr().String())) + } default: metrics.HandShakeErrorCounter.Inc() logutil.BgLogger().With(zap.Uint64("conn", conn.connectionID)). From d6724625ded8cb009b1985c3b2337ce41afe4a3a Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Wed, 22 Jun 2022 16:14:26 +0800 Subject: [PATCH 6/6] Fix --- server/server.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/server.go b/server/server.go index b657b2ef9a81e..13ed052391f59 100644 --- a/server/server.go +++ b/server/server.go @@ -47,6 +47,7 @@ import ( "time" "unsafe" + "github.com/blacktear23/go-proxyprotocol" "github.com/pingcap/errors" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/domain"