Files
tidb/pkg/telemetry/data_window.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
}