github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/ctl/master/binlog.go (about)

     1  // Copyright 2021 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 master
    15  
    16  import (
    17  	"github.com/pingcap/tiflow/dm/ctl/common"
    18  	"github.com/pingcap/tiflow/dm/pb"
    19  	"github.com/spf13/cobra"
    20  )
    21  
    22  // NewBinlogCmd creates a binlog command.
    23  func NewBinlogCmd() *cobra.Command {
    24  	cmd := &cobra.Command{
    25  		Use:   "binlog <command>",
    26  		Short: "manage or show binlog operations",
    27  	}
    28  	cmd.PersistentFlags().StringP("binlog-pos", "b", "", "position used to match binlog event if matched the binlog operation will be applied. The format like \"mysql-bin|000001.000003:3270\"")
    29  	cmd.AddCommand(
    30  		newBinlogSkipCmd(),
    31  		newBinlogReplaceCmd(),
    32  		newBinlogRevertCmd(),
    33  		newBinlogInjectCmd(),
    34  		newBinlogListCmd(),
    35  	)
    36  
    37  	return cmd
    38  }
    39  
    40  func newBinlogSkipCmd() *cobra.Command {
    41  	cmd := &cobra.Command{
    42  		Use:   "skip <task-name>",
    43  		Short: "skip the current error event or a specific binlog position (binlog-pos) event",
    44  		RunE: func(cmd *cobra.Command, args []string) error {
    45  			if len(args) != 1 {
    46  				return cmd.Help()
    47  			}
    48  			taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0))
    49  			request := &pb.HandleErrorRequest{
    50  				Op:   pb.ErrorOp_Skip,
    51  				Task: taskName,
    52  				Sqls: nil,
    53  			}
    54  			return sendHandleErrorRequest(cmd, request)
    55  		},
    56  	}
    57  	return cmd
    58  }
    59  
    60  func newBinlogListCmd() *cobra.Command {
    61  	cmd := &cobra.Command{
    62  		Use:   "list <task-name>",
    63  		Short: "list error handle command at binlog position (binlog-pos) or after binlog position (binlog-pos)",
    64  		RunE: func(cmd *cobra.Command, args []string) error {
    65  			if len(args) != 1 {
    66  				return cmd.Help()
    67  			}
    68  			taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0))
    69  			request := &pb.HandleErrorRequest{
    70  				Op:   pb.ErrorOp_List,
    71  				Task: taskName,
    72  				Sqls: nil,
    73  			}
    74  			return sendHandleErrorRequest(cmd, request)
    75  		},
    76  	}
    77  	return cmd
    78  }
    79  
    80  func newBinlogReplaceCmd() *cobra.Command {
    81  	cmd := &cobra.Command{
    82  		Use:   "replace <task-name> <replace-sql1> <replace-sql2>...",
    83  		Short: "replace the current error event or a specific binlog position (binlog-pos) with some ddls",
    84  		RunE: func(cmd *cobra.Command, args []string) error {
    85  			if len(args) <= 1 {
    86  				return cmd.Help()
    87  			}
    88  			taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0))
    89  			sqls, err := common.ExtractSQLsFromArgs(cmd.Flags().Args()[1:])
    90  			if err != nil {
    91  				return err
    92  			}
    93  			request := &pb.HandleErrorRequest{
    94  				Op:   pb.ErrorOp_Replace,
    95  				Task: taskName,
    96  				Sqls: sqls,
    97  			}
    98  			return sendHandleErrorRequest(cmd, request)
    99  		},
   100  	}
   101  	return cmd
   102  }
   103  
   104  func newBinlogRevertCmd() *cobra.Command {
   105  	cmd := &cobra.Command{
   106  		Use:   "revert <task-name>",
   107  		Short: "revert the current binlog operation or a specific binlog position (binlog-pos) operation",
   108  		RunE: func(cmd *cobra.Command, args []string) error {
   109  			if len(args) == 0 {
   110  				return cmd.Help()
   111  			}
   112  			taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0))
   113  			request := &pb.HandleErrorRequest{
   114  				Op:   pb.ErrorOp_Revert,
   115  				Task: taskName,
   116  				Sqls: nil,
   117  			}
   118  			return sendHandleErrorRequest(cmd, request)
   119  		},
   120  	}
   121  	return cmd
   122  }
   123  
   124  func newBinlogInjectCmd() *cobra.Command {
   125  	cmd := &cobra.Command{
   126  		Use:   "inject <task-name> <inject-sql1> <inject-sql2>...",
   127  		Short: "inject the current error event or a specific binlog position (binlog-pos) with some ddls",
   128  		RunE: func(cmd *cobra.Command, args []string) error {
   129  			if len(args) <= 1 {
   130  				return cmd.Help()
   131  			}
   132  			taskName := common.GetTaskNameFromArgOrFile(cmd.Flags().Arg(0))
   133  			sqls, err := common.ExtractSQLsFromArgs(cmd.Flags().Args()[1:])
   134  			if err != nil {
   135  				return err
   136  			}
   137  			request := &pb.HandleErrorRequest{
   138  				Op:   pb.ErrorOp_Inject,
   139  				Task: taskName,
   140  				Sqls: sqls,
   141  			}
   142  			return sendHandleErrorRequest(cmd, request)
   143  		},
   144  	}
   145  	return cmd
   146  }