Skip to content

Commit

Permalink
cliccl/debug_backup.go: refactor backup inspection tool
Browse files Browse the repository at this point in the history
Previously, cli backup inspection tool was incorporated
in cliccl/load.go. Both the command and syntax are
confusing in terms of backup inspection.

This patch refactors the naming and syntax of the tool
and hand the tool under `cockroach debug`, so that
it makes more sense when using it to debug backups.

Release note (cli change): Backup inspection used to be done via
`cockroach load show ..`, which was confusing to users with
ambiguous verbs in the command chain. We refactor the syntax of
tool and make the syntax  more clear and indicative for users to
debug backups. The changes are:
`load show summary <backup_url>` ->
`debug backup show <backup_url>`

`load show incremental <backup_url>` ->
`debug backup list-incremental <backup_url>`

`load show backups <collection_url>` ->
`debug backup list-backups <collection_url>`

`load show data <table_name> <backup_url> ->
`debug backup export <backup_url> --table=<table_name>`
  • Loading branch information
Elliebababa committed Apr 21, 2021
1 parent 8ae7146 commit 3caed9e
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 140 deletions.
9 changes: 6 additions & 3 deletions pkg/ccl/backupccl/targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,9 +474,12 @@ func MakeBackupTableEntry(
for i, b := range backupManifests {
if b.StartTime.Less(endTime) && endTime.LessEq(b.EndTime) {
if endTime != b.EndTime && b.MVCCFilter != MVCCFilter_All {
return BackupTableEntry{}, errors.Newf(
"reading data for requested time requires that BACKUP was created with %q"+
" or should specify the time to be an exact backup time, nearest backup time is %s", backupOptRevisionHistory, timeutil.Unix(0, b.EndTime.WallTime).UTC())
errorHints := "reading data for requested time requires that BACKUP was created with %q" +
" or should specify the time to be an exact backup time, nearest backup time is %s"
return BackupTableEntry{}, errors.WithHintf(
errors.Newf("unknown read time: %s", timeutil.Unix(0, endTime.WallTime).UTC()),
errorHints, backupOptRevisionHistory, timeutil.Unix(0, b.EndTime.WallTime).UTC(),
)
}
ind = i
break
Expand Down
4 changes: 2 additions & 2 deletions pkg/ccl/cliccl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go_library(
srcs = [
"cliccl.go",
"debug.go",
"debug_backup.go",
"demo.go",
"load.go",
"mtproxy.go",
"start.go",
],
Expand Down Expand Up @@ -65,7 +65,7 @@ go_test(
name = "cliccl_test",
size = "small",
srcs = [
"load_test.go",
"debug_backup_test.go",
"main_test.go",
],
embed = [":cliccl"],
Expand Down
132 changes: 65 additions & 67 deletions pkg/ccl/cliccl/load.go → pkg/ccl/cliccl/debug_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"os"
"path/filepath"
"strings"
"text/tabwriter"
"time"

"github.com/cockroachdb/apd/v2"
Expand Down Expand Up @@ -54,113 +53,111 @@ import (
)

var externalIODir string
var exportTableName string
var readTime string
var destination string
var format string
var nullas string

func init() {

loadShowSummaryCmd := &cobra.Command{
Use: "summary <backup_path>",
Short: "show backups summary",
showCmd := &cobra.Command{
Use: "show <backup_path>",
Short: "show backup summary",
Long: "Shows summary of meta information about a SQL backup.",
Args: cobra.ExactArgs(1),
RunE: cli.MaybeDecorateGRPCError(runLoadShowSummary),
RunE: cli.MaybeDecorateGRPCError(runShowCmd),
}

loadShowBackupsCmd := &cobra.Command{
Use: "backups <backup_path>",
Short: "show backups in collections",
Long: "Shows full backups in a backup collections.",
listBackupsCmd := &cobra.Command{
Use: "list-backups <collection_path>",
Short: "show backups in collection",
Long: "Shows full backup paths in a backup collection.",
Args: cobra.ExactArgs(1),
RunE: cli.MaybeDecorateGRPCError(runLoadShowBackups),
RunE: cli.MaybeDecorateGRPCError(runListBackupsCmd),
}

loadShowIncrementalCmd := &cobra.Command{
Use: "incremental <backup_path>",
listIncrementalCmd := &cobra.Command{
Use: "list-incremental <backup_path>",
Short: "show incremental backups",
Long: "Shows incremental chain of a SQL backup.",
Args: cobra.ExactArgs(1),
RunE: cli.MaybeDecorateGRPCError(runLoadShowIncremental),
RunE: cli.MaybeDecorateGRPCError(runListIncrementalCmd),
}

loadShowDataCmd := &cobra.Command{
Use: "data <table> <backup_path>",
Short: "show data",
Long: "Shows data of a SQL backup.",
Args: cobra.MinimumNArgs(2),
RunE: cli.MaybeDecorateGRPCError(runLoadShowData),
exportDataCmd := &cobra.Command{
Use: "export <backup_path>",
Short: "export table data from a backup",
Long: "export table data from a backup, requires specifying --table to export data from",
Args: cobra.MinimumNArgs(1),
RunE: cli.MaybeDecorateGRPCError(runExportDataCmd),
}

loadShowCmds := &cobra.Command{
Use: "show [command]",
Short: "show backups",
backupCmds := &cobra.Command{
Use: "backup [command]",
Short: "debug backups",
Long: "Shows information about a SQL backup.",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Usage()
},
}

loadCmds := &cobra.Command{
Use: "load [command]",
Short: "load backup commands",
Long: `Commands for bulk loading external files.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Usage()
},
}

