Skip to content

Commit

Permalink
infoschema: add mem table to show hot region (#10106)
Browse files Browse the repository at this point in the history
  • Loading branch information
winoros authored and zz-jason committed Apr 18, 2019
1 parent 1c63151 commit 76e0a91
Show file tree
Hide file tree
Showing 9 changed files with 388 additions and 234 deletions.
11 changes: 2 additions & 9 deletions domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ package domain

import (
"context"
"crypto/tls"
"os"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -44,6 +43,7 @@ import (
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/statistics/handle"
"github.com/pingcap/tidb/store/tikv"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/logutil"
"github.com/pingcap/tidb/util/sqlexec"
Expand Down Expand Up @@ -563,13 +563,6 @@ func (c *ddlCallback) OnChanged(err error) error {
return nil
}

// EtcdBackend is used for judging a storage is a real TiKV.
type EtcdBackend interface {
EtcdAddrs() []string
TLSConfig() *tls.Config
StartGCWorker() error
}

const resourceIdleTimeout = 3 * time.Minute // resources in the ResourcePool will be recycled after idleTimeout

// NewDomain creates a new domain. Should not create multiple domains for the same store.
Expand All @@ -589,7 +582,7 @@ func NewDomain(store kv.Storage, ddlLease time.Duration, statsLease time.Duratio
// Init initializes a domain.
func (do *Domain) Init(ddlLease time.Duration, sysFactory func(*Domain) (pools.Resource, error)) error {
perfschema.Init()
if ebd, ok := do.store.(EtcdBackend); ok {
if ebd, ok := do.store.(tikv.EtcdBackend); ok {
if addrs := ebd.EtcdAddrs(); addrs != nil {
cfg := config.GetGlobalConfig()
cli, err := clientv3.New(clientv3.Config{
Expand Down
66 changes: 66 additions & 0 deletions infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"sync"
"time"

"github.com/pingcap/errors"
"github.com/pingcap/parser/charset"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
Expand All @@ -27,8 +28,11 @@ import (
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/store/helper"
"github.com/pingcap/tidb/store/tikv"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/pdapi"
"github.com/pingcap/tidb/util/sqlexec"
)

Expand Down Expand Up @@ -67,6 +71,7 @@ const (
tableProcesslist = "PROCESSLIST"
tableTiDBIndexes = "TIDB_INDEXES"
tableSlowLog = "SLOW_QUERY"
tableTiDBHotRegions = "TIDB_HOT_REGIONS"
)

type columnInfo struct {
Expand Down Expand Up @@ -544,6 +549,18 @@ var tableTiDBIndexesCols = []columnInfo{
{"INDEX_ID", mysql.TypeLonglong, 21, 0, nil, nil},
}

var tableTiDBHotRegionsCols = []columnInfo{
{"TABLE_ID", mysql.TypeLonglong, 21, 0, nil, nil},
{"INDEX_ID", mysql.TypeLonglong, 21, 0, nil, nil},
{"DB_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"INDEX_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
{"MAX_HOT_DEGREE", mysql.TypeLonglong, 21, 0, nil, nil},
{"REGION_COUNT", mysql.TypeLonglong, 21, 0, nil, nil},
{"FLOW_BYTES", mysql.TypeLonglong, 21, 0, nil, nil},
}

func dataForCharacterSets() (records [][]types.Datum) {

charsets := charset.GetAllCharsets()
Expand Down Expand Up @@ -1418,6 +1435,52 @@ func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]typ
return rows
}

func dataForTiDBHotRegions(ctx sessionctx.Context) (records [][]types.Datum, err error) {
tikvStore, ok := ctx.GetStore().(tikv.Storage)
if !ok {
return nil, errors.New("Information about hot region can be gotten only when the storage is TiKV")
}
allSchemas := ctx.GetSessionVars().TxnCtx.InfoSchema.(InfoSchema).AllSchemas()
tikvHelper := &helper.Helper{
Store: tikvStore,
RegionCache: tikvStore.GetRegionCache(),
}
metrics, err := tikvHelper.ScrapeHotInfo(pdapi.HotRead, allSchemas)
if err != nil {
return nil, err
}
records = append(records, dataForHotRegionByMetrics(metrics, "read")...)
metrics, err = tikvHelper.ScrapeHotInfo(pdapi.HotWrite, allSchemas)
if err != nil {
return nil, err
}
records = append(records, dataForHotRegionByMetrics(metrics, "write")...)
return records, nil
}

func dataForHotRegionByMetrics(metrics map[helper.TblIndex]helper.RegionMetric, tp string) [][]types.Datum {
rows := make([][]types.Datum, 0, len(metrics))
for tblIndex, regionMetric := range metrics {
row := make([]types.Datum, len(tableTiDBHotRegionsCols))
if tblIndex.IndexName != "" {
row[1].SetInt64(tblIndex.IndexID)
row[4].SetString(tblIndex.IndexName)
} else {
row[1].SetNull()
row[4].SetNull()
}
row[0].SetInt64(tblIndex.TableID)
row[2].SetString(tblIndex.DbName)
row[3].SetString(tblIndex.TableName)
row[5].SetString(tp)
row[6].SetInt64(int64(regionMetric.MaxHotDegree))
row[7].SetInt64(int64(regionMetric.Count))
row[8].SetUint64(regionMetric.FlowBytes)
rows = append(rows, row)
}
return rows
}

var tableNameToColumns = map[string][]columnInfo{
tableSchemata: schemataCols,
tableTables: tablesCols,
Expand Down Expand Up @@ -1452,6 +1515,7 @@ var tableNameToColumns = map[string][]columnInfo{
tableProcesslist: tableProcesslistCols,
tableTiDBIndexes: tableTiDBIndexesCols,
tableSlowLog: slowQueryCols,
tableTiDBHotRegions: tableTiDBHotRegionsCols,
}

func createInfoSchemaTable(handle *Handle, meta *model.TableInfo) *infoschemaTable {
Expand Down Expand Up @@ -1545,6 +1609,8 @@ func (it *infoschemaTable) getRows(ctx sessionctx.Context, cols []*table.Column)
fullRows = dataForProcesslist(ctx)
case tableSlowLog:
fullRows, err = dataForSlowLog(ctx)
case tableTiDBHotRegions:
fullRows, err = dataForTiDBHotRegions(ctx)
}
if err != nil {
return nil, err
Expand Down
Loading

0 comments on commit 76e0a91

Please sign in to comment.