Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

task: expose table filter for backup full and restore full #313

Merged
merged 6 commits into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func newFullBackupCommand() *cobra.Command {
return runBackupCommand(command, "Full backup")
},
}
task.DefineFilterFlags(command)
return command
}

Expand Down
1 change: 1 addition & 0 deletions cmd/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func newFullRestoreCommand() *cobra.Command {
return runRestoreCommand(cmd, "Full restore")
},
}
task.DefineFilterFlags(command)
return command
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ require (
github.com/pingcap/parser v0.0.0-20200518090819-ec1e13b948b1
github.com/pingcap/pd/v4 v4.0.0-rc.2.0.20200520083007-2c251bd8f181
github.com/pingcap/tidb v1.1.0-beta.0.20200521154755-134e691d6f5f
github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200514040632-f76b3e428e19+incompatible
github.com/pingcap/tidb-tools v4.0.0-rc.2.0.20200521050818-6dd445d83fe0+incompatible
github.com/pingcap/tipb v0.0.0-20200417094153-7316d94df1ee
github.com/prometheus/client_golang v1.5.1
github.com/prometheus/common v0.9.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,8 @@ github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200421113014-507d2bb3a15e+incompat
github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200421113014-507d2bb3a15e+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200514040632-f76b3e428e19+incompatible h1:/JKsYjsa5Ug8v5CN4zIbJGIqsvgBUkGwaP/rEScVvWM=
github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200514040632-f76b3e428e19+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tidb-tools v4.0.0-rc.2.0.20200521050818-6dd445d83fe0+incompatible h1:e+j+rsJYX+J7eTkgjnGBH2/T3NS6GNSPD6nHA5bPdCI=
github.com/pingcap/tidb-tools v4.0.0-rc.2.0.20200521050818-6dd445d83fe0+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
github.com/pingcap/tipb v0.0.0-20200417094153-7316d94df1ee h1:XJQ6/LGzOSc/jo33AD8t7jtc4GohxcyODsYnb+kZXJM=
github.com/pingcap/tipb v0.0.0-20200417094153-7316d94df1ee/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
Expand Down
6 changes: 3 additions & 3 deletions pkg/backup/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"github.com/pingcap/log"
"github.com/pingcap/parser/model"
pd "github.com/pingcap/pd/v4/client"
"github.com/pingcap/tidb-tools/pkg/filter"
"github.com/pingcap/tidb-tools/pkg/table-filter"
"github.com/pingcap/tidb/distsql"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/kv"
Expand Down Expand Up @@ -210,7 +210,7 @@ func appendRanges(tbl *model.TableInfo, tblID int64) ([]kv.KeyRange, error) {
func BuildBackupRangeAndSchema(
dom *domain.Domain,
storage kv.Storage,
tableFilter *filter.Filter,
tableFilter filter.Filter,
backupTS uint64,
) ([]rtree.Range, *Schemas, error) {
info, err := dom.GetSnapshotInfoSchema(backupTS)
Expand All @@ -232,7 +232,7 @@ func BuildBackupRangeAndSchema(
randAlloc := autoid.NewAllocator(storage, dbInfo.ID, false, autoid.AutoRandomType)

for _, tableInfo := range dbInfo.Tables {
if !tableFilter.Match(&filter.Table{Schema: dbInfo.Name.L, Name: tableInfo.Name.L}) {
if !tableFilter.MatchTable(dbInfo.Name.O, tableInfo.Name.O) {
// Skip tables other than the given table.
continue
}
Expand Down
12 changes: 4 additions & 8 deletions pkg/backup/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"sync/atomic"

. "github.com/pingcap/check"
"github.com/pingcap/tidb-tools/pkg/filter"
"github.com/pingcap/tidb-tools/pkg/table-filter"
"github.com/pingcap/tidb/util/testkit"
"github.com/pingcap/tidb/util/testleak"

Expand Down Expand Up @@ -57,27 +57,23 @@ func (s *testBackupSchemaSuite) TestBuildBackupRangeAndSchema(c *C) {
tk := testkit.NewTestKit(c, s.mock.Storage)

// Table t1 is not exist.
testFilter, err := filter.New(false, &filter.Rules{
DoTables: []*filter.Table{{Schema: "test", Name: "t1"}},
})
testFilter, err := filter.Parse([]string{"test.t1"})
c.Assert(err, IsNil)
_, backupSchemas, err := backup.BuildBackupRangeAndSchema(
s.mock.Domain, s.mock.Storage, testFilter, math.MaxUint64)
c.Assert(err, IsNil)
c.Assert(backupSchemas, IsNil)

// Database is not exist.
fooFilter, err := filter.New(false, &filter.Rules{
DoTables: []*filter.Table{{Schema: "foo", Name: "t1"}},
})
fooFilter, err := filter.Parse([]string{"foo.t1"})
c.Assert(err, IsNil)
_, backupSchemas, err = backup.BuildBackupRangeAndSchema(
s.mock.Domain, s.mock.Storage, fooFilter, math.MaxUint64)
c.Assert(err, IsNil)
c.Assert(backupSchemas, IsNil)

// Empty database.
noFilter, err := filter.New(false, &filter.Rules{})
noFilter, err := filter.Parse([]string{"*.*"})
c.Assert(err, IsNil)
_, backupSchemas, err = backup.BuildBackupRangeAndSchema(
s.mock.Domain, s.mock.Storage, noFilter, math.MaxUint64)
Expand Down
7 changes: 1 addition & 6 deletions pkg/task/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/pingcap/log"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb-tools/pkg/filter"
"github.com/pingcap/tidb/sessionctx/stmtctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/types"
Expand Down Expand Up @@ -109,10 +108,6 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig
if err != nil {
return err
}
tableFilter, err := filter.New(cfg.CaseSensitive, &cfg.Filter)
if err != nil {
return err
}
mgr, err := newMgr(ctx, g, cfg.PD, cfg.TLS, conn.SkipTiFlash)
if err != nil {
return err
Expand All @@ -135,7 +130,7 @@ func RunBackup(c context.Context, g glue.Glue, cmdName string, cfg *BackupConfig
g.Record("BackupTS", backupTS)

ranges, backupSchemas, err := backup.BuildBackupRangeAndSchema(
mgr.GetDomain(), mgr.GetTiKV(), tableFilter, backupTS)
mgr.GetDomain(), mgr.GetTiKV(), cfg.TableFilter, backupTS)
if err != nil {
return err
}
Expand Down
66 changes: 48 additions & 18 deletions pkg/task/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ import (
"crypto/tls"
"fmt"
"net/url"
"regexp"
"strings"

"github.com/gogo/protobuf/proto"
"github.com/pingcap/errors"
"github.com/pingcap/kvproto/pkg/backup"
"github.com/pingcap/log"
pd "github.com/pingcap/pd/v4/client"
"github.com/pingcap/tidb-tools/pkg/filter"
filter "github.com/pingcap/tidb-tools/pkg/table-filter"
"github.com/pingcap/tidb/store/tikv"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -49,6 +48,8 @@ const (
flagRateLimitUnit = "ratelimit-unit"
flagConcurrency = "concurrency"
flagChecksum = "checksum"
flagFilter = "filter"
flagCaseSensitive = "case-sensitive"
)

// TLSConfig is the common configuration for TLS connection.
Expand Down Expand Up @@ -91,8 +92,18 @@ type Config struct {
// LogProgress is true means the progress bar is printed to the log instead of stdout.
LogProgress bool `json:"log-progress" toml:"log-progress"`

CaseSensitive bool `json:"case-sensitive" toml:"case-sensitive"`
Filter filter.Rules `json:"black-white-list" toml:"black-white-list"`
// CaseSensitive should not be used.
//
// Deprecated: This field is kept only to satisfy the cyclic dependency with TiDB. This field
// should be removed after TiDB upgrades the BR dependency.
CaseSensitive bool
// Filter should not be used, use TableFilter instead.
//
// Deprecated: This field is kept only to satisfy the cyclic dependency with TiDB. This field
// should be removed after TiDB upgrades the BR dependency.
Filter filter.MySQLReplicationRules

TableFilter filter.Filter `json:"-" toml:"-"`
}

// DefineCommonFlags defines the flags common to all BRIE commands.
Expand All @@ -119,19 +130,26 @@ func DefineCommonFlags(flags *pflag.FlagSet) {
storage.DefineFlags(flags)
}

// DefineDatabaseFlags defines the required --db flag.
// DefineDatabaseFlags defines the required --db flag for `db` subcommand.
func DefineDatabaseFlags(command *cobra.Command) {
command.Flags().String(flagDatabase, "", "database name")
_ = command.MarkFlagRequired(flagDatabase)
}

// DefineTableFlags defines the required --db and --table flags.
// DefineTableFlags defines the required --db and --table flags for `table` subcommand.
func DefineTableFlags(command *cobra.Command) {
DefineDatabaseFlags(command)
command.Flags().StringP(flagTable, "t", "", "table name")
_ = command.MarkFlagRequired(flagTable)
}

// DefineFilterFlags defines the --filter and --case-sensitive flags for `full` subcommand.
func DefineFilterFlags(command *cobra.Command) {
flags := command.Flags()
flags.StringArrayP(flagFilter, "f", []string{"*.*"}, "select tables to process")
flags.Bool(flagCaseSensitive, false, "whether the table names used in --filter should be case-sensitive")
}

// ParseFromFlags parses the TLS config from the flag set.
func (tls *TLSConfig) ParseFromFlags(flags *pflag.FlagSet) error {
var err error
Expand Down Expand Up @@ -188,20 +206,39 @@ func (cfg *Config) ParseFromFlags(flags *pflag.FlagSet) error {
}
cfg.RateLimit = rateLimit * rateLimitUnit

if dbFlag := flags.Lookup(flagDatabase); dbFlag != nil {
db := escapeFilterName(dbFlag.Value.String())
var caseSensitive bool
if filterFlag := flags.Lookup(flagFilter); filterFlag != nil {
f, err := filter.Parse(filterFlag.Value.(pflag.SliceValue).GetSlice())
if err != nil {
return err
}
cfg.TableFilter = f
caseSensitive, err = flags.GetBool(flagCaseSensitive)
if err != nil {
return errors.Trace(err)
}
} else if dbFlag := flags.Lookup(flagDatabase); dbFlag != nil {
db := dbFlag.Value.String()
if len(db) == 0 {
return errors.New("empty database name is not allowed")
}
if tblFlag := flags.Lookup(flagTable); tblFlag != nil {
tbl := escapeFilterName(tblFlag.Value.String())
tbl := tblFlag.Value.String()
if len(tbl) == 0 {
return errors.New("empty table name is not allowed")
}
cfg.Filter.DoTables = []*filter.Table{{Schema: db, Name: tbl}}
cfg.TableFilter = filter.NewTablesFilter(filter.Table{
Schema: db,
Name: tbl,
})
} else {
cfg.Filter.DoDBs = []string{db}
cfg.TableFilter = filter.NewSchemasFilter(db)
}
} else {
cfg.TableFilter, _ = filter.Parse([]string{"*.*"})
}
if !caseSensitive {
cfg.TableFilter = filter.CaseInsensitive(cfg.TableFilter)
}

if err := cfg.BackendOptions.ParseFromFlags(flags); err != nil {
Expand Down Expand Up @@ -283,13 +320,6 @@ func ReadBackupMeta(
return u, s, backupMeta, nil
}

func escapeFilterName(name string) string {
if !strings.HasPrefix(name, "~") {
return name
}
return "~^" + regexp.QuoteMeta(name) + "$"
}

// flagToZapField checks whether this flag can be logged,
// if need to log, return its zap field. Or return a field with hidden value.
func flagToZapField(f *pflag.Flag) zap.Field {
Expand Down
15 changes: 3 additions & 12 deletions pkg/task/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/pingcap/kvproto/pkg/backup"
"github.com/pingcap/log"
"github.com/pingcap/parser/model"
"github.com/pingcap/tidb-tools/pkg/filter"
"github.com/pingcap/tidb/config"
"github.com/spf13/pflag"
"go.uber.org/zap"
Expand Down Expand Up @@ -144,10 +143,7 @@ func RunRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf
return errors.New("cannot do transactional restore from raw kv data")
}

files, tables, dbs, err := filterRestoreFiles(client, cfg)
if err != nil {
return err
}
files, tables, dbs := filterRestoreFiles(client, cfg)

var newTS uint64
if client.IsIncremental() {
Expand Down Expand Up @@ -320,16 +316,11 @@ func RunRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf
func filterRestoreFiles(
client *restore.Client,
cfg *RestoreConfig,
) (files []*backup.File, tables []*utils.Table, dbs []*utils.Database, err error) {
tableFilter, err := filter.New(cfg.CaseSensitive, &cfg.Filter)
if err != nil {
return nil, nil, nil, err
}

) (files []*backup.File, tables []*utils.Table, dbs []*utils.Database) {
for _, db := range client.GetDatabases() {
createdDatabase := false
for _, table := range db.Tables {
if !tableFilter.Match(&filter.Table{Schema: db.Info.Name.O, Name: table.Info.Name.O}) {
if !cfg.TableFilter.MatchTable(db.Info.Name.O, table.Info.Name.O) {
continue
}

Expand Down
Loading