From 209dd45fee9e5961d8fdf4dc4eea187af9c1cbfb Mon Sep 17 00:00:00 2001 From: lysu Date: Thu, 11 Jul 2019 12:44:55 +0800 Subject: [PATCH] infochema, server: export region_id in hot_region table (#10982) --- infoschema/tables.go | 27 ++++++++++++++-------- server/http_handler.go | 13 ++--------- store/helper/helper.go | 52 +++++++++++++++++++----------------------- 3 files changed, 43 insertions(+), 49 deletions(-) diff --git a/infoschema/tables.go b/infoschema/tables.go index a2ac042066c63..f233404f94b4c 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -563,6 +563,7 @@ var tableTiDBHotRegionsCols = []columnInfo{ {"DB_NAME", mysql.TypeVarchar, 64, 0, nil, nil}, {"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil}, {"INDEX_NAME", mysql.TypeVarchar, 64, 0, nil, nil}, + {"REGION_ID", mysql.TypeLonglong, 21, 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}, @@ -685,18 +686,18 @@ func dataForTikVRegionPeers(ctx sessionctx.Context) (records [][]types.Datum, er row[0].SetInt64(regionStat.ID) row[1].SetInt64(peer.ID) row[2].SetInt64(peer.StoreID) - if peer.ID == regionStat.Leader.ID { + if peer.IsLearner { row[3].SetInt64(1) } else { row[3].SetInt64(0) } - if peer.IsLearner { + if peer.ID == regionStat.Leader.ID { row[4].SetInt64(1) } else { - row[4].SetInt64(0) + row[3].SetInt64(0) } if pendingPeerIDSet.Exist(peer.ID) { - row[5].SetString(pendingPeer) + row[4].SetString(pendingPeer) } else if downSec, ok := downPeerMap[peer.ID]; ok { row[5].SetString(downPeer) row[6].SetInt64(downSec) @@ -1663,9 +1664,9 @@ func dataForTiDBHotRegions(ctx sessionctx.Context) (records [][]types.Datum, err return records, nil } -func dataForHotRegionByMetrics(metrics map[helper.TblIndex]helper.RegionMetric, tp string) [][]types.Datum { +func dataForHotRegionByMetrics(metrics []helper.HotTableIndex, tp string) [][]types.Datum { rows := make([][]types.Datum, 0, len(metrics)) - for tblIndex, regionMetric := range metrics { + for _, tblIndex := range metrics { row := make([]types.Datum, len(tableTiDBHotRegionsCols)) if tblIndex.IndexName != "" { row[1].SetInt64(tblIndex.IndexID) @@ -1677,10 +1678,16 @@ func dataForHotRegionByMetrics(metrics map[helper.TblIndex]helper.RegionMetric, 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) + row[5].SetUint64(tblIndex.RegionID) + row[6].SetString(tp) + if tblIndex.RegionMetric == nil { + row[7].SetNull() + row[8].SetNull() + } else { + row[7].SetInt64(int64(tblIndex.RegionMetric.MaxHotDegree)) + row[8].SetInt64(int64(tblIndex.RegionMetric.Count)) + } + row[9].SetUint64(tblIndex.RegionMetric.FlowBytes) rows = append(rows, row) } return rows diff --git a/server/http_handler.go b/server/http_handler.go index 3066317006480..3aad7dfe08d70 100644 --- a/server/http_handler.go +++ b/server/http_handler.go @@ -23,7 +23,6 @@ import ( "math" "net/http" "net/url" - "sort" "strconv" "strings" "sync/atomic" @@ -1068,17 +1067,9 @@ func (h regionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { writeError(w, err) return } - asSortedEntry := func(metric map[helper.TblIndex]helper.RegionMetric) hotRegions { - hs := make(hotRegions, 0, len(metric)) - for key, value := range metric { - hs = append(hs, hotRegion{key, value}) - } - sort.Sort(hs) - return hs - } writeData(w, map[string]interface{}{ - "write": asSortedEntry(hotWrite), - "read": asSortedEntry(hotRead), + "write": hotWrite, + "read": hotRead, }) return } diff --git a/store/helper/helper.go b/store/helper/helper.go index 6e0e250755778..d094744467dda 100644 --- a/store/helper/helper.go +++ b/store/helper/helper.go @@ -99,7 +99,7 @@ type RegionMetric struct { } // ScrapeHotInfo gets the needed hot region information by the url given. -func (h *Helper) ScrapeHotInfo(rw string, allSchemas []*model.DBInfo) (map[TblIndex]RegionMetric, error) { +func (h *Helper) ScrapeHotInfo(rw string, allSchemas []*model.DBInfo) ([]HotTableIndex, error) { regionMetrics, err := h.FetchHotRegion(rw) if err != nil { return nil, err @@ -121,9 +121,7 @@ func (h *Helper) FetchHotRegion(rw string) (map[uint64]RegionMetric, error) { if err != nil { return nil, errors.Trace(err) } - timeout, cancelFunc := context.WithTimeout(context.Background(), 50*time.Millisecond) - resp, err := http.DefaultClient.Do(req.WithContext(timeout)) - cancelFunc() + resp, err := http.DefaultClient.Do(req) if err != nil { return nil, errors.Trace(err) } @@ -175,10 +173,22 @@ type RegionFrameRange struct { region *tikv.KeyLocation // the region } -// FetchRegionTableIndex constructs a map that maps a table to its hot region information by the given raw hot region metrics. -func (h *Helper) FetchRegionTableIndex(metrics map[uint64]RegionMetric, allSchemas []*model.DBInfo) (map[TblIndex]RegionMetric, error) { - idxMetrics := make(map[TblIndex]RegionMetric) +// HotTableIndex contains region and its table/index info. +type HotTableIndex struct { + RegionID uint64 `json:"region_id"` + RegionMetric *RegionMetric `json:"region_metric"` + DbName string `json:"db_name"` + TableName string `json:"table_name"` + TableID int64 `json:"table_id"` + IndexName string `json:"index_name"` + IndexID int64 `json:"index_id"` +} + +// FetchRegionTableIndex constructs a map that maps a table to its hot region information by the given raw hot RegionMetric metrics. +func (h *Helper) FetchRegionTableIndex(metrics map[uint64]RegionMetric, allSchemas []*model.DBInfo) ([]HotTableIndex, error) { + hotTables := make([]HotTableIndex, 0, len(metrics)) for regionID, regionMetric := range metrics { + t := HotTableIndex{RegionID: regionID, RegionMetric: ®ionMetric} region, err := h.RegionCache.LocateRegionByID(tikv.NewBackoffer(context.Background(), 500), regionID) if err != nil { logutil.Logger(context.Background()).Error("locate region failed", zap.Error(err)) @@ -189,32 +199,18 @@ func (h *Helper) FetchRegionTableIndex(metrics map[uint64]RegionMetric, allSchem if err != nil { return nil, err } - f := h.FindTableIndexOfRegion(allSchemas, hotRange) if f != nil { - idx := TblIndex{ - DbName: f.DBName, - TableName: f.TableName, - TableID: f.TableID, - IndexName: f.IndexName, - IndexID: f.IndexID, - } - metric, exists := idxMetrics[idx] - if !exists { - metric = regionMetric - metric.Count++ - idxMetrics[idx] = metric - } else { - metric.FlowBytes += regionMetric.FlowBytes - if metric.MaxHotDegree < regionMetric.MaxHotDegree { - metric.MaxHotDegree = regionMetric.MaxHotDegree - } - metric.Count++ - } + t.DbName = f.DBName + t.TableName = f.TableName + t.TableID = f.TableID + t.IndexName = f.IndexName + t.IndexID = f.IndexID } + hotTables = append(hotTables, t) } - return idxMetrics, nil + return hotTables, nil } // FindTableIndexOfRegion finds what table is involved in this hot region. And constructs the new frame item for future use.