From 9f8b5b9593bab6dd634ed6b0b7fda230aa30f89e Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 29 May 2024 13:13:43 +0800 Subject: [PATCH 1/4] fixup --- pkg/executor/compiler.go | 1 + pkg/planner/core/plan_cache.go | 39 +++++++++++++++++----------- pkg/planner/core/plan_cache_lru.go | 4 +++ pkg/planner/core/plan_cache_utils.go | 4 +-- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/pkg/executor/compiler.go b/pkg/executor/compiler.go index 8771753e78626..6ac3208060fa6 100644 --- a/pkg/executor/compiler.go +++ b/pkg/executor/compiler.go @@ -130,6 +130,7 @@ func (c *Compiler) Compile(ctx context.Context, stmtNode ast.StmtNode) (_ *ExecS if exec, isExec := finalPlan.(*plannercore.Execute); isExec { if pointPlan, isPointPlan := exec.Plan.(*plannercore.PointGetPlan); isPointPlan { stmt.PsStmt, stmt.Plan = preparedObj, pointPlan // notify to re-use the cached plan + stmtCtx.SetPlanDigest(preparedObj.NormalizedPlan, preparedObj.PlanDigest) } } } diff --git a/pkg/planner/core/plan_cache.go b/pkg/planner/core/plan_cache.go index c2ca1ff8d250b..4c907b9e2cc8e 100644 --- a/pkg/planner/core/plan_cache.go +++ b/pkg/planner/core/plan_cache.go @@ -215,30 +215,39 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, } } - matchOpts, err := GetMatchOpts(sctx, is, stmt, params) - if err != nil { - return nil, nil, err - } + var matchOpts *utilpc.PlanCacheMatchOpts if stmtCtx.UseCache() { - if plan, names, ok, err := getCachedPlan(sctx, isNonPrepared, cacheKey, bindSQL, is, stmt, matchOpts); err != nil || ok { - return plan, names, err + var cacheVal kvcache.Value + var hit bool + if stmt.PointGet.Executor != nil { // if it's PointGet Plan, no need to use MatchOpts + cacheVal, hit = sctx.GetSessionPlanCache().Get(cacheKey, nil) + } else { + matchOpts = GetMatchOpts(sctx, is, stmt, params) + cacheVal, hit = sctx.GetSessionPlanCache().Get(cacheKey, matchOpts) + } + if hit { + if plan, names, ok, err := adjustCachedPlan(sctx, cacheVal.(*PlanCacheValue), isNonPrepared, cacheKey, bindSQL, is, stmt); err != nil || ok { + return plan, names, err + } } } + if matchOpts == nil { + matchOpts = GetMatchOpts(sctx, is, stmt, params) + } return generateNewPlan(ctx, sctx, isNonPrepared, is, stmt, cacheKey, latestSchemaVersion, bindSQL, matchOpts) } -func getCachedPlan(sctx sessionctx.Context, isNonPrepared bool, cacheKey kvcache.Key, bindSQL string, - is infoschema.InfoSchema, stmt *PlanCacheStmt, matchOpts *utilpc.PlanCacheMatchOpts) (base.Plan, - []*types.FieldName, bool, error) { +func adjustCachedPlan( + sctx sessionctx.Context, + cachedVal *PlanCacheValue, + isNonPrepared bool, + cacheKey kvcache.Key, + bindSQL string, + is infoschema.InfoSchema, stmt *PlanCacheStmt) ( + base.Plan, []*types.FieldName, bool, error) { sessVars := sctx.GetSessionVars() stmtCtx := sessVars.StmtCtx - - candidate, exist := sctx.GetSessionPlanCache().Get(cacheKey, matchOpts) - if !exist { - return nil, nil, false, nil - } - cachedVal := candidate.(*PlanCacheValue) if err := checkPreparedPriv(sctx, stmt, is); err != nil { return nil, nil, false, err } diff --git a/pkg/planner/core/plan_cache_lru.go b/pkg/planner/core/plan_cache_lru.go index ce74307738e29..6be81eac0246e 100644 --- a/pkg/planner/core/plan_cache_lru.go +++ b/pkg/planner/core/plan_cache_lru.go @@ -253,6 +253,10 @@ func (l *LRUPlanCache) memoryControl() { // PickPlanFromBucket pick one plan from bucket func (l *LRUPlanCache) pickFromBucket(bucket map[*list.Element]struct{}, matchOpts *utilpc.PlanCacheMatchOpts) (*list.Element, bool) { for k := range bucket { + if matchOpts == nil { // for PointGet Plan + return k, true + } + plan := k.Value.(*planCacheEntry).PlanValue.(*PlanCacheValue) // check param types' compatibility ok1 := checkTypesCompatibility4PC(plan.matchOpts.ParamTypes, matchOpts.ParamTypes) diff --git a/pkg/planner/core/plan_cache_utils.go b/pkg/planner/core/plan_cache_utils.go index 7909f35921787..c5833c11a89bb 100644 --- a/pkg/planner/core/plan_cache_utils.go +++ b/pkg/planner/core/plan_cache_utils.go @@ -559,7 +559,7 @@ func GetPreparedStmt(stmt *ast.ExecuteStmt, vars *variable.SessionVars) (*PlanCa // GetMatchOpts get options to fetch plan or generate new plan // we can add more options here -func GetMatchOpts(sctx sessionctx.Context, is infoschema.InfoSchema, stmt *PlanCacheStmt, params []expression.Expression) (*utilpc.PlanCacheMatchOpts, error) { +func GetMatchOpts(sctx sessionctx.Context, is infoschema.InfoSchema, stmt *PlanCacheStmt, params []expression.Expression) *utilpc.PlanCacheMatchOpts { var statsVerHash uint64 var limitOffsetAndCount []uint64 @@ -606,7 +606,7 @@ func GetMatchOpts(sctx sessionctx.Context, is infoschema.InfoSchema, stmt *PlanC StatsVersionHash: statsVerHash, ParamTypes: parseParamTypes(sctx, params), ForeignKeyChecks: sctx.GetSessionVars().ForeignKeyChecks, - }, nil + } } // CheckTypesCompatibility4PC compares FieldSlice with []*types.FieldType From b13a21970b851a54e035b22d43aa612891c5f9f9 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 29 May 2024 14:54:33 +0800 Subject: [PATCH 2/4] fixup --- pkg/planner/core/plan_cache.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pkg/planner/core/plan_cache.go b/pkg/planner/core/plan_cache.go index 4c907b9e2cc8e..d82086280d492 100644 --- a/pkg/planner/core/plan_cache.go +++ b/pkg/planner/core/plan_cache.go @@ -238,14 +238,9 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, return generateNewPlan(ctx, sctx, isNonPrepared, is, stmt, cacheKey, latestSchemaVersion, bindSQL, matchOpts) } -func adjustCachedPlan( - sctx sessionctx.Context, - cachedVal *PlanCacheValue, - isNonPrepared bool, - cacheKey kvcache.Key, - bindSQL string, - is infoschema.InfoSchema, stmt *PlanCacheStmt) ( - base.Plan, []*types.FieldName, bool, error) { +func adjustCachedPlan(sctx sessionctx.Context, cachedVal *PlanCacheValue, isNonPrepared bool, + cacheKey kvcache.Key, bindSQL string, is infoschema.InfoSchema, stmt *PlanCacheStmt) (base.Plan, + []*types.FieldName, bool, error) { sessVars := sctx.GetSessionVars() stmtCtx := sessVars.StmtCtx if err := checkPreparedPriv(sctx, stmt, is); err != nil { From c90e8cb701c6488b409876ead7bb8ba677326d88 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 29 May 2024 14:55:35 +0800 Subject: [PATCH 3/4] fixup --- pkg/executor/compiler.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/executor/compiler.go b/pkg/executor/compiler.go index 6ac3208060fa6..8771753e78626 100644 --- a/pkg/executor/compiler.go +++ b/pkg/executor/compiler.go @@ -130,7 +130,6 @@ func (c *Compiler) Compile(ctx context.Context, stmtNode ast.StmtNode) (_ *ExecS if exec, isExec := finalPlan.(*plannercore.Execute); isExec { if pointPlan, isPointPlan := exec.Plan.(*plannercore.PointGetPlan); isPointPlan { stmt.PsStmt, stmt.Plan = preparedObj, pointPlan // notify to re-use the cached plan - stmtCtx.SetPlanDigest(preparedObj.NormalizedPlan, preparedObj.PlanDigest) } } } From ebefac28c2dc27f71e83475e0a362852e44dffc0 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Wed, 29 May 2024 15:48:48 +0800 Subject: [PATCH 4/4] fixup --- pkg/planner/core/plan_cache.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pkg/planner/core/plan_cache.go b/pkg/planner/core/plan_cache.go index d82086280d492..6ad798d3f80e3 100644 --- a/pkg/planner/core/plan_cache.go +++ b/pkg/planner/core/plan_cache.go @@ -218,15 +218,16 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, var matchOpts *utilpc.PlanCacheMatchOpts if stmtCtx.UseCache() { var cacheVal kvcache.Value - var hit bool + var hit, isPointPlan bool if stmt.PointGet.Executor != nil { // if it's PointGet Plan, no need to use MatchOpts cacheVal, hit = sctx.GetSessionPlanCache().Get(cacheKey, nil) + isPointPlan = true } else { matchOpts = GetMatchOpts(sctx, is, stmt, params) cacheVal, hit = sctx.GetSessionPlanCache().Get(cacheKey, matchOpts) } if hit { - if plan, names, ok, err := adjustCachedPlan(sctx, cacheVal.(*PlanCacheValue), isNonPrepared, cacheKey, bindSQL, is, stmt); err != nil || ok { + if plan, names, ok, err := adjustCachedPlan(sctx, cacheVal.(*PlanCacheValue), isNonPrepared, isPointPlan, cacheKey, bindSQL, is, stmt); err != nil || ok { return plan, names, err } } @@ -238,13 +239,15 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, return generateNewPlan(ctx, sctx, isNonPrepared, is, stmt, cacheKey, latestSchemaVersion, bindSQL, matchOpts) } -func adjustCachedPlan(sctx sessionctx.Context, cachedVal *PlanCacheValue, isNonPrepared bool, +func adjustCachedPlan(sctx sessionctx.Context, cachedVal *PlanCacheValue, isNonPrepared, isPointPlan bool, cacheKey kvcache.Key, bindSQL string, is infoschema.InfoSchema, stmt *PlanCacheStmt) (base.Plan, []*types.FieldName, bool, error) { sessVars := sctx.GetSessionVars() stmtCtx := sessVars.StmtCtx - if err := checkPreparedPriv(sctx, stmt, is); err != nil { - return nil, nil, false, err + if !isPointPlan { // keep the prior behavior + if err := checkPreparedPriv(sctx, stmt, is); err != nil { + return nil, nil, false, err + } } for tblInfo, unionScan := range cachedVal.TblInfo2UnionScan { if !unionScan && tableHasDirtyContent(sctx.GetPlanCtx(), tblInfo) {