Skip to content

Commit

Permalink
planner: evict all cached plans after disabling instance plan cache (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
qw4990 authored Nov 13, 2024
1 parent 2d9f829 commit 0dcd8e7
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
3 changes: 2 additions & 1 deletion pkg/domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -3207,7 +3207,8 @@ func (do *Domain) planCacheEvictTrigger() {
case <-ticker.C:
// trigger the eviction
begin := time.Now()
detailInfo, numEvicted := do.instancePlanCache.Evict()
enabled := variable.EnableInstancePlanCache.Load()
detailInfo, numEvicted := do.instancePlanCache.Evict(!enabled) // evict all if the plan cache is disabled
metrics2.GetPlanCacheInstanceEvict().Set(float64(numEvicted))
if numEvicted > 0 {
logutil.BgLogger().Info("instance plan eviction",
Expand Down
11 changes: 8 additions & 3 deletions pkg/planner/core/plan_cache_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,13 @@ func (pc *instancePlanCache) Put(key string, value, paramTypes any) (succ bool)
// step 1: iterate all values to collect their last_used
// step 2: estimate an eviction threshold time based on all last_used values
// step 3: iterate all values again and evict qualified values
func (pc *instancePlanCache) Evict() (detailInfo string, numEvicted int) {
func (pc *instancePlanCache) Evict(evictAll bool) (detailInfo string, numEvicted int) {
pc.evictMutex.Lock() // make sure only one thread to trigger eviction for safety
defer pc.evictMutex.Unlock()
pc.inEvict.Store(true)
defer pc.inEvict.Store(false)
currentTot, softLimit := pc.totCost.Load(), pc.softMemLimit.Load()
if currentTot < softLimit {
if !evictAll && currentTot < softLimit {
detailInfo = fmt.Sprintf("memory usage is below the soft limit, currentTot: %v, softLimit: %v", currentTot, softLimit)
return
}
Expand All @@ -149,7 +149,12 @@ func (pc *instancePlanCache) Evict() (detailInfo string, numEvicted int) {
lastUsedTimes = append(lastUsedTimes, this.lastUsed.Load())
return false
})
threshold := pc.calcEvictionThreshold(lastUsedTimes) // step 2
var threshold time.Time
if evictAll {
threshold = time.Now().Add(time.Hour * 24) // a future time
} else {
threshold = pc.calcEvictionThreshold(lastUsedTimes) // step 2
}
detailInfo = fmt.Sprintf("evict threshold: %v", threshold)
pc.foreach(func(prev, this *instancePCNode) bool { // step 3
if !this.lastUsed.Load().After(threshold) { // if lastUsed<=threshold, evict this value
Expand Down
29 changes: 25 additions & 4 deletions pkg/planner/core/plan_cache_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func TestInstancePlanCacheBasic(t *testing.T) {
_hit(t, pc, 1, 0) // access 1-3 to refresh their last_used
_hit(t, pc, 2, 0)
_hit(t, pc, 3, 0)
_, numEvicted := pc.Evict()
_, numEvicted := pc.Evict(false)
require.Equal(t, numEvicted > 0, true)
require.Equal(t, pc.MemUsage(), int64(300))
_hit(t, pc, 1, 0) // access 1-3 to refresh their last_used
Expand All @@ -98,7 +98,7 @@ func TestInstancePlanCacheBasic(t *testing.T) {
_put(pc, 1, 100, 0)
_put(pc, 2, 100, 0)
_put(pc, 3, 100, 0)
_, numEvicted = pc.Evict()
_, numEvicted = pc.Evict(false)
require.Equal(t, numEvicted > 0, false)
require.Equal(t, pc.MemUsage(), int64(300))
_hit(t, pc, 1, 0)
Expand All @@ -115,7 +115,7 @@ func TestInstancePlanCacheBasic(t *testing.T) {
numHeads := 0
pcImpl.heads.Range(func(k, v any) bool { numHeads++; return true })
require.Equal(t, numHeads, 3)
_, numEvicted = pc.Evict()
_, numEvicted = pc.Evict(false)
require.Equal(t, numEvicted > 0, true)
require.Equal(t, pc.MemUsage(), int64(0))
numHeads = 0
Expand Down Expand Up @@ -177,7 +177,7 @@ func TestInstancePlanCacheWithMatchOpts(t *testing.T) {
_hit(t, pc, 1, 1) // refresh 1-3's last_used
_hit(t, pc, 1, 2)
_hit(t, pc, 1, 3)
_, numEvicted := pc.Evict()
_, numEvicted := pc.Evict(false)
require.True(t, numEvicted > 0)
require.Equal(t, pc.MemUsage(), int64(300))
_hit(t, pc, 1, 1)
Expand All @@ -187,6 +187,27 @@ func TestInstancePlanCacheWithMatchOpts(t *testing.T) {
_miss(t, pc, 1, 5)
}

func TestInstancePlanCacheEvictAll(t *testing.T) {
sctx := MockContext()
defer func() {
domain.GetDomain(sctx).StatsHandle().Close()
}()
sctx.GetSessionVars().PlanCacheInvalidationOnFreshStats = true

// same key with different statsHash
pc := NewInstancePlanCache(1000, 1000)
_put(pc, 1, 100, 1)
_put(pc, 1, 100, 2)
_put(pc, 1, 100, 3)
_, numEvicted := pc.Evict(true)
require.Equal(t, 3, numEvicted)
_miss(t, pc, 1, 1)
_miss(t, pc, 1, 2)
_miss(t, pc, 1, 3)
require.Equal(t, pc.MemUsage(), int64(0))
require.Equal(t, pc.Size(), int64(0))
}

func TestInstancePlanCacheConcurrentRead(t *testing.T) {
sctx := MockContext()
defer func() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/sessionctx/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type InstancePlanCache interface {
// Put puts the key and value into the cache.
Put(key string, value, paramTypes any) (succ bool)
// Evict evicts some cached values.
Evict() (detailInfo string, numEvicted int)
Evict(evictAll bool) (detailInfo string, numEvicted int)
// Size returns the number of cached values.
Size() int64
// MemUsage returns the total memory usage of this plan cache.
Expand Down

0 comments on commit 0dcd8e7

Please sign in to comment.