Documentation ¶
Index ¶
- Constants
- Variables
- func BytesToString(numBytes int64) string
- func ForceReadMemStats() *runtime.MemStats
- func FormatBytes(numBytes int64) string
- func GetMemTotalIgnoreErr() uint64
- func InitMemoryHook()
- func InitTracker(t *Tracker, label int, bytesLimit int64, action ActionOnExceed)
- func InstanceMemUsed() (uint64, error)
- func MemTotalCGroup() (uint64, error)
- func MemTotalNormal() (uint64, error)
- func MemUsedCGroup() (uint64, error)
- func MemUsedNormal() (uint64, error)
- func NewActionWithPriority(action ActionOnExceed, priority int64) *actionWithPriority
- func ReadMemStats() (memStats *runtime.MemStats)
- type ActionOnExceed
- type BaseOOMAction
- type LogOnExceed
- type PanicOnExceed
- type Tracker
- func (t *Tracker) AttachTo(parent *Tracker)
- func (t *Tracker) AttachToGlobalTracker(globalTracker *Tracker)
- func (t *Tracker) BufferedConsume(bufferedMemSize *int64, bytes int64)
- func (t *Tracker) BufferedRelease(bufferedMemSize *int64, bytes int64)
- func (t *Tracker) BytesConsumed() int64
- func (t *Tracker) BytesReleased() int64
- func (t *Tracker) CheckBytesLimit(val int64) bool
- func (t *Tracker) CheckExceed() bool
- func (t *Tracker) Consume(bs int64)
- func (t *Tracker) CountAllChildrenMemUse() map[string]int64
- func (t *Tracker) Detach()
- func (t *Tracker) DetachFromGlobalTracker()
- func (t *Tracker) FallbackOldAndSetNewAction(a ActionOnExceed)
- func (t *Tracker) FallbackOldAndSetNewActionForSoftLimit(a ActionOnExceed)
- func (*Tracker) FormatBytes(numBytes int64) string
- func (t *Tracker) GetBytesLimit() int64
- func (t *Tracker) GetChildrenForTest() []*Tracker
- func (t *Tracker) GetFallbackForTest(ignoreFinishedAction bool) ActionOnExceed
- func (t *Tracker) HandleKillSignal()
- func (t *Tracker) Label() int
- func (t *Tracker) LessThan(t2 *Tracker) bool
- func (t *Tracker) MaxConsumed() int64
- func (t *Tracker) Release(bytes int64)
- func (t *Tracker) ReplaceBytesUsed(bytes int64)
- func (t *Tracker) ReplaceChild(oldChild, newChild *Tracker)
- func (t *Tracker) Reset()
- func (t *Tracker) ResetMaxConsumed()
- func (t *Tracker) SearchTrackerConsumedMoreThanNBytes(limit int64) (res []*Tracker)
- func (t *Tracker) SearchTrackerWithoutLock(label int) *Tracker
- func (t *Tracker) SetActionOnExceed(a ActionOnExceed)
- func (t *Tracker) SetBytesLimit(bytesLimit int64)
- func (t *Tracker) SetLabel(label int)
- func (t *Tracker) String() string
- func (t *Tracker) UnbindActionFromHardLimit(actionToUnbind ActionOnExceed)
- func (t *Tracker) UnbindActions()
Constants ¶
const ( DefPanicPriority = iota DefLogPriority DefSpillPriority // DefCursorFetchSpillPriority is higher than normal disk spill, because it can release much more memory in the future. // And the performance impaction of it is less than other disk-spill action, because it's write-only in execution stage. DefCursorFetchSpillPriority DefRateLimitPriority )
Default OOM Action priority.
const ( // LabelForSQLText represents the label of the SQL Text LabelForSQLText int = -1 // LabelForIndexWorker represents the label of the index worker LabelForIndexWorker int = -2 // LabelForInnerList represents the label of the inner list LabelForInnerList int = -3 // LabelForInnerTable represents the label of the inner table LabelForInnerTable int = -4 // LabelForOuterTable represents the label of the outer table LabelForOuterTable int = -5 // LabelForCoprocessor represents the label of the coprocessor LabelForCoprocessor int = -6 // LabelForChunkList represents the label of the chunk list LabelForChunkList int = -7 // LabelForGlobalSimpleLRUCache represents the label of the Global SimpleLRUCache LabelForGlobalSimpleLRUCache int = -8 // LabelForChunkDataInDiskByRows represents the label of the chunk list in disk LabelForChunkDataInDiskByRows int = -9 // LabelForRowContainer represents the label of the row container LabelForRowContainer int = -10 // LabelForGlobalStorage represents the label of the Global Storage LabelForGlobalStorage int = -11 // LabelForGlobalMemory represents the label of the Global Memory LabelForGlobalMemory int = -12 // LabelForBuildSideResult represents the label of the BuildSideResult LabelForBuildSideResult int = -13 // LabelForRowChunks represents the label of the row chunks LabelForRowChunks int = -14 // LabelForStatsCache represents the label of the stats cache LabelForStatsCache int = -15 // LabelForOuterList represents the label of the outer list LabelForOuterList int = -16 // LabelForApplyCache represents the label of the apply cache LabelForApplyCache int = -17 // LabelForSimpleTask represents the label of the simple task LabelForSimpleTask int = -18 // LabelForCTEStorage represents the label of CTE storage LabelForCTEStorage int = -19 // LabelForIndexJoinInnerWorker represents the label of IndexJoin InnerWorker LabelForIndexJoinInnerWorker int = -20 // LabelForIndexJoinOuterWorker represents the label of IndexJoin OuterWorker LabelForIndexJoinOuterWorker int = -21 // LabelForBindCache represents the label of the bind cache LabelForBindCache int = -22 // LabelForNonTransactionalDML represents the label of the non-transactional DML LabelForNonTransactionalDML = -23 // LabelForAnalyzeMemory represents the label of the memory of each analyze job LabelForAnalyzeMemory int = -24 // LabelForGlobalAnalyzeMemory represents the label of the global memory of all analyze jobs LabelForGlobalAnalyzeMemory int = -25 // LabelForPreparedPlanCache represents the label of the prepared plan cache memory usage LabelForPreparedPlanCache int = -26 // LabelForSession represents the label of a session. LabelForSession int = -27 // LabelForMemDB represents the label of the MemDB LabelForMemDB int = -28 // LabelForCursorFetch represents the label of the execution of cursor fetch LabelForCursorFetch int = -29 // LabelForChunkDataInDiskByChunks represents the label of the chunk list in disk LabelForChunkDataInDiskByChunks int = -30 // LabelForSortPartition represents the label of the sort partition LabelForSortPartition int = -31 // LabelForHashTableInHashJoinV2 represents the label of the hash join v2's hash table LabelForHashTableInHashJoinV2 int = -32 )
const DefMemQuotaQuery = 1073741824 // 1GB
DefMemQuotaQuery is default memory quota for query.
const ReadMemInterval = 300 * time.Millisecond
ReadMemInterval controls the interval to read memory stats.
const TrackMemWhenExceeds = 104857600 // 100MB
TrackMemWhenExceeds is the threshold when memory usage needs to be tracked.
Variables ¶
var ( ServerMemoryLimitOriginText = atomicutil.NewString("0") ServerMemoryLimit = atomicutil.NewUint64(0) ServerMemoryLimitSessMinSize = atomicutil.NewUint64(128 << 20) QueryForceDisk = atomicutil.NewInt64(0) TriggerMemoryLimitGC = atomicutil.NewBool(false) MemoryLimitGCLast = atomicutil.NewTime(time.Time{}) MemoryLimitGCTotal = atomicutil.NewInt64(0) )
Process global variables for memory limit.
var EnableGCAwareMemoryTrack = atomicutil.NewBool(false)
EnableGCAwareMemoryTrack is used to turn on/off the GC-aware memory track
var MemTotal func() (uint64, error)
MemTotal returns the total amount of RAM on this system
var MemUsageTop1Tracker atomic.Pointer[Tracker]
MemUsageTop1Tracker record the use memory top1 session's tracker for kill.
var MemUsed func() (uint64, error)
MemUsed returns the total used amount of RAM on this system
var MetricsTypes = map[int][]string{ LabelForGlobalAnalyzeMemory: {"analyze", "inuse", "released"}, }
MetricsTypes is used to get label for metrics string[0] is LblModule, string[1] is heap-in-use type, string[2] is released type
Functions ¶
func BytesToString ¶
BytesToString converts the memory consumption to a readable string.
func ForceReadMemStats ¶
ForceReadMemStats is to force read memory stats.
func FormatBytes ¶
FormatBytes uses to format bytes, this function will prune precision before format bytes.
func GetMemTotalIgnoreErr ¶
func GetMemTotalIgnoreErr() uint64
GetMemTotalIgnoreErr returns the total amount of RAM on this system/container. If error occurs, return 0.
func InitMemoryHook ¶
func InitMemoryHook()
InitMemoryHook initializes the memory hook. It is to solve the problem that tidb cannot read cgroup in the systemd. so if we are not in the container, we compare the cgroup memory limit and the physical memory, the cgroup memory limit is smaller, we use the cgroup memory hook.
func InitTracker ¶
func InitTracker(t *Tracker, label int, bytesLimit int64, action ActionOnExceed)
InitTracker initializes a memory tracker.
- "label" is the label used in the usage string.
- "bytesLimit <= 0" means no limit.
For the common tracker, isGlobal is default as false
func InstanceMemUsed ¶
InstanceMemUsed returns the memory usage of this TiDB server
func MemTotalCGroup ¶
MemTotalCGroup returns the total amount of RAM on this system in container environment.
func MemTotalNormal ¶
MemTotalNormal returns the total amount of RAM on this system in non-container environment.
func MemUsedCGroup ¶
MemUsedCGroup returns the total used amount of RAM on this system in container environment.
func MemUsedNormal ¶
MemUsedNormal returns the total used amount of RAM on this system in non-container environment.
func NewActionWithPriority ¶
func NewActionWithPriority(action ActionOnExceed, priority int64) *actionWithPriority
NewActionWithPriority wraps the action with a new priority
func ReadMemStats ¶
ReadMemStats read the mem stats from runtime.ReadMemStats
Types ¶
type ActionOnExceed ¶
type ActionOnExceed interface { // Action will be called when memory usage exceeds memory quota by the // corresponding Tracker. Action(t *Tracker) // SetFallback sets a fallback action which will be triggered if itself has // already been triggered. SetFallback(a ActionOnExceed) // GetFallback get the fallback action of the Action. GetFallback() ActionOnExceed // GetPriority get the priority of the Action. GetPriority() int64 // SetFinished sets the finished state of the Action. SetFinished() // IsFinished returns the finished state of the Action. IsFinished() bool }
ActionOnExceed is the action taken when memory usage exceeds memory quota. NOTE: All the implementors should be thread-safe.
type BaseOOMAction ¶
type BaseOOMAction struct {
// contains filtered or unexported fields
}
BaseOOMAction manages the fallback action for all Action.
func (*BaseOOMAction) GetFallback ¶
func (b *BaseOOMAction) GetFallback() ActionOnExceed
GetFallback get the fallback action and remove finished fallback.
func (*BaseOOMAction) IsFinished ¶
func (b *BaseOOMAction) IsFinished() bool
IsFinished returns the finished state of the Action.
func (*BaseOOMAction) SetFallback ¶
func (b *BaseOOMAction) SetFallback(a ActionOnExceed)
SetFallback sets a fallback action which will be triggered if itself has already been triggered.
func (*BaseOOMAction) SetFinished ¶
func (b *BaseOOMAction) SetFinished()
SetFinished sets the finished state of the Action.
func (*BaseOOMAction) TriggerFallBackAction ¶
func (b *BaseOOMAction) TriggerFallBackAction(tracker *Tracker)
TriggerFallBackAction triggers the fallback action of the current action
type LogOnExceed ¶
type LogOnExceed struct { BaseOOMAction ConnID uint64 // contains filtered or unexported fields }
LogOnExceed logs a warning only once when memory usage exceeds memory quota.
func (*LogOnExceed) Action ¶
func (a *LogOnExceed) Action(t *Tracker)
Action logs a warning only once when memory usage exceeds memory quota.
func (*LogOnExceed) GetPriority ¶
func (*LogOnExceed) GetPriority() int64
GetPriority get the priority of the Action
func (*LogOnExceed) SetLogHook ¶
func (a *LogOnExceed) SetLogHook(hook func(uint64))
SetLogHook sets a hook for LogOnExceed.
type PanicOnExceed ¶
type PanicOnExceed struct { Killer *sqlkiller.SQLKiller BaseOOMAction ConnID uint64 // contains filtered or unexported fields }
PanicOnExceed panics when memory usage exceeds memory quota.
func (*PanicOnExceed) Action ¶
func (a *PanicOnExceed) Action(t *Tracker)
Action panics when memory usage exceeds memory quota.
func (*PanicOnExceed) GetPriority ¶
func (*PanicOnExceed) GetPriority() int64
GetPriority get the priority of the Action
func (*PanicOnExceed) SetLogHook ¶
func (a *PanicOnExceed) SetLogHook(hook func(uint64))
SetLogHook sets a hook for PanicOnExceed.
type Tracker ¶
type Tracker struct { Killer *sqlkiller.SQLKiller SessionID atomicutil.Uint64 // SessionID indicates the sessionID the tracker is bound. IsRootTrackerOfSess bool // IsRootTrackerOfSess indicates whether this tracker is bound for session // contains filtered or unexported fields }
Tracker is used to track the memory usage during query execution. It contains an optional limit and can be arranged into a tree structure such that the consumption tracked by a Tracker is also tracked by its ancestors. The main idea comes from Apache Impala:
https://github.com/cloudera/Impala/blob/cdh5-trunk/be/src/runtime/mem-tracker.h
By default, memory consumption is tracked via calls to "Consume()", either to the tracker itself or to one of its descendents. A typical sequence of calls for a single Tracker is: 1. tracker.SetLabel() / tracker.SetActionOnExceed() / tracker.AttachTo() 2. tracker.Consume() / tracker.ReplaceChild() / tracker.BytesConsumed()
NOTE: We only protect concurrent access to "bytesConsumed" and "children", that is to say: 1. Only "BytesConsumed()", "Consume()" and "AttachTo()" are thread-safe. 2. Other operations of a Tracker tree is not thread-safe.
We have two limits for the memory quota: soft limit and hard limit. If the soft limit is exceeded, we will trigger the action that alleviates the speed of memory growth. The soft limit is hard-coded as `0.8*hard limit`. The actions that could be triggered are: AggSpillDiskAction.
If the hard limit is exceeded, we will trigger the action that immediately reduces memory usage. The hard limit is set by the system variable `tidb_mem_query_quota`. The actions that could be triggered are: SpillDiskAction, SortAndSpillDiskAction, rateLimitAction, PanicOnExceed, globalPanicOnExceed, LogOnExceed.
func NewGlobalTracker ¶
NewGlobalTracker creates a global tracker, its isGlobal is default as true
func NewTracker ¶
NewTracker creates a memory tracker.
- "label" is the label used in the usage string.
- "bytesLimit <= 0" means no limit.
For the common tracker, isGlobal is default as false
func (*Tracker) AttachTo ¶
AttachTo attaches this memory tracker as a child to another Tracker. If it already has a parent, this function will remove it from the old parent. Its consumed memory usage is used to update all its ancestors.
func (*Tracker) AttachToGlobalTracker ¶
AttachToGlobalTracker attach the tracker to the global tracker AttachToGlobalTracker should be called at the initialization for the session executor's tracker
func (*Tracker) BufferedConsume ¶
BufferedConsume is used to buffer memory usage and do late consume not thread-safe, should be called in one goroutine
func (*Tracker) BufferedRelease ¶
BufferedRelease is used to buffer memory release and do late release not thread-safe, should be called in one goroutine
func (*Tracker) BytesConsumed ¶
BytesConsumed returns the consumed memory usage value in bytes.
func (*Tracker) BytesReleased ¶
BytesReleased returns the released memory value in bytes.
func (*Tracker) CheckBytesLimit ¶
CheckBytesLimit check whether the bytes limit of the tracker is equal to a value. Only used in test.
func (*Tracker) CheckExceed ¶
CheckExceed checks whether the consumed bytes is exceed for this tracker.
func (*Tracker) Consume ¶
Consume is used to consume a memory usage. "bytes" can be a negative value, which means this is a memory release operation. When memory usage of a tracker exceeds its bytesSoftLimit/bytesHardLimit, the tracker calls its action, so does each of its ancestors.
func (*Tracker) CountAllChildrenMemUse ¶
CountAllChildrenMemUse return memory used tree for the tracker
func (*Tracker) Detach ¶
func (t *Tracker) Detach()
Detach de-attach the tracker child from its parent, then set its parent property as nil
func (*Tracker) DetachFromGlobalTracker ¶
func (t *Tracker) DetachFromGlobalTracker()
DetachFromGlobalTracker detach itself from its parent Note that only the parent of this tracker is Global Tracker could call this function Otherwise it should use Detach
func (*Tracker) FallbackOldAndSetNewAction ¶
func (t *Tracker) FallbackOldAndSetNewAction(a ActionOnExceed)
FallbackOldAndSetNewAction sets the action when memory usage exceeds bytesHardLimit and set the original action as its fallback.
func (*Tracker) FallbackOldAndSetNewActionForSoftLimit ¶
func (t *Tracker) FallbackOldAndSetNewActionForSoftLimit(a ActionOnExceed)
FallbackOldAndSetNewActionForSoftLimit sets the action when memory usage exceeds bytesSoftLimit and set the original action as its fallback.
func (*Tracker) FormatBytes ¶
FormatBytes uses to format bytes, this function will prune precision before format bytes.
func (*Tracker) GetBytesLimit ¶
GetBytesLimit gets the bytes limit for this tracker. "bytesHardLimit <= 0" means no limit.
func (*Tracker) GetChildrenForTest ¶
GetChildrenForTest returns children trackers
func (*Tracker) GetFallbackForTest ¶
func (t *Tracker) GetFallbackForTest(ignoreFinishedAction bool) ActionOnExceed
GetFallbackForTest get the oom action used by test.
func (*Tracker) HandleKillSignal ¶
func (t *Tracker) HandleKillSignal()
HandleKillSignal checks if a kill signal has been sent to the session root tracker. If a kill signal is detected, it panics with the error returned by the signal handler.
func (*Tracker) MaxConsumed ¶
MaxConsumed returns max number of bytes consumed during execution. Note: Don't make this method return -1 for special meanings in the future. Because binary plan has used -1 to distinguish between "0 bytes" and "N/A". ref: binaryOpFromFlatOp()
func (*Tracker) Release ¶
Release is used to release memory tracked, track the released memory until GC triggered if needed If you want your track to be GC-aware, please use Release(bytes) instead of Consume(-bytes), and pass the memory size of the real object. Only Analyze is integrated with Release so far.
func (*Tracker) ReplaceBytesUsed ¶
ReplaceBytesUsed replace bytesConsume for the tracker
func (*Tracker) ReplaceChild ¶
ReplaceChild removes the old child specified in "oldChild" and add a new child specified in "newChild". old child's memory consumption will be removed and new child's memory consumption will be added.
func (*Tracker) Reset ¶
func (t *Tracker) Reset()
Reset detach the tracker from the old parent and clear the old children. The label and byteLimit would not be reset.
func (*Tracker) ResetMaxConsumed ¶
func (t *Tracker) ResetMaxConsumed()
ResetMaxConsumed should be invoked before executing a new statement in a session.
func (*Tracker) SearchTrackerConsumedMoreThanNBytes ¶
SearchTrackerConsumedMoreThanNBytes searches the specific tracker that consumes more than NBytes.
func (*Tracker) SearchTrackerWithoutLock ¶
SearchTrackerWithoutLock searches the specific tracker under this tracker without lock.
func (*Tracker) SetActionOnExceed ¶
func (t *Tracker) SetActionOnExceed(a ActionOnExceed)
SetActionOnExceed sets the action when memory usage exceeds bytesHardLimit.
func (*Tracker) SetBytesLimit ¶
SetBytesLimit sets the bytes limit for this tracker. "bytesHardLimit <= 0" means no limit.
func (*Tracker) UnbindActionFromHardLimit ¶
func (t *Tracker) UnbindActionFromHardLimit(actionToUnbind ActionOnExceed)
UnbindActionFromHardLimit unbinds action from hardLimit.
func (*Tracker) UnbindActions ¶
func (t *Tracker) UnbindActions()
UnbindActions unbinds actionForHardLimit and actionForSoftLimit.