-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[vtctld] Add remaining reparent commands to VtctldServer #7536
Changes from 15 commits
8b1f317
4e20e14
8fd1a36
124bdee
a88301e
5ef0a56
0f3539c
f999833
d305e68
f7408dc
af7e8ca
ac10ae9
f21c590
a1ba1f8
24e393a
a0b69ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -17,27 +17,114 @@ limitations under the License. | |||||
package command | ||||||
|
||||||
import ( | ||||||
"fmt" | ||||||
"time" | ||||||
|
||||||
"github.com/spf13/cobra" | ||||||
|
||||||
"vitess.io/vitess/go/cmd/vtctldclient/cli" | ||||||
"vitess.io/vitess/go/protoutil" | ||||||
"vitess.io/vitess/go/vt/log" | ||||||
"vitess.io/vitess/go/vt/logutil" | ||||||
"vitess.io/vitess/go/vt/topo" | ||||||
"vitess.io/vitess/go/vt/topo/topoproto" | ||||||
|
||||||
topodatapb "vitess.io/vitess/go/vt/proto/topodata" | ||||||
vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" | ||||||
) | ||||||
|
||||||
var ( | ||||||
// EmergencyReparentShard makes an EmergencyReparent gRPC call to a vtctld. | ||||||
EmergencyReparentShard = &cobra.Command{ | ||||||
Use: "EmergencyReparentShard <keyspace/shard>", | ||||||
Args: cobra.ExactArgs(1), | ||||||
Long: "Reparents the shard to the new primary. Assumes the old primary is dead and not responding", | ||||||
RunE: commandEmergencyReparentShard, | ||||||
} | ||||||
// InitShardPrimary makes an InitShardPrimary gRPC call to a vtctld. | ||||||
InitShardPrimary = &cobra.Command{ | ||||||
Use: "InitShardPrimary", | ||||||
Args: cobra.ExactArgs(2), | ||||||
RunE: commandInitShardPrimary, | ||||||
} | ||||||
// PlannedReparentShard makes a PlannedReparentShard gRPC call to a vtctld. | ||||||
PlannedReparentShard = &cobra.Command{ | ||||||
Use: "PlannedReparentShard <keyspace/shard>", | ||||||
Args: cobra.ExactArgs(1), | ||||||
Long: "string", | ||||||
RunE: commandPlannedReparentShard, | ||||||
} | ||||||
// ReparentTablet makes a ReparentTablet gRPC call to a vtctld. | ||||||
ReparentTablet = &cobra.Command{ | ||||||
Use: "ReparentTablet ALIAS", | ||||||
Long: "Reparent a tablet to the current primary in the shard. This only works if the current replica position " + | ||||||
"matches the last known reparent action.", | ||||||
Args: cobra.ExactArgs(1), | ||||||
RunE: commandReparentTablet, | ||||||
} | ||||||
// TabletExternallyReparented makes a TabletExternallyReparented gRPC call | ||||||
// to a vtctld. | ||||||
TabletExternallyReparented = &cobra.Command{ | ||||||
Use: "TabletExternallyReparented ALIAS", | ||||||
Args: cobra.ExactArgs(1), | ||||||
RunE: commandTabletExternallyReparented, | ||||||
} | ||||||
) | ||||||
|
||||||
var emergencyReparentShardOptions = struct { | ||||||
Force bool | ||||||
WaitReplicasTimeout time.Duration | ||||||
NewPrimaryAliasStr string | ||||||
IgnoreReplicaAliasStrList []string | ||||||
}{} | ||||||
|
||||||
func commandEmergencyReparentShard(cmd *cobra.Command, args []string) error { | ||||||
keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
var ( | ||||||
newPrimaryAlias *topodatapb.TabletAlias | ||||||
ignoreReplicaAliases = make([]*topodatapb.TabletAlias, len(emergencyReparentShardOptions.IgnoreReplicaAliasStrList)) | ||||||
) | ||||||
|
||||||
if emergencyReparentShardOptions.NewPrimaryAliasStr != "" { | ||||||
newPrimaryAlias, err = topoproto.ParseTabletAlias(emergencyReparentShardOptions.NewPrimaryAliasStr) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
} | ||||||
|
||||||
for i, aliasStr := range emergencyReparentShardOptions.IgnoreReplicaAliasStrList { | ||||||
alias, err := topoproto.ParseTabletAlias(aliasStr) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
ignoreReplicaAliases[i] = alias | ||||||
} | ||||||
|
||||||
cli.FinishedParsing(cmd) | ||||||
|
||||||
resp, err := client.EmergencyReparentShard(commandCtx, &vtctldatapb.EmergencyReparentShardRequest{ | ||||||
Keyspace: keyspace, | ||||||
Shard: shard, | ||||||
NewPrimary: newPrimaryAlias, | ||||||
IgnoreReplicas: ignoreReplicaAliases, | ||||||
WaitReplicasTimeout: protoutil.DurationToProto(emergencyReparentShardOptions.WaitReplicasTimeout), | ||||||
}) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
for _, event := range resp.Events { | ||||||
fmt.Println(logutil.EventString(event)) | ||||||
} | ||||||
|
||||||
return nil | ||||||
} | ||||||
|
||||||
var initShardPrimaryOptions = struct { | ||||||
WaitReplicasTimeout time.Duration | ||||||
Force bool | ||||||
|
@@ -71,8 +158,118 @@ func commandInitShardPrimary(cmd *cobra.Command, args []string) error { | |||||
return err | ||||||
} | ||||||
|
||||||
var plannedReparentShardOptions = struct { | ||||||
NewPrimaryAliasStr string | ||||||
AvoidPrimaryAliasStr string | ||||||
WaitReplicasTimeout time.Duration | ||||||
}{} | ||||||
|
||||||
func commandPlannedReparentShard(cmd *cobra.Command, args []string) error { | ||||||
keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
var ( | ||||||
newPrimaryAlias *topodatapb.TabletAlias | ||||||
avoidPrimaryAlias *topodatapb.TabletAlias | ||||||
) | ||||||
|
||||||
if plannedReparentShardOptions.NewPrimaryAliasStr != "" { | ||||||
newPrimaryAlias, err = topoproto.ParseTabletAlias(plannedReparentShardOptions.NewPrimaryAliasStr) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
} | ||||||
|
||||||
if plannedReparentShardOptions.AvoidPrimaryAliasStr != "" { | ||||||
avoidPrimaryAlias, err = topoproto.ParseTabletAlias(plannedReparentShardOptions.AvoidPrimaryAliasStr) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
} | ||||||
|
||||||
cli.FinishedParsing(cmd) | ||||||
|
||||||
resp, err := client.PlannedReparentShard(commandCtx, &vtctldatapb.PlannedReparentShardRequest{ | ||||||
Keyspace: keyspace, | ||||||
Shard: shard, | ||||||
NewPrimary: newPrimaryAlias, | ||||||
AvoidPrimary: avoidPrimaryAlias, | ||||||
WaitReplicasTimeout: protoutil.DurationToProto(plannedReparentShardOptions.WaitReplicasTimeout), | ||||||
}) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
for _, event := range resp.Events { | ||||||
fmt.Println(logutil.EventString(event)) | ||||||
} | ||||||
|
||||||
return nil | ||||||
} | ||||||
|
||||||
func commandReparentTablet(cmd *cobra.Command, args []string) error { | ||||||
alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
resp, err := client.ReparentTablet(commandCtx, &vtctldatapb.ReparentTabletRequest{ | ||||||
Tablet: alias, | ||||||
}) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
data, err := cli.MarshalJSON(resp) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
fmt.Printf("%s\n", data) | ||||||
|
||||||
return nil | ||||||
} | ||||||
|
||||||
func commandTabletExternallyReparented(cmd *cobra.Command, args []string) error { | ||||||
alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
resp, err := client.TabletExternallyReparented(commandCtx, &vtctldatapb.TabletExternallyReparentedRequest{ | ||||||
Tablet: alias, | ||||||
}) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
data, err := cli.MarshalJSON(resp) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
fmt.Printf("%s\n", data) | ||||||
|
||||||
return nil | ||||||
} | ||||||
|
||||||
func init() { | ||||||
EmergencyReparentShard.Flags().DurationVar(&emergencyReparentShardOptions.WaitReplicasTimeout, "wait-replicas-timeout", *topo.RemoteOperationTimeout, "Time to wait for replicas to catch up in reparenting.") | ||||||
EmergencyReparentShard.Flags().StringVar(&emergencyReparentShardOptions.NewPrimaryAliasStr, "new-primary", "", "Alias of a tablet that should be the new primary. If not specified, the vtctld will select the best candidate to promote.") | ||||||
EmergencyReparentShard.Flags().StringSliceVarP(&emergencyReparentShardOptions.IgnoreReplicaAliasStrList, "ignore-replicas", "i", nil, "Comma-separated, repeated list of replica tablet aliases to ignore during the emergency reparent.") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I assume this is a typo. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why "Comma-separated, repeated list"? Why not just "Comma-separated list"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's repeated in the sense that you can specify the flag multiple times, so both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get it. Fine for right now, maybe we can revisit later. |
||||||
Root.AddCommand(EmergencyReparentShard) | ||||||
|
||||||
InitShardPrimary.Flags().DurationVar(&initShardPrimaryOptions.WaitReplicasTimeout, "wait-replicas-timeout", 30*time.Second, "time to wait for replicas to catch up in reparenting") | ||||||
InitShardPrimary.Flags().BoolVar(&initShardPrimaryOptions.Force, "force", false, "will force the reparent even if the provided tablet is not a master or the shard master") | ||||||
Root.AddCommand(InitShardPrimary) | ||||||
|
||||||
PlannedReparentShard.Flags().DurationVar(&plannedReparentShardOptions.WaitReplicasTimeout, "wait-replicas-timeout", *topo.RemoteOperationTimeout, "Time to wait for replicas to catch up on replication both before and after reparenting.") | ||||||
PlannedReparentShard.Flags().StringVar(&plannedReparentShardOptions.NewPrimaryAliasStr, "new-primary", "", "Alias of a tablet that should be the new primary.") | ||||||
PlannedReparentShard.Flags().StringVar(&plannedReparentShardOptions.AvoidPrimaryAliasStr, "avoid-primary", "", "Alias of a tablet that should not be the primary; i.e. \"reparent to any other tablet if this one is the primary\".") | ||||||
Root.AddCommand(PlannedReparentShard) | ||||||
|
||||||
Root.AddCommand(ReparentTablet) | ||||||
Root.AddCommand(TabletExternallyReparented) | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the old flags use underscore (
_
). Is it a cobra convention to use dash (-
)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a GNU convention [1] (and therefore more common among most CLIs), so I've been doing it for all the vtctldclient options (except the global
action_timeout
, which I copied from vtctlclient and for some reason didn't change at the time). Happy to back this out in a separate change (since I'll have to update a bunch of flags) if Vitess prefers to enforce underscores everywhere.[1]: Stack Overflow, which provides some additional reasoning as well as linking to the GNU style guide: https://stackoverflow.com/a/50537232
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.. let us follow the convention.