-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
add real tables for global/session status in performance schema #4523
Changes from all commits
9e4267d
b070112
c0e1fbf
2acc6c0
f530255
758c483
2a46e6d
f388d64
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright 2017 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package perfschema | ||
|
||
import ( | ||
"fmt" | ||
|
||
log "github.com/Sirupsen/logrus" | ||
"github.com/juju/errors" | ||
"github.com/pingcap/tidb/context" | ||
"github.com/pingcap/tidb/model" | ||
"github.com/pingcap/tidb/sessionctx/variable" | ||
"github.com/pingcap/tidb/table" | ||
"github.com/pingcap/tidb/table/tables" | ||
"github.com/pingcap/tidb/util/types" | ||
) | ||
|
||
// session/global status decided by scope. | ||
type statusDataSource struct { | ||
meta *model.TableInfo | ||
cols []*table.Column | ||
globalScope bool | ||
} | ||
|
||
// GetRows implements the interface of VirtualDataSource. | ||
func (ds *statusDataSource) GetRows(ctx context.Context) (fullRows [][]types.Datum, | ||
err error) { | ||
sessionVars := ctx.GetSessionVars() | ||
statusVars, err := variable.GetStatusVars(sessionVars) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
|
||
rows := [][]types.Datum{} | ||
for status, v := range statusVars { | ||
if ds.globalScope && v.Scope == variable.ScopeSession { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if data source is session scope and v.Scop == variable.ScopeGlobal ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. session status will show all status, including global andl local, global status will show global status only. |
||
continue | ||
} | ||
|
||
switch v.Value.(type) { | ||
case []interface{}, nil: | ||
v.Value = fmt.Sprintf("%v", v.Value) | ||
} | ||
value, err := types.ToString(v.Value) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
row := types.MakeDatums(status, value) | ||
rows = append(rows, row) | ||
} | ||
|
||
return rows, nil | ||
} | ||
|
||
// Meta implements the interface of VirtualDataSource. | ||
func (ds *statusDataSource) Meta() *model.TableInfo { | ||
return ds.meta | ||
} | ||
|
||
// Cols implements the interface of VirtualDataSource. | ||
func (ds *statusDataSource) Cols() []*table.Column { | ||
return ds.cols | ||
} | ||
|
||
func createVirtualDataSource(tableName string, meta *model.TableInfo) (tables.VirtualDataSource, error) { | ||
columns := make([]*table.Column, 0, len(meta.Columns)) | ||
for _, colInfo := range meta.Columns { | ||
col := table.ToColumn(colInfo) | ||
columns = append(columns, col) | ||
} | ||
|
||
switch tableName { | ||
case TableSessionStatus: | ||
return &statusDataSource{meta: meta, cols: columns, globalScope: false}, nil | ||
case TableGlobalStatus: | ||
return &statusDataSource{meta: meta, cols: columns, globalScope: true}, nil | ||
default: | ||
return nil, errors.New("can't find table named by " + tableName) | ||
} | ||
} | ||
|
||
func createVirtualTable(meta *model.TableInfo, tableName string) table.Table { | ||
dataSource, err := createVirtualDataSource(tableName, meta) | ||
if err != nil { | ||
log.Fatal(err.Error()) | ||
} | ||
return tables.CreateVirtualTable(dataSource) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Copyright 2017 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package perfschema | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/juju/errors" | ||
. "github.com/pingcap/check" | ||
"github.com/pingcap/tidb/store/localstore" | ||
"github.com/pingcap/tidb/store/localstore/goleveldb" | ||
"github.com/pingcap/tidb/util/mock" | ||
"github.com/pingcap/tidb/util/types" | ||
) | ||
|
||
func TestT(t *testing.T) { | ||
CustomVerboseFlag = true | ||
TestingT(t) | ||
} | ||
|
||
var _ = Suite(&testSuite{}) | ||
|
||
type testSuite struct { | ||
} | ||
|
||
func (*testSuite) TestSessionStatus(c *C) { | ||
driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}} | ||
store, err := driver.Open("memory") | ||
c.Assert(err, IsNil) | ||
|
||
ctx := mock.NewContext() | ||
ctx.Store = store | ||
ps := newPerfHandle() | ||
|
||
testTableName := []string{TableSessionStatus, TableGlobalStatus} | ||
for _, tableName := range testTableName { | ||
tb, _ := ps.GetTable(tableName) | ||
meta := ps.tables[tableName] | ||
c.Assert(tb, NotNil) | ||
|
||
sessionStatusHandle, _ := createVirtualDataSource(tableName, meta) | ||
rows, err := sessionStatusHandle.GetRows(ctx) | ||
c.Assert(err, IsNil) | ||
|
||
c.Assert(findSpecialStatus(rows, "Ssl_cipher"), IsNil) | ||
} | ||
} | ||
|
||
func findSpecialStatus(rows [][]types.Datum, name string) error { | ||
err := errors.New("cant find the status " + name) | ||
for _, row := range rows { | ||
statusNames, _ := row[0].ToString() | ||
if statusNames == name { | ||
err = nil | ||
break | ||
} | ||
} | ||
|
||
return err | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,18 @@ import ( | |
"github.com/pingcap/tidb/util/types" | ||
) | ||
|
||
// Type , the type of table, store data in different ways. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why add a space between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the rule of golint, otherwise it will report like this, "comment on exported type Type should be of the form "Type ..." (with optional leading article)" |
||
type Type int16 | ||
|
||
const ( | ||
// NormalTable , store data in tikv, mocktikv and so on. | ||
NormalTable Type = iota | ||
// VirtualTable , store no data, just extract data from the memory struct. | ||
VirtualTable | ||
// MemoryTable , store data only in local memory. | ||
MemoryTable | ||
) | ||
|
||
var ( | ||
// errNoDefaultValue is used when insert a row, the column value is not given, and the column has not null flag | ||
// and it doesn't have a default value. | ||
|
@@ -124,6 +136,9 @@ type Table interface { | |
|
||
// Seek returns the handle greater or equal to h. | ||
Seek(ctx context.Context, h int64) (handle int64, found bool, err error) | ||
|
||
// Type returns the type of table | ||
Type() Type | ||
} | ||
|
||
// TableFromMeta builds a table.Table from *model.TableInfo. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a blank line between system packages and custom packages like other files do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok