Merge pull request #888 from nieyy/master

performance_schema: code refactoring and remove old implementation
This commit is contained in:
cuiqiu
2016-02-02 16:01:09 +08:00
6 changed files with 504 additions and 1103 deletions

125
perfschema/common.go Normal file
View File

@ -0,0 +1,125 @@
// Copyright 2016 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 (
"strings"
"github.com/juju/errors"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/util/codec"
"github.com/pingcap/tidb/util/types"
)
// castValues casts values based on columns type.
func castValues(rec []interface{}, cols []*model.ColumnInfo) (err error) {
for _, c := range cols {
rec[c.Offset], err = types.Convert(rec[c.Offset], &c.FieldType)
if err != nil {
return errors.Trace(err)
}
}
return nil
}
// checkNotNull checks if nil value set to a column with NotNull flag is set.
func checkNotNull(c *model.ColumnInfo, data interface{}) error {
if mysql.HasNotNullFlag(c.Flag) && data == nil {
return errors.Errorf("Column %s can't be null.", c.Name)
}
return nil
}
// checkNotNulls checks if row has nil value set to a set of columns with NotNull flag set.
func checkNotNulls(cols []*model.ColumnInfo, row []interface{}) error {
for _, c := range cols {
if err := checkNotNull(c, row[c.Offset]); err != nil {
return errors.Trace(err)
}
}
return nil
}
func decodeValue(data []byte, cols []*model.ColumnInfo) ([]interface{}, error) {
values, err := codec.Decode(data)
if err != nil {
return nil, errors.Trace(err)
}
if len(values) != len(cols) {
return nil, errors.Errorf("Column count does not match, expect %d, actual %d", len(cols), len(values))
}
var rvalues []interface{}
for i, col := range cols {
// TODO: support more types if we really need.
switch col.Tp {
case mysql.TypeString, mysql.TypeVarchar:
val := string(values[i].([]byte))
rvalues = append(rvalues, val)
case mysql.TypeEnum:
val, err := mysql.ParseEnumValue(col.Elems, values[i].(uint64))
if err != nil {
return nil, errors.Trace(err)
}
rvalues = append(rvalues, val.String())
}
}
return rvalues, nil
}
// findCol finds column in cols by name.
func findCol(cols []*model.ColumnInfo, name string) *model.ColumnInfo {
for _, col := range cols {
if strings.EqualFold(col.Name.O, name) {
return col
}
}
return nil
}
// findCols finds columns in cols by names.
func findCols(cols []*model.ColumnInfo, names []string) ([]*model.ColumnInfo, error) {
var rcols []*model.ColumnInfo
for _, name := range names {
col := findCol(cols, name)
if col != nil {
rcols = append(rcols, col)
} else {
return nil, errors.Errorf("unknown column %s", name)
}
}
return rcols, nil
}
// getColDefaultValue gets default value of the column.
func getColDefaultValue(col *model.ColumnInfo) (interface{}, bool, error) {
// Check no default value flag.
if mysql.HasNoDefaultValueFlag(col.Flag) && col.Tp != mysql.TypeEnum {
return nil, false, errors.Errorf("Field '%s' doesn't have a default value", col.Name)
}
// Check and get timestamp/datetime default value.
if col.Tp == mysql.TypeEnum {
// For enum type, if no default value and not null is set,
// the default value is the first element of the enum list
if col.DefaultValue == nil && mysql.HasNotNullFlag(col.Flag) {
return col.FieldType.Elems[0], true, nil
}
}
return col.DefaultValue, true, nil
}

379
perfschema/const.go Normal file
View File

