Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: disable non-prep plan cache for DML statements for now #43258

Merged
merged 3 commits into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions planner/core/plan_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func TestNonPreparedPlanCacheDMLHints(t *testing.T) {
tk.MustExec(`use test`)
tk.MustExec(`create table t (a int)`)
tk.MustExec(`set @@tidb_enable_non_prepared_plan_cache=1`)
tk.MustExec(`set @@tidb_enable_non_prepared_plan_cache_for_dml=1`)

tk.MustExec(`insert into t values (1)`)
tk.MustExec(`insert into t values (1)`)
Expand Down Expand Up @@ -1570,6 +1571,33 @@ func TestPlanCacheSubquerySPMEffective(t *testing.T) {
}
}

func TestNonPreparedPlanCacheDMLSwitch(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec("create table t (a int)")
tk.MustExec("set tidb_enable_non_prepared_plan_cache=1")

tk.MustExec("set tidb_enable_non_prepared_plan_cache_for_dml=0")
tk.MustExec(`insert into t values (1)`)
tk.MustExec(`insert into t values (1)`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
tk.MustExec(`select a from t where a < 2 for update`)
tk.MustExec(`select a from t where a < 2 for update`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
tk.MustExec(`set @x:=1`)
tk.MustExec(`set @x:=1`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))

tk.MustExec("set tidb_enable_non_prepared_plan_cache_for_dml=1")
tk.MustExec(`insert into t values (1)`)
tk.MustExec(`insert into t values (1)`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1"))
tk.MustExec(`select a from t where a < 2 for update`)
tk.MustExec(`select a from t where a < 2 for update`)
tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1"))
}

func TestNonPreparedPlanCacheUnderscoreCharset(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down Expand Up @@ -1863,6 +1891,7 @@ func TestNonPreparedPlanCacheDML(t *testing.T) {
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`set tidb_enable_non_prepared_plan_cache=1`)
tk.MustExec(`set tidb_enable_non_prepared_plan_cache_for_dml=1`)
tk.MustExec("create table t (a int default 0, b int default 0)")

for _, sql := range []string{
Expand Down Expand Up @@ -1918,6 +1947,7 @@ func TestNonPreparedPlanCacheMultiStmt(t *testing.T) {
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`set tidb_enable_non_prepared_plan_cache=1`)
tk.MustExec(`set tidb_enable_non_prepared_plan_cache_for_dml=1`)
tk.MustExec("create table t (a int)")

tk.MustExec("update t set a=1 where a<10")
Expand Down
6 changes: 6 additions & 0 deletions planner/core/plan_cacheable_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ var nonPrepCacheCheckerPool = &sync.Pool{New: func() any { return &nonPreparedPl

// NonPreparedPlanCacheableWithCtx checks whether this SQL is cacheable for non-prepared plan cache.
func NonPreparedPlanCacheableWithCtx(sctx sessionctx.Context, node ast.Node, is infoschema.InfoSchema) (ok bool, reason string) {
selStmt, isSelect := node.(*ast.SelectStmt)
if !sctx.GetSessionVars().EnableNonPreparedPlanCacheForDML &&
(!isSelect || selStmt.LockInfo != nil) {
return false, "not a SELECT statement"
}

var tableNames []*ast.TableName
switch x := node.(type) {
case *ast.SelectStmt:
Expand Down
3 changes: 3 additions & 0 deletions sessionctx/variable/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,9 @@ type SessionVars struct {
// EnableNonPreparedPlanCache indicates whether to enable non-prepared plan cache.
EnableNonPreparedPlanCache bool

// EnableNonPreparedPlanCacheForDML indicates whether to enable non-prepared plan cache for DML statements.
EnableNonPreparedPlanCacheForDML bool

// NonPreparedPlanCacheSize controls the size of non-prepared plan cache.
NonPreparedPlanCacheSize uint64

Expand Down
4 changes: 4 additions & 0 deletions sessionctx/variable/sysvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,10 @@ var defaultSysVars = []*SysVar{
s.EnableNonPreparedPlanCache = TiDBOptOn(val)
return nil
}},
{Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableNonPreparedPlanCacheForDML, Value: BoolToOnOff(DefTiDBEnableNonPreparedPlanCacheForDML), Type: TypeBool, SetSession: func(s *SessionVars, val string) error {
s.EnableNonPreparedPlanCacheForDML = TiDBOptOn(val)
return nil
}},
{Scope: ScopeGlobal | ScopeSession, Name: TiDBNonPreparedPlanCacheSize, Value: strconv.FormatUint(uint64(DefTiDBNonPreparedPlanCacheSize), 10), Type: TypeUnsigned, MinValue: 1, MaxValue: 100000, SetSession: func(s *SessionVars, val string) error {
uVal, err := strconv.ParseUint(val, 10, 64)
if err == nil {
Expand Down
3 changes: 3 additions & 0 deletions sessionctx/variable/tidb_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,8 @@ const (

// TiDBEnableNonPreparedPlanCache indicates whether to enable non-prepared plan cache.
TiDBEnableNonPreparedPlanCache = "tidb_enable_non_prepared_plan_cache"
// TiDBEnableNonPreparedPlanCacheForDML indicates whether to enable non-prepared plan cache for DML statements.
TiDBEnableNonPreparedPlanCacheForDML = "tidb_enable_non_prepared_plan_cache_for_dml"
// TiDBNonPreparedPlanCacheSize controls the size of non-prepared plan cache.
// This variable is deprecated, use tidb_session_plan_cache_size instead.
TiDBNonPreparedPlanCacheSize = "tidb_non_prepared_plan_cache_size"
Expand Down Expand Up @@ -1204,6 +1206,7 @@ const (
DefTiDBDDLDiskQuota = 100 * 1024 * 1024 * 1024 // 100GB
DefExecutorConcurrency = 5
DefTiDBEnableNonPreparedPlanCache = true
DefTiDBEnableNonPreparedPlanCacheForDML = false
DefTiDBNonPreparedPlanCacheSize = 100
DefTiDBPlanCacheMaxPlanSize = 2 * size.MB
DefTiDBEnableTiFlashReadForWriteStmt = true
Expand Down