From 75b9470a74f5beab394d872f6fd68bab14152459 Mon Sep 17 00:00:00 2001 From: Feng Liyuan Date: Thu, 20 Jun 2019 11:48:49 +0800 Subject: [PATCH] *: add a column describing memory usage for table information_schema.processlist (#10837) *: add a column describing memory usage for table information_schema.processlist Closes #10199 --- executor/show.go | 2 +- infoschema/tables.go | 3 ++- infoschema/tables_test.go | 28 +++++++++++++++++++++++----- planner/core/logical_plans.go | 2 +- session/session.go | 2 +- util/misc_test.go | 14 ++++++++++++-- util/processinfo.go | 10 ++++++++-- 7 files changed, 48 insertions(+), 13 deletions(-) diff --git a/executor/show.go b/executor/show.go index b61941c203856..cc73b18a3d62e 100644 --- a/executor/show.go +++ b/executor/show.go @@ -269,7 +269,7 @@ func (e *ShowExec) fetchShowProcessList() error { if !hasProcessPriv && pi.User != loginUser.Username { continue } - row := pi.ToRow(e.Full) + row := pi.ToRowForShow(e.Full) e.appendRow(row) } return nil diff --git a/infoschema/tables.go b/infoschema/tables.go index 4a64164f69127..272e00da60995 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -543,6 +543,7 @@ var tableProcesslistCols = []columnInfo{ {"TIME", mysql.TypeLong, 7, mysql.NotNullFlag, 0, nil}, {"STATE", mysql.TypeVarchar, 7, 0, nil, nil}, {"INFO", mysql.TypeString, 512, 0, nil, nil}, + {"MEM", mysql.TypeLonglong, 21, 0, nil, nil}, } var tableTiDBIndexesCols = []columnInfo{ @@ -861,7 +862,7 @@ func dataForProcesslist(ctx sessionctx.Context) [][]types.Datum { continue } - rows := pi.ToRow(true) + rows := pi.ToRow() record := types.MakeDatums(rows...) records = append(records, record) } diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 6788d585656d3..a7ce9a22131ed 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -17,6 +17,7 @@ import ( "fmt" "os" "strconv" + "strings" . "github.com/pingcap/check" "github.com/pingcap/parser/auth" @@ -114,6 +115,7 @@ func (s *testTableSuite) TestInfoschemaFieldValue(c *C) { User: "root", Host: "127.0.0.1", Command: mysql.ComQuery, + StmtCtx: tk.Se.GetSessionVars().StmtCtx, } tk.Se.SetSessionManager(sm) tk.MustQuery("SELECT user,host,command FROM information_schema.processlist;").Check(testkit.Rows("root 127.0.0.1 Query")) @@ -275,7 +277,9 @@ func (s *testTableSuite) TestSomeTables(c *C) { DB: "information_schema", Command: byte(1), State: 1, - Info: "do something"} + Info: "do something", + StmtCtx: tk.Se.GetSessionVars().StmtCtx, + } sm.processInfoMap[2] = &util.ProcessInfo{ ID: 2, User: "user-2", @@ -283,11 +287,25 @@ func (s *testTableSuite) TestSomeTables(c *C) { DB: "test", Command: byte(2), State: 2, - Info: "do something"} + Info: strings.Repeat("x", 101), + StmtCtx: tk.Se.GetSessionVars().StmtCtx, + } tk.Se.SetSessionManager(sm) - tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Check( - testkit.Rows("1 user-1 localhost information_schema Quit 9223372036 1 do something", - "2 user-2 localhost test Init DB 9223372036 2 do something")) + tk.MustQuery("select * from information_schema.PROCESSLIST order by ID;").Sort().Check( + testkit.Rows( + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s 0", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s 0", strings.Repeat("x", 101)), + )) + tk.MustQuery("SHOW PROCESSLIST;").Sort().Check( + testkit.Rows( + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s", strings.Repeat("x", 100)), + )) + tk.MustQuery("SHOW FULL PROCESSLIST;").Sort().Check( + testkit.Rows( + fmt.Sprintf("1 user-1 localhost information_schema Quit 9223372036 1 %s", "do something"), + fmt.Sprintf("2 user-2 localhost test Init DB 9223372036 2 %s", strings.Repeat("x", 101)), + )) } func (s *testTableSuite) TestSchemataCharacterSet(c *C) { diff --git a/planner/core/logical_plans.go b/planner/core/logical_plans.go index 98a97c2ab6713..845c9cc6f55ac 100644 --- a/planner/core/logical_plans.go +++ b/planner/core/logical_plans.go @@ -318,7 +318,7 @@ type LogicalUnionScan struct { conditions []expression.Expression } -// DataSource represents a tablescan without condition push down. +// DataSource represents a tableScan without condition push down. type DataSource struct { logicalSchemaProducer diff --git a/session/session.go b/session/session.go index 56e30f70d3c7b..19bbfb182f3a8 100644 --- a/session/session.go +++ b/session/session.go @@ -97,7 +97,7 @@ var ( sessionExecuteParseDurationGeneral = metrics.SessionExecuteParseDuration.WithLabelValues(metrics.LblGeneral) ) -// Session context +// Session context, it is consistent with the lifecycle of a client connection. type Session interface { sessionctx.Context Status() uint16 // Flag of current status, such as autocommit. diff --git a/util/misc_test.go b/util/misc_test.go index 86ff839ad1f80..7c365a98fdb5a 100644 --- a/util/misc_test.go +++ b/util/misc_test.go @@ -22,6 +22,9 @@ import ( "github.com/pingcap/parser" "github.com/pingcap/parser/mysql" "github.com/pingcap/parser/terror" + "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/util/memory" + "github.com/pingcap/tidb/util/stringutil" "github.com/pingcap/tidb/util/testleak" ) @@ -152,9 +155,12 @@ func (s *testMiscSuite) TestBasicFunc(c *C) { Time: time.Now(), State: 1, Info: "test", + StmtCtx: &stmtctx.StatementContext{ + MemTracker: memory.NewTracker(stringutil.StringerStr(""), -1), + }, } - row := pi.ToRow(false) - row2 := pi.ToRow(true) + row := pi.ToRowForShow(false) + row2 := pi.ToRowForShow(true) c.Assert(row, DeepEquals, row2) c.Assert(len(row), Equals, 8) c.Assert(row[0], Equals, pi.ID) @@ -166,6 +172,10 @@ func (s *testMiscSuite) TestBasicFunc(c *C) { c.Assert(row[6], Equals, "1") c.Assert(row[7], Equals, "test") + row3 := pi.ToRow() + c.Assert(row3[:8], DeepEquals, row) + c.Assert(row3[8], Equals, int64(0)) + // Test for RandomBuf. buf := RandomBuf(5) c.Assert(len(buf), Equals, 5) diff --git a/util/processinfo.go b/util/processinfo.go index 956196cdfdb42..a2f5aa4b1a099 100644 --- a/util/processinfo.go +++ b/util/processinfo.go @@ -38,8 +38,8 @@ type ProcessInfo struct { ExceedExpensiveTimeThresh bool } -// ToRow returns []interface{} for the row data of "show processlist" and "select * from infoschema.processlist". -func (pi *ProcessInfo) ToRow(full bool) []interface{} { +// ToRowForShow returns []interface{} for the row data of "SHOW [FULL] PROCESSLIST". +func (pi *ProcessInfo) ToRowForShow(full bool) []interface{} { var info string if full { info = pi.Info @@ -59,6 +59,12 @@ func (pi *ProcessInfo) ToRow(full bool) []interface{} { } } +// ToRow returns []interface{} for the row data of +// "SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST". +func (pi *ProcessInfo) ToRow() []interface{} { + return append(pi.ToRowForShow(true), pi.StmtCtx.MemTracker.BytesConsumed()) +} + // SessionManager is an interface for session manage. Show processlist and // kill statement rely on this interface. type SessionManager interface {