@ -0,0 +1,379 @@
// Copyright 2016 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
// Performance Schema Name.
const (
Name = "PERFORMANCE_SCHEMA"
)
// Definition order same as MySQL's reference manual, so don't bother to
// adjust according to alphabetical order.
const (
TableSetupActors = "SETUP_ACTORS"
TableSetupObjects = "SETUP_OBJECTS"
TableSetupInstruments = "SETUP_INSTRUMENTS"
TableSetupConsumers = "SETUP_CONSUMERS"
TableSetupTimers = "SETUP_TIMERS"
TableStmtsCurrent = "EVENTS_STATEMENTS_CURRENT"
TableStmtsHistory = "EVENTS_STATEMENTS_HISTORY"
TableStmtsHistoryLong = "EVENTS_STATEMENTS_HISTORY_LONG"
TablePreparedStmtsInstances = "PREPARED_STATEMENTS_INSTANCES"
TableTransCurrent = "EVENTS_TRANSACTIONS_CURRENT"
TableTransHistory = "EVENTS_TRANSACTIONS_HISTORY"
TableTransHistoryLong = "EVENTS_TRANSACTIONS_HISTORY_LONG"
TableStagesCurrent = "EVENTS_STAGES_CURRENT"
TableStagesHistory = "EVENTS_STAGES_HISTORY"
TableStagesHistoryLong = "EVENTS_STAGES_HISTORY_LONG"
)
// PerfSchemaTables is a shortcut to involve all table names.
var PerfSchemaTables = []string{
TableSetupActors,
TableSetupObjects,
TableSetupInstruments,
TableSetupConsumers,
TableSetupTimers,
TableStmtsCurrent,
TableStmtsHistory,
TableStmtsHistoryLong,
TablePreparedStmtsInstances,
TableTransCurrent,
TableTransHistory,
TableTransHistoryLong,
TableStagesCurrent,
TableStagesHistory,
TableStagesHistoryLong,
}
// ColumnSetupActors contains the column name definitions for table setup_actors, same as MySQL.
var ColumnSetupActors = []string{"HOST", "USER", "ROLE", "ENABLED", "HISTORY"}
// ColumnSetupObjects contains the column name definitions for table setup_objects, same as MySQL.
var ColumnSetupObjects = []string{"OBJECT_TYPE", "OBJECT_SCHEMA", "OBJECT_NAME", "ENABLED", "TIMED"}
// ColumnSetupInstruments contains the column name definitions for table setup_instruments, same as MySQL.
var ColumnSetupInstruments = []string{"NAMED", "ENABLED", "TIMED"}
// ColumnSetupConsumers contains the column name definitions for table setup_consumers, same as MySQL.
var ColumnSetupConsumers = []string{"NAMED", "ENABLED"}
// ColumnSetupTimers contains the column name definitions for table setup_timers, same as MySQL.
var ColumnSetupTimers = []string{"NAME", "TIMER_NAME"}
// ColumnStmtsCurrent contains the column name definitions for table events_statements_current, same as MySQL.
var ColumnStmtsCurrent = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"LOCK_TIME",
"SQL_TEXT",
"DIGEST",
"DIGEST_TEXT",
"CURRENT_SCHEMA",
"OBJECT_TYPE",
"OBJECT_SCHEMA",
"OBJECT_NAME",
"OBJECT_INSTANCE_BEGIN",
"MYSQL_ERRNO",
"RETURNED_SQLSTATE",
"MESSAGE_TEXT",
"ERRORS",
"WARNINGS",
"ROWS_AFFECTED",
"ROWS_SENT",
"ROWS_EXAMINED",
"CREATED_TMP_DISK_TABLES",
"CREATED_TMP_TABLES",
"SELECT_FULL_JOIN",
"SELECT_FULL_RANGE_JOIN",
"SELECT_RANGE",
"SELECT_RANGE_CHECK",
"SELECT_SCAN",
"SORT_MERGE_PASSES",
"SORT_RANGE",
"SORT_ROWS",
"SORT_SCAN",
"NO_INDEX_USED",
"NO_GOOD_INDEX_USED",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
"NESTING_EVENT_LEVEL",
}
// ColumnStmtsHistory contains the column name definitions for table events_statements_history, same as MySQL.
var ColumnStmtsHistory = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"LOCK_TIME",
"SQL_TEXT",
"DIGEST",
"DIGEST_TEXT",
"CURRENT_SCHEMA",
"OBJECT_TYPE",
"OBJECT_SCHEMA",
"OBJECT_NAME",
"OBJECT_INSTANCE_BEGIN",
"MYSQL_ERRNO",
"RETURNED_SQLSTATE",
"MESSAGE_TEXT",
"ERRORS",
"WARNINGS",
"ROWS_AFFECTED",
"ROWS_SENT",
"ROWS_EXAMINED",
"CREATED_TMP_DISK_TABLES",
"CREATED_TMP_TABLES",
"SELECT_FULL_JOIN",
"SELECT_FULL_RANGE_JOIN",
"SELECT_RANGE",
"SELECT_RANGE_CHECK",
"SELECT_SCAN",
"SORT_MERGE_PASSES",
"SORT_RANGE",
"SORT_ROWS",
"SORT_SCAN",
"NO_INDEX_USED",
"NO_GOOD_INDEX_USED",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
"NESTING_EVENT_LEVEL",
}
// ColumnStmtsHistoryLong contains the column name definitions for table events_statements_history_long, same as MySQL.
var ColumnStmtsHistoryLong = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"LOCK_TIME",
"SQL_TEXT",
"DIGEST",
"DIGEST_TEXT",
"CURRENT_SCHEMA",
"OBJECT_TYPE",
"OBJECT_SCHEMA",
"OBJECT_NAME",
"OBJECT_INSTANCE_BEGIN",
"MYSQL_ERRNO",
"RETURNED_SQLSTATE",
"MESSAGE_TEXT",
"ERRORS",
"WARNINGS",
"ROWS_AFFECTED",
"ROWS_SENT",
"ROWS_EXAMINED",
"CREATED_TMP_DISK_TABLES",
"CREATED_TMP_TABLES",
"SELECT_FULL_JOIN",
"SELECT_FULL_RANGE_JOIN",
"SELECT_RANGE",
"SELECT_RANGE_CHECK",
"SELECT_SCAN",
"SORT_MERGE_PASSES",
"SORT_RANGE",
"SORT_ROWS",
"SORT_SCAN",
"NO_INDEX_USED",
"NO_GOOD_INDEX_USED",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
"NESTING_EVENT_LEVEL",
}
// ColumnPreparedStmtsInstances contains the column name definitions for table prepared_statements_instances, same as MySQL.
var ColumnPreparedStmtsInstances = []string{
"OBJECT_INSTANCE_BEGIN",
"STATEMENT_ID",
"STATEMENT_NAME",
"SQL_TEXT",
"OWNER_THREAD_ID",
"OWNER_EVENT_ID",
"OWNER_OBJECT_TYPE",
"OWNER_OBJECT_SCHEMA",
"OWNER_OBJECT_NAME",
"TIMER_PREPARE",
"COUNT_REPREPARE",
"COUNT_EXECUTE",
"SUM_TIMER_EXECUTE",
"MIN_TIMER_EXECUTE",
"AVG_TIMER_EXECUTE",
"MAX_TIMER_EXECUTE",
"SUM_LOCK_TIME",
"SUM_ERRORS",
"SUM_WARNINGS",
"SUM_ROWS_AFFECTED",
"SUM_ROWS_SENT",
"SUM_ROWS_EXAMINED",
"SUM_CREATED_TMP_DISK_TABLES",
"SUM_CREATED_TMP_TABLES",
"SUM_SELECT_FULL_JOIN",
"SUM_SELECT_FULL_RANGE_JOIN",
"SUM_SELECT_RANGE",
"SUM_SELECT_RANGE_CHECK",
"SUM_SELECT_SCAN",
"SUM_SORT_MERGE_PASSES",
"SUM_SORT_RANGE",
"SUM_SORT_ROWS",
"SUM_SORT_SCAN",
"SUM_NO_INDEX_USED",
"SUM_NO_GOOD_INDEX_USED",
}
// ColumnTransCurrent contains the column name definitions for table events_transactions_current, same as MySQL.
var ColumnTransCurrent = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"STATE",
"TRX_ID",
"GTID",
"XID_FORMAT_ID",
"XID_GTRID",
"XID_BQUAL",
"XA_STATE",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"ACCESS_MODE",
"ISOLATION_LEVEL",
"AUTOCOMMIT",
"NUMBER_OF_SAVEPOINTS",
"NUMBER_OF_ROLLBACK_TO_SAVEPOINT",
"NUMBER_OF_RELEASE_SAVEPOINT",
"OBJECT_INSTANCE_BEGIN",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
}
// ColumnTransHistory contains the column name definitions for table events_transactions_history, same as MySQL.
var ColumnTransHistory = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"STATE",
"TRX_ID",
"GTID",
"XID_FORMAT_ID",
"XID_GTRID",
"XID_BQUAL",
"XA_STATE",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"ACCESS_MODE",
"ISOLATION_LEVEL",
"AUTOCOMMIT",
"NUMBER_OF_SAVEPOINTS",
"NUMBER_OF_ROLLBACK_TO_SAVEPOINT",
"NUMBER_OF_RELEASE_SAVEPOINT",
"OBJECT_INSTANCE_BEGIN",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
}
// ColumnTransHistoryLong contains the column name definitions for table events_transactions_history_long, same as MySQL.
var ColumnTransHistoryLong = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"STATE",
"TRX_ID",
"GTID",
"XID_FORMAT_ID",
"XID_GTRID",
"XID_BQUAL",
"XA_STATE",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"ACCESS_MODE",
"ISOLATION_LEVEL",
"AUTOCOMMIT",
"NUMBER_OF_SAVEPOINTS",
"NUMBER_OF_ROLLBACK_TO_SAVEPOINT",
"NUMBER_OF_RELEASE_SAVEPOINT",
"OBJECT_INSTANCE_BEGIN",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
}
// ColumnStagesCurrent contains the column name definitions for table events_stages_current, same as MySQL.
var ColumnStagesCurrent = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"WORK_COMPLETED",
"WORK_ESTIMATED",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
}
// ColumnStagesHistory contains the column name definitions for table events_stages_history, same as MySQL.
var ColumnStagesHistory = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"WORK_COMPLETED",
"WORK_ESTIMATED",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
}
// ColumnStagesHistoryLong contains the column name definitions for table events_stages_history_long, same as MySQL.
var ColumnStagesHistoryLong = []string{
"THREAD_ID",
"EVENT_ID",
"END_EVENT_ID",
"EVENT_NAME",
"SOURCE",
"TIMER_START",
"TIMER_END",
"TIMER_WAIT",
"WORK_COMPLETED",
"WORK_ESTIMATED",
"NESTING_EVENT_ID",
"NESTING_EVENT_TYPE",
}

