Documentation ¶
Index ¶
- Constants
- Variables
- func BytesToString(numBytes int64) string
- func ForceReadMemStats() *runtime.MemStats
- func FormatBytes(numBytes int64) string
- func GetMemTotalIgnoreErr() uint64
- 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 ActionCareInvoker
- type ActionInvoker
- 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) 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) 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 ( // PanicMemoryExceedWarnMsg represents the panic message when out of memory quota. PanicMemoryExceedWarnMsg string = "Your query has been cancelled due to exceeding the allowed memory limit" // WarnMsgSuffixForSingleQuery represents the suffix of the warning message when out of memory quota for a single query. WarnMsgSuffixForSingleQuery string = " for a single SQL query. Please try narrowing your query scope or increase the tidb_mem_quota_query limit and try again." // WarnMsgSuffixForInstance represents the suffix of the warning message when out of memory quota for the tidb-server instance. WarnMsgSuffixForInstance string = "" /* 174-byte string literal not displayed */ )
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 // LabelForChunkListInDisk represents the label of the chunk list in disk LabelForChunkListInDisk 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 )
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 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 ActionCareInvoker ¶
type ActionCareInvoker interface {
SetInvoker(invoker ActionInvoker)
}
ActionCareInvoker is the interface for the Actions which need to be aware of the invoker.
type ActionInvoker ¶
type ActionInvoker byte
ActionInvoker indicates the invoker of the Action.
const ( // SingleQuery indicates the Action is invoked by a tidb_mem_quota_query. SingleQuery ActionInvoker = iota // Instance indicates the Action is invoked by a tidb_server_memory_limit. Instance )
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.
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 { 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) SetInvoker ¶
func (a *PanicOnExceed) SetInvoker(invoker ActionInvoker)
SetInvoker sets the invoker of the Action.
func (*PanicOnExceed) SetLogHook ¶
func (a *PanicOnExceed) SetLogHook(hook func(uint64))
SetLogHook sets a hook for PanicOnExceed.
type Tracker ¶
type Tracker struct { SessionID atomicutil.Uint64 // SessionID indicates the sessionID the tracker is bound. NeedKill atomic.Bool // NeedKill indicates whether this session need kill because OOM NeedKillReceived sync.Once 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) 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) UnbindActions ¶
func (t *Tracker) UnbindActions()
UnbindActions unbinds actionForHardLimit and actionForSoftLimit.