Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
125 changes: 113 additions & 12 deletions go/cmd/vtctldclient/internal/command/tablets.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,69 @@ import (
var (
// ChangeTabletType makes a ChangeTabletType gRPC call to a vtctld.
ChangeTabletType = &cobra.Command{
Use: "ChangeTabletType [--dry-run] TABLET_ALIAS TABLET_TYPE",
Args: cobra.ExactArgs(2),
RunE: commandChangeTabletType,
Use: "ChangeTabletType [--dry-run] <alias> <tablet-type>",
Short: "Changes the db type for the specified tablet, if possible.",
Long: `Changes the db type for the specified tablet, if possible.

This command is used primarily to arrange replicas, and it will not convert a primary.
NOTE: This command automatically updates the serving graph.`,
DisableFlagsInUseLine: true,
Args: cobra.ExactArgs(2),
RunE: commandChangeTabletType,
}
// DeleteTablets makes a DeleteTablets gRPC call to a vtctld.
DeleteTablets = &cobra.Command{
Use: "DeleteTablets TABLET_ALIAS [ TABLET_ALIAS ... ]",
Args: cobra.MinimumNArgs(1),
RunE: commandDeleteTablets,
Use: "DeleteTablets <alias> [ <alias> ... ]",
Short: "Deletes tablet(s) from the topology.",
DisableFlagsInUseLine: true,
Args: cobra.MinimumNArgs(1),
RunE: commandDeleteTablets,
}
// GetTablet makes a GetTablet gRPC call to a vtctld.
GetTablet = &cobra.Command{
Use: "GetTablet alias",
Args: cobra.ExactArgs(1),
RunE: commandGetTablet,
Use: "GetTablet <alias>",
Short: "Outputs a JSON structure that contains information about the tablet.",
DisableFlagsInUseLine: true,
Args: cobra.ExactArgs(1),
RunE: commandGetTablet,
}
// GetTablets makes a GetTablets gRPC call to a vtctld.
GetTablets = &cobra.Command{
Use: "GetTablets [--strict] [{--cell $c1 [--cell $c2 ...], --keyspace $ks [--shard $shard], --tablet-alias $alias}]",
Args: cobra.NoArgs,
RunE: commandGetTablets,
Use: "GetTablets [--strict] [{--cell $c1 [--cell $c2 ...], --keyspace $ks [--shard $shard], --tablet-alias $alias}]",
Short: "Looks up tablets according to filter criteria.",
Long: `Looks up tablets according to the filter criteria.

If --tablet-alias is passed, none of the other filters (keyspace, shard, cell) may
be passed, and tablets are looked up by tablet alias only.

If --keyspace is passed, then all tablets in the keyspace are retrieved. The
--shard flag may also be passed to further narrow the set of tablets to that
<keyspace/shard>. Passing --shard without also passing --keyspace will fail.

Passing --cell limits the set of tablets to those in the specified cells. The
--cell flag accepts a CSV argument (e.g. --cell "c1,c2") and may be repeated
(e.g. --cell "c1" --cell "c2").

Valid output formats are "awk" and "json".`,
DisableFlagsInUseLine: true,
Args: cobra.NoArgs,
RunE: commandGetTablets,
}
// RefreshState makes a RefreshState gRPC call to a vtctld.
RefreshState = &cobra.Command{
Use: "RefreshState <alias>",
Short: "Reloads the tablet record on the specified tablet.",
DisableFlagsInUseLine: true,
Args: cobra.ExactArgs(1),
RunE: commandRefreshState,
}
// RefreshStateByShard makes a RefreshStateByShard gRPC call to a vtcld.
RefreshStateByShard = &cobra.Command{
Use: "RefreshStateByShard [--cell <cell1> ...] <keyspace/shard>",
Short: "Reloads the tablet record all tablets in the shard, optionally limited to the specified cells.",
DisableFlagsInUseLine: true,
Args: cobra.ExactArgs(1),
RunE: commandRefreshStateByShard,
}
)

Expand Down Expand Up @@ -218,6 +260,60 @@ func commandGetTablets(cmd *cobra.Command, args []string) error {
return nil
}

func commandRefreshState(cmd *cobra.Command, args []string) error {
alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0))
if err != nil {
return err
}

cli.FinishedParsing(cmd)

_, err = client.RefreshState(commandCtx, &vtctldatapb.RefreshStateRequest{
TabletAlias: alias,
})
if err != nil {
return err
}

fmt.Printf("Refreshed state on %s\n", topoproto.TabletAliasString(alias))
return nil
}

var refreshStateByShardOptions = struct {
Cells []string
}{}

func commandRefreshStateByShard(cmd *cobra.Command, args []string) error {
keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0))
if err != nil {
return err
}

cli.FinishedParsing(cmd)

resp, err := client.RefreshStateByShard(commandCtx, &vtctldatapb.RefreshStateByShardRequest{
Keyspace: keyspace,
Shard: shard,
Cells: refreshStateByShardOptions.Cells,
})
if err != nil {
return err
}

msg := &strings.Builder{}
msg.WriteString(fmt.Sprintf("Refreshed state on %s/%s", keyspace, shard))
if len(refreshStateByShardOptions.Cells) > 0 {
msg.WriteString(fmt.Sprintf(" in cells %s", strings.Join(refreshStateByShardOptions.Cells, ", ")))
}
msg.WriteByte('\n')
if resp.IsPartialRefresh {
msg.WriteString("State refresh was partial; some tablets in the shard may not have succeeded.\n")
}

fmt.Print(msg.String())
return nil
}

func init() {
ChangeTabletType.Flags().BoolVarP(&changeTabletTypeOptions.DryRun, "dry-run", "d", false, "Shows the proposed change without actually executing it")
Root.AddCommand(ChangeTabletType)
Expand All @@ -234,4 +330,9 @@ func init() {
GetTablets.Flags().StringVar(&getTabletsOptions.Format, "format", "awk", "Output format to use; valid choices are (json, awk)")
GetTablets.Flags().BoolVar(&getTabletsOptions.Strict, "strict", false, "Require all cells to return successful tablet data. Without --strict, tablet listings may be partial.")
Root.AddCommand(GetTablets)

Root.AddCommand(RefreshState)

RefreshStateByShard.Flags().StringSliceVarP(&refreshStateByShardOptions.Cells, "cells", "c", nil, "If specified, only call RefreshState on tablets in the specified cells. If empty, all cells are considered.")
Root.AddCommand(RefreshStateByShard)
}
Loading