github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/explainfor_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package interlock_test
    15  
    16  import (
    17  	"crypto/tls"
    18  	"fmt"
    19  	"math"
    20  	"strconv"
    21  	"sync"
    22  
    23  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    24  	. "github.com/whtcorpsinc/check"
    25  	"github.com/whtcorpsinc/milevadb/causet/embedded"
    26  	"github.com/whtcorpsinc/milevadb/soliton"
    27  	"github.com/whtcorpsinc/milevadb/soliton/ekvcache"
    28  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    29  	"github.com/whtcorpsinc/milevadb/stochastik"
    30  )
    31  
    32  // mockStochastikManager is a mocked stochastik manager which is used for test.
    33  type mockStochastikManager1 struct {
    34  	PS []*soliton.ProcessInfo
    35  }
    36  
    37  // ShowProcessList implements the StochastikManager.ShowProcessList interface.
    38  func (msm *mockStochastikManager1) ShowProcessList() map[uint64]*soliton.ProcessInfo {
    39  	ret := make(map[uint64]*soliton.ProcessInfo)
    40  	for _, item := range msm.PS {
    41  		ret[item.ID] = item
    42  	}
    43  	return ret
    44  }
    45  
    46  func (msm *mockStochastikManager1) GetProcessInfo(id uint64) (*soliton.ProcessInfo, bool) {
    47  	for _, item := range msm.PS {
    48  		if item.ID == id {
    49  			return item, true
    50  		}
    51  	}
    52  	return &soliton.ProcessInfo{}, false
    53  }
    54  
    55  // Kill implements the StochastikManager.Kill interface.
    56  func (msm *mockStochastikManager1) Kill(cid uint64, query bool) {
    57  
    58  }
    59  
    60  func (msm *mockStochastikManager1) UFIDelateTLSConfig(cfg *tls.Config) {
    61  }
    62  
    63  func (s *testSuite) TestExplainFor(c *C) {
    64  	tkRoot := testkit.NewTestKitWithInit(c, s.causetstore)
    65  	tkUser := testkit.NewTestKitWithInit(c, s.causetstore)
    66  	tkRoot.MustInterDirc("create causet t1(c1 int, c2 int)")
    67  	tkRoot.MustInterDirc("create causet t2(c1 int, c2 int)")
    68  	tkRoot.MustInterDirc("create user tu@'%'")
    69  	tkRoot.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "localhost", CurrentUser: true, AuthUsername: "root", AuthHostname: "%"}, nil, []byte("012345678901234567890"))
    70  	tkUser.Se.Auth(&auth.UserIdentity{Username: "tu", Hostname: "localhost", CurrentUser: true, AuthUsername: "tu", AuthHostname: "%"}, nil, []byte("012345678901234567890"))
    71  
    72  	tkRoot.MustQuery("select * from t1;")
    73  	tkRootProcess := tkRoot.Se.ShowProcess()
    74  	ps := []*soliton.ProcessInfo{tkRootProcess}
    75  	tkRoot.Se.SetStochastikManager(&mockStochastikManager1{PS: ps})
    76  	tkUser.Se.SetStochastikManager(&mockStochastikManager1{PS: ps})
    77  	tkRoot.MustQuery(fmt.Sprintf("explain for connection %d", tkRootProcess.ID)).Check(testkit.Events(
    78  		"BlockReader_5 10000.00 root  data:BlockFullScan_4",
    79  		"└─BlockFullScan_4 10000.00 cop[einsteindb] causet:t1 keep order:false, stats:pseudo",
    80  	))
    81  	err := tkUser.InterDircToErr(fmt.Sprintf("explain for connection %d", tkRootProcess.ID))
    82  	c.Check(embedded.ErrAccessDenied.Equal(err), IsTrue)
    83  	err = tkUser.InterDircToErr("explain for connection 42")
    84  	c.Check(embedded.ErrNoSuchThread.Equal(err), IsTrue)
    85  
    86  	tkRootProcess.Causet = nil
    87  	ps = []*soliton.ProcessInfo{tkRootProcess}
    88  	tkRoot.Se.SetStochastikManager(&mockStochastikManager1{PS: ps})
    89  	tkRoot.MustInterDirc(fmt.Sprintf("explain for connection %d", tkRootProcess.ID))
    90  }
    91  
    92  func (s *testSuite) TestIssue11124(c *C) {
    93  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
    94  	tk2 := testkit.NewTestKitWithInit(c, s.causetstore)
    95  	tk.MustInterDirc("drop causet if exists kankan1")
    96  	tk.MustInterDirc("drop causet if exists kankan2")
    97  	tk.MustInterDirc("create causet kankan1(id int, name text);")
    98  	tk.MustInterDirc("create causet kankan2(id int, h1 text);")
    99  	tk.MustInterDirc("insert into kankan1 values(1, 'a'), (2, 'a');")
   100  	tk.MustInterDirc("insert into kankan2 values(2, 'z');")
   101  	tk.MustQuery("select t1.id from kankan1 t1 left join kankan2 t2 on t1.id = t2.id where (case  when t1.name='b' then 'case2' when t1.name='a' then 'case1' else NULL end) = 'case1'")
   102  	tkRootProcess := tk.Se.ShowProcess()
   103  	ps := []*soliton.ProcessInfo{tkRootProcess}
   104  	tk.Se.SetStochastikManager(&mockStochastikManager1{PS: ps})
   105  	tk2.Se.SetStochastikManager(&mockStochastikManager1{PS: ps})
   106  
   107  	rs := tk.MustQuery("explain select t1.id from kankan1 t1 left join kankan2 t2 on t1.id = t2.id where (case  when t1.name='b' then 'case2' when t1.name='a' then 'case1' else NULL end) = 'case1'").Events()
   108  	rs2 := tk2.MustQuery(fmt.Sprintf("explain for connection %d", tkRootProcess.ID)).Events()
   109  	for i := range rs {
   110  		c.Assert(rs[i], DeepEquals, rs2[i])
   111  	}
   112  }
   113  
   114  func (s *testSuite) TestExplainMemBlockPredicate(c *C) {
   115  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   116  	tk.MustQuery("desc select * from METRICS_SCHEMA.milevadb_query_duration where time >= '2020-12-23 16:10:13' and time <= '2020-12-23 16:30:13' ").Check(testkit.Events(
   117  		"MemBlockScan_5 10000.00 root causet:milevadb_query_duration PromQL:histogram_quantile(0.9, sum(rate(milevadb_server_handle_query_duration_seconds_bucket{}[60s])) by (le,sql_type,instance)), start_time:2020-12-23 16:10:13, end_time:2020-12-23 16:30:13, step:1m0s"))
   118  	tk.MustQuery("desc select * from METRICS_SCHEMA.up where time >= '2020-12-23 16:10:13' and time <= '2020-12-23 16:30:13' ").Check(testkit.Events(
   119  		"MemBlockScan_5 10000.00 root causet:up PromQL:up{}, start_time:2020-12-23 16:10:13, end_time:2020-12-23 16:30:13, step:1m0s"))
   120  	tk.MustQuery("desc select * from information_schema.cluster_log where time >= '2020-12-23 16:10:13' and time <= '2020-12-23 16:30:13'").Check(testkit.Events(
   121  		"MemBlockScan_5 10000.00 root causet:CLUSTER_LOG start_time:2020-12-23 16:10:13, end_time:2020-12-23 16:30:13"))
   122  	tk.MustQuery("desc select * from information_schema.cluster_log where level in ('warn','error') and time >= '2020-12-23 16:10:13' and time <= '2020-12-23 16:30:13'").Check(testkit.Events(
   123  		`MemBlockScan_5 10000.00 root causet:CLUSTER_LOG start_time:2020-12-23 16:10:13, end_time:2020-12-23 16:30:13, log_levels:["error","warn"]`))
   124  	tk.MustQuery("desc select * from information_schema.cluster_log where type in ('high_cpu_1','high_memory_1') and time >= '2020-12-23 16:10:13' and time <= '2020-12-23 16:30:13'").Check(testkit.Events(
   125  		`MemBlockScan_5 10000.00 root causet:CLUSTER_LOG start_time:2020-12-23 16:10:13, end_time:2020-12-23 16:30:13, node_types:["high_cpu_1","high_memory_1"]`))
   126  	tk.MustQuery("desc select * from information_schema.slow_query").Check(testkit.Events(
   127  		"MemBlockScan_4 10000.00 root causet:SLOW_QUERY only search in the current 'milevadb-slow.log' file"))
   128  	tk.MustQuery("desc select * from information_schema.slow_query where time >= '2020-12-23 16:10:13' and time <= '2020-12-23 16:30:13'").Check(testkit.Events(
   129  		"MemBlockScan_5 10000.00 root causet:SLOW_QUERY start_time:2020-12-23 16:10:13.000000, end_time:2020-12-23 16:30:13.000000"))
   130  	tk.MustInterDirc("set @@time_zone = '+00:00';")
   131  	tk.MustQuery("desc select * from information_schema.slow_query where time >= '2020-12-23 16:10:13' and time <= '2020-12-23 16:30:13'").Check(testkit.Events(
   132  		"MemBlockScan_5 10000.00 root causet:SLOW_QUERY start_time:2020-12-23 16:10:13.000000, end_time:2020-12-23 16:30:13.000000"))
   133  }
   134  
   135  func (s *testSuite) TestExplainClusterBlock(c *C) {
   136  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   137  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.cluster_config where type in ('einsteindb', 'milevadb')")).Check(testkit.Events(
   138  		`MemBlockScan_5 10000.00 root causet:CLUSTER_CONFIG node_types:["milevadb","einsteindb"]`))
   139  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.cluster_config where instance='192.168.1.7:2379'")).Check(testkit.Events(
   140  		`MemBlockScan_5 10000.00 root causet:CLUSTER_CONFIG instances:["192.168.1.7:2379"]`))
   141  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.cluster_config where type='milevadb' and instance='192.168.1.7:2379'")).Check(testkit.Events(
   142  		`MemBlockScan_5 10000.00 root causet:CLUSTER_CONFIG node_types:["milevadb"], instances:["192.168.1.7:2379"]`))
   143  }
   144  
   145  func (s *testSuite) TestInspectionResultBlock(c *C) {
   146  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   147  	tk.MustQuery("desc select * from information_schema.inspection_result where rule = 'dbs' and rule = 'config'").Check(testkit.Events(
   148  		`MemBlockScan_5 10000.00 root causet:INSPECTION_RESULT skip_inspection:true`))
   149  	tk.MustQuery("desc select * from information_schema.inspection_result where rule in ('dbs', 'config')").Check(testkit.Events(
   150  		`MemBlockScan_5 10000.00 root causet:INSPECTION_RESULT rules:["config","dbs"], items:[]`))
   151  	tk.MustQuery("desc select * from information_schema.inspection_result where item in ('dbs.lease', 'raftstore.threadpool')").Check(testkit.Events(
   152  		`MemBlockScan_5 10000.00 root causet:INSPECTION_RESULT rules:[], items:["dbs.lease","raftstore.threadpool"]`))
   153  	tk.MustQuery("desc select * from information_schema.inspection_result where item in ('dbs.lease', 'raftstore.threadpool') and rule in ('dbs', 'config')").Check(testkit.Events(
   154  		`MemBlockScan_5 10000.00 root causet:INSPECTION_RESULT rules:["config","dbs"], items:["dbs.lease","raftstore.threadpool"]`))
   155  }
   156  
   157  func (s *testSuite) TestInspectionMemruleBlock(c *C) {
   158  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   159  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.inspection_rules where type='inspection'")).Check(testkit.Events(
   160  		`MemBlockScan_5 10000.00 root causet:INSPECTION_RULES node_types:["inspection"]`))
   161  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.inspection_rules where type='inspection' or type='summary'")).Check(testkit.Events(
   162  		`MemBlockScan_5 10000.00 root causet:INSPECTION_RULES node_types:["inspection","summary"]`))
   163  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.inspection_rules where type='inspection' and type='summary'")).Check(testkit.Events(
   164  		`MemBlockScan_5 10000.00 root causet:INSPECTION_RULES skip_request: true`))
   165  }
   166  
   167  type testPrepareSerialSuite struct {
   168  	*baseTestSuite
   169  }
   170  
   171  func (s *testPrepareSerialSuite) TestExplainForConnCausetCache(c *C) {
   172  	orgEnable := embedded.PreparedCausetCacheEnabled()
   173  	defer func() {
   174  		embedded.SetPreparedCausetCache(orgEnable)
   175  	}()
   176  	embedded.SetPreparedCausetCache(true)
   177  
   178  	var err error
   179  	tk1 := testkit.NewTestKit(c, s.causetstore)
   180  	tk1.Se, err = stochastik.CreateStochastik4TestWithOpt(s.causetstore, &stochastik.Opt{
   181  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   182  	})
   183  	c.Assert(err, IsNil)
   184  	tk2 := testkit.NewTestKitWithInit(c, s.causetstore)
   185  
   186  	tk1.MustInterDirc("use test")
   187  	tk1.MustInterDirc("drop causet if exists t")
   188  	tk1.MustInterDirc("create causet t(a int)")
   189  	tk1.MustInterDirc("prepare stmt from 'select * from t where a = ?'")
   190  	tk1.MustInterDirc("set @p0='1'")
   191  
   192  	executeQuery := "execute stmt using @p0"
   193  	explainQuery := "explain for connection " + strconv.FormatUint(tk1.Se.ShowProcess().ID, 10)
   194  	explainResult := testkit.Events(
   195  		"BlockReader_7 8000.00 root  data:Selection_6",
   196  		"└─Selection_6 8000.00 cop[einsteindb]  eq(cast(test.t.a), 1)",
   197  		"  └─BlockFullScan_5 10000.00 cop[einsteindb] causet:t keep order:false, stats:pseudo",
   198  	)
   199  
   200  	// Now the ProcessInfo held by mockStochastikManager1 will not be uFIDelated in real time.
   201  	// So it needs to be reset every time before tk2 query.
   202  	// TODO: replace mockStochastikManager1 with another mockStochastikManager.
   203  
   204  	// single test
   205  	tk1.MustInterDirc(executeQuery)
   206  	tk2.Se.SetStochastikManager(&mockStochastikManager1{
   207  		PS: []*soliton.ProcessInfo{tk1.Se.ShowProcess()},
   208  	})
   209  	tk2.MustQuery(explainQuery).Check(explainResult)
   210  
   211  	// multiple test, '1000' is both effective and efficient.
   212  	repeats := 1000
   213  	var wg sync.WaitGroup
   214  	wg.Add(2)
   215  
   216  	go func() {
   217  		for i := 0; i < repeats; i++ {
   218  			tk1.MustInterDirc(executeQuery)
   219  		}
   220  		wg.Done()
   221  	}()
   222  
   223  	go func() {
   224  		for i := 0; i < repeats; i++ {
   225  			tk2.Se.SetStochastikManager(&mockStochastikManager1{
   226  				PS: []*soliton.ProcessInfo{tk1.Se.ShowProcess()},
   227  			})
   228  			tk2.MustQuery(explainQuery).Check(explainResult)
   229  		}
   230  		wg.Done()
   231  	}()
   232  
   233  	wg.Wait()
   234  }
   235  
   236  func (s *testPrepareSerialSuite) TestExplainDotForExplainCauset(c *C) {
   237  	tk := testkit.NewTestKit(c, s.causetstore)
   238  
   239  	rows := tk.MustQuery("select connection_id()").Events()
   240  	c.Assert(len(rows), Equals, 1)
   241  	connID := rows[0][0].(string)
   242  	tk.MustQuery("explain select 1").Check(testkit.Events(
   243  		"Projection_3 1.00 root  1->DeferredCauset#1",
   244  		"└─BlockDual_4 1.00 root  rows:1",
   245  	))
   246  
   247  	tkProcess := tk.Se.ShowProcess()
   248  	ps := []*soliton.ProcessInfo{tkProcess}
   249  	tk.Se.SetStochastikManager(&mockStochastikManager1{PS: ps})
   250  
   251  	tk.MustQuery(fmt.Sprintf("explain format=\"dot\" for connection %s", connID)).Check(nil)
   252  }
   253  
   254  func (s *testPrepareSerialSuite) TestExplainDotForQuery(c *C) {
   255  	tk := testkit.NewTestKit(c, s.causetstore)
   256  	tk2 := testkit.NewTestKit(c, s.causetstore)
   257  
   258  	rows := tk.MustQuery("select connection_id()").Events()
   259  	c.Assert(len(rows), Equals, 1)
   260  	connID := rows[0][0].(string)
   261  	tk.MustQuery("select 1")
   262  	tkProcess := tk.Se.ShowProcess()
   263  	ps := []*soliton.ProcessInfo{tkProcess}
   264  	tk.Se.SetStochastikManager(&mockStochastikManager1{PS: ps})
   265  
   266  	expected := tk2.MustQuery("explain format=\"dot\" select 1").Events()
   267  	got := tk.MustQuery(fmt.Sprintf("explain format=\"dot\" for connection %s", connID)).Events()
   268  	for i := range got {
   269  		c.Assert(got[i], DeepEquals, expected[i])
   270  	}
   271  }
   272  
   273  func (s *testSuite) TestExplainBlockStorage(c *C) {
   274  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   275  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'information_schema'")).Check(testkit.Events(
   276  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TABLE_STORAGE_STATS schemaReplicant:[\"information_schema\"]")))
   277  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TABLE_STORAGE_STATS where TABLE_NAME = 'schemata'")).Check(testkit.Events(
   278  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TABLE_STORAGE_STATS causet:[\"schemata\"]")))
   279  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'information_schema' and TABLE_NAME = 'schemata'")).Check(testkit.Events(
   280  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TABLE_STORAGE_STATS schemaReplicant:[\"information_schema\"], causet:[\"schemata\"]")))
   281  }
   282  
   283  func (s *testSuite) TestInspectionSummaryBlock(c *C) {
   284  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   285  
   286  	tk.MustQuery("desc select * from information_schema.inspection_summary where rule='dbs'").Check(testkit.Events(
   287  		`Selection_5 8000.00 root  eq(DeferredCauset#1, "dbs")`,
   288  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["dbs"]`,
   289  	))
   290  	tk.MustQuery("desc select * from information_schema.inspection_summary where 'dbs'=rule or rule='config'").Check(testkit.Events(
   291  		`Selection_5 8000.00 root  or(eq("dbs", DeferredCauset#1), eq(DeferredCauset#1, "config"))`,
   292  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["config","dbs"]`,
   293  	))
   294  	tk.MustQuery("desc select * from information_schema.inspection_summary where 'dbs'=rule or rule='config' or rule='slow_query'").Check(testkit.Events(
   295  		`Selection_5 8000.00 root  or(eq("dbs", DeferredCauset#1), or(eq(DeferredCauset#1, "config"), eq(DeferredCauset#1, "slow_query")))`,
   296  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["config","dbs","slow_query"]`,
   297  	))
   298  	tk.MustQuery("desc select * from information_schema.inspection_summary where (rule='config' or rule='slow_query') and (metrics_name='metric_name3' or metrics_name='metric_name1')").Check(testkit.Events(
   299  		`Selection_5 8000.00 root  or(eq(DeferredCauset#1, "config"), eq(DeferredCauset#1, "slow_query")), or(eq(DeferredCauset#3, "metric_name3"), eq(DeferredCauset#3, "metric_name1"))`,
   300  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["config","slow_query"], metric_names:["metric_name1","metric_name3"]`,
   301  	))
   302  	tk.MustQuery("desc select * from information_schema.inspection_summary where rule in ('dbs', 'slow_query')").Check(testkit.Events(
   303  		`Selection_5 8000.00 root  in(DeferredCauset#1, "dbs", "slow_query")`,
   304  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["dbs","slow_query"]`,
   305  	))
   306  	tk.MustQuery("desc select * from information_schema.inspection_summary where rule in ('dbs', 'slow_query') and metrics_name='metric_name1'").Check(testkit.Events(
   307  		`Selection_5 8000.00 root  eq(DeferredCauset#3, "metric_name1"), in(DeferredCauset#1, "dbs", "slow_query")`,
   308  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["dbs","slow_query"], metric_names:["metric_name1"]`,
   309  	))
   310  	tk.MustQuery("desc select * from information_schema.inspection_summary where rule in ('dbs', 'slow_query') and metrics_name in ('metric_name1', 'metric_name2')").Check(testkit.Events(
   311  		`Selection_5 8000.00 root  in(DeferredCauset#1, "dbs", "slow_query"), in(DeferredCauset#3, "metric_name1", "metric_name2")`,
   312  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["dbs","slow_query"], metric_names:["metric_name1","metric_name2"]`,
   313  	))
   314  	tk.MustQuery("desc select * from information_schema.inspection_summary where rule='dbs' and metrics_name in ('metric_name1', 'metric_name2')").Check(testkit.Events(
   315  		`Selection_5 8000.00 root  eq(DeferredCauset#1, "dbs"), in(DeferredCauset#3, "metric_name1", "metric_name2")`,
   316  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["dbs"], metric_names:["metric_name1","metric_name2"]`,
   317  	))
   318  	tk.MustQuery("desc select * from information_schema.inspection_summary where rule='dbs' and metrics_name='metric_NAME3'").Check(testkit.Events(
   319  		`Selection_5 8000.00 root  eq(DeferredCauset#1, "dbs"), eq(DeferredCauset#3, "metric_NAME3")`,
   320  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["dbs"], metric_names:["metric_name3"]`,
   321  	))
   322  	tk.MustQuery("desc select * from information_schema.inspection_summary where rule in ('dbs', 'config') and rule in ('slow_query', 'config')").Check(testkit.Events(
   323  		`Selection_5 8000.00 root  in(DeferredCauset#1, "dbs", "config"), in(DeferredCauset#1, "slow_query", "config")`,
   324  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["config"]`,
   325  	))
   326  	tk.MustQuery("desc select * from information_schema.inspection_summary where metrics_name in ('metric_name1', 'metric_name4') and metrics_name in ('metric_name5', 'metric_name4') and rule in ('dbs', 'config') and rule in ('slow_query', 'config') and quantile in (0.80, 0.90)").Check(testkit.Events(
   327  		`Selection_5 8000.00 root  in(DeferredCauset#1, "dbs", "config"), in(DeferredCauset#1, "slow_query", "config"), in(DeferredCauset#3, "metric_name1", "metric_name4"), in(DeferredCauset#3, "metric_name5", "metric_name4")`,
   328  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY rules:["config"], metric_names:["metric_name4"], quantiles:[0.800000,0.900000]`,
   329  	))
   330  	tk.MustQuery("desc select * from information_schema.inspection_summary where metrics_name in ('metric_name1', 'metric_name4') and metrics_name in ('metric_name5', 'metric_name4') and metrics_name in ('metric_name5', 'metric_name1') and metrics_name in ('metric_name1', 'metric_name3')").Check(testkit.Events(
   331  		`Selection_5 8000.00 root  in(DeferredCauset#3, "metric_name1", "metric_name3"), in(DeferredCauset#3, "metric_name1", "metric_name4"), in(DeferredCauset#3, "metric_name5", "metric_name1"), in(DeferredCauset#3, "metric_name5", "metric_name4")`,
   332  		`└─MemBlockScan_6 10000.00 root causet:INSPECTION_SUMMARY skip_inspection: true`,
   333  	))
   334  }
   335  
   336  func (s *testSuite) TestExplainTiFlashSystemBlocks(c *C) {
   337  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   338  	tiflashInstance := "192.168.1.7:3930"
   339  	database := "test"
   340  	causet := "t"
   341  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_TABLES where TIFLASH_INSTANCE = '%s'", tiflashInstance)).Check(testkit.Events(
   342  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_TABLES tiflash_instances:[\"%s\"]", tiflashInstance)))
   343  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_SEGMENTS where TIFLASH_INSTANCE = '%s'", tiflashInstance)).Check(testkit.Events(
   344  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_SEGMENTS tiflash_instances:[\"%s\"]", tiflashInstance)))
   345  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_TABLES where MilevaDB_DATABASE = '%s'", database)).Check(testkit.Events(
   346  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_TABLES milevadb_databases:[\"%s\"]", database)))
   347  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_SEGMENTS where MilevaDB_DATABASE = '%s'", database)).Check(testkit.Events(
   348  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_SEGMENTS milevadb_databases:[\"%s\"]", database)))
   349  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_TABLES where MilevaDB_TABLE = '%s'", causet)).Check(testkit.Events(
   350  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_TABLES milevadb_blocks:[\"%s\"]", causet)))
   351  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_SEGMENTS where MilevaDB_TABLE = '%s'", causet)).Check(testkit.Events(
   352  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_SEGMENTS milevadb_blocks:[\"%s\"]", causet)))
   353  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_TABLES where TIFLASH_INSTANCE = '%s' and MilevaDB_DATABASE = '%s' and MilevaDB_TABLE = '%s'", tiflashInstance, database, causet)).Check(testkit.Events(
   354  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_TABLES tiflash_instances:[\"%s\"], milevadb_databases:[\"%s\"], milevadb_blocks:[\"%s\"]", tiflashInstance, database, causet)))
   355  	tk.MustQuery(fmt.Sprintf("desc select * from information_schema.TIFLASH_SEGMENTS where TIFLASH_INSTANCE = '%s' and MilevaDB_DATABASE = '%s' and MilevaDB_TABLE = '%s'", tiflashInstance, database, causet)).Check(testkit.Events(
   356  		fmt.Sprintf("MemBlockScan_5 10000.00 root causet:TIFLASH_SEGMENTS tiflash_instances:[\"%s\"], milevadb_databases:[\"%s\"], milevadb_blocks:[\"%s\"]", tiflashInstance, database, causet)))
   357  }