github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cmd/filter-helper/main.go (about) 1 // Copyright 2019 PingCAP, 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 main 15 16 import ( 17 "fmt" 18 "strings" 19 20 timodel "github.com/pingcap/tidb/pkg/parser/model" 21 "github.com/pingcap/tiflow/cdc/model" 22 "github.com/pingcap/tiflow/pkg/cmd/util" 23 "github.com/pingcap/tiflow/pkg/config" 24 "github.com/pingcap/tiflow/pkg/filter" 25 "github.com/spf13/cobra" 26 ) 27 28 var ( 29 table string 30 ddl string 31 cfgPath string 32 ) 33 34 func main() { 35 rootCmd := &cobra.Command{ 36 Use: "TiCDC filter helper, use to check whether your filter config works as expected", 37 Short: "A tool to check table and ddl query against filter rules", 38 Run: runFilter, 39 } 40 rootCmd.Flags().StringVarP(&cfgPath, "config", "c", "", "changefeed config file path") 41 rootCmd.Flags().StringVarP(&table, "table", "t", "", "table name, format: [schema].[table] ") 42 rootCmd.Flags().StringVarP(&ddl, "ddl", "d", "", "ddl query") 43 if err := rootCmd.Execute(); err != nil { 44 fmt.Println(err) 45 } 46 } 47 48 func runFilter(cmd *cobra.Command, args []string) { 49 // fmt.Printf("Filter Rules: %v\n", filterRules) 50 // fmt.Printf("Schema Name: %s\n", schemaName) 51 // fmt.Printf("Table Name: %s\n", tableName) 52 cfg := &config.ReplicaConfig{} 53 err := util.StrictDecodeFile(cfgPath, "cdc filter helper", cfg) 54 if err != nil { 55 fmt.Printf("decode config file error: %v\n", err) 56 return 57 } 58 ft, err := filter.NewFilter(cfg, "") 59 if err != nil { 60 fmt.Printf("filter create error: %v\n", err) 61 return 62 } 63 tableAndSchema := strings.Split(table, ".") 64 if len(tableAndSchema) != 2 { 65 fmt.Printf("the input format is invalid, only support {schema}.{table}: %s\n", table) 66 return 67 } 68 69 target := "table" 70 if ddl != "" { 71 target = "ddl" 72 } 73 74 switch target { 75 case "table": 76 matched := !ft.ShouldIgnoreTable(tableAndSchema[0], tableAndSchema[1]) 77 if matched { 78 fmt.Printf("Table: %s, Matched filter rule\n", table) 79 return 80 } 81 fmt.Printf("Table: %s, Not matched filter rule\n", table) 82 case "ddl": 83 ddlType := timodel.ActionCreateTable 84 discard := ft.ShouldDiscardDDL(ddlType, tableAndSchema[0], tableAndSchema[1]) 85 if discard { 86 fmt.Printf("DDL: %s, should be discard by event filter rule\n", ddl) 87 return 88 } 89 ignored, err := ft.ShouldIgnoreDDLEvent(&model.DDLEvent{ 90 StartTs: uint64(0), 91 Query: ddl, 92 Type: ddlType, 93 TableInfo: &model.TableInfo{ 94 TableName: model.TableName{ 95 Schema: tableAndSchema[0], 96 Table: tableAndSchema[1], 97 }, 98 }, 99 }) 100 if err != nil { 101 fmt.Printf("filter ddl error: %s, error: %v\n", ddl, err) 102 return 103 } 104 if ignored { 105 fmt.Printf("DDL: %s, should be ignored by event filter rule\n", ddl) 106 return 107 } 108 fmt.Printf("DDL: %s, should not be discard by event filter rule\n", ddl) 109 default: 110 fmt.Printf("unknown target: %s", target) 111 112 } 113 }