View File

@ -1,19 +0,0 @@
// Copyright 2016 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
// Performance Schema Name.
const (
Name = "PERFORMANCE_SCHEMA"
)

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +0,0 @@
// Copyright 2016 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 plans_test
import (
"database/sql"
. "github.com/pingcap/check"
"github.com/pingcap/tidb"
)
type testPerfSchemaSuit struct {
vars map[string]interface{}
}
var _ = Suite(&testPerfSchemaSuit{
vars: make(map[string]interface{}),
})
func (p *testPerfSchemaSuit) TestPerfSchema(c *C) {
testDB, err := sql.Open(tidb.DriverName, tidb.EngineGoLevelDBMemory+"/test/test")
c.Assert(err, IsNil)
cnt := mustQuery(c, testDB, "select * from performance_schema.setup_actors")
c.Assert(cnt, Equals, 1)
cnt = mustQuery(c, testDB, "select * from performance_schema.setup_objects")
c.Assert(cnt, Equals, 12)
// Note: so far, there has no instrumentation point yet
cnt = mustQuery(c, testDB, "select * from performance_schema.setup_instruments")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.setup_consumers")
c.Assert(cnt, Equals, 12)
cnt = mustQuery(c, testDB, "select * from performance_schema.setup_timers")
c.Assert(cnt, Equals, 3)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_statements_current")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_statements_history")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_statements_history_long")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.prepared_statements_instances")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_transactions_current")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_transactions_history")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_transactions_history_long")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_stages_current")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_stages_history")
c.Assert(cnt, Equals, 0)
cnt = mustQuery(c, testDB, "select * from performance_schema.events_stages_history_long")
c.Assert(cnt, Equals, 0)
}

View File

@ -26,7 +26,6 @@ import (
"github.com/pingcap/tidb/field"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/perfschema"
"github.com/pingcap/tidb/plan"
"github.com/pingcap/tidb/plan/plans"
"github.com/pingcap/tidb/sessionctx"
@ -49,9 +48,6 @@ func (r *TableRset) Plan(ctx context.Context) (plan.Plan, error) {
if strings.EqualFold(r.Schema, infoschema.Name) {
return plans.NewInfoSchemaPlan(r.Name)
}
if strings.EqualFold(r.Schema, perfschema.Name) {
return plans.NewPerfSchemaPlan(r.Name)
}
is := sessionctx.GetDomain(ctx).InfoSchema()
t, err := is.TableByName(model.NewCIStr(r.Schema), model.NewCIStr(r.Name))
if err != nil {