You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

163 lines
4.1 KiB

// Copyright 2020 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 stmtsummary
import (
"fmt"
"strconv"
"strings"
"sync"
"sync/atomic"
"github.com/pingcap/errors"
"github.com/pingcap/tidb/config"
)
const (
typeEnable = iota
typeEnableInternalQuery
typeRefreshInterval
typeHistorySize
typeMaxStmtCount
typeMaxSQLLength
typesNum
)
type systemVars struct {
sync.Mutex
// This array itself won't be modified once created. Only its elements may be modified.
variables []variable
}
type variable struct {
sessionValue string
globalValue string
finalValue int64
}
func newSysVars() *systemVars {
s := &systemVars{
variables: make([]variable, typesNum),
}
// Initialize these configurations by values in the config file.
// They may be overwritten by system variables later.
for varType := range s.variables {
atomic.StoreInt64(&s.variables[varType].finalValue, getConfigValue(varType))
}
return s
}
func (s *systemVars) getVariable(varType int) int64 {
return atomic.LoadInt64(&s.variables[varType].finalValue)
}
func (s *systemVars) setVariable(varType int, valueStr string, isSession bool) error {
s.Lock()
defer s.Unlock()
v := &s.variables[varType]
if isSession {
v.sessionValue = valueStr
} else {
v.globalValue = valueStr
}
sessionValue := v.sessionValue
globalValue := v.globalValue
var valueInt int64
switch varType {
case typeEnable, typeEnableInternalQuery:
valueInt = getBoolFinalVariable(varType, sessionValue, globalValue)
case typeHistorySize, typeMaxSQLLength:
valueInt = getIntFinalVariable(varType, sessionValue, globalValue, 0)
case typeRefreshInterval, typeMaxStmtCount:
valueInt = getIntFinalVariable(varType, sessionValue, globalValue, 1)
default:
return errors.New(fmt.Sprintf("no such type of variable: %d", varType))
}
atomic.StoreInt64(&v.finalValue, valueInt)
return nil
}
func getBoolFinalVariable(varType int, sessionValue, globalValue string) int64 {
var valueInt int64
if len(sessionValue) > 0 {
valueInt = normalizeEnableValue(sessionValue)
} else if len(globalValue) > 0 {
valueInt = normalizeEnableValue(globalValue)
} else {
valueInt = getConfigValue(varType)
}
return valueInt
}
// normalizeEnableValue converts 'ON' or '1' to 1 and 'OFF' or '0' to 0.
func normalizeEnableValue(value string) int64 {
switch {
case strings.EqualFold(value, "ON"):
return 1
case value == "1":
return 1
default:
return 0
}
}
func getIntFinalVariable(varType int, sessionValue, globalValue string, minValue int64) int64 {
valueInt := minValue - 1
var err error
if len(sessionValue) > 0 {
valueInt, err = strconv.ParseInt(sessionValue, 10, 64)
if err != nil {
valueInt = minValue - 1
}
}
if valueInt < minValue {
valueInt, err = strconv.ParseInt(globalValue, 10, 64)
if err != nil {
valueInt = minValue - 1
}
}
// If session and global variables are both '', use the value in config.
if valueInt < minValue {
valueInt = getConfigValue(varType)
}
return valueInt
}
func getConfigValue(varType int) int64 {
var valueInt int64
stmtSummaryConfig := config.GetGlobalConfig().StmtSummary
switch varType {
case typeEnable:
if stmtSummaryConfig.Enable {
valueInt = 1
}
case typeEnableInternalQuery:
if stmtSummaryConfig.EnableInternalQuery {
valueInt = 1
}
case typeRefreshInterval:
valueInt = int64(stmtSummaryConfig.RefreshInterval)
case typeHistorySize:
valueInt = int64(stmtSummaryConfig.HistorySize)
case typeMaxStmtCount:
valueInt = int64(stmtSummaryConfig.MaxStmtCount)
case typeMaxSQLLength:
valueInt = int64(stmtSummaryConfig.MaxSQLLength)
default:
panic(fmt.Sprintf("No such type of variable: %d", varType))
}
return valueInt
}