diff --git a/pkg/executor/distsql_test.go b/pkg/executor/distsql_test.go index c883b178d1eb3..42c4531925e67 100644 --- a/pkg/executor/distsql_test.go +++ b/pkg/executor/distsql_test.go @@ -698,3 +698,25 @@ func TestIndexLookUpWithSelectForUpdateOnPartitionTable(t *testing.T) { tk.MustHavePlan("select b from t use index(k) where b > 2 order by b limit 1 for update", "IndexLookUp") tk.MustQuery("select b from t use index(k) where b > 2 order by b limit 1 for update").Check(testkit.Rows("3")) } + +func TestCoprCacheWithoutExecutionInfo(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk1 := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(id int)") + tk.MustExec("insert into t values(1), (2), (3)") + + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/store/mockstore/unistore/cophandler/mockCopCacheInUnistore", `return(123)`)) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/store/mockstore/unistore/cophandler/mockCopCacheInUnistore")) + }() + + defer tk.MustExec("set @@tidb_enable_collect_execution_info=1") + ctx := context.WithValue(context.Background(), "CheckSelectRequestHook", func(_ *kv.Request) { + tk1.MustExec("set @@tidb_enable_collect_execution_info=0") + }) + tk.MustQuery("select * from t").Check(testkit.Rows("1", "2", "3")) + tk.MustQueryWithContext(ctx, "select * from t").Check(testkit.Rows("1", "2", "3")) +} diff --git a/pkg/store/copr/coprocessor.go b/pkg/store/copr/coprocessor.go index 770b6a3dd6546..184d714fd52c3 100644 --- a/pkg/store/copr/coprocessor.go +++ b/pkg/store/copr/coprocessor.go @@ -1685,7 +1685,14 @@ func (worker *copIteratorWorker) handleCopCache(task *copTask, resp *copResponse resp.pbResp.Range = nil } } - resp.detail.CoprCacheHit = true + // `worker.enableCollectExecutionInfo` is loaded from the instance's config. Because it's not related to the request, + // the cache key can be same when `worker.enableCollectExecutionInfo` is true or false. + // When `worker.enableCollectExecutionInfo` is false, the `resp.detail` is nil, and hit cache is still possible. + // Check `resp.detail` to avoid panic. + // Details: https://github.com/pingcap/tidb/issues/48212 + if resp.detail != nil { + resp.detail.CoprCacheHit = true + } return nil } copr_metrics.CoprCacheCounterMiss.Add(1)