memory

package
v1.1.0-beta.0...-22c91d0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 17, 2024 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
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.

View Source
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
)
View Source
const DefMemQuotaQuery = 1073741824 // 1GB

DefMemQuotaQuery is default memory quota for query.

View Source
const ReadMemInterval = 300 * time.Millisecond

ReadMemInterval controls the interval to read memory stats.

View Source
const TrackMemWhenExceeds = 104857600 // 100MB

TrackMemWhenExceeds is the threshold when memory usage needs to be tracked.

Variables

View Source
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.

View Source
var EnableGCAwareMemoryTrack = atomicutil.NewBool(false)

EnableGCAwareMemoryTrack is used to turn on/off the GC-aware memory track

View Source
var MemTotal func() (uint64, error)

MemTotal returns the total amount of RAM on this system

View Source
var MemUsageTop1Tracker atomic.Pointer[Tracker]

MemUsageTop1Tracker record the use memory top1 session's tracker for kill.

View Source
var MemUsed func() (uint64, error)

MemUsed returns the total used amount of RAM on this system

View Source
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

func BytesToString(numBytes int64) string

BytesToString converts the memory consumption to a readable string.

func ForceReadMemStats

func ForceReadMemStats() *runtime.MemStats

ForceReadMemStats is to force read memory stats.

func FormatBytes

func FormatBytes(numBytes int64) string

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.

  1. "label" is the label used in the usage string.
  2. "bytesLimit <= 0" means no limit.

For the common tracker, isGlobal is default as false

func InstanceMemUsed

func InstanceMemUsed() (uint64, error)

InstanceMemUsed returns the memory usage of this TiDB server

func MemTotalCGroup

func MemTotalCGroup() (uint64, error)

MemTotalCGroup returns the total amount of RAM on this system in container environment.

func MemTotalNormal

func MemTotalNormal() (uint64, error)

MemTotalNormal returns the total amount of RAM on this system in non-container environment.

func MemUsedCGroup

func MemUsedCGroup() (uint64, error)

MemUsedCGroup returns the total used amount of RAM on this system in container environment.

func MemUsedNormal

func MemUsedNormal() (uint64, error)

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

func ReadMemStats() (memStats *runtime.MemStats)

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

func NewGlobalTracker(label int, bytesLimit int64) *Tracker

NewGlobalTracker creates a global tracker, its isGlobal is default as true

func NewTracker

func NewTracker(label int, bytesLimit int64) *Tracker

NewTracker creates a memory tracker.

  1. "label" is the label used in the usage string.
  2. "bytesLimit <= 0" means no limit.

For the common tracker, isGlobal is default as false

func (*Tracker) AttachTo

func (t *Tracker) AttachTo(parent *Tracker)

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

func (t *Tracker) AttachToGlobalTracker(globalTracker *Tracker)

AttachToGlobalTracker attach the tracker to the global tracker AttachToGlobalTracker should be called at the initialization for the session executor's tracker

func (*Tracker) BufferedConsume

func (t *Tracker) BufferedConsume(bufferedMemSize *int64, bytes int64)

BufferedConsume is used to buffer memory usage and do late consume not thread-safe, should be called in one goroutine

func (*Tracker) BufferedRelease

func (t *Tracker) BufferedRelease(bufferedMemSize *int64, bytes int64)

BufferedRelease is used to buffer memory release and do late release not thread-safe, should be called in one goroutine

func (*Tracker) BytesConsumed

func (t *Tracker) BytesConsumed() int64

BytesConsumed returns the consumed memory usage value in bytes.

func (*Tracker) BytesReleased

func (t *Tracker) BytesReleased() int64

BytesReleased returns the released memory value in bytes.

func (*Tracker) CheckBytesLimit

func (t *Tracker) CheckBytesLimit(val int64) bool

CheckBytesLimit check whether the bytes limit of the tracker is equal to a value. Only used in test.

func (*Tracker) CheckExceed

func (t *Tracker) CheckExceed() bool

CheckExceed checks whether the consumed bytes is exceed for this tracker.

func (*Tracker) Consume

func (t *Tracker) Consume(bs int64)

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

func (t *Tracker) CountAllChildrenMemUse() map[string]int64

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

func (*Tracker) FormatBytes(numBytes int64) string

FormatBytes uses to format bytes, this function will prune precision before format bytes.

func (*Tracker) GetBytesLimit

func (t *Tracker) GetBytesLimit() int64

GetBytesLimit gets the bytes limit for this tracker. "bytesHardLimit <= 0" means no limit.

func (*Tracker) GetChildrenForTest

func (t *Tracker) GetChildrenForTest() []*Tracker

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) Label

func (t *Tracker) Label() int

Label gets the label of a Tracker.

func (*Tracker) LessThan

func (t *Tracker) LessThan(t2 *Tracker) bool

LessThan indicates whether t byteConsumed is less than t2 byteConsumed.

func (*Tracker) MaxConsumed

func (t *Tracker) MaxConsumed() int64

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

func (t *Tracker) Release(bytes int64)

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

func (t *Tracker) ReplaceBytesUsed(bytes int64)

ReplaceBytesUsed replace bytesConsume for the tracker

func (*Tracker) ReplaceChild

func (t *Tracker) ReplaceChild(oldChild, newChild *Tracker)

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

func (t *Tracker) SearchTrackerConsumedMoreThanNBytes(limit int64) (res []*Tracker)

SearchTrackerConsumedMoreThanNBytes searches the specific tracker that consumes more than NBytes.

func (*Tracker) SearchTrackerWithoutLock

func (t *Tracker) SearchTrackerWithoutLock(label int) *Tracker

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

func (t *Tracker) SetBytesLimit(bytesLimit int64)

SetBytesLimit sets the bytes limit for this tracker. "bytesHardLimit <= 0" means no limit.

func (*Tracker) SetLabel

func (t *Tracker) SetLabel(label int)

SetLabel sets the label of a Tracker.

func (*Tracker) String

func (t *Tracker) String() string

String returns the string representation of this Tracker tree.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL