216 lines
7.9 KiB
Go
216 lines
7.9 KiB
Go
// Copyright 2021 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,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package telemetry
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"go.uber.org/atomic"
|
|
)
|
|
|
|
var (
|
|
// CurrentExecuteCount is CurrentExecuteCount
|
|
CurrentExecuteCount atomic.Uint64
|
|
// CurrentTiFlashPushDownCount is CurrentTiFlashPushDownCount
|
|
CurrentTiFlashPushDownCount atomic.Uint64
|
|
// CurrentTiFlashExchangePushDownCount is CurrentTiFlashExchangePushDownCount
|
|
CurrentTiFlashExchangePushDownCount atomic.Uint64
|
|
// CurrentCoprCacheHitRatioGTE0Count is CurrentCoprCacheHitRatioGTE0Count
|
|
CurrentCoprCacheHitRatioGTE0Count atomic.Uint64
|
|
// CurrentCoprCacheHitRatioGTE1Count is CurrentCoprCacheHitRatioGTE1Count
|
|
CurrentCoprCacheHitRatioGTE1Count atomic.Uint64
|
|
// CurrentCoprCacheHitRatioGTE10Count is CurrentCoprCacheHitRatioGTE10Count
|
|
CurrentCoprCacheHitRatioGTE10Count atomic.Uint64
|
|
// CurrentCoprCacheHitRatioGTE20Count is CurrentCoprCacheHitRatioGTE20Count
|
|
CurrentCoprCacheHitRatioGTE20Count atomic.Uint64
|
|
// CurrentCoprCacheHitRatioGTE40Count is CurrentCoprCacheHitRatioGTE40Count
|
|
CurrentCoprCacheHitRatioGTE40Count atomic.Uint64
|
|
// CurrentCoprCacheHitRatioGTE80Count is CurrentCoprCacheHitRatioGTE80Count
|
|
CurrentCoprCacheHitRatioGTE80Count atomic.Uint64
|
|
// CurrentCoprCacheHitRatioGTE100Count is CurrentCoprCacheHitRatioGTE100Count
|
|
CurrentCoprCacheHitRatioGTE100Count atomic.Uint64
|
|
// CurrentTiflashTableScanCount count the number of tiflash table scan and tiflash partition table scan
|
|
CurrentTiflashTableScanCount atomic.Uint64
|
|
// CurrentTiflashTableScanWithFastScanCount count the number of tiflash table scan and tiflash partition table scan which use fastscan
|
|
CurrentTiflashTableScanWithFastScanCount atomic.Uint64
|
|
)
|
|
|
|
const (
|
|
// WindowSize determines how long some data is aggregated by.
|
|
WindowSize = 1 * time.Hour
|
|
// SubWindowSize determines how often data is rotated.
|
|
SubWindowSize = 1 * time.Minute
|
|
|
|
maxSubWindowLength = int(ReportInterval / SubWindowSize) // TODO: Ceiling?
|
|
maxSubWindowLengthInWindow = int(WindowSize / SubWindowSize) // TODO: Ceiling?
|
|
)
|
|
|
|
type windowData struct {
|
|
BeginAt time.Time `json:"beginAt"`
|
|
ExecuteCount uint64 `json:"executeCount"`
|
|
TiFlashUsage tiFlashUsageData `json:"tiFlashUsage"`
|
|
CoprCacheUsage coprCacheUsageData `json:"coprCacheUsage"`
|
|
BuiltinFunctionsUsage map[string]uint32 `json:"builtinFunctionsUsage"`
|
|
}
|
|
|
|
type coprCacheUsageData struct {
|
|
GTE0 uint64 `json:"gte0"`
|
|
GTE1 uint64 `json:"gte1"`
|
|
GTE10 uint64 `json:"gte10"`
|
|
GTE20 uint64 `json:"gte20"`
|
|
GTE40 uint64 `json:"gte40"`
|
|
GTE80 uint64 `json:"gte80"`
|
|
GTE100 uint64 `json:"gte100"`
|
|
}
|
|
|
|
type tiFlashUsageData struct {
|
|
PushDown uint64 `json:"pushDown"`
|
|
ExchangePushDown uint64 `json:"exchangePushDown"`
|
|
TableScan uint64 `json:"tableScan"`
|
|
TableScanWithFastScan uint64 `json:"tableScanWithFastScan"`
|
|
}
|
|
|
|
// builtinFunctionsUsageCollector collects builtin functions usage information and dump it into windowData.
|
|
type builtinFunctionsUsageCollector struct {
|
|
sync.Mutex
|
|
|
|
// Should acquire lock to access this
|
|
usageData BuiltinFunctionsUsage
|
|
}
|
|
|
|
// Merge BuiltinFunctionsUsage data
|
|
func (b *builtinFunctionsUsageCollector) Collect(usageData BuiltinFunctionsUsage) {
|
|
// TODO(leiysky): use multi-worker to collect the usage information so we can make this asynchronous
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
b.usageData.Merge(usageData)
|
|
}
|
|
|
|
// Dump BuiltinFunctionsUsage data
|
|
func (b *builtinFunctionsUsageCollector) Dump() map[string]uint32 {
|
|
b.Lock()
|
|
ret := b.usageData
|
|
b.usageData = make(map[string]uint32)
|
|
b.Unlock()
|
|
|
|
return ret
|
|
}
|
|
|
|
// BuiltinFunctionsUsage is a map from ScalarFuncSig_name(string) to usage count(uint32)
|
|
type BuiltinFunctionsUsage map[string]uint32
|
|
|
|
// Inc will increase the usage count of scalar function by 1
|
|
func (b BuiltinFunctionsUsage) Inc(scalarFuncSigName string) {
|
|
v, ok := b[scalarFuncSigName]
|
|
if !ok {
|
|
b[scalarFuncSigName] = 1
|
|
} else {
|
|
b[scalarFuncSigName] = v + 1
|
|
}
|
|
}
|
|
|
|
// Merge BuiltinFunctionsUsage data
|
|
func (b BuiltinFunctionsUsage) Merge(usageData BuiltinFunctionsUsage) {
|
|
for k, v := range usageData {
|
|
prev, ok := b[k]
|
|
if !ok {
|
|
b[k] = v
|
|
} else {
|
|
b[k] = prev + v
|
|
}
|
|
}
|
|
}
|
|
|
|
// GlobalBuiltinFunctionsUsage is used to collect builtin functions usage information
|
|
var GlobalBuiltinFunctionsUsage = &builtinFunctionsUsageCollector{usageData: make(BuiltinFunctionsUsage)}
|
|
|
|
var (
|
|
rotatedSubWindows []*windowData
|
|
subWindowsLock = sync.RWMutex{}
|
|
)
|
|
|
|
// RotateSubWindow rotates the telemetry sub window.
|
|
func RotateSubWindow() {
|
|
thisSubWindow := windowData{
|
|
BeginAt: time.Now(),
|
|
ExecuteCount: CurrentExecuteCount.Swap(0),
|
|
TiFlashUsage: tiFlashUsageData{
|
|
PushDown: CurrentTiFlashPushDownCount.Swap(0),
|
|
ExchangePushDown: CurrentTiFlashExchangePushDownCount.Swap(0),
|
|
TableScan: CurrentTiflashTableScanCount.Swap(0),
|
|
TableScanWithFastScan: CurrentTiflashTableScanWithFastScanCount.Swap(0),
|
|
},
|
|
CoprCacheUsage: coprCacheUsageData{
|
|
GTE0: CurrentCoprCacheHitRatioGTE0Count.Swap(0),
|
|
GTE1: CurrentCoprCacheHitRatioGTE1Count.Swap(0),
|
|
GTE10: CurrentCoprCacheHitRatioGTE10Count.Swap(0),
|
|
GTE20: CurrentCoprCacheHitRatioGTE20Count.Swap(0),
|
|
GTE40: CurrentCoprCacheHitRatioGTE40Count.Swap(0),
|
|
GTE80: CurrentCoprCacheHitRatioGTE80Count.Swap(0),
|
|
GTE100: CurrentCoprCacheHitRatioGTE100Count.Swap(0),
|
|
},
|
|
BuiltinFunctionsUsage: GlobalBuiltinFunctionsUsage.Dump(),
|
|
}
|
|
|
|
subWindowsLock.Lock()
|
|
rotatedSubWindows = append(rotatedSubWindows, &thisSubWindow)
|
|
if len(rotatedSubWindows) > maxSubWindowLength {
|
|
// Only retain last N sub windows, according to the report interval.
|
|
rotatedSubWindows = rotatedSubWindows[len(rotatedSubWindows)-maxSubWindowLength:]
|
|
}
|
|
subWindowsLock.Unlock()
|
|
}
|
|
|
|
// getWindowData returns data aggregated by window size.
|
|
func getWindowData() []*windowData {
|
|
results := make([]*windowData, 0)
|
|
|
|
subWindowsLock.RLock()
|
|
|
|
i := 0
|
|
for i < len(rotatedSubWindows) {
|
|
thisWindow := *rotatedSubWindows[i]
|
|
aggregatedSubWindows := 1
|
|
// Aggregate later sub windows
|
|
i++
|
|
for i < len(rotatedSubWindows) && aggregatedSubWindows < maxSubWindowLengthInWindow {
|
|
thisWindow.ExecuteCount += rotatedSubWindows[i].ExecuteCount
|
|
thisWindow.TiFlashUsage.PushDown += rotatedSubWindows[i].TiFlashUsage.PushDown
|
|
thisWindow.TiFlashUsage.ExchangePushDown += rotatedSubWindows[i].TiFlashUsage.ExchangePushDown
|
|
thisWindow.TiFlashUsage.TableScan += rotatedSubWindows[i].TiFlashUsage.TableScan
|
|
thisWindow.TiFlashUsage.TableScanWithFastScan += rotatedSubWindows[i].TiFlashUsage.TableScanWithFastScan
|
|
thisWindow.CoprCacheUsage.GTE0 += rotatedSubWindows[i].CoprCacheUsage.GTE0
|
|
thisWindow.CoprCacheUsage.GTE1 += rotatedSubWindows[i].CoprCacheUsage.GTE1
|
|
thisWindow.CoprCacheUsage.GTE10 += rotatedSubWindows[i].CoprCacheUsage.GTE10
|
|
thisWindow.CoprCacheUsage.GTE20 += rotatedSubWindows[i].CoprCacheUsage.GTE20
|
|
thisWindow.CoprCacheUsage.GTE40 += rotatedSubWindows[i].CoprCacheUsage.GTE40
|
|
thisWindow.CoprCacheUsage.GTE80 += rotatedSubWindows[i].CoprCacheUsage.GTE80
|
|
thisWindow.CoprCacheUsage.GTE100 += rotatedSubWindows[i].CoprCacheUsage.GTE100
|
|
|
|
mergedBuiltinFunctionsUsage := BuiltinFunctionsUsage(thisWindow.BuiltinFunctionsUsage)
|
|
mergedBuiltinFunctionsUsage.Merge(BuiltinFunctionsUsage(rotatedSubWindows[i].BuiltinFunctionsUsage))
|
|
thisWindow.BuiltinFunctionsUsage = mergedBuiltinFunctionsUsage
|
|
aggregatedSubWindows++
|
|
i++
|
|
}
|
|
results = append(results, &thisWindow)
|
|
}
|
|
|
|
subWindowsLock.RUnlock()
|
|
|
|
return results
|
|
}
|