From 27f38dcc5e6589c040a0636417edc342837ae4b4 Mon Sep 17 00:00:00 2001 From: IcePigZDB Date: Mon, 13 Dec 2021 02:52:42 +0000 Subject: [PATCH 1/2] planner: add extractor for tikv_region_peers ref: #28330 Signed-off-by: IcePigZDB --- planner/core/logical_plan_builder.go | 2 + planner/core/memtable_predicate_extractor.go | 53 ++++++++ .../core/memtable_predicate_extractor_test.go | 123 ++++++++++++++++++ 3 files changed, 178 insertions(+) diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go index c3b1239d4ffac..6d4e4238dd362 100644 --- a/planner/core/logical_plan_builder.go +++ b/planner/core/logical_plan_builder.go @@ -4352,6 +4352,8 @@ func (b *PlanBuilder) buildMemTable(_ context.Context, dbName model.CIStr, table p.Extractor = &TiFlashSystemTableExtractor{} case infoschema.TableStatementsSummary, infoschema.TableStatementsSummaryHistory: p.Extractor = &StatementsSummaryExtractor{} + case infoschema.TableTiKVRegionPeers: + p.Extractor = &TikvRegionPeersExtractor{} } } return p, nil diff --git a/planner/core/memtable_predicate_extractor.go b/planner/core/memtable_predicate_extractor.go index 923d025ac7d13..57b53a75cc080 100644 --- a/planner/core/memtable_predicate_extractor.go +++ b/planner/core/memtable_predicate_extractor.go @@ -1415,3 +1415,56 @@ func (e *StatementsSummaryExtractor) explainInfo(p *PhysicalMemTable) string { } return fmt.Sprintf("digests: [%s]", extractStringFromStringSet(e.Digests)) } + +// TikvRegionPeersExtractor is used to extract some predicates of cluster table. +type TikvRegionPeersExtractor struct { + extractHelper + + // SkipRequest means the where clause always false, we don't need to request any component + SkipRequest bool + + // RegionIDs/StoreIDs represents all region/store ids we should filter in PD to reduce network IO. + // e.g: + // 1. SELECT * FROM tikv_region_peers WHERE region_id=1 + // 2. SELECT * FROM tikv_region_peers WHERE table_id in (11, 22) + RegionIDs []uint64 + StoreIDs []uint64 +} + +// Extract implements the MemTablePredicateExtractor Extract interface +func (e *TikvRegionPeersExtractor) Extract(_ sessionctx.Context, + schema *expression.Schema, + names []*types.FieldName, + predicates []expression.Expression, +) []expression.Expression { + // Extract the `region_id/store_id` columns. + remained, regionIDSkipRequest, regionIDs := e.extractCol(schema, names, predicates, "region_id", false) + remained, storeIDSkipRequest, storeIDs := e.extractCol(schema, names, remained, "store_id", false) + e.RegionIDs, e.StoreIDs = e.parseUint64(regionIDs), e.parseUint64(storeIDs) + + e.SkipRequest = regionIDSkipRequest || storeIDSkipRequest + if e.SkipRequest { + return nil + } + + return remained +} + +func (e *TikvRegionPeersExtractor) explainInfo(p *PhysicalMemTable) string { + if e.SkipRequest { + return "skip_request:true" + } + r := new(bytes.Buffer) + if len(e.RegionIDs) > 0 { + r.WriteString(fmt.Sprintf("region_ids:[%s], ", extractStringFromUint64Slice(e.RegionIDs))) + } + if len(e.StoreIDs) > 0 { + r.WriteString(fmt.Sprintf("store_ids:[%s], ", extractStringFromUint64Slice(e.StoreIDs))) + } + // remove the last ", " in the message info + s := r.String() + if len(s) > 2 { + return s[:len(s)-2] + } + return s +} diff --git a/planner/core/memtable_predicate_extractor_test.go b/planner/core/memtable_predicate_extractor_test.go index 311b9ae4a8838..b63d042c03a7e 100644 --- a/planner/core/memtable_predicate_extractor_test.go +++ b/planner/core/memtable_predicate_extractor_test.go @@ -1420,3 +1420,126 @@ func (s *extractorSuite) TestTiDBHotRegionsHistoryTableExtractor(c *C) { } } } + +func (s *extractorSuite) TestTikvRegionPeersExtractor(c *C) { + se, err := session.CreateSession4Test(s.store) + c.Assert(err, IsNil) + + var cases = []struct { + sql string + regionIDs, storeIDs []uint64 + skipRequest bool + }{ + // Test `region_id`, `store_id` columns. + { + sql: "select * from information_schema.tikv_region_peers where region_id=100", + regionIDs: []uint64{100}, + }, + { + sql: "select * from information_schema.tikv_region_peers where 100=region_id", + regionIDs: []uint64{100}, + }, + { + sql: "select * from information_schema.tikv_region_peers where 100=region_id or region_id=101", + regionIDs: []uint64{100, 101}, + }, + { + sql: "select * from information_schema.tikv_region_peers where 100=region_id or region_id=101 or region_id=102 or 103 = region_id", + regionIDs: []uint64{100, 101, 102, 103}, + }, + { + sql: "select * from information_schema.tikv_region_peers where (region_id=100 or region_id=101) and (store_id=200 or store_id=201)", + regionIDs: []uint64{100, 101}, + storeIDs: []uint64{200, 201}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id in (100, 101)", + regionIDs: []uint64{100, 101}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id in (100, 101) and store_id=200", + regionIDs: []uint64{100, 101}, + storeIDs: []uint64{200}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id in (100, 101) and store_id in (200, 201)", + regionIDs: []uint64{100, 101}, + storeIDs: []uint64{200, 201}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and store_id in (200, 201)", + regionIDs: []uint64{100}, + storeIDs: []uint64{200, 201}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and store_id=200", + regionIDs: []uint64{100}, + storeIDs: []uint64{200}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and region_id=101", + skipRequest: true, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and region_id in (100,101)", + regionIDs: []uint64{100}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and region_id in (100,101) and store_id=200 and store_id in (200,201)", + regionIDs: []uint64{100}, + storeIDs: []uint64{200}, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and region_id in (101,102)", + skipRequest: true, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and region_id in (101,102) and store_id=200 and store_id in (200,201)", + skipRequest: true, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id=100 and region_id in (100,101) and store_id=200 and store_id in (201,202)", + skipRequest: true, + }, + { + sql: `select * from information_schema.tikv_region_peers + where region_id=100 and region_id in (100,101) + and store_id=200 and store_id in (201,202)`, + skipRequest: true, + }, + { + sql: "select * from information_schema.tikv_region_peers where region_id in (100,101) and region_id in (101,102)", + regionIDs: []uint64{101}, + }, + { + sql: `select * from information_schema.tikv_region_peers + where region_id in (100,101) + and region_id in (101,102) + and store_id in (200,201) + and store_id in (201,202)`, + regionIDs: []uint64{101}, + storeIDs: []uint64{201}, + }, + { + sql: `select * from information_schema.tikv_region_peers + where region_id in (100,101) + and region_id in (100,102) + and region_id in (102,103) + and region_id in (103,104)`, + skipRequest: true, + }, + } + parser := parser.New() + for _, ca := range cases { + logicalMemTable := s.getLogicalMemTable(c, se, parser, ca.sql) + c.Assert(logicalMemTable.Extractor, NotNil) + + tikvRegionPeersExtractor := logicalMemTable.Extractor.(*plannercore.TikvRegionPeersExtractor) + if len(ca.regionIDs) > 0 { + c.Assert(tikvRegionPeersExtractor.RegionIDs, DeepEquals, ca.regionIDs, Commentf("SQL: %v", ca.sql)) + } + if len(ca.storeIDs) > 0 { + c.Assert(tikvRegionPeersExtractor.StoreIDs, DeepEquals, ca.storeIDs, Commentf("SQL: %v", ca.sql)) + } + } +} From 72e487876152c2b19d20f8d544b52f57398891ee Mon Sep 17 00:00:00 2001 From: IcePigZDB Date: Mon, 20 Dec 2021 17:32:49 +0800 Subject: [PATCH 2/2] extractor: add a test caseto test columns that is not extracted by TikvRegionPeersExtractor Signed-off-by: IcePigZDB --- planner/core/memtable_predicate_extractor_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/planner/core/memtable_predicate_extractor_test.go b/planner/core/memtable_predicate_extractor_test.go index b63d042c03a7e..d932176b9f2eb 100644 --- a/planner/core/memtable_predicate_extractor_test.go +++ b/planner/core/memtable_predicate_extractor_test.go @@ -1528,6 +1528,15 @@ func (s *extractorSuite) TestTikvRegionPeersExtractor(c *C) { and region_id in (103,104)`, skipRequest: true, }, + // Test columns that is not extracted by TikvRegionPeersExtractor + { + sql: `select * from information_schema.tikv_region_peers + where peer_id=100 + and is_learner=0 + and is_leader=1 + and status='NORMAL' + and down_seconds=1000`, + }, } parser := parser.New() for _, ca := range cases {