github.com/pingcap/br@v5.3.0-alpha.0.20220125034240-ec59c7b6ce30+incompatible/cmd/br/backup.go (about)

     1  // Copyright 2020 PingCAP, Inc. Licensed under Apache-2.0.
     2  
     3  package main
     4  
     5  import (
     6  	"github.com/pingcap/errors"
     7  	"github.com/pingcap/log"
     8  	"github.com/pingcap/tidb/ddl"
     9  	"github.com/pingcap/tidb/session"
    10  	"github.com/spf13/cobra"
    11  	"go.uber.org/zap"
    12  	"sourcegraph.com/sourcegraph/appdash"
    13  
    14  	"github.com/pingcap/br/pkg/gluetikv"
    15  	"github.com/pingcap/br/pkg/summary"
    16  	"github.com/pingcap/br/pkg/task"
    17  	"github.com/pingcap/br/pkg/trace"
    18  	"github.com/pingcap/br/pkg/utils"
    19  	"github.com/pingcap/br/pkg/version/build"
    20  )
    21  
    22  func runBackupCommand(command *cobra.Command, cmdName string) error {
    23  	cfg := task.BackupConfig{Config: task.Config{LogProgress: HasLogFile()}}
    24  	if err := cfg.ParseFromFlags(command.Flags()); err != nil {
    25  		command.SilenceUsage = false
    26  		return errors.Trace(err)
    27  	}
    28  
    29  	ctx := GetDefaultContext()
    30  	if cfg.EnableOpenTracing {
    31  		var store *appdash.MemoryStore
    32  		ctx, store = trace.TracerStartSpan(ctx)
    33  		defer trace.TracerFinishSpan(ctx, store)
    34  	}
    35  	if cfg.IgnoreStats {
    36  		// Do not run stat worker in BR.
    37  		session.DisableStats4Test()
    38  	}
    39  
    40  	if err := task.RunBackup(ctx, tidbGlue, cmdName, &cfg); err != nil {
    41  		log.Error("failed to backup", zap.Error(err))
    42  		return errors.Trace(err)
    43  	}
    44  	return nil
    45  }
    46  
    47  func runBackupRawCommand(command *cobra.Command, cmdName string) error {
    48  	cfg := task.RawKvConfig{Config: task.Config{LogProgress: HasLogFile()}}
    49  	if err := cfg.ParseBackupConfigFromFlags(command.Flags()); err != nil {
    50  		command.SilenceUsage = false
    51  		return errors.Trace(err)
    52  	}
    53  
    54  	ctx := GetDefaultContext()
    55  	if cfg.EnableOpenTracing {
    56  		var store *appdash.MemoryStore
    57  		ctx, store = trace.TracerStartSpan(ctx)
    58  		defer trace.TracerFinishSpan(ctx, store)
    59  	}
    60  	if err := task.RunBackupRaw(ctx, gluetikv.Glue{}, cmdName, &cfg); err != nil {
    61  		log.Error("failed to backup raw kv", zap.Error(err))
    62  		return errors.Trace(err)
    63  	}
    64  	return nil
    65  }
    66  
    67  // NewBackupCommand return a full backup subcommand.
    68  func NewBackupCommand() *cobra.Command {
    69  	command := &cobra.Command{
    70  		Use:          "backup",
    71  		Short:        "backup a TiDB/TiKV cluster",
    72  		SilenceUsage: true,
    73  		PersistentPreRunE: func(c *cobra.Command, args []string) error {
    74  			if err := Init(c); err != nil {
    75  				return errors.Trace(err)
    76  			}
    77  			build.LogInfo(build.BR)
    78  			utils.LogEnvVariables()
    79  			task.LogArguments(c)
    80  
    81  			// Do not run ddl worker in BR.
    82  			ddl.RunWorker = false
    83  
    84  			summary.SetUnit(summary.BackupUnit)
    85  			return nil
    86  		},
    87  	}
    88  	command.AddCommand(
    89  		newFullBackupCommand(),
    90  		newDBBackupCommand(),
    91  		newTableBackupCommand(),
    92  		newRawBackupCommand(),
    93  	)
    94  
    95  	task.DefineBackupFlags(command.PersistentFlags())
    96  	return command
    97  }
    98  
    99  // newFullBackupCommand return a full backup subcommand.
   100  func newFullBackupCommand() *cobra.Command {
   101  	command := &cobra.Command{
   102  		Use:   "full",
   103  		Short: "backup all database",
   104  		// prevents incorrect usage like `--checksum false` instead of `--checksum=false`.
   105  		// the former, according to pflag parsing rules, means `--checksum=true false`.
   106  		Args: cobra.NoArgs,
   107  		RunE: func(command *cobra.Command, _ []string) error {
   108  			// empty db/table means full backup.
   109  			return runBackupCommand(command, "Full backup")
   110  		},
   111  	}
   112  	task.DefineFilterFlags(command, acceptAllTables)
   113  	return command
   114  }
   115  
   116  // newDBBackupCommand return a db backup subcommand.
   117  func newDBBackupCommand() *cobra.Command {
   118  	command := &cobra.Command{
   119  		Use:   "db",
   120  		Short: "backup a database",
   121  		Args:  cobra.NoArgs,
   122  		RunE: func(command *cobra.Command, _ []string) error {
   123  			return runBackupCommand(command, "Database backup")
   124  		},
   125  	}
   126  	task.DefineDatabaseFlags(command)
   127  	return command
   128  }
   129  
   130  // newTableBackupCommand return a table backup subcommand.
   131  func newTableBackupCommand() *cobra.Command {
   132  	command := &cobra.Command{
   133  		Use:   "table",
   134  		Short: "backup a table",
   135  		Args:  cobra.NoArgs,
   136  		RunE: func(command *cobra.Command, _ []string) error {
   137  			return runBackupCommand(command, "Table backup")
   138  		},
   139  	}
   140  	task.DefineTableFlags(command)
   141  	return command
   142  }
   143  
   144  // newRawBackupCommand return a raw kv range backup subcommand.
   145  func newRawBackupCommand() *cobra.Command {
   146  	// TODO: remove experimental tag if it's stable
   147  	command := &cobra.Command{
   148  		Use:   "raw",
   149  		Short: "(experimental) backup a raw kv range from TiKV cluster",
   150  		Args:  cobra.NoArgs,
   151  		RunE: func(command *cobra.Command, _ []string) error {
   152  			return runBackupRawCommand(command, "Raw backup")
   153  		},
   154  	}
   155  
   156  	task.DefineRawBackupFlags(command)
   157  	return command
   158  }