loadFlags := loadCmds.Flags()
loadFlags.StringVarP(
backupFlags := backupCmds.Flags()
backupFlags.StringVarP(
&externalIODir,
cliflags.ExternalIODir.Name,
cliflags.ExternalIODir.Shorthand,
"", /*value*/
cliflags.ExternalIODir.Usage())

loadShowDataCmd.Flags().StringVarP(
exportDataCmd.Flags().StringVarP(
&exportTableName,
cliflags.ExportTableTarget.Name,
cliflags.ExportTableTarget.Shorthand,
"", /*value*/
cliflags.ExportTableTarget.Usage())

exportDataCmd.Flags().StringVarP(
&readTime,
cliflags.ReadTime.Name,
cliflags.ReadTime.Shorthand,
"", /*value*/
cliflags.ReadTime.Usage())

loadShowDataCmd.Flags().StringVarP(
exportDataCmd.Flags().StringVarP(
&destination,
cliflags.ExportDestination.Name,
cliflags.ExportDestination.Shorthand,
"", /*value*/
cliflags.ExportDestination.Usage())

loadShowDataCmd.Flags().StringVarP(
exportDataCmd.Flags().StringVarP(
&format,
cliflags.ExportTableFormat.Name,
cliflags.ExportTableFormat.Shorthand,
"csv", /*value*/
cliflags.ExportTableFormat.Usage())

loadShowDataCmd.Flags().StringVarP(
exportDataCmd.Flags().StringVarP(
&nullas,
cliflags.ExportCSVNullas.Name,
cliflags.ExportCSVNullas.Shorthand,
"null", /*value*/
cliflags.ExportCSVNullas.Usage())

cli.AddCmd(loadCmds)
loadCmds.AddCommand(loadShowCmds)
cli.DebugCmd.AddCommand(backupCmds)

loadShowSubCmds := []*cobra.Command{
loadShowSummaryCmd,
loadShowBackupsCmd,
loadShowIncrementalCmd,
loadShowDataCmd,
backupSubCmds := []*cobra.Command{
showCmd,
listBackupsCmd,
listIncrementalCmd,
exportDataCmd,
}

for _, cmd := range loadShowSubCmds {
loadShowCmds.AddCommand(cmd)
cmd.Flags().AddFlagSet(loadFlags)
for _, cmd := range backupSubCmds {
backupCmds.AddCommand(cmd)
cmd.Flags().AddFlagSet(backupFlags)
}
}

Expand Down Expand Up @@ -198,7 +195,7 @@ func getManifestFromURI(ctx context.Context, path string) (backupccl.BackupManif
return backupManifest, nil
}

func runLoadShowSummary(cmd *cobra.Command, args []string) error {
func runShowCmd(cmd *cobra.Command, args []string) error {

path := args[0]
ctx := context.Background()
Expand All @@ -217,7 +214,7 @@ func runLoadShowSummary(cmd *cobra.Command, args []string) error {
return nil
}

func runLoadShowBackups(cmd *cobra.Command, args []string) error {
func runListBackupsCmd(cmd *cobra.Command, args []string) error {

path := args[0]
if !strings.Contains(path, "://") {
Expand All @@ -235,18 +232,17 @@ func runLoadShowBackups(cmd *cobra.Command, args []string) error {
return errors.Wrapf(err, "list full backups in collection")
}

if len(backupPaths) == 0 {
fmt.Println("no backups found.")
}

cols := []string{"path"}
rows := make([][]string, 0)
for _, backupPath := range backupPaths {
fmt.Println("./" + backupPath)
newRow := []string{"./" + backupPath}
rows = append(rows, newRow)
}

return nil
rowSliceIter := cli.NewRowSliceIter(rows, "l" /*align*/)
return cli.PrintQueryOutput(os.Stdout, cols, rowSliceIter)
}

func runLoadShowIncremental(cmd *cobra.Command, args []string) error {
func runListIncrementalCmd(cmd *cobra.Command, args []string) error {

path := args[0]
if !strings.Contains(path, "://") {
Expand All @@ -270,12 +266,12 @@ func runLoadShowIncremental(cmd *cobra.Command, args []string) error {
return err
}

w := tabwriter.NewWriter(os.Stdout, 28 /*minwidth*/, 1 /*tabwidth*/, 2 /*padding*/, ' ' /*padchar*/, 0 /*flags*/)
basepath := uri.Path
manifestPaths := append([]string{""}, incPaths...)
stores := make([]cloud.ExternalStorage, len(manifestPaths))
stores[0] = store

rows := make([][]string, 0)
for i := range manifestPaths {

if i > 0 {
Expand All @@ -296,19 +292,21 @@ func runLoadShowIncremental(cmd *cobra.Command, args []string) error {
if i == 0 {
startTime = "-"
}
fmt.Fprintf(w, "%s %s %s\n", uri.Path, startTime, endTime)
}

if err := w.Flush(); err != nil {
return err
newRow := []string{uri.Path, startTime, endTime}
rows = append(rows, newRow)
}
return nil
cols := []string{"path", "start time", "end time"}
rowSliceIter := cli.NewRowSliceIter(rows, "lll" /*align*/)
return cli.PrintQueryOutput(os.Stdout, cols, rowSliceIter)
}

func runLoadShowData(cmd *cobra.Command, args []string) error {
func runExportDataCmd(cmd *cobra.Command, args []string) error {

fullyQualifiedTableName := strings.ToLower(args[0])
manifestPaths := args[1:]
if exportTableName == "" {
return errors.New("export data requires table name specified by --table flag")
}
fullyQualifiedTableName := strings.ToLower(exportTableName)
manifestPaths := args

ctx := context.Background()
manifests := make([]backupccl.BackupManifest, 0, len(manifestPaths))
Expand Down
Loading

0 comments on commit 3caed9e

Please sign in to comment.