diff --git a/go/cmd/vtctldclient/command/onlineddl.go b/go/cmd/vtctldclient/command/onlineddl.go index b2092ab0b2d..660f41f60b3 100644 --- a/go/cmd/vtctldclient/command/onlineddl.go +++ b/go/cmd/vtctldclient/command/onlineddl.go @@ -28,7 +28,10 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/vtctl/schematools" + "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle" + "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -83,6 +86,22 @@ var ( Args: cobra.ExactArgs(2), RunE: commandOnlineDDLRetry, } + OnlineDDLThrottle = &cobra.Command{ + Use: "throttle ", + Short: "Throttles one or all migrations", + Example: "OnlineDDL throttle all", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(2), + RunE: commandOnlineDDLThrottle, + } + OnlineDDLUnthrottle = &cobra.Command{ + Use: "unthrottle ", + Short: "Unthrottles one or all migrations", + Example: "OnlineDDL unthrottle all", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(2), + RunE: commandOnlineDDLUnthrottle, + } OnlineDDLShow = &cobra.Command{ Use: "show", Short: "Display information about online DDL operations.", @@ -239,6 +258,64 @@ func commandOnlineDDLRetry(cmd *cobra.Command, args []string) error { return nil } +// throttleCommandHelper is a helper function that implements the logic for both +// commandOnlineDDLThrottle and commandOnlineDDLUnthrottle ; the only difference between the two +// is the ThrottledApp *rule* sent in UpdateThrottlerConfigRequest. +// input: `throttleType`: true stands for "throttle", `false` stands for "unthrottle" +func throttleCommandHelper(cmd *cobra.Command, throttleType bool) error { + keyspace, uuid, err := analyzeOnlineDDLCommandWithUuidOrAllArgument(cmd) + if err != nil { + return err + } + cli.FinishedParsing(cmd) + + var rule topodatapb.ThrottledAppRule + if throttleType { + rule.Ratio = throttle.DefaultThrottleRatio + rule.ExpiresAt = protoutil.TimeToProto(time.Now().Add(throttle.DefaultAppThrottleDuration)) + } else { + rule.Ratio = 0 + rule.ExpiresAt = protoutil.TimeToProto(time.Now()) + } + + if strings.ToLower(uuid) == AllMigrationsIndicator { + rule.Name = throttlerapp.OnlineDDLName.String() + } else { + rule.Name = uuid + } + + updateThrottlerConfigOptions := vtctldatapb.UpdateThrottlerConfigRequest{ + Keyspace: keyspace, + ThrottledApp: &rule, + } + resp, err := client.UpdateThrottlerConfig(commandCtx, &updateThrottlerConfigOptions) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + return nil +} + +// commandOnlineDDLThrottle throttles one or multiple migrations. +// As opposed to *most* OnlineDDL functions, this functionality does not end up calling a gRPC on tablets. +// Instead, it updates Keyspace and SrvKeyspace entries, on which the tablets listen. +func commandOnlineDDLThrottle(cmd *cobra.Command, args []string) error { + return throttleCommandHelper(cmd, true) +} + +// commandOnlineDDLUnthrottle unthrottles one or multiple migrations. +// As opposed to *most* OnlineDDL functions, this functionality does not end up calling a gRPC on tablets. +// Instead, it updates Keyspace and SrvKeyspace entries, on which the tablets listen. +func commandOnlineDDLUnthrottle(cmd *cobra.Command, args []string) error { + return throttleCommandHelper(cmd, false) +} + var onlineDDLShowArgs = struct { JSON bool OrderStr string @@ -314,6 +391,8 @@ func init() { OnlineDDL.AddCommand(OnlineDDLComplete) OnlineDDL.AddCommand(OnlineDDLLaunch) OnlineDDL.AddCommand(OnlineDDLRetry) + OnlineDDL.AddCommand(OnlineDDLThrottle) + OnlineDDL.AddCommand(OnlineDDLUnthrottle) OnlineDDLShow.Flags().BoolVar(&onlineDDLShowArgs.JSON, "json", false, "Output JSON instead of human-readable table.") OnlineDDLShow.Flags().StringVar(&onlineDDLShowArgs.OrderStr, "order", "asc", "Sort the results by `id` property of the Schema migration.") diff --git a/go/vt/vtgate/planbuilder/migration.go b/go/vt/vtgate/planbuilder/migration.go index 375d4e97dea..6fb73a9039d 100644 --- a/go/vt/vtgate/planbuilder/migration.go +++ b/go/vt/vtgate/planbuilder/migration.go @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" ) @@ -40,7 +41,7 @@ func validateThrottleParams(alterMigrationType sqlparser.AlterMigrationType, exp // Unthrottling is like throttling with duration=0 duration = 0 default: - duration = time.Hour * 24 * 365 * 100 + duration = throttle.DefaultAppThrottleDuration if expireString != "" { duration, err = time.ParseDuration(expireString) if err != nil || duration < 0 {