From 5da131fb1b524f786b95b53c0a3237e275396bdc Mon Sep 17 00:00:00 2001 From: He Cao Date: Mon, 4 Mar 2019 15:39:54 +0800 Subject: [PATCH] cherry pick planner, executor: support SQL show pump/drainer status (#9456) and solve conflict --- executor/show.go | 47 +++++++++++++++++++++++++++++++++++++ go.mod | 4 +--- go.sum | 2 ++ planner/core/planbuilder.go | 6 +++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/executor/show.go b/executor/show.go index de25b448ef0fd..69fe15fa0000e 100644 --- a/executor/show.go +++ b/executor/show.go @@ -29,6 +29,10 @@ import ( "github.com/pingcap/parser/model" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" + "github.com/pingcap/tidb-tools/pkg/etcd" + "github.com/pingcap/tidb-tools/pkg/utils" + "github.com/pingcap/tidb-tools/tidb-binlog/node" + "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/privilege" "github.com/pingcap/tidb/sessionctx/stmtctx" @@ -41,6 +45,8 @@ import ( "golang.org/x/net/context" ) +var etcdDialTimeout = 5 * time.Second + // ShowExec represents a show executor. type ShowExec struct { baseExecutor @@ -107,6 +113,8 @@ func (e *ShowExec) fetchAll() error { return e.fetchShowCreateDatabase() case ast.ShowDatabases: return e.fetchShowDatabases() + case ast.ShowDrainerStatus: + return e.fetchShowPumpOrDrainerStatus(node.DrainerNode) case ast.ShowEngines: return e.fetchShowEngines() case ast.ShowGrants: @@ -115,6 +123,8 @@ func (e *ShowExec) fetchAll() error { return e.fetchShowIndex() case ast.ShowProcedureStatus: return e.fetchShowProcedureStatus() + case ast.ShowPumpStatus: + return e.fetchShowPumpOrDrainerStatus(node.PumpNode) case ast.ShowStatus: return e.fetchShowStatus() case ast.ShowTables: @@ -828,6 +838,43 @@ func (e *ShowExec) fetchShowWarnings(errOnly bool) error { return nil } +// fetchShowPumpOrDrainerStatus gets status of all pumps or drainers and fill them into e.rows. +func (e *ShowExec) fetchShowPumpOrDrainerStatus(kind string) error { + registry, err := createRegistry(config.GetGlobalConfig().Path) + if err != nil { + return errors.Trace(err) + } + + nodes, _, err := registry.Nodes(context.Background(), node.NodePrefix[kind]) + if err != nil { + return errors.Trace(err) + } + err = registry.Close() + if err != nil { + return errors.Trace(err) + } + + for _, n := range nodes { + e.appendRow([]interface{}{n.NodeID, n.Addr, n.State, n.MaxCommitTS, utils.TSOToRoughTime(n.UpdateTS).Format(types.TimeFormat)}) + } + + return nil +} + +// createRegistry returns an ectd registry +func createRegistry(urls string) (*node.EtcdRegistry, error) { + ectdEndpoints, err := utils.ParseHostPortAddr(urls) + if err != nil { + return nil, errors.Trace(err) + } + cli, err := etcd.NewClientFromCfg(ectdEndpoints, etcdDialTimeout, node.DefaultRootPath, nil) + if err != nil { + return nil, errors.Trace(err) + } + + return node.NewEtcdRegistry(cli, etcdDialTimeout), nil +} + func (e *ShowExec) getTable() (table.Table, error) { if e.Table == nil { return nil, errors.New("table not found") diff --git a/go.mod b/go.mod index cdf05c3016f22..3fba7f14b42c4 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,7 @@ require ( github.com/pingcap/gofail v0.0.0-20181217135706-6a951c1e42c3 github.com/pingcap/goleveldb v0.0.0-20171020084629-8d44bfdf1030 github.com/pingcap/kvproto v0.0.0-20190226063853-f6c0b7ffff11 - github.com/pingcap/parser v0.0.0-20190305073013-4f60445a0550 + github.com/pingcap/parser v0.0.0-20190326030543-750ee1d923e5 github.com/pingcap/pd v2.1.0-rc.4+incompatible github.com/pingcap/tidb-tools v2.1.3-0.20190116051332-34c808eef588+incompatible github.com/pingcap/tipb v0.0.0-20180910045846-371b48b15d93 @@ -81,5 +81,3 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.2.1 // indirect ) - -replace github.com/pingcap/parser => github.com/lysu/parser v0.0.0-20190325074808-d880cf39390b diff --git a/go.sum b/go.sum index 236bb1ebe2a46..ad7e211a06453 100644 --- a/go.sum +++ b/go.sum @@ -94,6 +94,8 @@ github.com/pingcap/goleveldb v0.0.0-20171020084629-8d44bfdf1030 h1:XJLuW0lsP7vAt github.com/pingcap/goleveldb v0.0.0-20171020084629-8d44bfdf1030/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= github.com/pingcap/kvproto v0.0.0-20190226063853-f6c0b7ffff11 h1:iGNfAHgK0VHJobW4bPTlFmdnt3YWsEHdSTIcjut6ffk= github.com/pingcap/kvproto v0.0.0-20190226063853-f6c0b7ffff11/go.mod h1:0gwbe1F2iBIjuQ9AH0DbQhL+Dpr5GofU8fgYyXk+ykk= +github.com/pingcap/parser v0.0.0-20190326030543-750ee1d923e5 h1:a7/kE/0gRUzO9ZpmantcRbTILozM8O5a1FCBg43eUQk= +github.com/pingcap/parser v0.0.0-20190326030543-750ee1d923e5/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE= github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E= github.com/pingcap/tidb-tools v2.1.3-0.20190116051332-34c808eef588+incompatible h1:e9Gi/LP9181HT3gBfSOeSBA+5JfemuE4aEAhqNgoE4k= diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index 475f353c769c8..66e82d8b79fc9 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -1621,6 +1621,9 @@ func buildShowSchema(s *ast.ShowStmt) (schema *expression.Schema) { names = []string{"Table", "Create Table"} case ast.ShowCreateDatabase: names = []string{"Database", "Create Database"} + case ast.ShowDrainerStatus: + names = []string{"NodeID", "Address", "State", "Max_Commit_Ts", "Update_Time"} + ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong, mysql.TypeVarchar} case ast.ShowGrants: names = []string{fmt.Sprintf("Grants for %s", s.User)} case ast.ShowIndex: @@ -1639,6 +1642,9 @@ func buildShowSchema(s *ast.ShowStmt) (schema *expression.Schema) { names = []string{"Id", "User", "Host", "db", "Command", "Time", "State", "Info", "Mem"} ftypes = []byte{mysql.TypeLonglong, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLong, mysql.TypeVarchar, mysql.TypeString, mysql.TypeLonglong} + case ast.ShowPumpStatus: + names = []string{"NodeID", "Address", "State", "Max_Commit_Ts", "Update_Time"} + ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong, mysql.TypeVarchar} case ast.ShowStatsMeta: names = []string{"Db_name", "Table_name", "Update_time", "Modify_count", "Row_count"} ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeDatetime, mysql.TypeLonglong, mysql.TypeLonglong}