diff --git a/pkg/planner/core/casetest/instanceplancache/BUILD.bazel b/pkg/planner/core/casetest/instanceplancache/BUILD.bazel index e1c1af9568a0a..e361ad0bed836 100644 --- a/pkg/planner/core/casetest/instanceplancache/BUILD.bazel +++ b/pkg/planner/core/casetest/instanceplancache/BUILD.bazel @@ -10,7 +10,7 @@ go_test( "others_test.go", ], flaky = True, - shard_count = 16, + shard_count = 17, deps = [ "//pkg/parser/auth", "//pkg/testkit", diff --git a/pkg/planner/core/casetest/instanceplancache/concurrency_test.go b/pkg/planner/core/casetest/instanceplancache/concurrency_test.go index 2b170da074d8c..8c22c1b01fb43 100644 --- a/pkg/planner/core/casetest/instanceplancache/concurrency_test.go +++ b/pkg/planner/core/casetest/instanceplancache/concurrency_test.go @@ -230,7 +230,7 @@ func TestInstancePlanCacheConcurrencySysbench(t *testing.T) { } } - nStmt := 7000 + nStmt := 2000 nInitialRecords := 100 stmts := make([]*testStmt, 0, nStmt) stmts = append(stmts, &testStmt{normalStmt: "begin"}) @@ -265,3 +265,276 @@ func TestInstancePlanCacheConcurrencySysbench(t *testing.T) { testWithWorkers(TKs, stmts) } + +func TestInstancePlanCacheConcurrencyComp(t *testing.T) { + // cases from https://github.com/PingCAP-QE/qa/tree/master/comp/yy/plan-cache + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`create database normal`) + tk.MustExec(`create database prepared`) + tk.MustExec(`set global tidb_enable_instance_plan_cache=1`) + for _, db := range []string{"normal", "prepared"} { + tk.MustExec("use " + db) + tk.MustExec(`create table t1 (col1 int, col2 int, key(col1, col2))`) + } + + genInsert := func() *testStmt { + col1 := rand.Intn(1000) + col2 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("insert into normal.t1 values (%v, %v)", col1, col2), + prepStmt: "prepare st from 'insert into prepared.t1 values (?, ?)'", + setStmt: fmt.Sprintf("set @col1 = %v, @col2 = %v", col1, col2), + execStmt: "execute st using @col1, @col2", + } + } + genBasicSelect := func() *testStmt { + switch rand.Intn(2) { + case 0: // point + switch rand.Intn(3) { + case 0: // select * from t1 where col1=? + col1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 where col1=%v", col1), + prepStmt: "prepare st from 'select * from prepared.t1 where col1=?'", + setStmt: fmt.Sprintf("set @col1 = %v", col1), + execStmt: "execute st using @col1", + } + case 1: // select * from t1 where col1 is null + return &testStmt{ + normalStmt: "select * from normal.t1 where col1 is null", + prepStmt: "prepare st from 'select * from prepared.t1 where col1 is null'", + setStmt: "", + execStmt: "execute st", + } + case 2: // select * from t1 where col1 in (?, ?, ?) + v1 := rand.Intn(1000) + v2 := rand.Intn(1000) + v3 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 where col1 in (%v, %v, %v)", v1, v2, v3), + prepStmt: "prepare st from 'select * from prepared.t1 where col1 in (?, ?, ?)'", + setStmt: fmt.Sprintf("set @v1 = %v, @v2 = %v, @v3 = %v", v1, v2, v3), + execStmt: "execute st using @v1, @v2, @v3", + } + } + default: // range + switch rand.Intn(4) { + case 0: // select * from t1 where col1 between ? and ? + v1 := rand.Intn(1000) + v2 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 where col1 between %v and %v", v1, v2), + prepStmt: "prepare st from 'select * from prepared.t1 where col1 between ? and ?'", + setStmt: fmt.Sprintf("set @v1 = %v, @v2 = %v", v1, v2), + execStmt: "execute st using @v1, @v2", + } + case 1: // select * from t1 where col1 > ? + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 where col1 > %v", v1), + prepStmt: "prepare st from 'select * from prepared.t1 where col1 > ?'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + case 2: // select * from t1 where col1 <= ? + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 where col1 <= %v", v1), + prepStmt: "prepare st from 'select * from prepared.t1 where col1 <= ?'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + default: // select * from t1 where col1 != ? + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 where col1 != %v", v1), + prepStmt: "prepare st from 'select * from prepared.t1 where col1 != ?'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + } + } + return nil + } + genAggSelect := func() *testStmt { + switch rand.Intn(5) { + case 0: // select sum(col1), col2 from t1 where col1=? group by col2 + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select sum(col1), col2 from normal.t1 where col1=%v group by col2", v1), + prepStmt: "prepare st from 'select sum(col1), col2 from prepared.t1 where col1=? group by col2'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + case 1: // select sum(col1), col2 from t1 where col1 between ? and ? group by col2 + v1 := rand.Intn(1000) + v2 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select sum(col1), col2 from normal.t1 where col1 between %v and %v group by col2", v1, v2), + prepStmt: "prepare st from 'select sum(col1), col2 from prepared.t1 where col1 between ? and ? group by col2'", + setStmt: fmt.Sprintf("set @v1 = %v, @v2 = %v", v1, v2), + execStmt: "execute st using @v1, @v2", + } + case 2: // select sum(col1), col2 from t1 where col1 > ? group by col2 + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select sum(col1), col2 from normal.t1 where col1 > %v group by col2", v1), + prepStmt: "prepare st from 'select sum(col1), col2 from prepared.t1 where col1 > ? group by col2'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + case 3: // select sum(col1), col2 from t1 where col1 <= ? group by col2 + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select sum(col1), col2 from normal.t1 where col1 <= %v group by col2", v1), + prepStmt: "prepare st from 'select sum(col1), col2 from prepared.t1 where col1 <= ? group by col2'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + default: // select sum(col1), col2 from t1 where col1 = ? group by col2 + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select sum(col1), col2 from normal.t1 where col1 = %v group by col2", v1), + prepStmt: "prepare st from 'select sum(col1), col2 from prepared.t1 where col1 = ? group by col2'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + } + } + genJoinSelect := func() *testStmt { + switch rand.Intn(4) { + case 0: // select * from t1 t1 join t1 t2 on t1.col1=t2.col1 where t1.col1=? + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 t1 join normal.t1 t2 on t1.col1=t2.col1 where t1.col1=%v", v1), + prepStmt: "prepare st from 'select * from prepared.t1 t1 join prepared.t1 t2 on t1.col1=t2.col1 where t1.col1=?'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + case 1: // select * from t1 t1 join t1 t2 on t1.col1=t2.col1 where t1.col1 between ? and ? + v1 := rand.Intn(1000) + v2 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 t1 join normal.t1 t2 on t1.col1=t2.col1 where t1.col1 between %v and %v", v1, v2), + prepStmt: "prepare st from 'select * from prepared.t1 t1 join prepared.t1 t2 on t1.col1=t2.col1 where t1.col1 between ? and ?'", + setStmt: fmt.Sprintf("set @v1 = %v, @v2 = %v", v1, v2), + execStmt: "execute st using @v1, @v2", + } + case 2: // select * from t1 t1 left join t1 t2 on t1.col1=t2.col1 where t1.col1 > ? + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 t1 left join normal.t1 t2 on t1.col1=t2.col1 where t1.col1 > %v", v1), + prepStmt: "prepare st from 'select * from prepared.t1 t1 left join prepared.t1 t2 on t1.col1=t2.col1 where t1.col1 > ?'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + case 3: // select * from t1 t1 join t1 t2 on t1.col1>t2.col1 where t1.col1 <= ? + v1 := rand.Intn(1000) + return &testStmt{ + normalStmt: fmt.Sprintf("select * from normal.t1 t1 join normal.t1 t2 on t1.col1>t2.col1 where t1.col1 <= %v", v1), + prepStmt: "prepare st from 'select * from prepared.t1 t1 join prepared.t1 t2 on t1.col1>t2.col1 where t1.col1 <= ?'", + setStmt: fmt.Sprintf("set @v1 = %v", v1), + execStmt: "execute st using @v1", + } + default: // select * from t1 t1 join t1 t2 on t1.col1