From 79983de85b5e1b679230157542bff64bff2f958a Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 21 May 2024 23:19:07 -0400 Subject: [PATCH 01/27] add support for vtgate traffic mirroring (topo, workflow) Signed-off-by: Max Englander --- changelog/20.0/20.0.0/summary.md | 37 +- go/cmd/vtcombo/cli/main.go | 5 + go/cmd/vtctldclient/command/mirror_rules.go | 157 ++ .../vreplication/common/mirrortraffic.go | 89 + .../command/vreplication/common/utils.go | 6 + .../vreplication/movetables/movetables.go | 6 + go/flags/endtoend/vtctldclient.txt | 2 + .../movetables_mirrortraffic_test.go | 116 + .../resharding_workflows_v2_test.go | 4 + .../vreplication_vtctldclient_cli_test.go | 19 + .../endtoend/vreplication/wrappers_test.go | 23 + go/vt/proto/vschema/vschema.pb.go | 274 ++- go/vt/proto/vschema/vschema_vtproto.pb.go | 442 ++++ go/vt/proto/vtctldata/vtctldata.pb.go | 1115 +++++++--- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 1195 ++++++++++ go/vt/proto/vtctlservice/vtctlservice.pb.go | 500 +++-- .../vtctlservice/vtctlservice_grpc.pb.go | 112 + go/vt/proto/vttest/vttest.pb.go | 34 +- go/vt/proto/vttest/vttest_vtproto.pb.go | 51 + go/vt/topo/server.go | 1 + go/vt/topo/srv_vschema.go | 6 + go/vt/topo/topotests/srv_vschema_test.go | 5 + go/vt/topo/vschema.go | 36 + go/vt/topotools/mirror_rules.go | 72 + go/vt/topotools/mirror_rules_test.go | 79 + go/vt/vtcombo/tablet_map.go | 17 + go/vt/vtctl/grpcvtctldclient/client_gen.go | 27 + go/vt/vtctl/grpcvtctldserver/server.go | 61 + go/vt/vtctl/grpcvtctldserver/server_test.go | 3 + go/vt/vtctl/localvtctldclient/client_gen.go | 15 + .../{materializer_env_test.go => env_test.go} | 223 +- go/vt/vtctl/workflow/materializer_test.go | 26 +- go/vt/vtctl/workflow/server.go | 101 +- go/vt/vtctl/workflow/server_test.go | 416 ++++ go/vt/vtctl/workflow/state.go | 1 + go/vt/vtctl/workflow/switcher.go | 4 + go/vt/vtctl/workflow/switcher_dry_run.go | 10 + go/vt/vtctl/workflow/switcher_interface.go | 1 + go/vt/vtctl/workflow/traffic_switcher.go | 49 +- proto/vschema.proto | 15 + proto/vtctldata.proto | 35 + proto/vtctlservice.proto | 5 + proto/vttest.proto | 3 + web/vtadmin/src/proto/vtadmin.d.ts | 824 +++++++ web/vtadmin/src/proto/vtadmin.js | 1944 +++++++++++++++++ 45 files changed, 7431 insertions(+), 735 deletions(-) create mode 100644 go/cmd/vtctldclient/command/mirror_rules.go create mode 100644 go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go create mode 100644 go/test/endtoend/vreplication/movetables_mirrortraffic_test.go create mode 100644 go/vt/topotools/mirror_rules.go create mode 100644 go/vt/topotools/mirror_rules_test.go rename go/vt/vtctl/workflow/{materializer_env_test.go => env_test.go} (54%) diff --git a/changelog/20.0/20.0.0/summary.md b/changelog/20.0/20.0.0/summary.md index 996967650c2..7f59d0f0b0a 100644 --- a/changelog/20.0/20.0.0/summary.md +++ b/changelog/20.0/20.0.0/summary.md @@ -26,6 +26,7 @@ - [Delete with Multi Target Support](#delete-multi-target) - [User Defined Functions Support](#udf-support) - [Insert Row Alias Support](#insert-row-alias-support) + - **[Traffic Mirroring](#traffic-mirroring)** - **[Query Timeout](#query-timeout)** - **[Flag changes](#flag-changes)** - [`pprof-http` default change](#pprof-http-default) @@ -289,6 +290,40 @@ Example: More details about how it works is available in [MySQL Docs](https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html) +### Traffic Mirroring + +Traffic mirroring is intended to help reduce some of the uncertainty inherent to `MoveTables SwitchTraffic`. When traffic mirroring is enabled, VTGate will mirror a percentage of traffic from one keyspace to another. + +Mirror rules may be enabled through `vtctldclient` in two ways: + + * With `ApplyMirrorRules`. + * With `MoveTables MirrorTraffic`, which uses `ApplyMirrorRules` under the hood. + +Example with `ApplyMirrorRules`: + +```bash +$ vtctldclient --server :15999 ApplyMirrorRules --rules "$(cat <Query Timeout On a query timeout, Vitess closed the connection using the `kill connection` statement. This leads to connection churn which is not desirable in some cases. To avoid this, Vitess now uses the `kill query` statement to cancel the query. @@ -334,4 +369,4 @@ The internal gRPC client now caches the static auth credentials and supports rel #### vtadmin-web updated to node v20.12.2 (LTS) Building `vtadmin-web` now requires node >= v20.12.0 (LTS). Breaking changes from v18 to v20 can be found at https://nodejs.org/en/blog/release/v20.12.0 -- with no known issues that apply to VTAdmin. -Full details on the node v20.12.2 release can be found at https://nodejs.org/en/blog/release/v20.12.2. \ No newline at end of file +Full details on the node v20.12.2 release can be found at https://nodejs.org/en/blog/release/v20.12.2. diff --git a/go/cmd/vtcombo/cli/main.go b/go/cmd/vtcombo/cli/main.go index 189441594bb..5f27e581a24 100644 --- a/go/cmd/vtcombo/cli/main.go +++ b/go/cmd/vtcombo/cli/main.go @@ -206,6 +206,11 @@ func run(cmd *cobra.Command, args []string) (err error) { return fmt.Errorf("Failed to load routing rules: %w", err) } + // attempt to load any mirror rules specified by tpb + if err := vtcombo.InitMirrorRules(context.Background(), ts, tpb.GetMirrorRules()); err != nil { + return fmt.Errorf("Failed to load mirror rules: %w", err) + } + servenv.Init() tabletenv.Init() diff --git a/go/cmd/vtctldclient/command/mirror_rules.go b/go/cmd/vtctldclient/command/mirror_rules.go new file mode 100644 index 00000000000..50acaf8be75 --- /dev/null +++ b/go/cmd/vtctldclient/command/mirror_rules.go @@ -0,0 +1,157 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "errors" + "fmt" + "os" + "strings" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/json2" + + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // ApplyMirrorRules makes an ApplyMirrorRules gRPC call to a vtctld. + ApplyMirrorRules = &cobra.Command{ + Use: "ApplyMirrorRules {--rules RULES | --rules-file RULES_FILE} [--cells=c1,c2,...] [--skip-rebuild] [--dry-run]", + Short: "Applies the VSchema mirror rules.", + DisableFlagsInUseLine: true, + Args: cobra.NoArgs, + RunE: commandApplyMirrorRules, + } + // GetMirrorRules makes a GetMirrorRules gRPC call to a vtctld. + GetMirrorRules = &cobra.Command{ + Use: "GetMirrorRules", + Short: "Displays the VSchema mirror rules.", + DisableFlagsInUseLine: true, + Args: cobra.NoArgs, + RunE: commandGetMirrorRules, + } +) + +var applyMirrorRulesOptions = struct { + Rules string + RulesFilePath string + Cells []string + SkipRebuild bool + DryRun bool +}{} + +func commandApplyMirrorRules(cmd *cobra.Command, args []string) error { + if applyMirrorRulesOptions.Rules != "" && applyMirrorRulesOptions.RulesFilePath != "" { + return fmt.Errorf("cannot pass both --rules (=%s) and --rules-file (=%s)", applyMirrorRulesOptions.Rules, applyMirrorRulesOptions.RulesFilePath) + } + + if applyMirrorRulesOptions.Rules == "" && applyMirrorRulesOptions.RulesFilePath == "" { + return errors.New("must pass exactly one of --rules or --rules-file") + } + + cli.FinishedParsing(cmd) + + var rulesBytes []byte + if applyMirrorRulesOptions.RulesFilePath != "" { + data, err := os.ReadFile(applyMirrorRulesOptions.RulesFilePath) + if err != nil { + return err + } + + rulesBytes = data + } else { + rulesBytes = []byte(applyMirrorRulesOptions.Rules) + } + + rr := &vschemapb.MirrorRules{} + if err := json2.Unmarshal(rulesBytes, &rr); err != nil { + return err + } + + // Round-trip so when we display the result it's readable. + data, err := cli.MarshalJSON(rr) + if err != nil { + return err + } + + if applyMirrorRulesOptions.DryRun { + fmt.Printf("[DRY RUN] Would have saved new MirrorRules object:\n%s\n", data) + + if applyMirrorRulesOptions.SkipRebuild { + fmt.Println("[DRY RUN] Would not have rebuilt VSchema graph, would have required operator to run RebuildVSchemaGraph for changes to take effect") + } else { + fmt.Print("[DRY RUN] Would have rebuilt the VSchema graph") + if len(applyMirrorRulesOptions.Cells) == 0 { + fmt.Print(" in all cells\n") + } else { + fmt.Printf(" in the following cells: %s.\n", strings.Join(applyMirrorRulesOptions.Cells, ", ")) + } + } + + return nil + } + + _, err = client.ApplyMirrorRules(commandCtx, &vtctldatapb.ApplyMirrorRulesRequest{ + MirrorRules: rr, + SkipRebuild: applyMirrorRulesOptions.SkipRebuild, + RebuildCells: applyMirrorRulesOptions.Cells, + }) + if err != nil { + return err + } + + fmt.Printf("New MirrorRules object:\n%s\nIf this is not what you expected, check the input data (as JSON parsing will skip unexpected fields).\n", data) + + if applyMirrorRulesOptions.SkipRebuild { + fmt.Println("Skipping rebuild of VSchema graph, will need to run RebuildVSchemaGraph for changes to take effect.") + } + + return nil +} + +func commandGetMirrorRules(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + + resp, err := client.GetMirrorRules(commandCtx, &vtctldatapb.GetMirrorRulesRequest{}) + if err != nil { + return err + } + + data, err := cli.MarshalJSON(resp.MirrorRules) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + + return nil +} + +func init() { + ApplyMirrorRules.Flags().StringVarP(&applyMirrorRulesOptions.Rules, "rules", "r", "", "Mirror rules, specified as a string.") + ApplyMirrorRules.Flags().StringVarP(&applyMirrorRulesOptions.RulesFilePath, "rules-file", "f", "", "Path to a file containing mirror rules specified as JSON.") + ApplyMirrorRules.Flags().StringSliceVarP(&applyMirrorRulesOptions.Cells, "cells", "c", nil, "Limit the VSchema graph rebuilding to the specified cells. Ignored if --skip-rebuild is specified.") + ApplyMirrorRules.Flags().BoolVar(&applyMirrorRulesOptions.SkipRebuild, "skip-rebuild", false, "Skip rebuilding the SrvVSchema objects.") + ApplyMirrorRules.Flags().BoolVarP(&applyMirrorRulesOptions.DryRun, "dry-run", "d", false, "Load the specified mirror rules as a validation step, but do not actually apply the rules to the topo.") + Root.AddCommand(ApplyMirrorRules) + + Root.AddCommand(GetMirrorRules) +} diff --git a/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go b/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go new file mode 100644 index 00000000000..601af477c95 --- /dev/null +++ b/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go @@ -0,0 +1,89 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "bytes" + "fmt" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +func GetMirrorTrafficCommand(opts *SubCommandsOpts) *cobra.Command { + cmd := &cobra.Command{ + Use: "mirrortraffic", + Short: fmt.Sprintf("Mirror traffic for a %s VReplication workflow.", opts.SubCommand), + Example: fmt.Sprintf(`vtctldclient --server localhost:15999 %s --workflow %s --target-keyspace customer mirrortraffic --percent 50.0`, opts.SubCommand, opts.Workflow), + DisableFlagsInUseLine: true, + Aliases: []string{"MirrorTraffic"}, + Args: cobra.NoArgs, + PreRun: func(cmd *cobra.Command, args []string) { + if !cmd.Flags().Lookup("tablet-types").Changed { + // We mirror traffic for all tablet types if none are provided. + MirrorTrafficOptions.TabletTypes = []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + } + } + }, + RunE: commandMirrorTraffic, + } + return cmd +} + +func commandMirrorTraffic(cmd *cobra.Command, args []string) error { + format, err := GetOutputFormat(cmd) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + req := &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: BaseOptions.TargetKeyspace, + Workflow: BaseOptions.Workflow, + TabletTypes: MirrorTrafficOptions.TabletTypes, + Percent: MirrorTrafficOptions.Percent, + } + resp, err := GetClient().WorkflowMirrorTraffic(GetCommandCtx(), req) + if err != nil { + return err + } + + var output []byte + if format == "json" { + output, err = cli.MarshalJSONPretty(resp) + if err != nil { + return err + } + } else { + tout := bytes.Buffer{} + tout.WriteString(resp.Summary + "\n\n") + tout.WriteString(fmt.Sprintf("Start State: %s\n", resp.StartState)) + tout.WriteString(fmt.Sprintf("Current State: %s\n", resp.CurrentState)) + output = tout.Bytes() + } + fmt.Printf("%s\n", output) + + return nil +} diff --git a/go/cmd/vtctldclient/command/vreplication/common/utils.go b/go/cmd/vtctldclient/command/vreplication/common/utils.go index a742f31a9ff..cb408add490 100644 --- a/go/cmd/vtctldclient/command/vreplication/common/utils.go +++ b/go/cmd/vtctldclient/command/vreplication/common/utils.go @@ -224,6 +224,12 @@ func AddCommonCreateFlags(cmd *cobra.Command) { cmd.Flags().BoolVar(&CreateOptions.StopAfterCopy, "stop-after-copy", false, "Stop the workflow after it's finished copying the existing rows and before it starts replicating changes.") } +var MirrorTrafficOptions = struct { + DryRun bool + Percent float32 + TabletTypes []topodatapb.TabletType +}{} + var SwitchTrafficOptions = struct { Cells []string TabletTypes []topodatapb.TabletType diff --git a/go/cmd/vtctldclient/command/vreplication/movetables/movetables.go b/go/cmd/vtctldclient/command/vreplication/movetables/movetables.go index d729230e7a7..4d8f9eaf3f0 100644 --- a/go/cmd/vtctldclient/command/vreplication/movetables/movetables.go +++ b/go/cmd/vtctldclient/command/vreplication/movetables/movetables.go @@ -20,6 +20,7 @@ import ( "github.com/spf13/cobra" "vitess.io/vitess/go/cmd/vtctldclient/command/vreplication/common" + "vitess.io/vitess/go/vt/topo/topoproto" ) var ( @@ -67,6 +68,11 @@ func registerCommands(root *cobra.Command) { base.AddCommand(common.GetStartCommand(opts)) base.AddCommand(common.GetStopCommand(opts)) + mirrorTrafficCommand := common.GetMirrorTrafficCommand(opts) + mirrorTrafficCommand.Flags().Var((*topoproto.TabletTypeListFlag)(&common.MirrorTrafficOptions.TabletTypes), "tablet-types", "Tablet types to mirror traffic for.") + mirrorTrafficCommand.Flags().Float32Var(&common.MirrorTrafficOptions.Percent, "percent", 1.0, "Percentage of traffic to mirror.") + base.AddCommand(mirrorTrafficCommand) + switchTrafficCommand := common.GetSwitchTrafficCommand(opts) common.AddCommonSwitchTrafficFlags(switchTrafficCommand, true) common.AddShardSubsetFlag(switchTrafficCommand, &common.SwitchTrafficOptions.Shards) diff --git a/go/flags/endtoend/vtctldclient.txt b/go/flags/endtoend/vtctldclient.txt index 393b9ada10d..89d12e3545d 100644 --- a/go/flags/endtoend/vtctldclient.txt +++ b/go/flags/endtoend/vtctldclient.txt @@ -12,6 +12,7 @@ Available Commands: AddCellInfo Registers a local topology service in a new cell by creating the CellInfo. AddCellsAlias Defines a group of cells that can be referenced by a single name (the alias). ApplyKeyspaceRoutingRules Applies the provided keyspace routing rules. + ApplyMirrorRules Applies the VSchema mirror rules. ApplyRoutingRules Applies the VSchema routing rules. ApplySchema Applies the schema change to the specified keyspace on every primary, running in parallel on all shards. The changes are then propagated to replicas via replication. ApplyShardRoutingRules Applies the provided shard routing rules. @@ -42,6 +43,7 @@ Available Commands: GetKeyspace Returns information about the given keyspace from the topology. GetKeyspaceRoutingRules Displays the currently active keyspace routing rules. GetKeyspaces Returns information about every keyspace in the topology. + GetMirrorRules Displays the VSchema mirror rules. GetPermissions Displays the permissions for a tablet. GetRoutingRules Displays the VSchema routing rules. GetSchema Displays the full schema for a tablet, optionally restricted to the specified tables/views. diff --git a/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go b/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go new file mode 100644 index 00000000000..1c6d24ef721 --- /dev/null +++ b/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go @@ -0,0 +1,116 @@ +/* +Copyright 2022 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vreplication + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + "vitess.io/vitess/go/vt/topo/topoproto" +) + +func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { + setSidecarDBName("_vt") + vc = setupMinimalCluster(t) + defer vc.TearDown() + + sourceKeyspace := "product" + targetKeyspace := "customer" + workflowName := "wf1" + + _ = setupMinimalCustomerKeyspace(t) + + mt := newMoveTables(vc, &moveTablesWorkflow{ + workflowInfo: &workflowInfo{ + vc: vc, + workflowName: workflowName, + targetKeyspace: targetKeyspace, + }, + sourceKeyspace: sourceKeyspace, + tables: "customer,loadtest,customer2", + mirrorFlags: []string{"--percent", "25"}, + }, flavor) + + mt.Create() + confirmNoMirrorRules(t) + + waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) + + mt.MirrorTraffic() + confirmMirrorRulesExist(t) + + // Each table should have a mirror rule for each serving type. + mirrorRules := getMirrorRules(t) + require.Len(t, mirrorRules.Rules, 9) + fromTableToRule := make(map[string]*vschemapb.MirrorRule) + for _, rule := range mirrorRules.Rules { + fromTableToRule[rule.FromTable] = rule + } + for _, table := range []string{"customer", "loadtest", "customer2"} { + for _, tabletType := range []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + } { + fromTable := fmt.Sprintf("%s.%s", sourceKeyspace, table) + if tabletType != topodatapb.TabletType_PRIMARY { + fromTable = fmt.Sprintf("%s@%s", fromTable, topoproto.TabletTypeLString(tabletType)) + } + require.Contains(t, fromTableToRule, fromTable) + require.Equal(t, fmt.Sprintf("%s.%s", targetKeyspace, table), fromTableToRule[fromTable].ToTable) + require.Equal(t, float32(25), fromTableToRule[fromTable].Percent) + } + } + + lg := newLoadGenerator(t, vc) + go func() { + lg.start() + }() + lg.waitForCount(1000) + + mt.SwitchReads() + confirmMirrorRulesExist(t) + + // Each table should only have a mirror rule for primary serving type. + mirrorRules = getMirrorRules(t) + require.Len(t, mirrorRules.Rules, 3) + fromTableToRule = make(map[string]*vschemapb.MirrorRule) + for _, rule := range mirrorRules.Rules { + fromTableToRule[rule.FromTable] = rule + } + for _, table := range []string{"customer", "loadtest", "customer2"} { + fromTable := fmt.Sprintf("%s.%s", sourceKeyspace, table) + require.Contains(t, fromTableToRule, fromTable) + require.Equal(t, fmt.Sprintf("%s.%s", targetKeyspace, table), fromTableToRule[fromTable].ToTable) + require.Equal(t, float32(25), fromTableToRule[fromTable].Percent) + } + + mt.SwitchWrites() + confirmNoMirrorRules(t) +} + +func TestMoveTablesMirrorTraffic(t *testing.T) { + currentWorkflowType = binlogdatapb.VReplicationWorkflowType_MoveTables + t.Run(workflowFlavorNames[workflowFlavorVtctld], func(t *testing.T) { + testMoveTablesMirrorTraffic(t, workflowFlavorVtctld) + }) +} diff --git a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go index 34a4b269b53..07b38940852 100644 --- a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go +++ b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go @@ -52,6 +52,7 @@ const ( const ( workflowActionCreate = "Create" + workflowActionMirrorTraffic = "Mirror" workflowActionSwitchTraffic = "SwitchTraffic" workflowActionReverseTraffic = "ReverseTraffic" workflowActionComplete = "Complete" @@ -70,6 +71,7 @@ type workflowExecOptions struct { deferSecondaryKeys bool atomicCopy bool shardSubset string + percent float32 } var defaultWorkflowExecOptions = &workflowExecOptions{ @@ -222,6 +224,8 @@ func tstWorkflowExecVtctl(t *testing.T, cells, workflow, sourceKs, targetKs, tab } args = append(args, "--initialize-target-sequences") // Only used for MoveTables } + case workflowActionMirrorTraffic: + args = append(args, "--percent", strconv.FormatFloat(float64(options.percent), byte('f'), -1, 32)) default: if options.shardSubset != "" { args = append(args, "--shards", options.shardSubset) diff --git a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go index bca51512a3c..90822a2835c 100644 --- a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go +++ b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go @@ -390,6 +390,25 @@ func checkTablesExist(t *testing.T, tabletAlias string, tables []string) bool { return true } +func getMirrorRules(t *testing.T) *vschemapb.MirrorRules { + mirrorRules, err := vc.VtctldClient.ExecuteCommandWithOutput("GetMirrorRules") + require.NoError(t, err) + var mirrorRulesResponse vschemapb.MirrorRules + err = protojson.Unmarshal([]byte(mirrorRules), &mirrorRulesResponse) + require.NoError(t, err) + return &mirrorRulesResponse +} + +func confirmNoMirrorRules(t *testing.T) { + mirrorRulesResponse := getMirrorRules(t) + require.Zero(t, len(mirrorRulesResponse.Rules)) +} + +func confirmMirrorRulesExist(t *testing.T) { + mirrorRulesResponse := getMirrorRules(t) + require.NotZero(t, len(mirrorRulesResponse.Rules)) +} + func getRoutingRules(t *testing.T) *vschemapb.RoutingRules { routingRules, err := vc.VtctldClient.ExecuteCommandWithOutput("GetRoutingRules") require.NoError(t, err) diff --git a/go/test/endtoend/vreplication/wrappers_test.go b/go/test/endtoend/vreplication/wrappers_test.go index e1028fafa9f..96c54b89fe8 100644 --- a/go/test/endtoend/vreplication/wrappers_test.go +++ b/go/test/endtoend/vreplication/wrappers_test.go @@ -29,6 +29,7 @@ import ( type iWorkflow interface { Create() Show() + MirrorTraffic() SwitchReads() SwitchWrites() SwitchReadsAndWrites() @@ -79,6 +80,7 @@ type moveTablesWorkflow struct { lastOutput string createFlags []string completeFlags []string + mirrorFlags []string switchFlags []string showFlags []string } @@ -122,6 +124,11 @@ func (vmt *VtctlMoveTables) Create() { vmt.exec(workflowActionCreate) } +func (vmt *VtctlMoveTables) MirrorTraffic() { + // TODO implement me + panic("implement me") +} + func (vmt *VtctlMoveTables) SwitchReadsAndWrites() { err := tstWorkflowExecVtctl(vmt.vc.t, "", vmt.workflowName, vmt.sourceKeyspace, vmt.targetKeyspace, vmt.tables, workflowActionSwitchTraffic, "", "", "", defaultWorkflowExecOptions) @@ -218,6 +225,12 @@ func (v VtctldMoveTables) Create() { v.exec(args...) } +func (v VtctldMoveTables) MirrorTraffic() { + args := []string{"MirrorTraffic"} + args = append(args, v.mirrorFlags...) + v.exec(args...) +} + func (v VtctldMoveTables) SwitchReadsAndWrites() { args := []string{"SwitchTraffic"} args = append(args, v.switchFlags...) @@ -323,6 +336,11 @@ func (vrs *VtctlReshard) Create() { vrs.exec(workflowActionCreate) } +func (vrs *VtctlReshard) MirrorTraffic() { + // TODO implement me + panic("implement me") +} + func (vrs *VtctlReshard) SwitchReadsAndWrites() { vrs.exec(workflowActionSwitchTraffic) } @@ -411,6 +429,11 @@ func (v VtctldReshard) Create() { v.exec(args...) } +func (v VtctldReshard) MirrorTraffic() { + // TODO implement me + panic("implement me") +} + func (v VtctldReshard) SwitchReadsAndWrites() { args := []string{"SwitchTraffic"} args = append(args, v.switchFlags...) diff --git a/go/vt/proto/vschema/vschema.pb.go b/go/vt/proto/vschema/vschema.pb.go index 10ef8c1296b..7e6c0633e35 100644 --- a/go/vt/proto/vschema/vschema.pb.go +++ b/go/vt/proto/vschema/vschema.pb.go @@ -784,6 +784,7 @@ type SrvVSchema struct { RoutingRules *RoutingRules `protobuf:"bytes,2,opt,name=routing_rules,json=routingRules,proto3" json:"routing_rules,omitempty"` // table routing rules ShardRoutingRules *ShardRoutingRules `protobuf:"bytes,3,opt,name=shard_routing_rules,json=shardRoutingRules,proto3" json:"shard_routing_rules,omitempty"` KeyspaceRoutingRules *KeyspaceRoutingRules `protobuf:"bytes,4,opt,name=keyspace_routing_rules,json=keyspaceRoutingRules,proto3" json:"keyspace_routing_rules,omitempty"` + MirrorRules *MirrorRules `protobuf:"bytes,5,opt,name=mirror_rules,json=mirrorRules,proto3" json:"mirror_rules,omitempty"` // mirror rules } func (x *SrvVSchema) Reset() { @@ -846,6 +847,13 @@ func (x *SrvVSchema) GetKeyspaceRoutingRules() *KeyspaceRoutingRules { return nil } +func (x *SrvVSchema) GetMirrorRules() *MirrorRules { + if x != nil { + return x.MirrorRules + } + return nil +} + // ShardRoutingRules specify the shard routing rules for the VSchema. type ShardRoutingRules struct { state protoimpl.MessageState @@ -1060,6 +1068,121 @@ func (x *KeyspaceRoutingRule) GetToKeyspace() string { return "" } +// MirrorRules specify the high level mirror rules for the VSchema. +type MirrorRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // rules should ideally be a map. However protos dont't allow + // repeated fields as elements of a map. So, we use a list + // instead. + Rules []*MirrorRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` +} + +func (x *MirrorRules) Reset() { + *x = MirrorRules{} + if protoimpl.UnsafeEnabled { + mi := &file_vschema_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MirrorRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MirrorRules) ProtoMessage() {} + +func (x *MirrorRules) ProtoReflect() protoreflect.Message { + mi := &file_vschema_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MirrorRules.ProtoReflect.Descriptor instead. +func (*MirrorRules) Descriptor() ([]byte, []int) { + return file_vschema_proto_rawDescGZIP(), []int{14} +} + +func (x *MirrorRules) GetRules() []*MirrorRule { + if x != nil { + return x.Rules + } + return nil +} + +// MirrorRule specifies a mirror rule. +type MirrorRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromTable string `protobuf:"bytes,1,opt,name=from_table,json=fromTable,proto3" json:"from_table,omitempty"` + ToTable string `protobuf:"bytes,2,opt,name=to_table,json=toTable,proto3" json:"to_table,omitempty"` + Percent float32 `protobuf:"fixed32,3,opt,name=percent,proto3" json:"percent,omitempty"` +} + +func (x *MirrorRule) Reset() { + *x = MirrorRule{} + if protoimpl.UnsafeEnabled { + mi := &file_vschema_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MirrorRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MirrorRule) ProtoMessage() {} + +func (x *MirrorRule) ProtoReflect() protoreflect.Message { + mi := &file_vschema_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MirrorRule.ProtoReflect.Descriptor instead. +func (*MirrorRule) Descriptor() ([]byte, []int) { + return file_vschema_proto_rawDescGZIP(), []int{15} +} + +func (x *MirrorRule) GetFromTable() string { + if x != nil { + return x.FromTable + } + return "" +} + +func (x *MirrorRule) GetToTable() string { + if x != nil { + return x.ToTable + } + return "" +} + +func (x *MirrorRule) GetPercent() float32 { + if x != nil { + return x.Percent + } + return 0 +} + var File_vschema_proto protoreflect.FileDescriptor var file_vschema_proto_rawDesc = []byte{ @@ -1175,7 +1298,7 @@ var file_vschema_proto_rawDesc = []byte{ 0x00, 0x52, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x61, - 0x62, 0x6c, 0x65, 0x22, 0xfc, 0x02, 0x0a, 0x0a, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, + 0x62, 0x6c, 0x65, 0x22, 0xb5, 0x03, 0x0a, 0x0a, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x40, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, @@ -1194,37 +1317,50 @@ var file_vschema_proto_rawDesc = []byte{ 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x14, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x73, 0x1a, 0x4f, 0x0a, 0x0e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x44, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x4a, 0x0a, 0x14, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, - 0x12, 0x32, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x13, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, - 0x72, 0x6f, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x42, 0x26, 0x5a, 0x24, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, - 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x75, 0x6c, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0b, 0x6d, + 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x4f, 0x0a, 0x0e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x27, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, 0x0a, 0x11, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x12, 0x2f, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, + 0x73, 0x22, 0x6e, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, + 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x22, 0x4a, 0x0a, 0x14, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x05, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x5b, 0x0a, + 0x13, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x72, 0x6f, + 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x5f, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x38, 0x0a, 0x0b, 0x4d, 0x69, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, + 0x75, 0x6c, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x0a, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, + 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6f, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x6f, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, 0x70, + 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x42, 0x26, 0x5a, 0x24, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, + 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1240,7 +1376,7 @@ func file_vschema_proto_rawDescGZIP() []byte { } var file_vschema_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_vschema_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_vschema_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_vschema_proto_goTypes = []interface{}{ (Keyspace_ForeignKeyMode)(0), // 0: vschema.Keyspace.ForeignKeyMode (*RoutingRules)(nil), // 1: vschema.RoutingRules @@ -1257,38 +1393,42 @@ var file_vschema_proto_goTypes = []interface{}{ (*ShardRoutingRule)(nil), // 12: vschema.ShardRoutingRule (*KeyspaceRoutingRules)(nil), // 13: vschema.KeyspaceRoutingRules (*KeyspaceRoutingRule)(nil), // 14: vschema.KeyspaceRoutingRule - nil, // 15: vschema.Keyspace.VindexesEntry - nil, // 16: vschema.Keyspace.TablesEntry - nil, // 17: vschema.Vindex.ParamsEntry - nil, // 18: vschema.SrvVSchema.KeyspacesEntry - (query.Type)(0), // 19: query.Type + (*MirrorRules)(nil), // 15: vschema.MirrorRules + (*MirrorRule)(nil), // 16: vschema.MirrorRule + nil, // 17: vschema.Keyspace.VindexesEntry + nil, // 18: vschema.Keyspace.TablesEntry + nil, // 19: vschema.Vindex.ParamsEntry + nil, // 20: vschema.SrvVSchema.KeyspacesEntry + (query.Type)(0), // 21: query.Type } var file_vschema_proto_depIdxs = []int32{ 2, // 0: vschema.RoutingRules.rules:type_name -> vschema.RoutingRule - 15, // 1: vschema.Keyspace.vindexes:type_name -> vschema.Keyspace.VindexesEntry - 16, // 2: vschema.Keyspace.tables:type_name -> vschema.Keyspace.TablesEntry + 17, // 1: vschema.Keyspace.vindexes:type_name -> vschema.Keyspace.VindexesEntry + 18, // 2: vschema.Keyspace.tables:type_name -> vschema.Keyspace.TablesEntry 0, // 3: vschema.Keyspace.foreign_key_mode:type_name -> vschema.Keyspace.ForeignKeyMode 4, // 4: vschema.Keyspace.multi_tenant_spec:type_name -> vschema.MultiTenantSpec - 19, // 5: vschema.MultiTenantSpec.tenant_id_column_type:type_name -> query.Type - 17, // 6: vschema.Vindex.params:type_name -> vschema.Vindex.ParamsEntry + 21, // 5: vschema.MultiTenantSpec.tenant_id_column_type:type_name -> query.Type + 19, // 6: vschema.Vindex.params:type_name -> vschema.Vindex.ParamsEntry 7, // 7: vschema.Table.column_vindexes:type_name -> vschema.ColumnVindex 8, // 8: vschema.Table.auto_increment:type_name -> vschema.AutoIncrement 9, // 9: vschema.Table.columns:type_name -> vschema.Column - 19, // 10: vschema.Column.type:type_name -> query.Type - 18, // 11: vschema.SrvVSchema.keyspaces:type_name -> vschema.SrvVSchema.KeyspacesEntry + 21, // 10: vschema.Column.type:type_name -> query.Type + 20, // 11: vschema.SrvVSchema.keyspaces:type_name -> vschema.SrvVSchema.KeyspacesEntry 1, // 12: vschema.SrvVSchema.routing_rules:type_name -> vschema.RoutingRules 11, // 13: vschema.SrvVSchema.shard_routing_rules:type_name -> vschema.ShardRoutingRules 13, // 14: vschema.SrvVSchema.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 12, // 15: vschema.ShardRoutingRules.rules:type_name -> vschema.ShardRoutingRule - 14, // 16: vschema.KeyspaceRoutingRules.rules:type_name -> vschema.KeyspaceRoutingRule - 5, // 17: vschema.Keyspace.VindexesEntry.value:type_name -> vschema.Vindex - 6, // 18: vschema.Keyspace.TablesEntry.value:type_name -> vschema.Table - 3, // 19: vschema.SrvVSchema.KeyspacesEntry.value:type_name -> vschema.Keyspace - 20, // [20:20] is the sub-list for method output_type - 20, // [20:20] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 15, // 15: vschema.SrvVSchema.mirror_rules:type_name -> vschema.MirrorRules + 12, // 16: vschema.ShardRoutingRules.rules:type_name -> vschema.ShardRoutingRule + 14, // 17: vschema.KeyspaceRoutingRules.rules:type_name -> vschema.KeyspaceRoutingRule + 16, // 18: vschema.MirrorRules.rules:type_name -> vschema.MirrorRule + 5, // 19: vschema.Keyspace.VindexesEntry.value:type_name -> vschema.Vindex + 6, // 20: vschema.Keyspace.TablesEntry.value:type_name -> vschema.Table + 3, // 21: vschema.SrvVSchema.KeyspacesEntry.value:type_name -> vschema.Keyspace + 22, // [22:22] is the sub-list for method output_type + 22, // [22:22] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_vschema_proto_init() } @@ -1465,6 +1605,30 @@ func file_vschema_proto_init() { return nil } } + file_vschema_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MirrorRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vschema_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MirrorRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_vschema_proto_msgTypes[8].OneofWrappers = []interface{}{} type x struct{} @@ -1473,7 +1637,7 @@ func file_vschema_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vschema_proto_rawDesc, NumEnums: 1, - NumMessages: 18, + NumMessages: 20, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/vschema/vschema_vtproto.pb.go b/go/vt/proto/vschema/vschema_vtproto.pb.go index 8cf523f4009..1951f430a15 100644 --- a/go/vt/proto/vschema/vschema_vtproto.pb.go +++ b/go/vt/proto/vschema/vschema_vtproto.pb.go @@ -5,10 +5,12 @@ package vschema import ( + binary "encoding/binary" fmt "fmt" proto "google.golang.org/protobuf/proto" protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" + math "math" bits "math/bits" query "vitess.io/vitess/go/vt/proto/query" ) @@ -266,6 +268,7 @@ func (m *SrvVSchema) CloneVT() *SrvVSchema { RoutingRules: m.RoutingRules.CloneVT(), ShardRoutingRules: m.ShardRoutingRules.CloneVT(), KeyspaceRoutingRules: m.KeyspaceRoutingRules.CloneVT(), + MirrorRules: m.MirrorRules.CloneVT(), } if rhs := m.Keyspaces; rhs != nil { tmpContainer := make(map[string]*Keyspace, len(rhs)) @@ -370,6 +373,49 @@ func (m *KeyspaceRoutingRule) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *MirrorRules) CloneVT() *MirrorRules { + if m == nil { + return (*MirrorRules)(nil) + } + r := &MirrorRules{} + if rhs := m.Rules; rhs != nil { + tmpContainer := make([]*MirrorRule, len(rhs)) + for k, v := range rhs { + tmpContainer[k] = v.CloneVT() + } + r.Rules = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *MirrorRules) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *MirrorRule) CloneVT() *MirrorRule { + if m == nil { + return (*MirrorRule)(nil) + } + r := &MirrorRule{ + FromTable: m.FromTable, + ToTable: m.ToTable, + Percent: m.Percent, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *MirrorRule) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *RoutingRules) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1016,6 +1062,16 @@ func (m *SrvVSchema) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.MirrorRules != nil { + size, err := m.MirrorRules.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } if m.KeyspaceRoutingRules != nil { size, err := m.KeyspaceRoutingRules.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -1262,6 +1318,104 @@ func (m *KeyspaceRoutingRule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *MirrorRules) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MirrorRules) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *MirrorRules) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Rules) > 0 { + for iNdEx := len(m.Rules) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Rules[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *MirrorRule) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MirrorRule) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *MirrorRule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Percent != 0 { + i -= 4 + binary.LittleEndian.PutUint32(dAtA[i:], uint32(math.Float32bits(float32(m.Percent)))) + i-- + dAtA[i] = 0x1d + } + if len(m.ToTable) > 0 { + i -= len(m.ToTable) + copy(dAtA[i:], m.ToTable) + i = encodeVarint(dAtA, i, uint64(len(m.ToTable))) + i-- + dAtA[i] = 0x12 + } + if len(m.FromTable) > 0 { + i -= len(m.FromTable) + copy(dAtA[i:], m.FromTable) + i = encodeVarint(dAtA, i, uint64(len(m.FromTable))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarint(dAtA []byte, offset int, v uint64) int { offset -= sov(v) base := offset @@ -1558,6 +1712,10 @@ func (m *SrvVSchema) SizeVT() (n int) { l = m.KeyspaceRoutingRules.SizeVT() n += 1 + l + sov(uint64(l)) } + if m.MirrorRules != nil { + l = m.MirrorRules.SizeVT() + n += 1 + l + sov(uint64(l)) + } n += len(m.unknownFields) return n } @@ -1634,6 +1792,43 @@ func (m *KeyspaceRoutingRule) SizeVT() (n int) { return n } +func (m *MirrorRules) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Rules) > 0 { + for _, e := range m.Rules { + l = e.SizeVT() + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *MirrorRule) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FromTable) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.ToTable) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.Percent != 0 { + n += 5 + } + n += len(m.unknownFields) + return n +} + func sov(x uint64) (n int) { return (bits.Len64(x|1) + 6) / 7 } @@ -3664,6 +3859,42 @@ func (m *SrvVSchema) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MirrorRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MirrorRules == nil { + m.MirrorRules = &MirrorRules{} + } + if err := m.MirrorRules.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) @@ -4118,6 +4349,217 @@ func (m *KeyspaceRoutingRule) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *MirrorRules) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MirrorRules: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MirrorRules: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Rules = append(m.Rules, &MirrorRule{}) + if err := m.Rules[len(m.Rules)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MirrorRule) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MirrorRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MirrorRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromTable", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FromTable = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ToTable", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ToTable = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 5 { + return fmt.Errorf("proto: wrong wireType = %d for field Percent", wireType) + } + var v uint32 + if (iNdEx + 4) > l { + return io.ErrUnexpectedEOF + } + v = uint32(binary.LittleEndian.Uint32(dAtA[iNdEx:])) + iNdEx += 4 + m.Percent = float32(math.Float32frombits(v)) + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skip(dAtA []byte) (n int, err error) { l := len(dAtA) diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 06f600f4cf5..7398d7a542d 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -15082,6 +15082,332 @@ func (x *WorkflowUpdateResponse) GetDetails() []*WorkflowUpdateResponse_TabletIn return nil } +type ApplyMirrorRulesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MirrorRules *vschema.MirrorRules `protobuf:"bytes,1,opt,name=mirror_rules,json=mirrorRules,proto3" json:"mirror_rules,omitempty"` + // SkipRebuild, if set, will cause ApplyRoutingRules to skip rebuilding the + // SrvVSchema objects in each cell in RebuildCells. + SkipRebuild bool `protobuf:"varint,2,opt,name=skip_rebuild,json=skipRebuild,proto3" json:"skip_rebuild,omitempty"` + // RebuildCells limits the SrvVSchema rebuild to the specified cells. If not + // provided the SrvVSchema will be rebuilt in every cell in the topology. + // + // Ignored if SkipRebuild is set. + RebuildCells []string `protobuf:"bytes,3,rep,name=rebuild_cells,json=rebuildCells,proto3" json:"rebuild_cells,omitempty"` +} + +func (x *ApplyMirrorRulesRequest) Reset() { + *x = ApplyMirrorRulesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[241] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyMirrorRulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyMirrorRulesRequest) ProtoMessage() {} + +func (x *ApplyMirrorRulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[241] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyMirrorRulesRequest.ProtoReflect.Descriptor instead. +func (*ApplyMirrorRulesRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{241} +} + +func (x *ApplyMirrorRulesRequest) GetMirrorRules() *vschema.MirrorRules { + if x != nil { + return x.MirrorRules + } + return nil +} + +func (x *ApplyMirrorRulesRequest) GetSkipRebuild() bool { + if x != nil { + return x.SkipRebuild + } + return false +} + +func (x *ApplyMirrorRulesRequest) GetRebuildCells() []string { + if x != nil { + return x.RebuildCells + } + return nil +} + +type ApplyMirrorRulesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ApplyMirrorRulesResponse) Reset() { + *x = ApplyMirrorRulesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[242] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyMirrorRulesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyMirrorRulesResponse) ProtoMessage() {} + +func (x *ApplyMirrorRulesResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[242] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyMirrorRulesResponse.ProtoReflect.Descriptor instead. +func (*ApplyMirrorRulesResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{242} +} + +type GetMirrorRulesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetMirrorRulesRequest) Reset() { + *x = GetMirrorRulesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[243] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMirrorRulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMirrorRulesRequest) ProtoMessage() {} + +func (x *GetMirrorRulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[243] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMirrorRulesRequest.ProtoReflect.Descriptor instead. +func (*GetMirrorRulesRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{243} +} + +type GetMirrorRulesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MirrorRules *vschema.MirrorRules `protobuf:"bytes,1,opt,name=mirror_rules,json=mirrorRules,proto3" json:"mirror_rules,omitempty"` +} + +func (x *GetMirrorRulesResponse) Reset() { + *x = GetMirrorRulesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[244] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetMirrorRulesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetMirrorRulesResponse) ProtoMessage() {} + +func (x *GetMirrorRulesResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[244] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetMirrorRulesResponse.ProtoReflect.Descriptor instead. +func (*GetMirrorRulesResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{244} +} + +func (x *GetMirrorRulesResponse) GetMirrorRules() *vschema.MirrorRules { + if x != nil { + return x.MirrorRules + } + return nil +} + +type WorkflowMirrorTrafficRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Workflow string `protobuf:"bytes,2,opt,name=workflow,proto3" json:"workflow,omitempty"` + TabletTypes []topodata.TabletType `protobuf:"varint,3,rep,packed,name=tablet_types,json=tabletTypes,proto3,enum=topodata.TabletType" json:"tablet_types,omitempty"` + Percent float32 `protobuf:"fixed32,4,opt,name=percent,proto3" json:"percent,omitempty"` +} + +func (x *WorkflowMirrorTrafficRequest) Reset() { + *x = WorkflowMirrorTrafficRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[245] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkflowMirrorTrafficRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkflowMirrorTrafficRequest) ProtoMessage() {} + +func (x *WorkflowMirrorTrafficRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[245] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkflowMirrorTrafficRequest.ProtoReflect.Descriptor instead. +func (*WorkflowMirrorTrafficRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{245} +} + +func (x *WorkflowMirrorTrafficRequest) GetKeyspace() string { + if x != nil { + return x.Keyspace + } + return "" +} + +func (x *WorkflowMirrorTrafficRequest) GetWorkflow() string { + if x != nil { + return x.Workflow + } + return "" +} + +func (x *WorkflowMirrorTrafficRequest) GetTabletTypes() []topodata.TabletType { + if x != nil { + return x.TabletTypes + } + return nil +} + +func (x *WorkflowMirrorTrafficRequest) GetPercent() float32 { + if x != nil { + return x.Percent + } + return 0 +} + +type WorkflowMirrorTrafficResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Summary string `protobuf:"bytes,1,opt,name=summary,proto3" json:"summary,omitempty"` + StartState string `protobuf:"bytes,2,opt,name=start_state,json=startState,proto3" json:"start_state,omitempty"` + CurrentState string `protobuf:"bytes,3,opt,name=current_state,json=currentState,proto3" json:"current_state,omitempty"` +} + +func (x *WorkflowMirrorTrafficResponse) Reset() { + *x = WorkflowMirrorTrafficResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[246] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkflowMirrorTrafficResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkflowMirrorTrafficResponse) ProtoMessage() {} + +func (x *WorkflowMirrorTrafficResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[246] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkflowMirrorTrafficResponse.ProtoReflect.Descriptor instead. +func (*WorkflowMirrorTrafficResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{246} +} + +func (x *WorkflowMirrorTrafficResponse) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *WorkflowMirrorTrafficResponse) GetStartState() string { + if x != nil { + return x.StartState + } + return "" +} + +func (x *WorkflowMirrorTrafficResponse) GetCurrentState() string { + if x != nil { + return x.CurrentState + } + return "" +} + type Workflow_ReplicationLocation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -15094,7 +15420,7 @@ type Workflow_ReplicationLocation struct { func (x *Workflow_ReplicationLocation) Reset() { *x = Workflow_ReplicationLocation{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[242] + mi := &file_vtctldata_proto_msgTypes[248] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15107,7 +15433,7 @@ func (x *Workflow_ReplicationLocation) String() string { func (*Workflow_ReplicationLocation) ProtoMessage() {} func (x *Workflow_ReplicationLocation) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[242] + mi := &file_vtctldata_proto_msgTypes[248] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15150,7 +15476,7 @@ type Workflow_ShardStream struct { func (x *Workflow_ShardStream) Reset() { *x = Workflow_ShardStream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[243] + mi := &file_vtctldata_proto_msgTypes[249] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15163,7 +15489,7 @@ func (x *Workflow_ShardStream) String() string { func (*Workflow_ShardStream) ProtoMessage() {} func (x *Workflow_ShardStream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[243] + mi := &file_vtctldata_proto_msgTypes[249] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15238,7 +15564,7 @@ type Workflow_Stream struct { func (x *Workflow_Stream) Reset() { *x = Workflow_Stream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[244] + mi := &file_vtctldata_proto_msgTypes[250] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15251,7 +15577,7 @@ func (x *Workflow_Stream) String() string { func (*Workflow_Stream) ProtoMessage() {} func (x *Workflow_Stream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[244] + mi := &file_vtctldata_proto_msgTypes[250] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15420,7 +15746,7 @@ type Workflow_Stream_CopyState struct { func (x *Workflow_Stream_CopyState) Reset() { *x = Workflow_Stream_CopyState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[245] + mi := &file_vtctldata_proto_msgTypes[251] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15433,7 +15759,7 @@ func (x *Workflow_Stream_CopyState) String() string { func (*Workflow_Stream_CopyState) ProtoMessage() {} func (x *Workflow_Stream_CopyState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[245] + mi := &file_vtctldata_proto_msgTypes[251] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15488,7 +15814,7 @@ type Workflow_Stream_Log struct { func (x *Workflow_Stream_Log) Reset() { *x = Workflow_Stream_Log{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[246] + mi := &file_vtctldata_proto_msgTypes[252] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15501,7 +15827,7 @@ func (x *Workflow_Stream_Log) String() string { func (*Workflow_Stream_Log) ProtoMessage() {} func (x *Workflow_Stream_Log) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[246] + mi := &file_vtctldata_proto_msgTypes[252] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15585,7 +15911,7 @@ type Workflow_Stream_ThrottlerStatus struct { func (x *Workflow_Stream_ThrottlerStatus) Reset() { *x = Workflow_Stream_ThrottlerStatus{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[247] + mi := &file_vtctldata_proto_msgTypes[253] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15598,7 +15924,7 @@ func (x *Workflow_Stream_ThrottlerStatus) String() string { func (*Workflow_Stream_ThrottlerStatus) ProtoMessage() {} func (x *Workflow_Stream_ThrottlerStatus) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[247] + mi := &file_vtctldata_proto_msgTypes[253] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15639,7 +15965,7 @@ type ApplyVSchemaResponse_ParamList struct { func (x *ApplyVSchemaResponse_ParamList) Reset() { *x = ApplyVSchemaResponse_ParamList{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[250] + mi := &file_vtctldata_proto_msgTypes[256] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15652,7 +15978,7 @@ func (x *ApplyVSchemaResponse_ParamList) String() string { func (*ApplyVSchemaResponse_ParamList) ProtoMessage() {} func (x *ApplyVSchemaResponse_ParamList) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[250] + mi := &file_vtctldata_proto_msgTypes[256] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15686,7 +16012,7 @@ type GetSrvKeyspaceNamesResponse_NameList struct { func (x *GetSrvKeyspaceNamesResponse_NameList) Reset() { *x = GetSrvKeyspaceNamesResponse_NameList{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[259] + mi := &file_vtctldata_proto_msgTypes[265] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15699,7 +16025,7 @@ func (x *GetSrvKeyspaceNamesResponse_NameList) String() string { func (*GetSrvKeyspaceNamesResponse_NameList) ProtoMessage() {} func (x *GetSrvKeyspaceNamesResponse_NameList) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[259] + mi := &file_vtctldata_proto_msgTypes[265] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15735,7 +16061,7 @@ type MoveTablesCreateResponse_TabletInfo struct { func (x *MoveTablesCreateResponse_TabletInfo) Reset() { *x = MoveTablesCreateResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[263] + mi := &file_vtctldata_proto_msgTypes[269] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15748,7 +16074,7 @@ func (x *MoveTablesCreateResponse_TabletInfo) String() string { func (*MoveTablesCreateResponse_TabletInfo) ProtoMessage() {} func (x *MoveTablesCreateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[263] + mi := &file_vtctldata_proto_msgTypes[269] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15791,7 +16117,7 @@ type WorkflowDeleteResponse_TabletInfo struct { func (x *WorkflowDeleteResponse_TabletInfo) Reset() { *x = WorkflowDeleteResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[273] + mi := &file_vtctldata_proto_msgTypes[279] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15804,7 +16130,7 @@ func (x *WorkflowDeleteResponse_TabletInfo) String() string { func (*WorkflowDeleteResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowDeleteResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[273] + mi := &file_vtctldata_proto_msgTypes[279] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15850,7 +16176,7 @@ type WorkflowStatusResponse_TableCopyState struct { func (x *WorkflowStatusResponse_TableCopyState) Reset() { *x = WorkflowStatusResponse_TableCopyState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[274] + mi := &file_vtctldata_proto_msgTypes[280] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15863,7 +16189,7 @@ func (x *WorkflowStatusResponse_TableCopyState) String() string { func (*WorkflowStatusResponse_TableCopyState) ProtoMessage() {} func (x *WorkflowStatusResponse_TableCopyState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[274] + mi := &file_vtctldata_proto_msgTypes[280] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15937,7 +16263,7 @@ type WorkflowStatusResponse_ShardStreamState struct { func (x *WorkflowStatusResponse_ShardStreamState) Reset() { *x = WorkflowStatusResponse_ShardStreamState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[275] + mi := &file_vtctldata_proto_msgTypes[281] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15950,7 +16276,7 @@ func (x *WorkflowStatusResponse_ShardStreamState) String() string { func (*WorkflowStatusResponse_ShardStreamState) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreamState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[275] + mi := &file_vtctldata_proto_msgTypes[281] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16019,7 +16345,7 @@ type WorkflowStatusResponse_ShardStreams struct { func (x *WorkflowStatusResponse_ShardStreams) Reset() { *x = WorkflowStatusResponse_ShardStreams{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[276] + mi := &file_vtctldata_proto_msgTypes[282] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16032,7 +16358,7 @@ func (x *WorkflowStatusResponse_ShardStreams) String() string { func (*WorkflowStatusResponse_ShardStreams) ProtoMessage() {} func (x *WorkflowStatusResponse_ShardStreams) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[276] + mi := &file_vtctldata_proto_msgTypes[282] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -16069,7 +16395,7 @@ type WorkflowUpdateResponse_TabletInfo struct { func (x *WorkflowUpdateResponse_TabletInfo) Reset() { *x = WorkflowUpdateResponse_TabletInfo{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[279] + mi := &file_vtctldata_proto_msgTypes[285] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -16082,7 +16408,7 @@ func (x *WorkflowUpdateResponse_TabletInfo) String() string { func (*WorkflowUpdateResponse_TabletInfo) ProtoMessage() {} func (x *WorkflowUpdateResponse_TabletInfo) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[279] + mi := &file_vtctldata_proto_msgTypes[285] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -18469,18 +18795,55 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, - 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, - 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, - 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, 0x45, 0x58, - 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, - 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, - 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x42, 0x28, 0x5a, 0x26, - 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, - 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x9a, 0x01, 0x0a, 0x17, 0x41, 0x70, 0x70, 0x6c, 0x79, + 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0b, + 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x23, + 0x0a, 0x0d, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x65, + 0x6c, 0x6c, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x4d, 0x69, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x51, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4d, + 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0b, + 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x1c, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x37, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, + 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x7f, 0x0a, 0x1d, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x4a, 0x0a, 0x15, 0x4d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x00, 0x12, 0x0e, 0x0a, + 0x0a, 0x4d, 0x4f, 0x56, 0x45, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x15, 0x0a, + 0x11, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x4c, 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x49, 0x4e, 0x44, + 0x45, 0x58, 0x10, 0x02, 0x2a, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, + 0x0d, 0x0a, 0x09, 0x41, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, + 0x0a, 0x0a, 0x44, 0x45, 0x53, 0x43, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x42, 0x28, + 0x5a, 0x26, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, + 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -18496,7 +18859,7 @@ func file_vtctldata_proto_rawDescGZIP() []byte { } var file_vtctldata_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 280) +var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 286) var file_vtctldata_proto_goTypes = []interface{}{ (MaterializationIntent)(0), // 0: vtctldata.MaterializationIntent (QueryOrdering)(0), // 1: vtctldata.QueryOrdering @@ -18743,308 +19106,318 @@ var file_vtctldata_proto_goTypes = []interface{}{ (*WorkflowSwitchTrafficResponse)(nil), // 242: vtctldata.WorkflowSwitchTrafficResponse (*WorkflowUpdateRequest)(nil), // 243: vtctldata.WorkflowUpdateRequest (*WorkflowUpdateResponse)(nil), // 244: vtctldata.WorkflowUpdateResponse - nil, // 245: vtctldata.Workflow.ShardStreamsEntry - (*Workflow_ReplicationLocation)(nil), // 246: vtctldata.Workflow.ReplicationLocation - (*Workflow_ShardStream)(nil), // 247: vtctldata.Workflow.ShardStream - (*Workflow_Stream)(nil), // 248: vtctldata.Workflow.Stream - (*Workflow_Stream_CopyState)(nil), // 249: vtctldata.Workflow.Stream.CopyState - (*Workflow_Stream_Log)(nil), // 250: vtctldata.Workflow.Stream.Log - (*Workflow_Stream_ThrottlerStatus)(nil), // 251: vtctldata.Workflow.Stream.ThrottlerStatus - nil, // 252: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - nil, // 253: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry - (*ApplyVSchemaResponse_ParamList)(nil), // 254: vtctldata.ApplyVSchemaResponse.ParamList - nil, // 255: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 256: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 257: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 258: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - nil, // 259: vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 260: vtctldata.GetCellsAliasesResponse.AliasesEntry - nil, // 261: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry - nil, // 262: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 263: vtctldata.GetSrvKeyspaceNamesResponse.NameList - nil, // 264: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - nil, // 265: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - nil, // 266: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - (*MoveTablesCreateResponse_TabletInfo)(nil), // 267: vtctldata.MoveTablesCreateResponse.TabletInfo - nil, // 268: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - nil, // 269: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - nil, // 270: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - nil, // 271: vtctldata.ValidateResponse.ResultsByKeyspaceEntry - nil, // 272: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - nil, // 273: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - nil, // 274: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - nil, // 275: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - nil, // 276: vtctldata.VDiffShowResponse.TabletResponsesEntry - (*WorkflowDeleteResponse_TabletInfo)(nil), // 277: vtctldata.WorkflowDeleteResponse.TabletInfo - (*WorkflowStatusResponse_TableCopyState)(nil), // 278: vtctldata.WorkflowStatusResponse.TableCopyState - (*WorkflowStatusResponse_ShardStreamState)(nil), // 279: vtctldata.WorkflowStatusResponse.ShardStreamState - (*WorkflowStatusResponse_ShardStreams)(nil), // 280: vtctldata.WorkflowStatusResponse.ShardStreams - nil, // 281: vtctldata.WorkflowStatusResponse.TableCopyStateEntry - nil, // 282: vtctldata.WorkflowStatusResponse.ShardStreamsEntry - (*WorkflowUpdateResponse_TabletInfo)(nil), // 283: vtctldata.WorkflowUpdateResponse.TabletInfo - (*logutil.Event)(nil), // 284: logutil.Event - (tabletmanagerdata.TabletSelectionPreference)(0), // 285: tabletmanagerdata.TabletSelectionPreference - (*topodata.Keyspace)(nil), // 286: topodata.Keyspace - (*vttime.Time)(nil), // 287: vttime.Time - (*topodata.TabletAlias)(nil), // 288: topodata.TabletAlias - (*vttime.Duration)(nil), // 289: vttime.Duration - (*topodata.Shard)(nil), // 290: topodata.Shard - (*topodata.CellInfo)(nil), // 291: topodata.CellInfo - (*vschema.KeyspaceRoutingRules)(nil), // 292: vschema.KeyspaceRoutingRules - (*vschema.RoutingRules)(nil), // 293: vschema.RoutingRules - (*vschema.ShardRoutingRules)(nil), // 294: vschema.ShardRoutingRules - (*vtrpc.CallerID)(nil), // 295: vtrpc.CallerID - (*vschema.Keyspace)(nil), // 296: vschema.Keyspace - (topodata.TabletType)(0), // 297: topodata.TabletType - (*topodata.Tablet)(nil), // 298: topodata.Tablet - (topodata.KeyspaceType)(0), // 299: topodata.KeyspaceType - (*query.QueryResult)(nil), // 300: query.QueryResult - (*tabletmanagerdata.ExecuteHookRequest)(nil), // 301: tabletmanagerdata.ExecuteHookRequest - (*tabletmanagerdata.ExecuteHookResponse)(nil), // 302: tabletmanagerdata.ExecuteHookResponse - (*mysqlctl.BackupInfo)(nil), // 303: mysqlctl.BackupInfo - (*replicationdata.FullStatus)(nil), // 304: replicationdata.FullStatus - (*tabletmanagerdata.Permissions)(nil), // 305: tabletmanagerdata.Permissions - (*tabletmanagerdata.SchemaDefinition)(nil), // 306: tabletmanagerdata.SchemaDefinition - (*topodata.ThrottledAppRule)(nil), // 307: topodata.ThrottledAppRule - (*vschema.SrvVSchema)(nil), // 308: vschema.SrvVSchema - (*topodata.ShardReplicationError)(nil), // 309: topodata.ShardReplicationError - (*topodata.KeyRange)(nil), // 310: topodata.KeyRange - (*topodata.CellsAlias)(nil), // 311: topodata.CellsAlias - (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 312: tabletmanagerdata.UpdateVReplicationWorkflowRequest - (*topodata.Shard_TabletControl)(nil), // 313: topodata.Shard.TabletControl - (*binlogdata.BinlogSource)(nil), // 314: binlogdata.BinlogSource - (*topodata.ShardReplication)(nil), // 315: topodata.ShardReplication - (*topodata.SrvKeyspace)(nil), // 316: topodata.SrvKeyspace - (*replicationdata.Status)(nil), // 317: replicationdata.Status - (*tabletmanagerdata.VDiffResponse)(nil), // 318: tabletmanagerdata.VDiffResponse + (*ApplyMirrorRulesRequest)(nil), // 245: vtctldata.ApplyMirrorRulesRequest + (*ApplyMirrorRulesResponse)(nil), // 246: vtctldata.ApplyMirrorRulesResponse + (*GetMirrorRulesRequest)(nil), // 247: vtctldata.GetMirrorRulesRequest + (*GetMirrorRulesResponse)(nil), // 248: vtctldata.GetMirrorRulesResponse + (*WorkflowMirrorTrafficRequest)(nil), // 249: vtctldata.WorkflowMirrorTrafficRequest + (*WorkflowMirrorTrafficResponse)(nil), // 250: vtctldata.WorkflowMirrorTrafficResponse + nil, // 251: vtctldata.Workflow.ShardStreamsEntry + (*Workflow_ReplicationLocation)(nil), // 252: vtctldata.Workflow.ReplicationLocation + (*Workflow_ShardStream)(nil), // 253: vtctldata.Workflow.ShardStream + (*Workflow_Stream)(nil), // 254: vtctldata.Workflow.Stream + (*Workflow_Stream_CopyState)(nil), // 255: vtctldata.Workflow.Stream.CopyState + (*Workflow_Stream_Log)(nil), // 256: vtctldata.Workflow.Stream.Log + (*Workflow_Stream_ThrottlerStatus)(nil), // 257: vtctldata.Workflow.Stream.ThrottlerStatus + nil, // 258: vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + nil, // 259: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry + (*ApplyVSchemaResponse_ParamList)(nil), // 260: vtctldata.ApplyVSchemaResponse.ParamList + nil, // 261: vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 262: vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 263: vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 264: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + nil, // 265: vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 266: vtctldata.GetCellsAliasesResponse.AliasesEntry + nil, // 267: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry + nil, // 268: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + (*GetSrvKeyspaceNamesResponse_NameList)(nil), // 269: vtctldata.GetSrvKeyspaceNamesResponse.NameList + nil, // 270: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + nil, // 271: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + nil, // 272: vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + (*MoveTablesCreateResponse_TabletInfo)(nil), // 273: vtctldata.MoveTablesCreateResponse.TabletInfo + nil, // 274: vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + nil, // 275: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + nil, // 276: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + nil, // 277: vtctldata.ValidateResponse.ResultsByKeyspaceEntry + nil, // 278: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + nil, // 279: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + nil, // 280: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + nil, // 281: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + nil, // 282: vtctldata.VDiffShowResponse.TabletResponsesEntry + (*WorkflowDeleteResponse_TabletInfo)(nil), // 283: vtctldata.WorkflowDeleteResponse.TabletInfo + (*WorkflowStatusResponse_TableCopyState)(nil), // 284: vtctldata.WorkflowStatusResponse.TableCopyState + (*WorkflowStatusResponse_ShardStreamState)(nil), // 285: vtctldata.WorkflowStatusResponse.ShardStreamState + (*WorkflowStatusResponse_ShardStreams)(nil), // 286: vtctldata.WorkflowStatusResponse.ShardStreams + nil, // 287: vtctldata.WorkflowStatusResponse.TableCopyStateEntry + nil, // 288: vtctldata.WorkflowStatusResponse.ShardStreamsEntry + (*WorkflowUpdateResponse_TabletInfo)(nil), // 289: vtctldata.WorkflowUpdateResponse.TabletInfo + (*logutil.Event)(nil), // 290: logutil.Event + (tabletmanagerdata.TabletSelectionPreference)(0), // 291: tabletmanagerdata.TabletSelectionPreference + (*topodata.Keyspace)(nil), // 292: topodata.Keyspace + (*vttime.Time)(nil), // 293: vttime.Time + (*topodata.TabletAlias)(nil), // 294: topodata.TabletAlias + (*vttime.Duration)(nil), // 295: vttime.Duration + (*topodata.Shard)(nil), // 296: topodata.Shard + (*topodata.CellInfo)(nil), // 297: topodata.CellInfo + (*vschema.KeyspaceRoutingRules)(nil), // 298: vschema.KeyspaceRoutingRules + (*vschema.RoutingRules)(nil), // 299: vschema.RoutingRules + (*vschema.ShardRoutingRules)(nil), // 300: vschema.ShardRoutingRules + (*vtrpc.CallerID)(nil), // 301: vtrpc.CallerID + (*vschema.Keyspace)(nil), // 302: vschema.Keyspace + (topodata.TabletType)(0), // 303: topodata.TabletType + (*topodata.Tablet)(nil), // 304: topodata.Tablet + (topodata.KeyspaceType)(0), // 305: topodata.KeyspaceType + (*query.QueryResult)(nil), // 306: query.QueryResult + (*tabletmanagerdata.ExecuteHookRequest)(nil), // 307: tabletmanagerdata.ExecuteHookRequest + (*tabletmanagerdata.ExecuteHookResponse)(nil), // 308: tabletmanagerdata.ExecuteHookResponse + (*mysqlctl.BackupInfo)(nil), // 309: mysqlctl.BackupInfo + (*replicationdata.FullStatus)(nil), // 310: replicationdata.FullStatus + (*tabletmanagerdata.Permissions)(nil), // 311: tabletmanagerdata.Permissions + (*tabletmanagerdata.SchemaDefinition)(nil), // 312: tabletmanagerdata.SchemaDefinition + (*topodata.ThrottledAppRule)(nil), // 313: topodata.ThrottledAppRule + (*vschema.SrvVSchema)(nil), // 314: vschema.SrvVSchema + (*topodata.ShardReplicationError)(nil), // 315: topodata.ShardReplicationError + (*topodata.KeyRange)(nil), // 316: topodata.KeyRange + (*topodata.CellsAlias)(nil), // 317: topodata.CellsAlias + (*tabletmanagerdata.UpdateVReplicationWorkflowRequest)(nil), // 318: tabletmanagerdata.UpdateVReplicationWorkflowRequest + (*vschema.MirrorRules)(nil), // 319: vschema.MirrorRules + (*topodata.Shard_TabletControl)(nil), // 320: topodata.Shard.TabletControl + (*binlogdata.BinlogSource)(nil), // 321: binlogdata.BinlogSource + (*topodata.ShardReplication)(nil), // 322: topodata.ShardReplication + (*topodata.SrvKeyspace)(nil), // 323: topodata.SrvKeyspace + (*replicationdata.Status)(nil), // 324: replicationdata.Status + (*tabletmanagerdata.VDiffResponse)(nil), // 325: tabletmanagerdata.VDiffResponse } var file_vtctldata_proto_depIdxs = []int32{ - 284, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event + 290, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event 6, // 1: vtctldata.MaterializeSettings.table_settings:type_name -> vtctldata.TableMaterializeSettings 0, // 2: vtctldata.MaterializeSettings.materialization_intent:type_name -> vtctldata.MaterializationIntent - 285, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 291, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference 11, // 4: vtctldata.MaterializeSettings.workflow_options:type_name -> vtctldata.WorkflowOptions - 286, // 5: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace + 292, // 5: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace 2, // 6: vtctldata.SchemaMigration.strategy:type_name -> vtctldata.SchemaMigration.Strategy - 287, // 7: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time - 287, // 8: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time - 287, // 9: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time - 287, // 10: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time - 287, // 11: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time - 287, // 12: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time - 287, // 13: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time + 293, // 7: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time + 293, // 8: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time + 293, // 9: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time + 293, // 10: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time + 293, // 11: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time + 293, // 12: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time + 293, // 13: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time 3, // 14: vtctldata.SchemaMigration.status:type_name -> vtctldata.SchemaMigration.Status - 288, // 15: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias - 289, // 16: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration - 287, // 17: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time - 287, // 18: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time - 287, // 19: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time - 287, // 20: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time - 290, // 21: vtctldata.Shard.shard:type_name -> topodata.Shard - 246, // 22: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation - 246, // 23: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation - 245, // 24: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry + 294, // 15: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias + 295, // 16: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration + 293, // 17: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time + 293, // 18: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time + 293, // 19: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time + 293, // 20: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time + 296, // 21: vtctldata.Shard.shard:type_name -> topodata.Shard + 252, // 22: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation + 252, // 23: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation + 251, // 24: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry 11, // 25: vtctldata.Workflow.options:type_name -> vtctldata.WorkflowOptions - 291, // 26: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 292, // 27: vtctldata.ApplyKeyspaceRoutingRulesRequest.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 292, // 28: vtctldata.ApplyKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 293, // 29: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules - 294, // 30: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 289, // 31: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration - 295, // 32: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID - 252, // 33: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - 296, // 34: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace - 296, // 35: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 253, // 36: vtctldata.ApplyVSchemaResponse.unknown_vindex_params:type_name -> vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry - 288, // 37: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 38: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 284, // 39: vtctldata.BackupResponse.event:type_name -> logutil.Event - 255, // 40: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - 288, // 41: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias - 297, // 42: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType - 298, // 43: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet - 298, // 44: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet - 256, // 45: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - 257, // 46: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - 299, // 47: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType - 287, // 48: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time + 297, // 26: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 298, // 27: vtctldata.ApplyKeyspaceRoutingRulesRequest.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 298, // 28: vtctldata.ApplyKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 299, // 29: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules + 300, // 30: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 295, // 31: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration + 301, // 32: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID + 258, // 33: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + 302, // 34: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace + 302, // 35: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 259, // 36: vtctldata.ApplyVSchemaResponse.unknown_vindex_params:type_name -> vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry + 294, // 37: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 294, // 38: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 290, // 39: vtctldata.BackupResponse.event:type_name -> logutil.Event + 261, // 40: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + 294, // 41: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias + 303, // 42: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType + 304, // 43: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet + 304, // 44: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet + 262, // 45: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + 263, // 46: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + 305, // 47: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType + 293, // 48: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time 8, // 49: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace 8, // 50: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace 10, // 51: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard 10, // 52: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard - 288, // 53: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 288, // 54: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 288, // 55: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias - 289, // 56: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 288, // 57: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 284, // 58: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event - 288, // 59: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias - 300, // 60: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult - 288, // 61: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 300, // 62: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult - 288, // 63: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias - 301, // 64: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest - 302, // 65: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse - 288, // 66: vtctldata.ExecuteMultiFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 300, // 67: vtctldata.ExecuteMultiFetchAsDBAResponse.results:type_name -> query.QueryResult - 258, // 68: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - 259, // 69: vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry - 303, // 70: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo - 291, // 71: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 260, // 72: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry - 288, // 73: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias - 304, // 74: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus + 294, // 53: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 294, // 54: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 294, // 55: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias + 295, // 56: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 294, // 57: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 290, // 58: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event + 294, // 59: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias + 306, // 60: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult + 294, // 61: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 306, // 62: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult + 294, // 63: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 64: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest + 308, // 65: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse + 294, // 66: vtctldata.ExecuteMultiFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 306, // 67: vtctldata.ExecuteMultiFetchAsDBAResponse.results:type_name -> query.QueryResult + 264, // 68: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + 265, // 69: vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry + 309, // 70: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo + 297, // 71: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 266, // 72: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry + 294, // 73: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias + 310, // 74: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus 8, // 75: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace 8, // 76: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 288, // 77: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias - 305, // 78: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions - 292, // 79: vtctldata.GetKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 293, // 80: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules - 288, // 81: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 306, // 82: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition + 294, // 77: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias + 311, // 78: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions + 298, // 79: vtctldata.GetKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 299, // 80: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules + 294, // 81: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 312, // 82: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition 3, // 83: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status - 289, // 84: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration + 295, // 84: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration 1, // 85: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering 9, // 86: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration - 261, // 87: vtctldata.GetShardReplicationResponse.shard_replication_by_cell:type_name -> vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry + 267, // 87: vtctldata.GetShardReplicationResponse.shard_replication_by_cell:type_name -> vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry 10, // 88: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard - 294, // 89: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 262, // 90: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - 264, // 91: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - 307, // 92: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule - 308, // 93: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema - 265, // 94: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - 288, // 95: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 298, // 96: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet - 288, // 97: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 297, // 98: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType - 298, // 99: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet + 300, // 89: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 268, // 90: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + 270, // 91: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + 313, // 92: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule + 314, // 93: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema + 271, // 94: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + 294, // 95: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 304, // 96: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet + 294, // 97: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 303, // 98: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType + 304, // 99: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet 114, // 100: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell - 288, // 101: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias - 296, // 102: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 294, // 101: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias + 302, // 102: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace 12, // 103: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow - 288, // 104: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias - 289, // 105: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration - 284, // 106: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event - 266, // 107: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - 296, // 108: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace - 297, // 109: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType - 285, // 110: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 294, // 104: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias + 295, // 105: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration + 290, // 106: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event + 272, // 107: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + 302, // 108: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace + 303, // 109: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType + 291, // 110: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference 7, // 111: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings - 297, // 112: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType - 285, // 113: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 297, // 114: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType - 285, // 115: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 303, // 112: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType + 291, // 113: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 303, // 114: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType + 291, // 115: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference 11, // 116: vtctldata.MoveTablesCreateRequest.workflow_options:type_name -> vtctldata.WorkflowOptions - 267, // 117: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo - 288, // 118: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 119: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 288, // 120: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias - 289, // 121: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 289, // 122: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration - 288, // 123: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 284, // 124: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 288, // 125: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 126: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 284, // 127: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event - 284, // 128: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event - 288, // 129: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 288, // 130: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 297, // 131: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType - 285, // 132: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 288, // 133: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 287, // 134: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time - 287, // 135: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time - 288, // 136: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 284, // 137: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event - 268, // 138: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - 288, // 139: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias - 286, // 140: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace - 286, // 141: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace - 290, // 142: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard - 297, // 143: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType - 290, // 144: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard - 288, // 145: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 146: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 147: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError - 269, // 148: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 270, // 149: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 288, // 150: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 151: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 289, // 152: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration - 310, // 153: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange - 290, // 154: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard - 290, // 155: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard - 288, // 156: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 157: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 288, // 158: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 288, // 159: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 288, // 160: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 291, // 161: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 291, // 162: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 311, // 163: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 311, // 164: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias - 271, // 165: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry - 272, // 166: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - 273, // 167: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - 274, // 168: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - 275, // 169: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - 297, // 170: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType - 285, // 171: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 289, // 172: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration - 289, // 173: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration - 289, // 174: vtctldata.VDiffCreateRequest.max_diff_duration:type_name -> vttime.Duration - 276, // 175: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry - 277, // 176: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo - 281, // 177: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry - 282, // 178: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry - 297, // 179: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType - 289, // 180: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration - 289, // 181: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration - 312, // 182: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest - 283, // 183: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo - 247, // 184: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream - 248, // 185: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 313, // 186: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 288, // 187: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 314, // 188: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 287, // 189: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 287, // 190: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time - 249, // 191: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 250, // 192: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log - 251, // 193: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus - 297, // 194: vtctldata.Workflow.Stream.tablet_types:type_name -> topodata.TabletType - 285, // 195: vtctldata.Workflow.Stream.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 287, // 196: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time - 287, // 197: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time - 287, // 198: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time - 254, // 199: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry.value:type_name -> vtctldata.ApplyVSchemaResponse.ParamList - 10, // 200: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 311, // 201: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 315, // 202: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry.value:type_name -> topodata.ShardReplication - 263, // 203: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList - 316, // 204: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 308, // 205: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 288, // 206: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 317, // 207: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 298, // 208: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 216, // 209: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse - 220, // 210: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 220, // 211: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 220, // 212: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 220, // 213: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 318, // 214: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse - 288, // 215: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 288, // 216: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias - 279, // 217: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState - 278, // 218: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState - 280, // 219: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams - 288, // 220: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 221, // [221:221] is the sub-list for method output_type - 221, // [221:221] is the sub-list for method input_type - 221, // [221:221] is the sub-list for extension type_name - 221, // [221:221] is the sub-list for extension extendee - 0, // [0:221] is the sub-list for field type_name + 273, // 117: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo + 294, // 118: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 294, // 119: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 294, // 120: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias + 295, // 121: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 295, // 122: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration + 294, // 123: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 290, // 124: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 294, // 125: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias + 294, // 126: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 290, // 127: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event + 290, // 128: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event + 294, // 129: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 294, // 130: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 303, // 131: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType + 291, // 132: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 294, // 133: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 293, // 134: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time + 293, // 135: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time + 294, // 136: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 290, // 137: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event + 274, // 138: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + 294, // 139: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias + 292, // 140: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace + 292, // 141: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace + 296, // 142: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard + 303, // 143: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType + 296, // 144: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard + 294, // 145: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias + 294, // 146: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias + 315, // 147: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError + 275, // 148: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 276, // 149: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 294, // 150: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias + 294, // 151: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 295, // 152: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration + 316, // 153: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange + 296, // 154: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard + 296, // 155: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard + 294, // 156: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 294, // 157: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 294, // 158: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 294, // 159: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 294, // 160: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 297, // 161: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 297, // 162: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 317, // 163: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 317, // 164: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 277, // 165: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry + 278, // 166: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + 279, // 167: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + 280, // 168: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + 281, // 169: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + 303, // 170: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType + 291, // 171: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 295, // 172: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration + 295, // 173: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration + 295, // 174: vtctldata.VDiffCreateRequest.max_diff_duration:type_name -> vttime.Duration + 282, // 175: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry + 283, // 176: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo + 287, // 177: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry + 288, // 178: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry + 303, // 179: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType + 295, // 180: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration + 295, // 181: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration + 318, // 182: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest + 289, // 183: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo + 319, // 184: vtctldata.ApplyMirrorRulesRequest.mirror_rules:type_name -> vschema.MirrorRules + 319, // 185: vtctldata.GetMirrorRulesResponse.mirror_rules:type_name -> vschema.MirrorRules + 303, // 186: vtctldata.WorkflowMirrorTrafficRequest.tablet_types:type_name -> topodata.TabletType + 253, // 187: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream + 254, // 188: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream + 320, // 189: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 294, // 190: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 321, // 191: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 293, // 192: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 293, // 193: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 255, // 194: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState + 256, // 195: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 257, // 196: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus + 303, // 197: vtctldata.Workflow.Stream.tablet_types:type_name -> topodata.TabletType + 291, // 198: vtctldata.Workflow.Stream.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 293, // 199: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 293, // 200: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 293, // 201: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time + 260, // 202: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry.value:type_name -> vtctldata.ApplyVSchemaResponse.ParamList + 10, // 203: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 317, // 204: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 322, // 205: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry.value:type_name -> topodata.ShardReplication + 269, // 206: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList + 323, // 207: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 314, // 208: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 294, // 209: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 324, // 210: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 304, // 211: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 216, // 212: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse + 220, // 213: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 220, // 214: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 220, // 215: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 220, // 216: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 325, // 217: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse + 294, // 218: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 294, // 219: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias + 285, // 220: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState + 284, // 221: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState + 286, // 222: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams + 294, // 223: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 224, // [224:224] is the sub-list for method output_type + 224, // [224:224] is the sub-list for method input_type + 224, // [224:224] is the sub-list for extension type_name + 224, // [224:224] is the sub-list for extension extendee + 0, // [0:224] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } @@ -21945,8 +22318,20 @@ func file_vtctldata_proto_init() { return nil } } + file_vtctldata_proto_msgTypes[241].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyMirrorRulesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } file_vtctldata_proto_msgTypes[242].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Workflow_ReplicationLocation); i { + switch v := v.(*ApplyMirrorRulesResponse); i { case 0: return &v.state case 1: @@ -21958,7 +22343,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[243].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Workflow_ShardStream); i { + switch v := v.(*GetMirrorRulesRequest); i { case 0: return &v.state case 1: @@ -21970,7 +22355,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[244].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Workflow_Stream); i { + switch v := v.(*GetMirrorRulesResponse); i { case 0: return &v.state case 1: @@ -21982,7 +22367,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[245].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Workflow_Stream_CopyState); i { + switch v := v.(*WorkflowMirrorTrafficRequest); i { case 0: return &v.state case 1: @@ -21994,6 +22379,66 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[246].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkflowMirrorTrafficResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[248].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workflow_ReplicationLocation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[249].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workflow_ShardStream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[250].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workflow_Stream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[251].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workflow_Stream_CopyState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[252].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_Log); i { case 0: return &v.state @@ -22005,7 +22450,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[247].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[253].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_ThrottlerStatus); i { case 0: return &v.state @@ -22017,7 +22462,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[250].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[256].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyVSchemaResponse_ParamList); i { case 0: return &v.state @@ -22029,7 +22474,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[259].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[265].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetSrvKeyspaceNamesResponse_NameList); i { case 0: return &v.state @@ -22041,7 +22486,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[263].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[269].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MoveTablesCreateResponse_TabletInfo); i { case 0: return &v.state @@ -22053,7 +22498,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[273].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[279].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowDeleteResponse_TabletInfo); i { case 0: return &v.state @@ -22065,7 +22510,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[274].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[280].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_TableCopyState); i { case 0: return &v.state @@ -22077,7 +22522,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[275].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[281].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_ShardStreamState); i { case 0: return &v.state @@ -22089,7 +22534,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[276].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[282].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowStatusResponse_ShardStreams); i { case 0: return &v.state @@ -22101,7 +22546,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[279].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[285].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WorkflowUpdateResponse_TabletInfo); i { case 0: return &v.state @@ -22120,7 +22565,7 @@ func file_vtctldata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vtctldata_proto_rawDesc, NumEnums: 4, - NumMessages: 280, + NumMessages: 286, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go index b3721495678..b1f8b1cf588 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -5560,6 +5560,125 @@ func (m *WorkflowUpdateResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *ApplyMirrorRulesRequest) CloneVT() *ApplyMirrorRulesRequest { + if m == nil { + return (*ApplyMirrorRulesRequest)(nil) + } + r := &ApplyMirrorRulesRequest{ + MirrorRules: m.MirrorRules.CloneVT(), + SkipRebuild: m.SkipRebuild, + } + if rhs := m.RebuildCells; rhs != nil { + tmpContainer := make([]string, len(rhs)) + copy(tmpContainer, rhs) + r.RebuildCells = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *ApplyMirrorRulesRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *ApplyMirrorRulesResponse) CloneVT() *ApplyMirrorRulesResponse { + if m == nil { + return (*ApplyMirrorRulesResponse)(nil) + } + r := &ApplyMirrorRulesResponse{} + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *ApplyMirrorRulesResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *GetMirrorRulesRequest) CloneVT() *GetMirrorRulesRequest { + if m == nil { + return (*GetMirrorRulesRequest)(nil) + } + r := &GetMirrorRulesRequest{} + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *GetMirrorRulesRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *GetMirrorRulesResponse) CloneVT() *GetMirrorRulesResponse { + if m == nil { + return (*GetMirrorRulesResponse)(nil) + } + r := &GetMirrorRulesResponse{ + MirrorRules: m.MirrorRules.CloneVT(), + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *GetMirrorRulesResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *WorkflowMirrorTrafficRequest) CloneVT() *WorkflowMirrorTrafficRequest { + if m == nil { + return (*WorkflowMirrorTrafficRequest)(nil) + } + r := &WorkflowMirrorTrafficRequest{ + Keyspace: m.Keyspace, + Workflow: m.Workflow, + Percent: m.Percent, + } + if rhs := m.TabletTypes; rhs != nil { + tmpContainer := make([]topodata.TabletType, len(rhs)) + copy(tmpContainer, rhs) + r.TabletTypes = tmpContainer + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *WorkflowMirrorTrafficRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *WorkflowMirrorTrafficResponse) CloneVT() *WorkflowMirrorTrafficResponse { + if m == nil { + return (*WorkflowMirrorTrafficResponse)(nil) + } + r := &WorkflowMirrorTrafficResponse{ + Summary: m.Summary, + StartState: m.StartState, + CurrentState: m.CurrentState, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *WorkflowMirrorTrafficResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *ExecuteVtctlCommandRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -20255,6 +20374,305 @@ func (m *WorkflowUpdateResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *ApplyMirrorRulesRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ApplyMirrorRulesRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ApplyMirrorRulesRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.RebuildCells) > 0 { + for iNdEx := len(m.RebuildCells) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.RebuildCells[iNdEx]) + copy(dAtA[i:], m.RebuildCells[iNdEx]) + i = encodeVarint(dAtA, i, uint64(len(m.RebuildCells[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if m.SkipRebuild { + i-- + if m.SkipRebuild { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if m.MirrorRules != nil { + size, err := m.MirrorRules.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ApplyMirrorRulesResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ApplyMirrorRulesResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ApplyMirrorRulesResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *GetMirrorRulesRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetMirrorRulesRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetMirrorRulesRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *GetMirrorRulesResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetMirrorRulesResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GetMirrorRulesResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.MirrorRules != nil { + size, err := m.MirrorRules.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *WorkflowMirrorTrafficRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkflowMirrorTrafficRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *WorkflowMirrorTrafficRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Percent != 0 { + i -= 4 + binary.LittleEndian.PutUint32(dAtA[i:], uint32(math.Float32bits(float32(m.Percent)))) + i-- + dAtA[i] = 0x25 + } + if len(m.TabletTypes) > 0 { + var pksize2 int + for _, num := range m.TabletTypes { + pksize2 += sov(uint64(num)) + } + i -= pksize2 + j1 := i + for _, num1 := range m.TabletTypes { + num := uint64(num1) + for num >= 1<<7 { + dAtA[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA[j1] = uint8(num) + j1++ + } + i = encodeVarint(dAtA, i, uint64(pksize2)) + i-- + dAtA[i] = 0x1a + } + if len(m.Workflow) > 0 { + i -= len(m.Workflow) + copy(dAtA[i:], m.Workflow) + i = encodeVarint(dAtA, i, uint64(len(m.Workflow))) + i-- + dAtA[i] = 0x12 + } + if len(m.Keyspace) > 0 { + i -= len(m.Keyspace) + copy(dAtA[i:], m.Keyspace) + i = encodeVarint(dAtA, i, uint64(len(m.Keyspace))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *WorkflowMirrorTrafficResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WorkflowMirrorTrafficResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *WorkflowMirrorTrafficResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.CurrentState) > 0 { + i -= len(m.CurrentState) + copy(dAtA[i:], m.CurrentState) + i = encodeVarint(dAtA, i, uint64(len(m.CurrentState))) + i-- + dAtA[i] = 0x1a + } + if len(m.StartState) > 0 { + i -= len(m.StartState) + copy(dAtA[i:], m.StartState) + i = encodeVarint(dAtA, i, uint64(len(m.StartState))) + i-- + dAtA[i] = 0x12 + } + if len(m.Summary) > 0 { + i -= len(m.Summary) + copy(dAtA[i:], m.Summary) + i = encodeVarint(dAtA, i, uint64(len(m.Summary))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarint(dAtA []byte, offset int, v uint64) int { offset -= sov(v) base := offset @@ -25787,6 +26205,113 @@ func (m *WorkflowUpdateResponse) SizeVT() (n int) { return n } +func (m *ApplyMirrorRulesRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MirrorRules != nil { + l = m.MirrorRules.SizeVT() + n += 1 + l + sov(uint64(l)) + } + if m.SkipRebuild { + n += 2 + } + if len(m.RebuildCells) > 0 { + for _, s := range m.RebuildCells { + l = len(s) + n += 1 + l + sov(uint64(l)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *ApplyMirrorRulesResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *GetMirrorRulesRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *GetMirrorRulesResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MirrorRules != nil { + l = m.MirrorRules.SizeVT() + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *WorkflowMirrorTrafficRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Keyspace) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.Workflow) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if len(m.TabletTypes) > 0 { + l = 0 + for _, e := range m.TabletTypes { + l += sov(uint64(e)) + } + n += 1 + sov(uint64(l)) + l + } + if m.Percent != 0 { + n += 5 + } + n += len(m.unknownFields) + return n +} + +func (m *WorkflowMirrorTrafficResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Summary) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.StartState) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.CurrentState) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + func sov(x uint64) (n int) { return (bits.Len64(x|1) + 6) / 7 } @@ -61769,6 +62294,676 @@ func (m *WorkflowUpdateResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *ApplyMirrorRulesRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ApplyMirrorRulesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplyMirrorRulesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MirrorRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MirrorRules == nil { + m.MirrorRules = &vschema.MirrorRules{} + } + if err := m.MirrorRules.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SkipRebuild", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SkipRebuild = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RebuildCells", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RebuildCells = append(m.RebuildCells, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ApplyMirrorRulesResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ApplyMirrorRulesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ApplyMirrorRulesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetMirrorRulesRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetMirrorRulesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetMirrorRulesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetMirrorRulesResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetMirrorRulesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetMirrorRulesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MirrorRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MirrorRules == nil { + m.MirrorRules = &vschema.MirrorRules{} + } + if err := m.MirrorRules.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WorkflowMirrorTrafficRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WorkflowMirrorTrafficRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WorkflowMirrorTrafficRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Workflow", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Workflow = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType == 0 { + var v topodata.TabletType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= topodata.TabletType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TabletTypes = append(m.TabletTypes, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + if elementCount != 0 && len(m.TabletTypes) == 0 { + m.TabletTypes = make([]topodata.TabletType, 0, elementCount) + } + for iNdEx < postIndex { + var v topodata.TabletType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= topodata.TabletType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TabletTypes = append(m.TabletTypes, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field TabletTypes", wireType) + } + case 4: + if wireType != 5 { + return fmt.Errorf("proto: wrong wireType = %d for field Percent", wireType) + } + var v uint32 + if (iNdEx + 4) > l { + return io.ErrUnexpectedEOF + } + v = uint32(binary.LittleEndian.Uint32(dAtA[iNdEx:])) + iNdEx += 4 + m.Percent = float32(math.Float32frombits(v)) + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WorkflowMirrorTrafficResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WorkflowMirrorTrafficResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WorkflowMirrorTrafficResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Summary", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Summary = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StartState", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StartState = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentState", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurrentState = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skip(dAtA []byte) (n int, err error) { l := len(dAtA) diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 3bd9b3f847a..582641fd0e1 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -51,7 +51,7 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0xda, 0x54, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, + 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0x80, 0x57, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x12, 0x4e, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, @@ -729,10 +729,28 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, - 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x4d, 0x69, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x4d, 0x69, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x57, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, + 0x66, 0x66, 0x69, 0x63, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, + 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x76, 0x69, 0x74, + 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, + 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_vtctlservice_proto_goTypes = []interface{}{ @@ -852,118 +870,124 @@ var file_vtctlservice_proto_goTypes = []interface{}{ (*vtctldata.WorkflowStatusRequest)(nil), // 113: vtctldata.WorkflowStatusRequest (*vtctldata.WorkflowSwitchTrafficRequest)(nil), // 114: vtctldata.WorkflowSwitchTrafficRequest (*vtctldata.WorkflowUpdateRequest)(nil), // 115: vtctldata.WorkflowUpdateRequest - (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 116: vtctldata.ExecuteVtctlCommandResponse - (*vtctldata.AddCellInfoResponse)(nil), // 117: vtctldata.AddCellInfoResponse - (*vtctldata.AddCellsAliasResponse)(nil), // 118: vtctldata.AddCellsAliasResponse - (*vtctldata.ApplyRoutingRulesResponse)(nil), // 119: vtctldata.ApplyRoutingRulesResponse - (*vtctldata.ApplySchemaResponse)(nil), // 120: vtctldata.ApplySchemaResponse - (*vtctldata.ApplyKeyspaceRoutingRulesResponse)(nil), // 121: vtctldata.ApplyKeyspaceRoutingRulesResponse - (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 122: vtctldata.ApplyShardRoutingRulesResponse - (*vtctldata.ApplyVSchemaResponse)(nil), // 123: vtctldata.ApplyVSchemaResponse - (*vtctldata.BackupResponse)(nil), // 124: vtctldata.BackupResponse - (*vtctldata.CancelSchemaMigrationResponse)(nil), // 125: vtctldata.CancelSchemaMigrationResponse - (*vtctldata.ChangeTabletTypeResponse)(nil), // 126: vtctldata.ChangeTabletTypeResponse - (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 127: vtctldata.CleanupSchemaMigrationResponse - (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 128: vtctldata.CompleteSchemaMigrationResponse - (*vtctldata.CreateKeyspaceResponse)(nil), // 129: vtctldata.CreateKeyspaceResponse - (*vtctldata.CreateShardResponse)(nil), // 130: vtctldata.CreateShardResponse - (*vtctldata.DeleteCellInfoResponse)(nil), // 131: vtctldata.DeleteCellInfoResponse - (*vtctldata.DeleteCellsAliasResponse)(nil), // 132: vtctldata.DeleteCellsAliasResponse - (*vtctldata.DeleteKeyspaceResponse)(nil), // 133: vtctldata.DeleteKeyspaceResponse - (*vtctldata.DeleteShardsResponse)(nil), // 134: vtctldata.DeleteShardsResponse - (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 135: vtctldata.DeleteSrvVSchemaResponse - (*vtctldata.DeleteTabletsResponse)(nil), // 136: vtctldata.DeleteTabletsResponse - (*vtctldata.EmergencyReparentShardResponse)(nil), // 137: vtctldata.EmergencyReparentShardResponse - (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 138: vtctldata.ExecuteFetchAsAppResponse - (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 139: vtctldata.ExecuteFetchAsDBAResponse - (*vtctldata.ExecuteHookResponse)(nil), // 140: vtctldata.ExecuteHookResponse - (*vtctldata.ExecuteMultiFetchAsDBAResponse)(nil), // 141: vtctldata.ExecuteMultiFetchAsDBAResponse - (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 142: vtctldata.FindAllShardsInKeyspaceResponse - (*vtctldata.ForceCutOverSchemaMigrationResponse)(nil), // 143: vtctldata.ForceCutOverSchemaMigrationResponse - (*vtctldata.GetBackupsResponse)(nil), // 144: vtctldata.GetBackupsResponse - (*vtctldata.GetCellInfoResponse)(nil), // 145: vtctldata.GetCellInfoResponse - (*vtctldata.GetCellInfoNamesResponse)(nil), // 146: vtctldata.GetCellInfoNamesResponse - (*vtctldata.GetCellsAliasesResponse)(nil), // 147: vtctldata.GetCellsAliasesResponse - (*vtctldata.GetFullStatusResponse)(nil), // 148: vtctldata.GetFullStatusResponse - (*vtctldata.GetKeyspaceResponse)(nil), // 149: vtctldata.GetKeyspaceResponse - (*vtctldata.GetKeyspacesResponse)(nil), // 150: vtctldata.GetKeyspacesResponse - (*vtctldata.GetKeyspaceRoutingRulesResponse)(nil), // 151: vtctldata.GetKeyspaceRoutingRulesResponse - (*vtctldata.GetPermissionsResponse)(nil), // 152: vtctldata.GetPermissionsResponse - (*vtctldata.GetRoutingRulesResponse)(nil), // 153: vtctldata.GetRoutingRulesResponse - (*vtctldata.GetSchemaResponse)(nil), // 154: vtctldata.GetSchemaResponse - (*vtctldata.GetSchemaMigrationsResponse)(nil), // 155: vtctldata.GetSchemaMigrationsResponse - (*vtctldata.GetShardReplicationResponse)(nil), // 156: vtctldata.GetShardReplicationResponse - (*vtctldata.GetShardResponse)(nil), // 157: vtctldata.GetShardResponse - (*vtctldata.GetShardRoutingRulesResponse)(nil), // 158: vtctldata.GetShardRoutingRulesResponse - (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 159: vtctldata.GetSrvKeyspaceNamesResponse - (*vtctldata.GetSrvKeyspacesResponse)(nil), // 160: vtctldata.GetSrvKeyspacesResponse - (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 161: vtctldata.UpdateThrottlerConfigResponse - (*vtctldata.GetSrvVSchemaResponse)(nil), // 162: vtctldata.GetSrvVSchemaResponse - (*vtctldata.GetSrvVSchemasResponse)(nil), // 163: vtctldata.GetSrvVSchemasResponse - (*vtctldata.GetTabletResponse)(nil), // 164: vtctldata.GetTabletResponse - (*vtctldata.GetTabletsResponse)(nil), // 165: vtctldata.GetTabletsResponse - (*vtctldata.GetTopologyPathResponse)(nil), // 166: vtctldata.GetTopologyPathResponse - (*vtctldata.GetVersionResponse)(nil), // 167: vtctldata.GetVersionResponse - (*vtctldata.GetVSchemaResponse)(nil), // 168: vtctldata.GetVSchemaResponse - (*vtctldata.GetWorkflowsResponse)(nil), // 169: vtctldata.GetWorkflowsResponse - (*vtctldata.InitShardPrimaryResponse)(nil), // 170: vtctldata.InitShardPrimaryResponse - (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 171: vtctldata.LaunchSchemaMigrationResponse - (*vtctldata.LookupVindexCreateResponse)(nil), // 172: vtctldata.LookupVindexCreateResponse - (*vtctldata.LookupVindexExternalizeResponse)(nil), // 173: vtctldata.LookupVindexExternalizeResponse - (*vtctldata.MaterializeCreateResponse)(nil), // 174: vtctldata.MaterializeCreateResponse - (*vtctldata.WorkflowStatusResponse)(nil), // 175: vtctldata.WorkflowStatusResponse - (*vtctldata.MountRegisterResponse)(nil), // 176: vtctldata.MountRegisterResponse - (*vtctldata.MountUnregisterResponse)(nil), // 177: vtctldata.MountUnregisterResponse - (*vtctldata.MountShowResponse)(nil), // 178: vtctldata.MountShowResponse - (*vtctldata.MountListResponse)(nil), // 179: vtctldata.MountListResponse - (*vtctldata.MoveTablesCompleteResponse)(nil), // 180: vtctldata.MoveTablesCompleteResponse - (*vtctldata.PingTabletResponse)(nil), // 181: vtctldata.PingTabletResponse - (*vtctldata.PlannedReparentShardResponse)(nil), // 182: vtctldata.PlannedReparentShardResponse - (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 183: vtctldata.RebuildKeyspaceGraphResponse - (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 184: vtctldata.RebuildVSchemaGraphResponse - (*vtctldata.RefreshStateResponse)(nil), // 185: vtctldata.RefreshStateResponse - (*vtctldata.RefreshStateByShardResponse)(nil), // 186: vtctldata.RefreshStateByShardResponse - (*vtctldata.ReloadSchemaResponse)(nil), // 187: vtctldata.ReloadSchemaResponse - (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 188: vtctldata.ReloadSchemaKeyspaceResponse - (*vtctldata.ReloadSchemaShardResponse)(nil), // 189: vtctldata.ReloadSchemaShardResponse - (*vtctldata.RemoveBackupResponse)(nil), // 190: vtctldata.RemoveBackupResponse - (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 191: vtctldata.RemoveKeyspaceCellResponse - (*vtctldata.RemoveShardCellResponse)(nil), // 192: vtctldata.RemoveShardCellResponse - (*vtctldata.ReparentTabletResponse)(nil), // 193: vtctldata.ReparentTabletResponse - (*vtctldata.RestoreFromBackupResponse)(nil), // 194: vtctldata.RestoreFromBackupResponse - (*vtctldata.RetrySchemaMigrationResponse)(nil), // 195: vtctldata.RetrySchemaMigrationResponse - (*vtctldata.RunHealthCheckResponse)(nil), // 196: vtctldata.RunHealthCheckResponse - (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 197: vtctldata.SetKeyspaceDurabilityPolicyResponse - (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 198: vtctldata.SetShardIsPrimaryServingResponse - (*vtctldata.SetShardTabletControlResponse)(nil), // 199: vtctldata.SetShardTabletControlResponse - (*vtctldata.SetWritableResponse)(nil), // 200: vtctldata.SetWritableResponse - (*vtctldata.ShardReplicationAddResponse)(nil), // 201: vtctldata.ShardReplicationAddResponse - (*vtctldata.ShardReplicationFixResponse)(nil), // 202: vtctldata.ShardReplicationFixResponse - (*vtctldata.ShardReplicationPositionsResponse)(nil), // 203: vtctldata.ShardReplicationPositionsResponse - (*vtctldata.ShardReplicationRemoveResponse)(nil), // 204: vtctldata.ShardReplicationRemoveResponse - (*vtctldata.SleepTabletResponse)(nil), // 205: vtctldata.SleepTabletResponse - (*vtctldata.SourceShardAddResponse)(nil), // 206: vtctldata.SourceShardAddResponse - (*vtctldata.SourceShardDeleteResponse)(nil), // 207: vtctldata.SourceShardDeleteResponse - (*vtctldata.StartReplicationResponse)(nil), // 208: vtctldata.StartReplicationResponse - (*vtctldata.StopReplicationResponse)(nil), // 209: vtctldata.StopReplicationResponse - (*vtctldata.TabletExternallyReparentedResponse)(nil), // 210: vtctldata.TabletExternallyReparentedResponse - (*vtctldata.UpdateCellInfoResponse)(nil), // 211: vtctldata.UpdateCellInfoResponse - (*vtctldata.UpdateCellsAliasResponse)(nil), // 212: vtctldata.UpdateCellsAliasResponse - (*vtctldata.ValidateResponse)(nil), // 213: vtctldata.ValidateResponse - (*vtctldata.ValidateKeyspaceResponse)(nil), // 214: vtctldata.ValidateKeyspaceResponse - (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 215: vtctldata.ValidateSchemaKeyspaceResponse - (*vtctldata.ValidateShardResponse)(nil), // 216: vtctldata.ValidateShardResponse - (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 217: vtctldata.ValidateVersionKeyspaceResponse - (*vtctldata.ValidateVersionShardResponse)(nil), // 218: vtctldata.ValidateVersionShardResponse - (*vtctldata.ValidateVSchemaResponse)(nil), // 219: vtctldata.ValidateVSchemaResponse - (*vtctldata.VDiffCreateResponse)(nil), // 220: vtctldata.VDiffCreateResponse - (*vtctldata.VDiffDeleteResponse)(nil), // 221: vtctldata.VDiffDeleteResponse - (*vtctldata.VDiffResumeResponse)(nil), // 222: vtctldata.VDiffResumeResponse - (*vtctldata.VDiffShowResponse)(nil), // 223: vtctldata.VDiffShowResponse - (*vtctldata.VDiffStopResponse)(nil), // 224: vtctldata.VDiffStopResponse - (*vtctldata.WorkflowDeleteResponse)(nil), // 225: vtctldata.WorkflowDeleteResponse - (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 226: vtctldata.WorkflowSwitchTrafficResponse - (*vtctldata.WorkflowUpdateResponse)(nil), // 227: vtctldata.WorkflowUpdateResponse + (*vtctldata.ApplyMirrorRulesRequest)(nil), // 116: vtctldata.ApplyMirrorRulesRequest + (*vtctldata.GetMirrorRulesRequest)(nil), // 117: vtctldata.GetMirrorRulesRequest + (*vtctldata.WorkflowMirrorTrafficRequest)(nil), // 118: vtctldata.WorkflowMirrorTrafficRequest + (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 119: vtctldata.ExecuteVtctlCommandResponse + (*vtctldata.AddCellInfoResponse)(nil), // 120: vtctldata.AddCellInfoResponse + (*vtctldata.AddCellsAliasResponse)(nil), // 121: vtctldata.AddCellsAliasResponse + (*vtctldata.ApplyRoutingRulesResponse)(nil), // 122: vtctldata.ApplyRoutingRulesResponse + (*vtctldata.ApplySchemaResponse)(nil), // 123: vtctldata.ApplySchemaResponse + (*vtctldata.ApplyKeyspaceRoutingRulesResponse)(nil), // 124: vtctldata.ApplyKeyspaceRoutingRulesResponse + (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 125: vtctldata.ApplyShardRoutingRulesResponse + (*vtctldata.ApplyVSchemaResponse)(nil), // 126: vtctldata.ApplyVSchemaResponse + (*vtctldata.BackupResponse)(nil), // 127: vtctldata.BackupResponse + (*vtctldata.CancelSchemaMigrationResponse)(nil), // 128: vtctldata.CancelSchemaMigrationResponse + (*vtctldata.ChangeTabletTypeResponse)(nil), // 129: vtctldata.ChangeTabletTypeResponse + (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 130: vtctldata.CleanupSchemaMigrationResponse + (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 131: vtctldata.CompleteSchemaMigrationResponse + (*vtctldata.CreateKeyspaceResponse)(nil), // 132: vtctldata.CreateKeyspaceResponse + (*vtctldata.CreateShardResponse)(nil), // 133: vtctldata.CreateShardResponse + (*vtctldata.DeleteCellInfoResponse)(nil), // 134: vtctldata.DeleteCellInfoResponse + (*vtctldata.DeleteCellsAliasResponse)(nil), // 135: vtctldata.DeleteCellsAliasResponse + (*vtctldata.DeleteKeyspaceResponse)(nil), // 136: vtctldata.DeleteKeyspaceResponse + (*vtctldata.DeleteShardsResponse)(nil), // 137: vtctldata.DeleteShardsResponse + (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 138: vtctldata.DeleteSrvVSchemaResponse + (*vtctldata.DeleteTabletsResponse)(nil), // 139: vtctldata.DeleteTabletsResponse + (*vtctldata.EmergencyReparentShardResponse)(nil), // 140: vtctldata.EmergencyReparentShardResponse + (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 141: vtctldata.ExecuteFetchAsAppResponse + (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 142: vtctldata.ExecuteFetchAsDBAResponse + (*vtctldata.ExecuteHookResponse)(nil), // 143: vtctldata.ExecuteHookResponse + (*vtctldata.ExecuteMultiFetchAsDBAResponse)(nil), // 144: vtctldata.ExecuteMultiFetchAsDBAResponse + (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 145: vtctldata.FindAllShardsInKeyspaceResponse + (*vtctldata.ForceCutOverSchemaMigrationResponse)(nil), // 146: vtctldata.ForceCutOverSchemaMigrationResponse + (*vtctldata.GetBackupsResponse)(nil), // 147: vtctldata.GetBackupsResponse + (*vtctldata.GetCellInfoResponse)(nil), // 148: vtctldata.GetCellInfoResponse + (*vtctldata.GetCellInfoNamesResponse)(nil), // 149: vtctldata.GetCellInfoNamesResponse + (*vtctldata.GetCellsAliasesResponse)(nil), // 150: vtctldata.GetCellsAliasesResponse + (*vtctldata.GetFullStatusResponse)(nil), // 151: vtctldata.GetFullStatusResponse + (*vtctldata.GetKeyspaceResponse)(nil), // 152: vtctldata.GetKeyspaceResponse + (*vtctldata.GetKeyspacesResponse)(nil), // 153: vtctldata.GetKeyspacesResponse + (*vtctldata.GetKeyspaceRoutingRulesResponse)(nil), // 154: vtctldata.GetKeyspaceRoutingRulesResponse + (*vtctldata.GetPermissionsResponse)(nil), // 155: vtctldata.GetPermissionsResponse + (*vtctldata.GetRoutingRulesResponse)(nil), // 156: vtctldata.GetRoutingRulesResponse + (*vtctldata.GetSchemaResponse)(nil), // 157: vtctldata.GetSchemaResponse + (*vtctldata.GetSchemaMigrationsResponse)(nil), // 158: vtctldata.GetSchemaMigrationsResponse + (*vtctldata.GetShardReplicationResponse)(nil), // 159: vtctldata.GetShardReplicationResponse + (*vtctldata.GetShardResponse)(nil), // 160: vtctldata.GetShardResponse + (*vtctldata.GetShardRoutingRulesResponse)(nil), // 161: vtctldata.GetShardRoutingRulesResponse + (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 162: vtctldata.GetSrvKeyspaceNamesResponse + (*vtctldata.GetSrvKeyspacesResponse)(nil), // 163: vtctldata.GetSrvKeyspacesResponse + (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 164: vtctldata.UpdateThrottlerConfigResponse + (*vtctldata.GetSrvVSchemaResponse)(nil), // 165: vtctldata.GetSrvVSchemaResponse + (*vtctldata.GetSrvVSchemasResponse)(nil), // 166: vtctldata.GetSrvVSchemasResponse + (*vtctldata.GetTabletResponse)(nil), // 167: vtctldata.GetTabletResponse + (*vtctldata.GetTabletsResponse)(nil), // 168: vtctldata.GetTabletsResponse + (*vtctldata.GetTopologyPathResponse)(nil), // 169: vtctldata.GetTopologyPathResponse + (*vtctldata.GetVersionResponse)(nil), // 170: vtctldata.GetVersionResponse + (*vtctldata.GetVSchemaResponse)(nil), // 171: vtctldata.GetVSchemaResponse + (*vtctldata.GetWorkflowsResponse)(nil), // 172: vtctldata.GetWorkflowsResponse + (*vtctldata.InitShardPrimaryResponse)(nil), // 173: vtctldata.InitShardPrimaryResponse + (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 174: vtctldata.LaunchSchemaMigrationResponse + (*vtctldata.LookupVindexCreateResponse)(nil), // 175: vtctldata.LookupVindexCreateResponse + (*vtctldata.LookupVindexExternalizeResponse)(nil), // 176: vtctldata.LookupVindexExternalizeResponse + (*vtctldata.MaterializeCreateResponse)(nil), // 177: vtctldata.MaterializeCreateResponse + (*vtctldata.WorkflowStatusResponse)(nil), // 178: vtctldata.WorkflowStatusResponse + (*vtctldata.MountRegisterResponse)(nil), // 179: vtctldata.MountRegisterResponse + (*vtctldata.MountUnregisterResponse)(nil), // 180: vtctldata.MountUnregisterResponse + (*vtctldata.MountShowResponse)(nil), // 181: vtctldata.MountShowResponse + (*vtctldata.MountListResponse)(nil), // 182: vtctldata.MountListResponse + (*vtctldata.MoveTablesCompleteResponse)(nil), // 183: vtctldata.MoveTablesCompleteResponse + (*vtctldata.PingTabletResponse)(nil), // 184: vtctldata.PingTabletResponse + (*vtctldata.PlannedReparentShardResponse)(nil), // 185: vtctldata.PlannedReparentShardResponse + (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 186: vtctldata.RebuildKeyspaceGraphResponse + (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 187: vtctldata.RebuildVSchemaGraphResponse + (*vtctldata.RefreshStateResponse)(nil), // 188: vtctldata.RefreshStateResponse + (*vtctldata.RefreshStateByShardResponse)(nil), // 189: vtctldata.RefreshStateByShardResponse + (*vtctldata.ReloadSchemaResponse)(nil), // 190: vtctldata.ReloadSchemaResponse + (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 191: vtctldata.ReloadSchemaKeyspaceResponse + (*vtctldata.ReloadSchemaShardResponse)(nil), // 192: vtctldata.ReloadSchemaShardResponse + (*vtctldata.RemoveBackupResponse)(nil), // 193: vtctldata.RemoveBackupResponse + (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 194: vtctldata.RemoveKeyspaceCellResponse + (*vtctldata.RemoveShardCellResponse)(nil), // 195: vtctldata.RemoveShardCellResponse + (*vtctldata.ReparentTabletResponse)(nil), // 196: vtctldata.ReparentTabletResponse + (*vtctldata.RestoreFromBackupResponse)(nil), // 197: vtctldata.RestoreFromBackupResponse + (*vtctldata.RetrySchemaMigrationResponse)(nil), // 198: vtctldata.RetrySchemaMigrationResponse + (*vtctldata.RunHealthCheckResponse)(nil), // 199: vtctldata.RunHealthCheckResponse + (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 200: vtctldata.SetKeyspaceDurabilityPolicyResponse + (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 201: vtctldata.SetShardIsPrimaryServingResponse + (*vtctldata.SetShardTabletControlResponse)(nil), // 202: vtctldata.SetShardTabletControlResponse + (*vtctldata.SetWritableResponse)(nil), // 203: vtctldata.SetWritableResponse + (*vtctldata.ShardReplicationAddResponse)(nil), // 204: vtctldata.ShardReplicationAddResponse + (*vtctldata.ShardReplicationFixResponse)(nil), // 205: vtctldata.ShardReplicationFixResponse + (*vtctldata.ShardReplicationPositionsResponse)(nil), // 206: vtctldata.ShardReplicationPositionsResponse + (*vtctldata.ShardReplicationRemoveResponse)(nil), // 207: vtctldata.ShardReplicationRemoveResponse + (*vtctldata.SleepTabletResponse)(nil), // 208: vtctldata.SleepTabletResponse + (*vtctldata.SourceShardAddResponse)(nil), // 209: vtctldata.SourceShardAddResponse + (*vtctldata.SourceShardDeleteResponse)(nil), // 210: vtctldata.SourceShardDeleteResponse + (*vtctldata.StartReplicationResponse)(nil), // 211: vtctldata.StartReplicationResponse + (*vtctldata.StopReplicationResponse)(nil), // 212: vtctldata.StopReplicationResponse + (*vtctldata.TabletExternallyReparentedResponse)(nil), // 213: vtctldata.TabletExternallyReparentedResponse + (*vtctldata.UpdateCellInfoResponse)(nil), // 214: vtctldata.UpdateCellInfoResponse + (*vtctldata.UpdateCellsAliasResponse)(nil), // 215: vtctldata.UpdateCellsAliasResponse + (*vtctldata.ValidateResponse)(nil), // 216: vtctldata.ValidateResponse + (*vtctldata.ValidateKeyspaceResponse)(nil), // 217: vtctldata.ValidateKeyspaceResponse + (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 218: vtctldata.ValidateSchemaKeyspaceResponse + (*vtctldata.ValidateShardResponse)(nil), // 219: vtctldata.ValidateShardResponse + (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 220: vtctldata.ValidateVersionKeyspaceResponse + (*vtctldata.ValidateVersionShardResponse)(nil), // 221: vtctldata.ValidateVersionShardResponse + (*vtctldata.ValidateVSchemaResponse)(nil), // 222: vtctldata.ValidateVSchemaResponse + (*vtctldata.VDiffCreateResponse)(nil), // 223: vtctldata.VDiffCreateResponse + (*vtctldata.VDiffDeleteResponse)(nil), // 224: vtctldata.VDiffDeleteResponse + (*vtctldata.VDiffResumeResponse)(nil), // 225: vtctldata.VDiffResumeResponse + (*vtctldata.VDiffShowResponse)(nil), // 226: vtctldata.VDiffShowResponse + (*vtctldata.VDiffStopResponse)(nil), // 227: vtctldata.VDiffStopResponse + (*vtctldata.WorkflowDeleteResponse)(nil), // 228: vtctldata.WorkflowDeleteResponse + (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 229: vtctldata.WorkflowSwitchTrafficResponse + (*vtctldata.WorkflowUpdateResponse)(nil), // 230: vtctldata.WorkflowUpdateResponse + (*vtctldata.ApplyMirrorRulesResponse)(nil), // 231: vtctldata.ApplyMirrorRulesResponse + (*vtctldata.GetMirrorRulesResponse)(nil), // 232: vtctldata.GetMirrorRulesResponse + (*vtctldata.WorkflowMirrorTrafficResponse)(nil), // 233: vtctldata.WorkflowMirrorTrafficResponse } var file_vtctlservice_proto_depIdxs = []int32{ 0, // 0: vtctlservice.Vtctl.ExecuteVtctlCommand:input_type -> vtctldata.ExecuteVtctlCommandRequest @@ -1082,124 +1106,130 @@ var file_vtctlservice_proto_depIdxs = []int32{ 113, // 113: vtctlservice.Vtctld.WorkflowStatus:input_type -> vtctldata.WorkflowStatusRequest 114, // 114: vtctlservice.Vtctld.WorkflowSwitchTraffic:input_type -> vtctldata.WorkflowSwitchTrafficRequest 115, // 115: vtctlservice.Vtctld.WorkflowUpdate:input_type -> vtctldata.WorkflowUpdateRequest - 116, // 116: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse - 117, // 117: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse - 118, // 118: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse - 119, // 119: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse - 120, // 120: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse - 121, // 121: vtctlservice.Vtctld.ApplyKeyspaceRoutingRules:output_type -> vtctldata.ApplyKeyspaceRoutingRulesResponse - 122, // 122: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse - 123, // 123: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse - 124, // 124: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse - 124, // 125: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse - 125, // 126: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse - 126, // 127: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse - 127, // 128: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse - 128, // 129: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse - 129, // 130: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse - 130, // 131: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse - 131, // 132: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse - 132, // 133: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse - 133, // 134: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse - 134, // 135: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse - 135, // 136: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse - 136, // 137: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse - 137, // 138: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse - 138, // 139: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse - 139, // 140: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse - 140, // 141: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse - 141, // 142: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:output_type -> vtctldata.ExecuteMultiFetchAsDBAResponse - 142, // 143: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse - 143, // 144: vtctlservice.Vtctld.ForceCutOverSchemaMigration:output_type -> vtctldata.ForceCutOverSchemaMigrationResponse - 144, // 145: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse - 145, // 146: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse - 146, // 147: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse - 147, // 148: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse - 148, // 149: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse - 149, // 150: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse - 150, // 151: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse - 151, // 152: vtctlservice.Vtctld.GetKeyspaceRoutingRules:output_type -> vtctldata.GetKeyspaceRoutingRulesResponse - 152, // 153: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse - 153, // 154: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse - 154, // 155: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse - 155, // 156: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse - 156, // 157: vtctlservice.Vtctld.GetShardReplication:output_type -> vtctldata.GetShardReplicationResponse - 157, // 158: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse - 158, // 159: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse - 159, // 160: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse - 160, // 161: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse - 161, // 162: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse - 162, // 163: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse - 163, // 164: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse - 164, // 165: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse - 165, // 166: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse - 166, // 167: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse - 167, // 168: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse - 168, // 169: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse - 169, // 170: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse - 170, // 171: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse - 171, // 172: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse - 172, // 173: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse - 173, // 174: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse - 174, // 175: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse - 175, // 176: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse - 176, // 177: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse - 177, // 178: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse - 178, // 179: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse - 179, // 180: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse - 175, // 181: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse - 180, // 182: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse - 181, // 183: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse - 182, // 184: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse - 183, // 185: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse - 184, // 186: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse - 185, // 187: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse - 186, // 188: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse - 187, // 189: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse - 188, // 190: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse - 189, // 191: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse - 190, // 192: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse - 191, // 193: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse - 192, // 194: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse - 193, // 195: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse - 175, // 196: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse - 194, // 197: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse - 195, // 198: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse - 196, // 199: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse - 197, // 200: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse - 198, // 201: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse - 199, // 202: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse - 200, // 203: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse - 201, // 204: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse - 202, // 205: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse - 203, // 206: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse - 204, // 207: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse - 205, // 208: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse - 206, // 209: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse - 207, // 210: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse - 208, // 211: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse - 209, // 212: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse - 210, // 213: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse - 211, // 214: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse - 212, // 215: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse - 213, // 216: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse - 214, // 217: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse - 215, // 218: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse - 216, // 219: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse - 217, // 220: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse - 218, // 221: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse - 219, // 222: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse - 220, // 223: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse - 221, // 224: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse - 222, // 225: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse - 223, // 226: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse - 224, // 227: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse - 225, // 228: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse - 175, // 229: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse - 226, // 230: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse - 227, // 231: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse - 116, // [116:232] is the sub-list for method output_type - 0, // [0:116] is the sub-list for method input_type + 116, // 116: vtctlservice.Vtctld.ApplyMirrorRules:input_type -> vtctldata.ApplyMirrorRulesRequest + 117, // 117: vtctlservice.Vtctld.GetMirrorRules:input_type -> vtctldata.GetMirrorRulesRequest + 118, // 118: vtctlservice.Vtctld.WorkflowMirrorTraffic:input_type -> vtctldata.WorkflowMirrorTrafficRequest + 119, // 119: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse + 120, // 120: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse + 121, // 121: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse + 122, // 122: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse + 123, // 123: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse + 124, // 124: vtctlservice.Vtctld.ApplyKeyspaceRoutingRules:output_type -> vtctldata.ApplyKeyspaceRoutingRulesResponse + 125, // 125: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse + 126, // 126: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse + 127, // 127: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse + 127, // 128: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse + 128, // 129: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse + 129, // 130: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse + 130, // 131: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse + 131, // 132: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse + 132, // 133: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse + 133, // 134: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse + 134, // 135: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse + 135, // 136: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse + 136, // 137: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse + 137, // 138: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse + 138, // 139: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse + 139, // 140: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse + 140, // 141: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse + 141, // 142: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse + 142, // 143: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse + 143, // 144: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse + 144, // 145: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:output_type -> vtctldata.ExecuteMultiFetchAsDBAResponse + 145, // 146: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse + 146, // 147: vtctlservice.Vtctld.ForceCutOverSchemaMigration:output_type -> vtctldata.ForceCutOverSchemaMigrationResponse + 147, // 148: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse + 148, // 149: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse + 149, // 150: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse + 150, // 151: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse + 151, // 152: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse + 152, // 153: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse + 153, // 154: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse + 154, // 155: vtctlservice.Vtctld.GetKeyspaceRoutingRules:output_type -> vtctldata.GetKeyspaceRoutingRulesResponse + 155, // 156: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse + 156, // 157: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse + 157, // 158: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse + 158, // 159: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse + 159, // 160: vtctlservice.Vtctld.GetShardReplication:output_type -> vtctldata.GetShardReplicationResponse + 160, // 161: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse + 161, // 162: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse + 162, // 163: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse + 163, // 164: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse + 164, // 165: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse + 165, // 166: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse + 166, // 167: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse + 167, // 168: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse + 168, // 169: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse + 169, // 170: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse + 170, // 171: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse + 171, // 172: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse + 172, // 173: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse + 173, // 174: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse + 174, // 175: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse + 175, // 176: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse + 176, // 177: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse + 177, // 178: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse + 178, // 179: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse + 179, // 180: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse + 180, // 181: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse + 181, // 182: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse + 182, // 183: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse + 178, // 184: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse + 183, // 185: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse + 184, // 186: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse + 185, // 187: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse + 186, // 188: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse + 187, // 189: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse + 188, // 190: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse + 189, // 191: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse + 190, // 192: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse + 191, // 193: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse + 192, // 194: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse + 193, // 195: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse + 194, // 196: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse + 195, // 197: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse + 196, // 198: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse + 178, // 199: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse + 197, // 200: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse + 198, // 201: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse + 199, // 202: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse + 200, // 203: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse + 201, // 204: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse + 202, // 205: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse + 203, // 206: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse + 204, // 207: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse + 205, // 208: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse + 206, // 209: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse + 207, // 210: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse + 208, // 211: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse + 209, // 212: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse + 210, // 213: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse + 211, // 214: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse + 212, // 215: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse + 213, // 216: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse + 214, // 217: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse + 215, // 218: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse + 216, // 219: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse + 217, // 220: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse + 218, // 221: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse + 219, // 222: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse + 220, // 223: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse + 221, // 224: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse + 222, // 225: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse + 223, // 226: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse + 224, // 227: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse + 225, // 228: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse + 226, // 229: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse + 227, // 230: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse + 228, // 231: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse + 178, // 232: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse + 229, // 233: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse + 230, // 234: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse + 231, // 235: vtctlservice.Vtctld.ApplyMirrorRules:output_type -> vtctldata.ApplyMirrorRulesResponse + 232, // 236: vtctlservice.Vtctld.GetMirrorRules:output_type -> vtctldata.GetMirrorRulesResponse + 233, // 237: vtctlservice.Vtctld.WorkflowMirrorTraffic:output_type -> vtctldata.WorkflowMirrorTrafficResponse + 119, // [119:238] is the sub-list for method output_type + 0, // [0:119] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go index 37448e9d850..e0d14c16a03 100644 --- a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go @@ -460,6 +460,11 @@ type VtctldClient interface { // WorkflowUpdate updates the configuration of a vreplication workflow // using the provided updated parameters. WorkflowUpdate(ctx context.Context, in *vtctldata.WorkflowUpdateRequest, opts ...grpc.CallOption) (*vtctldata.WorkflowUpdateResponse, error) + // ApplyMirrorRules applies the VSchema routing rules. + ApplyMirrorRules(ctx context.Context, in *vtctldata.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.ApplyMirrorRulesResponse, error) + // GetMirrorRules returns the VSchema routing rules. + GetMirrorRules(ctx context.Context, in *vtctldata.GetMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.GetMirrorRulesResponse, error) + WorkflowMirrorTraffic(ctx context.Context, in *vtctldata.WorkflowMirrorTrafficRequest, opts ...grpc.CallOption) (*vtctldata.WorkflowMirrorTrafficResponse, error) } type vtctldClient struct { @@ -1574,6 +1579,33 @@ func (c *vtctldClient) WorkflowUpdate(ctx context.Context, in *vtctldata.Workflo return out, nil } +func (c *vtctldClient) ApplyMirrorRules(ctx context.Context, in *vtctldata.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.ApplyMirrorRulesResponse, error) { + out := new(vtctldata.ApplyMirrorRulesResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/ApplyMirrorRules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) GetMirrorRules(ctx context.Context, in *vtctldata.GetMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.GetMirrorRulesResponse, error) { + out := new(vtctldata.GetMirrorRulesResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetMirrorRules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) WorkflowMirrorTraffic(ctx context.Context, in *vtctldata.WorkflowMirrorTrafficRequest, opts ...grpc.CallOption) (*vtctldata.WorkflowMirrorTrafficResponse, error) { + out := new(vtctldata.WorkflowMirrorTrafficResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/WorkflowMirrorTraffic", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // VtctldServer is the server API for Vtctld service. // All implementations must embed UnimplementedVtctldServer // for forward compatibility @@ -1902,6 +1934,11 @@ type VtctldServer interface { // WorkflowUpdate updates the configuration of a vreplication workflow // using the provided updated parameters. WorkflowUpdate(context.Context, *vtctldata.WorkflowUpdateRequest) (*vtctldata.WorkflowUpdateResponse, error) + // ApplyMirrorRules applies the VSchema routing rules. + ApplyMirrorRules(context.Context, *vtctldata.ApplyMirrorRulesRequest) (*vtctldata.ApplyMirrorRulesResponse, error) + // GetMirrorRules returns the VSchema routing rules. + GetMirrorRules(context.Context, *vtctldata.GetMirrorRulesRequest) (*vtctldata.GetMirrorRulesResponse, error) + WorkflowMirrorTraffic(context.Context, *vtctldata.WorkflowMirrorTrafficRequest) (*vtctldata.WorkflowMirrorTrafficResponse, error) mustEmbedUnimplementedVtctldServer() } @@ -2254,6 +2291,15 @@ func (UnimplementedVtctldServer) WorkflowSwitchTraffic(context.Context, *vtctlda func (UnimplementedVtctldServer) WorkflowUpdate(context.Context, *vtctldata.WorkflowUpdateRequest) (*vtctldata.WorkflowUpdateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method WorkflowUpdate not implemented") } +func (UnimplementedVtctldServer) ApplyMirrorRules(context.Context, *vtctldata.ApplyMirrorRulesRequest) (*vtctldata.ApplyMirrorRulesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ApplyMirrorRules not implemented") +} +func (UnimplementedVtctldServer) GetMirrorRules(context.Context, *vtctldata.GetMirrorRulesRequest) (*vtctldata.GetMirrorRulesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMirrorRules not implemented") +} +func (UnimplementedVtctldServer) WorkflowMirrorTraffic(context.Context, *vtctldata.WorkflowMirrorTrafficRequest) (*vtctldata.WorkflowMirrorTrafficResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method WorkflowMirrorTraffic not implemented") +} func (UnimplementedVtctldServer) mustEmbedUnimplementedVtctldServer() {} // UnsafeVtctldServer may be embedded to opt out of forward compatibility for this service. @@ -4346,6 +4392,60 @@ func _Vtctld_WorkflowUpdate_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _Vtctld_ApplyMirrorRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.ApplyMirrorRulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).ApplyMirrorRules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/ApplyMirrorRules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).ApplyMirrorRules(ctx, req.(*vtctldata.ApplyMirrorRulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_GetMirrorRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.GetMirrorRulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).GetMirrorRules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/GetMirrorRules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).GetMirrorRules(ctx, req.(*vtctldata.GetMirrorRulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_WorkflowMirrorTraffic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.WorkflowMirrorTrafficRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).WorkflowMirrorTraffic(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/WorkflowMirrorTraffic", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).WorkflowMirrorTraffic(ctx, req.(*vtctldata.WorkflowMirrorTrafficRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Vtctld_ServiceDesc is the grpc.ServiceDesc for Vtctld service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -4801,6 +4901,18 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "WorkflowUpdate", Handler: _Vtctld_WorkflowUpdate_Handler, }, + { + MethodName: "ApplyMirrorRules", + Handler: _Vtctld_ApplyMirrorRules_Handler, + }, + { + MethodName: "GetMirrorRules", + Handler: _Vtctld_GetMirrorRules_Handler, + }, + { + MethodName: "WorkflowMirrorTraffic", + Handler: _Vtctld_WorkflowMirrorTraffic_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/go/vt/proto/vttest/vttest.pb.go b/go/vt/proto/vttest/vttest.pb.go index 6295c1b6e68..157284d4d1f 100644 --- a/go/vt/proto/vttest/vttest.pb.go +++ b/go/vt/proto/vttest/vttest.pb.go @@ -212,6 +212,8 @@ type VTTestTopology struct { Cells []string `protobuf:"bytes,2,rep,name=cells,proto3" json:"cells,omitempty"` // routing rules for the topology. RoutingRules *vschema.RoutingRules `protobuf:"bytes,3,opt,name=routing_rules,json=routingRules,proto3" json:"routing_rules,omitempty"` + // mirror rules for the topology. + MirrorRules *vschema.MirrorRules `protobuf:"bytes,4,opt,name=mirror_rules,json=mirrorRules,proto3" json:"mirror_rules,omitempty"` } func (x *VTTestTopology) Reset() { @@ -267,6 +269,13 @@ func (x *VTTestTopology) GetRoutingRules() *vschema.RoutingRules { return nil } +func (x *VTTestTopology) GetMirrorRules() *vschema.MirrorRules { + if x != nil { + return x.MirrorRules + } + return nil +} + var File_vttest_proto protoreflect.FileDescriptor var file_vttest_proto_rawDesc = []byte{ @@ -286,7 +295,7 @@ var file_vttest_proto_rawDesc = []byte{ 0x6c, 0x69, 0x63, 0x61, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x72, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a, 0x04, 0x08, 0x03, - 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x92, + 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xcb, 0x01, 0x0a, 0x0e, 0x56, 0x54, 0x54, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x2e, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4b, 0x65, @@ -296,10 +305,13 @@ var file_vttest_proto_rawDesc = []byte{ 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x42, 0x25, 0x5a, 0x23, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, - 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x6c, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0c, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x75, + 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x0b, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x25, 0x5a, 0x23, + 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, + 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -320,16 +332,18 @@ var file_vttest_proto_goTypes = []interface{}{ (*Keyspace)(nil), // 1: vttest.Keyspace (*VTTestTopology)(nil), // 2: vttest.VTTestTopology (*vschema.RoutingRules)(nil), // 3: vschema.RoutingRules + (*vschema.MirrorRules)(nil), // 4: vschema.MirrorRules } var file_vttest_proto_depIdxs = []int32{ 0, // 0: vttest.Keyspace.shards:type_name -> vttest.Shard 1, // 1: vttest.VTTestTopology.keyspaces:type_name -> vttest.Keyspace 3, // 2: vttest.VTTestTopology.routing_rules:type_name -> vschema.RoutingRules - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 4, // 3: vttest.VTTestTopology.mirror_rules:type_name -> vschema.MirrorRules + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_vttest_proto_init() } diff --git a/go/vt/proto/vttest/vttest_vtproto.pb.go b/go/vt/proto/vttest/vttest_vtproto.pb.go index 8000a036a5f..82ad7a17e2c 100644 --- a/go/vt/proto/vttest/vttest_vtproto.pb.go +++ b/go/vt/proto/vttest/vttest_vtproto.pb.go @@ -72,6 +72,7 @@ func (m *VTTestTopology) CloneVT() *VTTestTopology { } r := &VTTestTopology{ RoutingRules: m.RoutingRules.CloneVT(), + MirrorRules: m.MirrorRules.CloneVT(), } if rhs := m.Keyspaces; rhs != nil { tmpContainer := make([]*Keyspace, len(rhs)) @@ -235,6 +236,16 @@ func (m *VTTestTopology) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.MirrorRules != nil { + size, err := m.MirrorRules.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } if m.RoutingRules != nil { size, err := m.RoutingRules.MarshalToSizedBufferVT(dAtA[:i]) if err != nil { @@ -346,6 +357,10 @@ func (m *VTTestTopology) SizeVT() (n int) { l = m.RoutingRules.SizeVT() n += 1 + l + sov(uint64(l)) } + if m.MirrorRules != nil { + l = m.MirrorRules.SizeVT() + n += 1 + l + sov(uint64(l)) + } n += len(m.unknownFields) return n } @@ -757,6 +772,42 @@ func (m *VTTestTopology) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MirrorRules", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MirrorRules == nil { + m.MirrorRules = &vschema.MirrorRules{} + } + if err := m.MirrorRules.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/topo/server.go b/go/vt/topo/server.go index 6e5fadd8b97..f2a3e8774e7 100644 --- a/go/vt/topo/server.go +++ b/go/vt/topo/server.go @@ -81,6 +81,7 @@ const ( ExternalClustersFile = "ExternalClusters" ShardRoutingRulesFile = "ShardRoutingRules" CommonRoutingRulesFile = "Rules" + MirrorRulesFile = "MirrorRules" ) // Path for all object types. diff --git a/go/vt/topo/srv_vschema.go b/go/vt/topo/srv_vschema.go index c118253e8a8..f69fca83537 100644 --- a/go/vt/topo/srv_vschema.go +++ b/go/vt/topo/srv_vschema.go @@ -210,6 +210,12 @@ func (ts *Server) RebuildSrvVSchema(ctx context.Context, cells []string) error { } srvVSchema.KeyspaceRoutingRules = krr + mr, err := ts.GetMirrorRules(ctx) + if err != nil { + return fmt.Errorf("GetMirrorRules failed: %v", err) + } + srvVSchema.MirrorRules = mr + // now save the SrvVSchema in all cells in parallel for _, cell := range cells { wg.Add(1) diff --git a/go/vt/topo/topotests/srv_vschema_test.go b/go/vt/topo/topotests/srv_vschema_test.go index 85a2d65c4ec..8fd818150b0 100644 --- a/go/vt/topo/topotests/srv_vschema_test.go +++ b/go/vt/topo/topotests/srv_vschema_test.go @@ -29,6 +29,7 @@ import ( func TestRebuildVSchema(t *testing.T) { emptySrvVSchema := &vschemapb.SrvVSchema{ + MirrorRules: &vschemapb.MirrorRules{}, RoutingRules: &vschemapb.RoutingRules{}, ShardRoutingRules: &vschemapb.ShardRoutingRules{}, } @@ -52,6 +53,7 @@ func TestRebuildVSchema(t *testing.T) { // create a keyspace, rebuild, should see an empty entry emptyKs1SrvVSchema := &vschemapb.SrvVSchema{ + MirrorRules: &vschemapb.MirrorRules{}, RoutingRules: &vschemapb.RoutingRules{}, ShardRoutingRules: &vschemapb.ShardRoutingRules{}, Keyspaces: map[string]*vschemapb.Keyspace{ @@ -81,6 +83,7 @@ func TestRebuildVSchema(t *testing.T) { t.Errorf("RebuildVSchema failed: %v", err) } wanted1 := &vschemapb.SrvVSchema{ + MirrorRules: &vschemapb.MirrorRules{}, RoutingRules: &vschemapb.RoutingRules{}, ShardRoutingRules: &vschemapb.ShardRoutingRules{}, Keyspaces: map[string]*vschemapb.Keyspace{ @@ -122,6 +125,7 @@ func TestRebuildVSchema(t *testing.T) { t.Errorf("RebuildVSchema failed: %v", err) } wanted2 := &vschemapb.SrvVSchema{ + MirrorRules: &vschemapb.MirrorRules{}, RoutingRules: &vschemapb.RoutingRules{}, ShardRoutingRules: &vschemapb.ShardRoutingRules{}, Keyspaces: map[string]*vschemapb.Keyspace{ @@ -160,6 +164,7 @@ func TestRebuildVSchema(t *testing.T) { t.Errorf("RebuildVSchema failed: %v", err) } wanted3 := &vschemapb.SrvVSchema{ + MirrorRules: &vschemapb.MirrorRules{}, RoutingRules: rr, ShardRoutingRules: &vschemapb.ShardRoutingRules{}, Keyspaces: map[string]*vschemapb.Keyspace{ diff --git a/go/vt/topo/vschema.go b/go/vt/topo/vschema.go index c6845691b25..d9802da2c35 100644 --- a/go/vt/topo/vschema.go +++ b/go/vt/topo/vschema.go @@ -212,3 +212,39 @@ func (ts *Server) GetKeyspaceRoutingRules(ctx context.Context) (*vschemapb.Keysp } return rules, nil } + +// GetMirrorRules fetches the mirror rules from the topo. +func (ts *Server) GetMirrorRules(ctx context.Context) (*vschemapb.MirrorRules, error) { + rr := &vschemapb.MirrorRules{} + data, _, err := ts.globalCell.Get(ctx, MirrorRulesFile) + if err != nil { + if IsErrType(err, NoNode) { + return rr, nil + } + return nil, err + } + err = rr.UnmarshalVT(data) + if err != nil { + return nil, vterrors.Wrapf(err, "bad mirror rules data: %q", data) + } + return rr, nil +} + +// SaveMirrorRules saves the mirror rules into the topo. +func (ts *Server) SaveMirrorRules(ctx context.Context, mirrorRules *vschemapb.MirrorRules) error { + data, err := mirrorRules.MarshalVT() + if err != nil { + return err + } + + if len(data) == 0 { + // No vschema, remove it. So we can remove the keyspace. + if err := ts.globalCell.Delete(ctx, MirrorRulesFile, nil); err != nil && !IsErrType(err, NoNode) { + return err + } + return nil + } + + _, err = ts.globalCell.Update(ctx, MirrorRulesFile, data, nil) + return err +} diff --git a/go/vt/topotools/mirror_rules.go b/go/vt/topotools/mirror_rules.go new file mode 100644 index 00000000000..3076a12b394 --- /dev/null +++ b/go/vt/topotools/mirror_rules.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package topotools + +import ( + "context" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" + + vschemapb "vitess.io/vitess/go/vt/proto/vschema" +) + +func GetMirrorRulesMap(rules *vschemapb.MirrorRules) map[string]map[string]float32 { + if rules == nil { + return nil + } + rulesMap := make(map[string]map[string]float32) + for _, mr := range rules.Rules { + if _, ok := rulesMap[mr.FromTable]; !ok { + rulesMap[mr.FromTable] = make(map[string]float32) + } + rulesMap[mr.FromTable][mr.ToTable] = mr.Percent + } + return rulesMap +} + +// GetMirrorRules fetches mirror rules from the topology server and returns a +// mapping of fromTable=>toTable=>percent. +func GetMirrorRules(ctx context.Context, ts *topo.Server) (map[string]map[string]float32, error) { + mrs, err := ts.GetMirrorRules(ctx) + if err != nil { + return nil, err + } + + rules := GetMirrorRulesMap(mrs) + + return rules, nil +} + +// SaveMirrorRules converts a mapping of fromTable=>[]toTables into a +// vschemapb.MirrorRules protobuf message and saves it in the topology. +func SaveMirrorRules(ctx context.Context, ts *topo.Server, rules map[string]map[string]float32) error { + log.Infof("Saving mirror rules %v\n", rules) + + rrs := &vschemapb.MirrorRules{Rules: make([]*vschemapb.MirrorRule, 0)} + for fromTable, mrs := range rules { + for toTable, percent := range mrs { + rrs.Rules = append(rrs.Rules, &vschemapb.MirrorRule{ + FromTable: fromTable, + Percent: percent, + ToTable: toTable, + }) + } + } + + return ts.SaveMirrorRules(ctx, rrs) +} diff --git a/go/vt/topotools/mirror_rules_test.go b/go/vt/topotools/mirror_rules_test.go new file mode 100644 index 00000000000..3ce25cb4de6 --- /dev/null +++ b/go/vt/topotools/mirror_rules_test.go @@ -0,0 +1,79 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package topotools + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +func TestMirrorRulesRoundTrip(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ts := memorytopo.NewServer(ctx, "zone1") + defer ts.Close() + + rules := map[string]map[string]float32{ + "k1.t1@replica": { + "k2": 50.0, + }, + "k1.t4": { + "k3": 75.0, + }, + } + + err := SaveMirrorRules(ctx, ts, rules) + require.NoError(t, err, "could not save mirror rules to topo %v", rules) + + roundtripRules, err := GetMirrorRules(ctx, ts) + require.NoError(t, err, "could not fetch mirror rules from topo") + + assert.Equal(t, rules, roundtripRules) +} + +func TestMirrorRulesErrors(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ts, factory := memorytopo.NewServerAndFactory(ctx, "zone1") + defer ts.Close() + factory.SetError(errors.New("topo failure for testing")) + + t.Run("GetMirrorRules error", func(t *testing.T) { + rules, err := GetMirrorRules(ctx, ts) + assert.Error(t, err, "expected error from GetMirrorRules, got rules=%v", rules) + }) + + t.Run("SaveMirrorRules error", func(t *testing.T) { + rules := map[string]map[string]float32{ + "k1.t1@replica": { + "k2": 50.0, + }, + "k1.t4": { + "k3": 75.0, + }, + } + + err := SaveMirrorRules(ctx, ts, rules) + assert.Error(t, err, "expected error from SaveMirrorRules, got rules=%v", rules) + }) +} diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index a4b6a1a61f3..2fe6e6ef839 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -165,6 +165,23 @@ func InitRoutingRules( return ts.RebuildSrvVSchema(ctx, nil) } +// InitMirrorRules saves the mirror rules into ts and reloads the vschema. +func InitMirrorRules( + ctx context.Context, + ts *topo.Server, + mr *vschemapb.MirrorRules, +) error { + if mr == nil { + return nil + } + + if err := ts.SaveMirrorRules(ctx, mr); err != nil { + return err + } + + return ts.RebuildSrvVSchema(ctx, nil) +} + // InitTabletMap creates the action tms and associated data structures // for all tablets, based on the vttest proto parameter. func InitTabletMap( diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index ff753111020..c8bb47b470f 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -56,6 +56,15 @@ func (client *gRPCVtctldClient) ApplyKeyspaceRoutingRules(ctx context.Context, i return client.c.ApplyKeyspaceRoutingRules(ctx, in, opts...) } +// ApplyMirrorRules is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) ApplyMirrorRules(ctx context.Context, in *vtctldatapb.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyMirrorRulesResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.ApplyMirrorRules(ctx, in, opts...) +} + // ApplyRoutingRules is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) ApplyRoutingRules(ctx context.Context, in *vtctldatapb.ApplyRoutingRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyRoutingRulesResponse, error) { if client.c == nil { @@ -353,6 +362,15 @@ func (client *gRPCVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldatap return client.c.GetKeyspaces(ctx, in, opts...) } +// GetMirrorRules is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) GetMirrorRules(ctx context.Context, in *vtctldatapb.GetMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.GetMirrorRulesResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.GetMirrorRules(ctx, in, opts...) +} + // GetPermissions is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) GetPermissions(ctx context.Context, in *vtctldatapb.GetPermissionsRequest, opts ...grpc.CallOption) (*vtctldatapb.GetPermissionsResponse, error) { if client.c == nil { @@ -1037,6 +1055,15 @@ func (client *gRPCVtctldClient) WorkflowDelete(ctx context.Context, in *vtctldat return client.c.WorkflowDelete(ctx, in, opts...) } +// WorkflowMirrorTraffic is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) WorkflowMirrorTraffic(ctx context.Context, in *vtctldatapb.WorkflowMirrorTrafficRequest, opts ...grpc.CallOption) (*vtctldatapb.WorkflowMirrorTrafficResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.WorkflowMirrorTraffic(ctx, in, opts...) +} + // WorkflowStatus is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) WorkflowStatus(ctx context.Context, in *vtctldatapb.WorkflowStatusRequest, opts ...grpc.CallOption) (*vtctldatapb.WorkflowStatusResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index e2d7edcf2f5..aecf61b217d 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -5057,6 +5057,67 @@ func (s *VtctldServer) WorkflowUpdate(ctx context.Context, req *vtctldatapb.Work return resp, err } +// ApplyMirrorRules is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) ApplyMirrorRules(ctx context.Context, req *vtctldatapb.ApplyMirrorRulesRequest) (resp *vtctldatapb.ApplyMirrorRulesResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.ApplyMirrorRules") + defer span.Finish() + + defer panicHandler(&err) + + span.Annotate("skip_rebuild", req.SkipRebuild) + span.Annotate("rebuild_cells", strings.Join(req.RebuildCells, ",")) + + if err = s.ts.SaveMirrorRules(ctx, req.MirrorRules); err != nil { + return nil, err + } + + resp = &vtctldatapb.ApplyMirrorRulesResponse{} + + if req.SkipRebuild { + log.Warningf("Skipping rebuild of SrvVSchema, will need to run RebuildVSchemaGraph for changes to take effect") + return resp, nil + } + + if err = s.ts.RebuildSrvVSchema(ctx, req.RebuildCells); err != nil { + err = vterrors.Wrapf(err, "RebuildSrvVSchema(%v) failed: %v", req.RebuildCells, err) + return nil, err + } + + return resp, nil +} + +// GetMirrorRules is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) GetMirrorRules(ctx context.Context, req *vtctldatapb.GetMirrorRulesRequest) (resp *vtctldatapb.GetMirrorRulesResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.GetMirrorRules") + defer span.Finish() + + defer panicHandler(&err) + + mr, err := s.ts.GetMirrorRules(ctx) + if err != nil { + return nil, err + } + + return &vtctldatapb.GetMirrorRulesResponse{ + MirrorRules: mr, + }, nil +} + +// WorkflowMirrorTraffic is part of the vtctlservicepb.VtctldServer interface. +func (s *VtctldServer) WorkflowMirrorTraffic(ctx context.Context, req *vtctldatapb.WorkflowMirrorTrafficRequest) (resp *vtctldatapb.WorkflowMirrorTrafficResponse, err error) { + span, ctx := trace.NewSpan(ctx, "VtctldServer.WorkflowMirrorTraffic") + defer span.Finish() + + defer panicHandler(&err) + + span.Annotate("keyspace", req.Keyspace) + span.Annotate("workflow", req.Workflow) + span.Annotate("percent", req.Percent) + + resp, err = s.ws.WorkflowMirrorTraffic(ctx, req) + return resp, err +} + // StartServer registers a VtctldServer for RPCs on the given gRPC server. func StartServer(s *grpc.Server, env *vtenv.Environment, ts *topo.Server) { vtctlservicepb.RegisterVtctldServer(s, NewVtctldServer(env, ts)) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 426f54c074b..d1f2c7e11ac 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -665,6 +665,9 @@ func TestApplyVSchema(t *testing.T) { Sharded: false, }, }, + MirrorRules: &vschemapb.MirrorRules{ + Rules: []*vschemapb.MirrorRule{}, + }, RoutingRules: &vschemapb.RoutingRules{ Rules: []*vschemapb.RoutingRule{}, }, diff --git a/go/vt/vtctl/localvtctldclient/client_gen.go b/go/vt/vtctl/localvtctldclient/client_gen.go index e854514dcfa..79778913bd4 100644 --- a/go/vt/vtctl/localvtctldclient/client_gen.go +++ b/go/vt/vtctl/localvtctldclient/client_gen.go @@ -44,6 +44,11 @@ func (client *localVtctldClient) ApplyKeyspaceRoutingRules(ctx context.Context, return client.s.ApplyKeyspaceRoutingRules(ctx, in) } +// ApplyMirrorRules is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) ApplyMirrorRules(ctx context.Context, in *vtctldatapb.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyMirrorRulesResponse, error) { + return client.s.ApplyMirrorRules(ctx, in) +} + // ApplyRoutingRules is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) ApplyRoutingRules(ctx context.Context, in *vtctldatapb.ApplyRoutingRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyRoutingRulesResponse, error) { return client.s.ApplyRoutingRules(ctx, in) @@ -301,6 +306,11 @@ func (client *localVtctldClient) GetKeyspaces(ctx context.Context, in *vtctldata return client.s.GetKeyspaces(ctx, in) } +// GetMirrorRules is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) GetMirrorRules(ctx context.Context, in *vtctldatapb.GetMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.GetMirrorRulesResponse, error) { + return client.s.GetMirrorRules(ctx, in) +} + // GetPermissions is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) GetPermissions(ctx context.Context, in *vtctldatapb.GetPermissionsRequest, opts ...grpc.CallOption) (*vtctldatapb.GetPermissionsResponse, error) { return client.s.GetPermissions(ctx, in) @@ -727,6 +737,11 @@ func (client *localVtctldClient) WorkflowDelete(ctx context.Context, in *vtctlda return client.s.WorkflowDelete(ctx, in) } +// WorkflowMirrorTraffic is part of the vtctlservicepb.VtctldClient interface. +func (client *localVtctldClient) WorkflowMirrorTraffic(ctx context.Context, in *vtctldatapb.WorkflowMirrorTrafficRequest, opts ...grpc.CallOption) (*vtctldatapb.WorkflowMirrorTrafficResponse, error) { + return client.s.WorkflowMirrorTraffic(ctx, in) +} + // WorkflowStatus is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) WorkflowStatus(ctx context.Context, in *vtctldatapb.WorkflowStatusRequest, opts ...grpc.CallOption) (*vtctldatapb.WorkflowStatusResponse, error) { return client.s.WorkflowStatus(ctx, in) diff --git a/go/vt/vtctl/workflow/materializer_env_test.go b/go/vt/vtctl/workflow/env_test.go similarity index 54% rename from go/vt/vtctl/workflow/materializer_env_test.go rename to go/vt/vtctl/workflow/env_test.go index 587712f620c..6740f3a9ba0 100644 --- a/go/vt/vtctl/workflow/materializer_env_test.go +++ b/go/vt/vtctl/workflow/env_test.go @@ -26,13 +26,17 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" "vitess.io/vitess/go/protoutil" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/tmutils" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tmclient" @@ -42,6 +46,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) @@ -51,7 +56,7 @@ type queryResult struct { result *querypb.QueryResult } -type testMaterializerEnv struct { +type testEnv struct { ws *Server ms *vtctldatapb.MaterializeSettings sources []string @@ -59,41 +64,66 @@ type testMaterializerEnv struct { tablets map[int]*topodatapb.Tablet topoServ *topo.Server cell string - tmc *testMaterializerTMClient + tmc *testTMClient + venv *vtenv.Environment } //---------------------------------------------- -// testMaterializerEnv +// testEnv func TestMain(m *testing.M) { _flag.ParseFlagsForTest() os.Exit(m.Run()) } -func newTestMaterializerEnv(t *testing.T, ctx context.Context, ms *vtctldatapb.MaterializeSettings, sources, targets []string) *testMaterializerEnv { +func newTestEnv(t *testing.T, ctx context.Context, ms *vtctldatapb.MaterializeSettings, sourceShards, targetShards []string) *testEnv { t.Helper() - env := &testMaterializerEnv{ + + tmc := newTestTMClient(ms.SourceKeyspace, sourceShards, ms.TableSettings) + topoServ := memorytopo.NewServer(ctx, "cell") + venv := vtenv.NewTestEnv() + env := &testEnv{ ms: ms, - sources: sources, - targets: targets, + sources: sourceShards, + targets: targetShards, tablets: make(map[int]*topodatapb.Tablet), - topoServ: memorytopo.NewServer(ctx, "cell"), + topoServ: topoServ, cell: "cell", - tmc: newTestMaterializerTMClient(), + tmc: tmc, + ws: NewServer(venv, topoServ, tmc), + venv: venv, } - venv := vtenv.NewTestEnv() - env.ws = NewServer(venv, env.topoServ, env.tmc) + + require.NoError(t, topoServ.CreateKeyspace(ctx, ms.SourceKeyspace, &topodatapb.Keyspace{})) + require.NoError(t, topoServ.SaveVSchema(ctx, ms.SourceKeyspace, &vschemapb.Keyspace{})) + if ms.SourceKeyspace != ms.TargetKeyspace { + require.NoError(t, topoServ.CreateKeyspace(ctx, ms.TargetKeyspace, &topodatapb.Keyspace{})) + require.NoError(t, topoServ.SaveVSchema(ctx, ms.TargetKeyspace, &vschemapb.Keyspace{})) + } + logger := logutil.NewConsoleLogger() + require.NoError(t, topoServ.RebuildSrvVSchema(ctx, []string{"cell"})) + tabletID := 100 - for _, shard := range sources { - _ = env.addTablet(tabletID, env.ms.SourceKeyspace, shard, topodatapb.TabletType_PRIMARY) + sourceShardsMap := make(map[string]any) + for _, shard := range sourceShards { + sourceShardsMap[shard] = nil + require.NoError(t, topoServ.CreateShard(ctx, ms.SourceKeyspace, shard)) + _ = env.addTablet(t, tabletID, env.ms.SourceKeyspace, shard, topodatapb.TabletType_PRIMARY) tabletID += 10 } - if ms.SourceKeyspace != ms.TargetKeyspace { - tabletID = 200 - for _, shard := range targets { - _ = env.addTablet(tabletID, env.ms.TargetKeyspace, shard, topodatapb.TabletType_PRIMARY) - tabletID += 10 + + require.NoError(t, topotools.RebuildKeyspace(ctx, logger, topoServ, ms.SourceKeyspace, []string{"cell"}, false)) + + tabletID = 200 + for _, shard := range targetShards { + if ms.SourceKeyspace == ms.TargetKeyspace { + if _, ok := sourceShardsMap[shard]; ok { + continue + } } + require.NoError(t, topoServ.CreateShard(ctx, ms.TargetKeyspace, shard)) + _ = env.addTablet(t, tabletID, env.ms.TargetKeyspace, shard, topodatapb.TabletType_PRIMARY) + tabletID += 10 } for _, ts := range ms.TableSettings { @@ -115,16 +145,24 @@ func newTestMaterializerEnv(t *testing.T, ctx context.Context, ms *vtctldatapb.M }}, } } + + if ms.SourceKeyspace != ms.TargetKeyspace { + require.NoError(t, topotools.RebuildKeyspace(ctx, logger, topoServ, ms.TargetKeyspace, []string{"cell"}, false)) + } + return env } -func (env *testMaterializerEnv) close() { +func (env *testEnv) close() { for _, t := range env.tablets { env.deleteTablet(t) } } -func (env *testMaterializerEnv) addTablet(id int, keyspace, shard string, tabletType topodatapb.TabletType) *topodatapb.Tablet { +func (env *testEnv) addTablet(t *testing.T, id int, keyspace, shard string, tabletType topodatapb.TabletType) *topodatapb.Tablet { + keyRanges, err := key.ParseShardingSpec(shard) + require.NoError(t, err) + require.Len(t, keyRanges, 1) tablet := &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ Cell: env.cell, @@ -132,7 +170,7 @@ func (env *testMaterializerEnv) addTablet(id int, keyspace, shard string, tablet }, Keyspace: keyspace, Shard: shard, - KeyRange: &topodatapb.KeyRange{}, + KeyRange: keyRanges[0], Type: tabletType, PortMap: map[string]int32{ "test": int32(id), @@ -155,17 +193,21 @@ func (env *testMaterializerEnv) addTablet(id int, keyspace, shard string, tablet return tablet } -func (env *testMaterializerEnv) deleteTablet(tablet *topodatapb.Tablet) { +func (env *testEnv) deleteTablet(tablet *topodatapb.Tablet) { _ = env.topoServ.DeleteTablet(context.Background(), tablet.Alias) delete(env.tablets, int(tablet.Alias.Uid)) } -//---------------------------------------------- -// testMaterializerTMClient +// ---------------------------------------------- +// testTMClient +type readVReplicationWorkflowFunc = func(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) -type testMaterializerTMClient struct { +type testTMClient struct { tmclient.TabletManagerClient - schema map[string]*tabletmanagerdatapb.SchemaDefinition + keyspace string + schema map[string]*tabletmanagerdatapb.SchemaDefinition + sourceShards []string + tableSettings []*vtctldatapb.TableMaterializeSettings mu sync.Mutex vrQueries map[int][]*queryResult @@ -173,17 +215,23 @@ type testMaterializerTMClient struct { // Used to confirm the number of times WorkflowDelete was called. workflowDeleteCalls int + + // Used to override the response to ReadVReplicationWorkflow. + readVReplicationWorkflow readVReplicationWorkflowFunc } -func newTestMaterializerTMClient() *testMaterializerTMClient { - return &testMaterializerTMClient{ +func newTestTMClient(keyspace string, sourceShards []string, tableSettings []*vtctldatapb.TableMaterializeSettings) *testTMClient { + return &testTMClient{ + keyspace: keyspace, schema: make(map[string]*tabletmanagerdatapb.SchemaDefinition), + sourceShards: sourceShards, + tableSettings: tableSettings, vrQueries: make(map[int][]*queryResult), createVReplicationWorkflowRequests: make(map[uint32]*tabletmanagerdatapb.CreateVReplicationWorkflowRequest), } } -func (tmc *testMaterializerTMClient) CreateVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.CreateVReplicationWorkflowRequest) (*tabletmanagerdatapb.CreateVReplicationWorkflowResponse, error) { +func (tmc *testTMClient) CreateVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.CreateVReplicationWorkflowRequest) (*tabletmanagerdatapb.CreateVReplicationWorkflowResponse, error) { if expect := tmc.createVReplicationWorkflowRequests[tablet.Alias.Uid]; expect != nil { if !proto.Equal(expect, request) { return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected CreateVReplicationWorkflow request: got %+v, want %+v", request, expect) @@ -193,34 +241,49 @@ func (tmc *testMaterializerTMClient) CreateVReplicationWorkflow(ctx context.Cont return &tabletmanagerdatapb.CreateVReplicationWorkflowResponse{Result: sqltypes.ResultToProto3(res)}, nil } -func (tmc *testMaterializerTMClient) ReadVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { +func (tmc *testTMClient) ReadVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { + if tmc.readVReplicationWorkflow != nil { + return tmc.readVReplicationWorkflow(ctx, tablet, request) + } + workflowType := binlogdatapb.VReplicationWorkflowType_MoveTables if strings.Contains(request.Workflow, "lookup") { workflowType = binlogdatapb.VReplicationWorkflowType_CreateLookupIndex } + + rules := make([]*binlogdatapb.Rule, len(tmc.tableSettings)) + if len(rules) == 0 { + rules = append(rules, &binlogdatapb.Rule{Match: "table1"}) + } else { + for i, tableSetting := range tmc.tableSettings { + rules[i] = &binlogdatapb.Rule{ + Match: tableSetting.TargetTable, + Filter: tableSetting.SourceExpression, + } + } + } + + streams := make([]*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream, len(tmc.sourceShards)) + for i, shard := range tmc.sourceShards { + streams[i] = &tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + Id: int32(i + 1), + Bls: &binlogdatapb.BinlogSource{ + Keyspace: tmc.keyspace, + Shard: shard, + Filter: &binlogdatapb.Filter{ + Rules: rules, + }, + }, + } + } return &tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ Workflow: request.Workflow, WorkflowType: workflowType, - Streams: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ - { - Id: 1, - Bls: &binlogdatapb.BinlogSource{ - Keyspace: "sourceks", - Shard: "0", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{ - { - Match: ".*", - }, - }, - }, - }, - }, - }, + Streams: streams, }, nil } -func (tmc *testMaterializerTMClient) DeleteVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.DeleteVReplicationWorkflowRequest) (response *tabletmanagerdatapb.DeleteVReplicationWorkflowResponse, err error) { +func (tmc *testTMClient) DeleteVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.DeleteVReplicationWorkflowRequest) (response *tabletmanagerdatapb.DeleteVReplicationWorkflowResponse, err error) { tmc.mu.Lock() defer tmc.mu.Unlock() tmc.workflowDeleteCalls++ @@ -231,7 +294,7 @@ func (tmc *testMaterializerTMClient) DeleteVReplicationWorkflow(ctx context.Cont }, nil } -func (tmc *testMaterializerTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.GetSchemaRequest) (*tabletmanagerdatapb.SchemaDefinition, error) { +func (tmc *testTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.GetSchemaRequest) (*tabletmanagerdatapb.SchemaDefinition, error) { schemaDefn := &tabletmanagerdatapb.SchemaDefinition{} for _, table := range request.Tables { if table == "/.*/" { @@ -254,7 +317,7 @@ func (tmc *testMaterializerTMClient) GetSchema(ctx context.Context, tablet *topo return schemaDefn, nil } -func (tmc *testMaterializerTMClient) expectVRQuery(tabletID int, query string, result *sqltypes.Result) { +func (tmc *testTMClient) expectVRQuery(tabletID int, query string, result *sqltypes.Result) { tmc.mu.Lock() defer tmc.mu.Unlock() @@ -264,14 +327,14 @@ func (tmc *testMaterializerTMClient) expectVRQuery(tabletID int, query string, r }) } -func (tmc *testMaterializerTMClient) expectCreateVReplicationWorkflowRequest(tabletID uint32, req *tabletmanagerdatapb.CreateVReplicationWorkflowRequest) { +func (tmc *testTMClient) expectCreateVReplicationWorkflowRequest(tabletID uint32, req *tabletmanagerdatapb.CreateVReplicationWorkflowRequest) { tmc.mu.Lock() defer tmc.mu.Unlock() tmc.createVReplicationWorkflowRequests[tabletID] = req } -func (tmc *testMaterializerTMClient) verifyQueries(t *testing.T) { +func (tmc *testTMClient) verifyQueries(t *testing.T) { t.Helper() tmc.mu.Lock() defer tmc.mu.Unlock() @@ -287,7 +350,7 @@ func (tmc *testMaterializerTMClient) verifyQueries(t *testing.T) { } } -func (tmc *testMaterializerTMClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) { +func (tmc *testTMClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) { tmc.mu.Lock() defer tmc.mu.Unlock() @@ -308,17 +371,17 @@ func (tmc *testMaterializerTMClient) VReplicationExec(ctx context.Context, table return qrs[0].result, nil } -func (tmc *testMaterializerTMClient) ExecuteFetchAsDba(ctx context.Context, tablet *topodatapb.Tablet, usePool bool, req *tabletmanagerdatapb.ExecuteFetchAsDbaRequest) (*querypb.QueryResult, error) { +func (tmc *testTMClient) ExecuteFetchAsDba(ctx context.Context, tablet *topodatapb.Tablet, usePool bool, req *tabletmanagerdatapb.ExecuteFetchAsDbaRequest) (*querypb.QueryResult, error) { // Reuse VReplicationExec return tmc.VReplicationExec(ctx, tablet, string(req.Query)) } -func (tmc *testMaterializerTMClient) ExecuteFetchAsAllPrivs(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ExecuteFetchAsAllPrivsRequest) (*querypb.QueryResult, error) { +func (tmc *testTMClient) ExecuteFetchAsAllPrivs(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ExecuteFetchAsAllPrivsRequest) (*querypb.QueryResult, error) { return nil, nil } // Note: ONLY breaks up change.SQL into individual statements and executes it. Does NOT fully implement ApplySchema. -func (tmc *testMaterializerTMClient) ApplySchema(ctx context.Context, tablet *topodatapb.Tablet, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) { +func (tmc *testTMClient) ApplySchema(ctx context.Context, tablet *topodatapb.Tablet, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) { stmts := strings.Split(change.SQL, ";") for _, stmt := range stmts { @@ -335,7 +398,7 @@ func (tmc *testMaterializerTMClient) ApplySchema(ctx context.Context, tablet *to return nil, nil } -func (tmc *testMaterializerTMClient) VDiff(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.VDiffRequest) (*tabletmanagerdatapb.VDiffResponse, error) { +func (tmc *testTMClient) VDiff(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.VDiffRequest) (*tabletmanagerdatapb.VDiffResponse, error) { return &tabletmanagerdatapb.VDiffResponse{ Id: 1, VdiffUuid: req.VdiffUuid, @@ -345,13 +408,13 @@ func (tmc *testMaterializerTMClient) VDiff(ctx context.Context, tablet *topodata }, nil } -func (tmc *testMaterializerTMClient) HasVReplicationWorkflows(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.HasVReplicationWorkflowsRequest) (*tabletmanagerdatapb.HasVReplicationWorkflowsResponse, error) { +func (tmc *testTMClient) HasVReplicationWorkflows(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.HasVReplicationWorkflowsRequest) (*tabletmanagerdatapb.HasVReplicationWorkflowsResponse, error) { return &tabletmanagerdatapb.HasVReplicationWorkflowsResponse{ Has: false, }, nil } -func (tmc *testMaterializerTMClient) ReadVReplicationWorkflows(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ReadVReplicationWorkflowsRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowsResponse, error) { +func (tmc *testTMClient) ReadVReplicationWorkflows(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ReadVReplicationWorkflowsRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowsResponse, error) { workflowType := binlogdatapb.VReplicationWorkflowType_MoveTables if len(req.IncludeWorkflows) > 0 { for _, wf := range req.IncludeWorkflows { @@ -359,31 +422,33 @@ func (tmc *testMaterializerTMClient) ReadVReplicationWorkflows(ctx context.Conte workflowType = binlogdatapb.VReplicationWorkflowType_CreateLookupIndex } } + streams := make([]*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream, len(tmc.sourceShards)) + for i, shard := range tmc.sourceShards { + streams[i] = &tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + Id: 1, + State: binlogdatapb.VReplicationWorkflowState_Running, + Bls: &binlogdatapb.BinlogSource{ + Keyspace: tmc.keyspace, + Shard: shard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{ + { + Match: ".*", + }, + }, + }, + }, + Pos: "MySQL56/" + position, + TimeUpdated: protoutil.TimeToProto(time.Now()), + TimeHeartbeat: protoutil.TimeToProto(time.Now()), + } + } return &tabletmanagerdatapb.ReadVReplicationWorkflowsResponse{ Workflows: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ { Workflow: req.IncludeWorkflows[0], WorkflowType: workflowType, - Streams: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ - { - Id: 1, - State: binlogdatapb.VReplicationWorkflowState_Running, - Bls: &binlogdatapb.BinlogSource{ - Keyspace: "sourceks", - Shard: "0", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{ - { - Match: ".*", - }, - }, - }, - }, - Pos: "MySQL56/" + position, - TimeUpdated: protoutil.TimeToProto(time.Now()), - TimeHeartbeat: protoutil.TimeToProto(time.Now()), - }, - }, + Streams: streams, }, }, }, nil @@ -392,7 +457,7 @@ func (tmc *testMaterializerTMClient) ReadVReplicationWorkflows(ctx context.Conte } } -func (tmc *testMaterializerTMClient) UpdateVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.UpdateVReplicationWorkflowRequest) (*tabletmanagerdatapb.UpdateVReplicationWorkflowResponse, error) { +func (tmc *testTMClient) UpdateVReplicationWorkflow(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.UpdateVReplicationWorkflowRequest) (*tabletmanagerdatapb.UpdateVReplicationWorkflowResponse, error) { return &tabletmanagerdatapb.UpdateVReplicationWorkflowResponse{ Result: &querypb.QueryResult{ RowsAffected: 1, diff --git a/go/vt/vtctl/workflow/materializer_test.go b/go/vt/vtctl/workflow/materializer_test.go index 9a43ea5ed7e..15a4f1ec06b 100644 --- a/go/vt/vtctl/workflow/materializer_test.go +++ b/go/vt/vtctl/workflow/materializer_test.go @@ -507,7 +507,7 @@ func TestMigrateVSchema(t *testing.T) { SourceExpression: "select * from t1", }}, } - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() env.tmc.expectVRQuery(100, mzCheckJournal, &sqltypes.Result{}) @@ -557,7 +557,7 @@ func TestMoveTablesDDLFlag(t *testing.T) { t.Run(fmt.Sprintf("OnDDL Flag:%v", onDDLAction), func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() // This is the default and go does not marshal defaults // for prototext fields so we use the default insert stmt. @@ -606,7 +606,7 @@ func TestMoveTablesNoRoutingRules(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() // This is the default and go does not marshal defaults // for prototext fields so we use the default insert stmt. @@ -669,7 +669,7 @@ func TestCreateLookupVindexFull(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() specs := &vschemapb.Keyspace{ @@ -804,7 +804,7 @@ func TestCreateLookupVindexCreateDDL(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() vs := &vschemapb.Keyspace{ Sharded: true, @@ -1024,7 +1024,7 @@ func TestCreateLookupVindexSourceVSchema(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() specs := &vschemapb.Keyspace{ @@ -1263,7 +1263,7 @@ func TestCreateLookupVindexTargetVSchema(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() sourcevs := &vschemapb.Keyspace{ Sharded: true, @@ -1502,7 +1502,7 @@ func TestCreateLookupVindexSameKeyspace(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() specs := &vschemapb.Keyspace{ @@ -1615,7 +1615,7 @@ func TestCreateCustomizedVindex(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() specs := &vschemapb.Keyspace{ @@ -1741,7 +1741,7 @@ func TestCreateLookupVindexIgnoreNulls(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() specs := &vschemapb.Keyspace{ @@ -1862,7 +1862,7 @@ func TestStopAfterCopyFlag(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"0"}) defer env.close() specs := &vschemapb.Keyspace{ Vindexes: map[string]*vschemapb.Vindex{ @@ -1943,7 +1943,7 @@ func TestCreateLookupVindexFailures(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"-80", "80-"}) + env := newTestEnv(t, ctx, ms, []string{"0"}, []string{"-80", "80-"}) defer env.close() unique := map[string]*vschemapb.Vindex{ @@ -2507,7 +2507,7 @@ func TestKeyRangesEqualOptimization(t *testing.T) { SourceShards: tc.moveTablesReq.SourceShards, TableSettings: tableSettings, } - env := newTestMaterializerEnv(t, ctx, ms, tc.sourceShards, tc.targetShards) + env := newTestEnv(t, ctx, ms, tc.sourceShards, tc.targetShards) defer env.close() // Target is always sharded. diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 17b01736a77..d96397ad5c4 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -67,6 +67,7 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + "vitess.io/vitess/go/vt/proto/topodata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" @@ -959,10 +960,7 @@ func (s *Server) getWorkflowState(ctx context.Context, targetKeyspace, workflowN return ts, state, nil } - var ( - reverse bool - sourceKeyspace string - ) + var sourceKeyspace string // We reverse writes by using the source_keyspace.workflowname_reverse workflow // spec, so we need to use the source of the reverse workflow, which is the @@ -971,7 +969,7 @@ func (s *Server) getWorkflowState(ctx context.Context, targetKeyspace, workflowN // source to check if writes have been switched. if strings.HasSuffix(workflowName, "_reverse") { - reverse = true + state.IsReverse = true // Flip the source and target keyspaces. sourceKeyspace = state.TargetKeyspace targetKeyspace = state.SourceKeyspace @@ -1040,7 +1038,7 @@ func (s *Server) getWorkflowState(ctx context.Context, targetKeyspace, workflowN // We assume a consistent state, so only choose one shard. var shard *topo.ShardInfo - if reverse { + if state.IsReverse { shard = ts.TargetShards()[0] } else { shard = ts.SourceShards()[0] @@ -3195,6 +3193,12 @@ func (s *Server) switchReads(ctx context.Context, req *vtctldatapb.WorkflowSwitc return handleError("workflow validation failed", err) } + // Remove mirror rules for the specified tablet types. + if err := sw.mirrorTableTraffic(ctx, roTabletTypes, 0); err != nil { + return handleError(fmt.Sprintf("failed to remove mirror rules from source keyspace %s to target keyspace %s, workflow %s, for read-only tablet types", + ts.SourceKeyspaceName(), ts.TargetKeyspaceName(), ts.WorkflowName()), err) + } + // For reads, locking the source keyspace is sufficient. ctx, unlock, lockErr := sw.lockKeyspace(ctx, ts.SourceKeyspaceName(), "SwitchReads") if lockErr != nil { @@ -3267,6 +3271,12 @@ func (s *Server) switchWrites(ctx context.Context, req *vtctldatapb.WorkflowSwit } } + // Remove mirror rules for the primary tablet type. + if err := sw.mirrorTableTraffic(ctx, []topodata.TabletType{topodatapb.TabletType_PRIMARY}, 0); err != nil { + return handleError(fmt.Sprintf("failed to remove mirror rules from source keyspace %s to target keyspace %s, workflow %s, for primary tablet type", + ts.SourceKeyspaceName(), ts.TargetKeyspaceName(), ts.WorkflowName()), err) + } + // Need to lock both source and target keyspaces. tctx, sourceUnlock, lockErr := sw.lockKeyspace(ctx, ts.SourceKeyspaceName(), "SwitchWrites") if lockErr != nil { @@ -4008,3 +4018,82 @@ func (s *Server) getWorkflowStatus(ctx context.Context, keyspace string, workflo } return workflowStatus, nil } + +// WorkflowMirrorTraffic mirrors traffic from the source keyspace to the target keyspace. +func (s *Server) WorkflowMirrorTraffic(ctx context.Context, req *vtctldatapb.WorkflowMirrorTrafficRequest) (*vtctldatapb.WorkflowMirrorTrafficResponse, error) { + ts, startState, err := s.getWorkflowState(ctx, req.Keyspace, req.Workflow) + if err != nil { + return nil, err + } + + // Traffic mirroring was built with basic MoveTables workflows in mind. In + // theory, other workflow types (e.g. Migrate) and variants (e.g. partial, + // multi-tenant) could be supported. Until demand for these use cases + // arises, reject everything but basic MoveTables. + if startState.WorkflowType != TypeMoveTables { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid action for %s workflow: MirrorTraffic", string(startState.WorkflowType)) + } + if startState.IsReverse { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid action for reverse workflow: MirrorTraffic") + } + if ts.MigrationType() != binlogdatapb.MigrationType_TABLES { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid action for %s migration type: MirrorTraffic", binlogdatapb.MigrationType_name[int32(ts.MigrationType())]) + } + if ts.IsPartialMigration() { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid action for partial migration: MirrorTraffic") + } + if ts.IsMultiTenantMigration() { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid action for multi-tenant migration: MirrorTraffic") + } + + // Don't allow traffic to be mirrored if any traffic has been switched over + // to the target keyspace. + if len(startState.RdonlyCellsSwitched) > 0 || len(startState.ReplicaCellsSwitched) > 0 || startState.WritesSwitched { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot mirror traffic for workflow %s at this time: traffic is switched", startState.Workflow) + } + + if err := s.mirrorTraffic(ctx, req, ts, startState); err != nil { + return nil, err + } + + cmd := "MirrorTraffic" + resp := &vtctldatapb.WorkflowMirrorTrafficResponse{} + log.Infof("Mirror Traffic done for workflow %s.%s", req.Keyspace, req.Workflow) + resp.Summary = fmt.Sprintf("%s was successful for workflow %s.%s", cmd, req.Keyspace, req.Workflow) + // Reload the state after the MirrorTraffic operation + // and return that as a string. + keyspace := req.Keyspace + workflow := req.Workflow + resp.StartState = startState.String() + log.Infof("Before reloading workflow state after mirror traffic: %+v\n", resp.StartState) + _, currentState, err := s.getWorkflowState(ctx, keyspace, workflow) + if err != nil { + resp.CurrentState = fmt.Sprintf("Error reloading workflow state after mirror traffic: %v", err) + } else { + resp.CurrentState = currentState.String() + } + return resp, nil +} + +// mirrorTraffic manages mirror routing rules for tables in the workflow. +func (s *Server) mirrorTraffic(ctx context.Context, req *vtctldatapb.WorkflowMirrorTrafficRequest, ts *trafficSwitcher, state *State) (err error) { + // Consistently handle errors by logging and returning them. + handleError := func(message string, err error) error { + ts.Logger().Error(err) + return err + } + + log.Infof("Mirroring traffic: %s.%s, workflow state: %s", ts.targetKeyspace, ts.workflow, state.String()) + + sw := &switcher{ts: ts, s: s} + + if err := ts.validate(ctx); err != nil { + return handleError("workflow validation failed", err) + } + + if err := sw.mirrorTableTraffic(ctx, req.TabletTypes, req.Percent); err != nil { + return handleError("failed to mirror traffic for the tables", err) + } + + return nil +} diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go index 174cc2aaf6a..8a411d46c15 100644 --- a/go/vt/vtctl/workflow/server_test.go +++ b/go/vt/vtctl/workflow/server_test.go @@ -18,6 +18,7 @@ package workflow import ( "context" + "encoding/json" "fmt" "testing" @@ -29,11 +30,13 @@ import ( "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vttablet/tmclient" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -199,3 +202,416 @@ func TestVDiffCreate(t *testing.T) { }) } } + +func TestMirrorTraffic(t *testing.T) { + ctx := context.Background() + sourceKs := "source" + sourceShards := []string{"-"} + targetKs := "target" + targetShards := []string{"-80", "80-"} + table1 := "table1" + table2 := "table2" + workflow := "src2target" + + mirrorRules := map[string]map[string]float32{} + routingRules := map[string][]string{ + fmt.Sprintf("%s.%s@rdonly", sourceKs, table1): {fmt.Sprintf("%s.%s", targetKs, table1)}, + fmt.Sprintf("%s.%s@rdonly", sourceKs, table2): {fmt.Sprintf("%s.%s", targetKs, table2)}, + } + + tabletTypes := []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + } + + tests := []struct { + name string + + req *vtctldatapb.WorkflowMirrorTrafficRequest + mirrorRules map[string]map[string]float32 + routingRules map[string][]string + setup func(*testing.T, context.Context, *testEnv) + sourceKeyspace string + sourceShards []string + targetKeyspace string + targetShards []string + + wantErr string + wantMirrorRules map[string]map[string]float32 + }{ + { + name: "no such keyspace", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: "no_ks", + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + wantErr: "FindAllShardsInKeyspace(no_ks): List: node doesn't exist: keyspaces/no_ks/shards", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "no such workflow", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: "no_workflow", + TabletTypes: tabletTypes, + Percent: 50.0, + }, + setup: func(t *testing.T, ctx context.Context, te *testEnv) { + te.tmc.readVReplicationWorkflow = func( + ctx context.Context, + tablet *topodatapb.Tablet, + request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest, + ) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { + return nil, nil + } + }, + wantErr: "no streams found in keyspace target for no_workflow", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "cannot mirror traffic for migrate workflows", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: "migrate", + TabletTypes: tabletTypes, + Percent: 50.0, + }, + setup: func(t *testing.T, ctx context.Context, te *testEnv) { + te.tmc.readVReplicationWorkflow = createReadVReplicationWorkflowFunc(t, binlogdatapb.VReplicationWorkflowType_Migrate, nil, te.tmc.keyspace, sourceShards, []string{table1, table2}) + }, + wantErr: "invalid action for Migrate workflow: MirrorTraffic", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "cannot mirror traffic for reshard workflows", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: sourceKs, + Workflow: "reshard", + TabletTypes: tabletTypes, + Percent: 50.0, + }, + sourceKeyspace: sourceKs, + sourceShards: []string{"-80", "80-"}, + targetKeyspace: sourceKs, + targetShards: []string{"-55", "55-aa", "55-"}, + setup: func(t *testing.T, ctx context.Context, te *testEnv) { + te.tmc.readVReplicationWorkflow = createReadVReplicationWorkflowFunc(t, binlogdatapb.VReplicationWorkflowType_Reshard, nil, sourceKs, []string{"-80", "80-"}, []string{table1, table2}) + }, + wantErr: "invalid action for Reshard workflow: MirrorTraffic", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "cannot mirror traffic after switch rdonly traffic", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + routingRules: map[string][]string{ + fmt.Sprintf("%s.%s@rdonly", targetKs, table1): {fmt.Sprintf("%s.%s@rdonly", targetKs, table1)}, + fmt.Sprintf("%s.%s@rdonly", targetKs, table2): {fmt.Sprintf("%s.%s@rdonly", targetKs, table2)}, + }, + wantErr: "cannot mirror traffic for workflow src2target at this time: traffic is switched", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "cannot mirror traffic after switch replica traffic", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + routingRules: map[string][]string{ + fmt.Sprintf("%s.%s@replica", targetKs, table1): {fmt.Sprintf("%s.%s@replica", targetKs, table1)}, + fmt.Sprintf("%s.%s@replica", targetKs, table2): {fmt.Sprintf("%s.%s@replica", targetKs, table2)}, + }, + wantErr: "cannot mirror traffic for workflow src2target at this time: traffic is switched", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "cannot mirror traffic after switch traffic", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + routingRules: map[string][]string{ + table1: {fmt.Sprintf("%s.%s", targetKs, table1)}, + table2: {fmt.Sprintf("%s.%s", targetKs, table2)}, + }, + wantErr: "cannot mirror traffic for workflow src2target at this time: traffic is switched", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "does not mirror traffic for partial move tables", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + setup: func(t *testing.T, ctx context.Context, te *testEnv) { + te.tmc.readVReplicationWorkflow = func( + ctx context.Context, + tablet *topodatapb.Tablet, + request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest, + ) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { + if tablet.Shard != "-80" { + return nil, nil + } + return &tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ + Workflow: request.Workflow, + WorkflowType: binlogdatapb.VReplicationWorkflowType_MoveTables, + Streams: []*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + { + Id: 1, + Bls: &binlogdatapb.BinlogSource{ + Keyspace: sourceKs, + Shard: "-80", + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{ + {Match: table1}, + {Match: table2}, + }, + }, + }, + }, + }, + }, nil + } + }, + sourceShards: []string{"-80", "80-"}, + targetShards: []string{"-80", "80-"}, + wantErr: "invalid action for partial migration: MirrorTraffic", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "does not mirror traffic for multi-tenant move tables", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + setup: func(t *testing.T, ctx context.Context, te *testEnv) { + te.tmc.readVReplicationWorkflow = createReadVReplicationWorkflowFunc(t, binlogdatapb.VReplicationWorkflowType_MoveTables, &vtctldatapb.WorkflowOptions{TenantId: "123"}, te.tmc.keyspace, sourceShards, []string{table1, table2}) + }, + wantErr: "invalid action for multi-tenant migration: MirrorTraffic", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "does not mirror traffic for reverse move tables", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow + "_reverse", + TabletTypes: tabletTypes, + Percent: 50.0, + }, + wantErr: "invalid action for reverse workflow: MirrorTraffic", + wantMirrorRules: make(map[string]map[string]float32), + }, + { + name: "ok", + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + wantMirrorRules: map[string]map[string]float32{ + fmt.Sprintf("%s.%s", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 50.0, + }, + fmt.Sprintf("%s.%s@replica", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 50.0, + }, + fmt.Sprintf("%s.%s@rdonly", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 50.0, + }, + fmt.Sprintf("%s.%s", sourceKs, table2): { + fmt.Sprintf("%s.%s", targetKs, table2): 50.0, + }, + fmt.Sprintf("%s.%s@replica", sourceKs, table2): { + fmt.Sprintf("%s.%s", targetKs, table2): 50.0, + }, + fmt.Sprintf("%s.%s@rdonly", sourceKs, table2): { + fmt.Sprintf("%s.%s", targetKs, table2): 50.0, + }, + }, + }, + { + name: "does not overwrite unrelated mirror rules", + mirrorRules: map[string]map[string]float32{ + "other_source.table2": { + fmt.Sprintf("%s.table2", targetKs): 25.0, + }, + }, + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + wantMirrorRules: map[string]map[string]float32{ + fmt.Sprintf("%s.%s", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 50.0, + }, + fmt.Sprintf("%s.%s@replica", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 50.0, + }, + fmt.Sprintf("%s.%s@rdonly", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 50.0, + }, + fmt.Sprintf("%s.%s", sourceKs, table2): { + fmt.Sprintf("%s.%s", targetKs, table2): 50.0, + }, + fmt.Sprintf("%s.%s@replica", sourceKs, table2): { + fmt.Sprintf("%s.%s", targetKs, table2): 50.0, + }, + fmt.Sprintf("%s.%s@rdonly", sourceKs, table2): { + fmt.Sprintf("%s.%s", targetKs, table2): 50.0, + }, + "other_source.table2": { + fmt.Sprintf("%s.table2", targetKs): 25.0, + }, + }, + }, + { + name: "does not overwrite when some but not all mirror rules already exist", + mirrorRules: map[string]map[string]float32{ + fmt.Sprintf("%s.%s", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 25.0, + }, + fmt.Sprintf("%s.%s@replica", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 25.0, + }, + fmt.Sprintf("%s.%s@rdonly", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 25.0, + }, + }, + req: &vtctldatapb.WorkflowMirrorTrafficRequest{ + Keyspace: targetKs, + Workflow: workflow, + TabletTypes: tabletTypes, + Percent: 50.0, + }, + wantErr: "wrong number of pre-existing mirror rules", + wantMirrorRules: map[string]map[string]float32{ + fmt.Sprintf("%s.%s", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 25.0, + }, + fmt.Sprintf("%s.%s@replica", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 25.0, + }, + fmt.Sprintf("%s.%s@rdonly", sourceKs, table1): { + fmt.Sprintf("%s.%s", targetKs, table1): 25.0, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.mirrorRules == nil { + tt.mirrorRules = mirrorRules + } + if tt.routingRules == nil { + tt.routingRules = routingRules + } + if tt.sourceKeyspace == "" { + tt.sourceKeyspace = sourceKs + } + if tt.sourceShards == nil { + tt.sourceShards = sourceShards + } + if tt.targetKeyspace == "" { + tt.targetKeyspace = targetKs + } + if tt.targetShards == nil { + tt.targetShards = targetShards + } + + te := newTestEnv(t, ctx, &vtctldatapb.MaterializeSettings{ + SourceKeyspace: tt.sourceKeyspace, + TargetKeyspace: tt.targetKeyspace, + Workflow: workflow, + TableSettings: []*vtctldatapb.TableMaterializeSettings{ + { + TargetTable: table1, + SourceExpression: fmt.Sprintf("select * from %s", table1), + }, + { + TargetTable: table2, + SourceExpression: fmt.Sprintf("select * from %s", table2), + }, + }, + }, tt.sourceShards, tt.targetShards) + + require.NoError(t, topotools.SaveMirrorRules(ctx, te.topoServ, tt.mirrorRules)) + require.NoError(t, topotools.SaveRoutingRules(ctx, te.topoServ, tt.routingRules)) + require.NoError(t, te.topoServ.RebuildSrvVSchema(ctx, []string{te.cell})) + + if tt.setup != nil { + tt.setup(t, ctx, te) + } + + got, err := te.ws.WorkflowMirrorTraffic(ctx, tt.req) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + require.NotNil(t, got) + } + mr, err := topotools.GetMirrorRules(ctx, te.topoServ) + require.NoError(t, err) + wantMirrorRules := tt.mirrorRules + if tt.wantMirrorRules != nil { + wantMirrorRules = tt.wantMirrorRules + } + require.Equal(t, wantMirrorRules, mr) + }) + } +} + +func createReadVReplicationWorkflowFunc(t *testing.T, workflowType binlogdatapb.VReplicationWorkflowType, workflowOptions *vtctldatapb.WorkflowOptions, sourceKeyspace string, sourceShards []string, sourceTables []string) readVReplicationWorkflowFunc { + return func(ctx context.Context, tablet *topodatapb.Tablet, request *tabletmanagerdatapb.ReadVReplicationWorkflowRequest) (*tabletmanagerdatapb.ReadVReplicationWorkflowResponse, error) { + streams := make([]*tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream, 0) + for i, shard := range sourceShards { + if shard == tablet.Shard { + return nil, nil + } + rules := make([]*binlogdatapb.Rule, len(sourceTables)) + for i, table := range sourceTables { + rules[i] = &binlogdatapb.Rule{Match: table} + } + streams = append(streams, &tabletmanagerdatapb.ReadVReplicationWorkflowResponse_Stream{ + Id: int32(i + 1), + Bls: &binlogdatapb.BinlogSource{ + Keyspace: sourceKeyspace, + Shard: shard, + Filter: &binlogdatapb.Filter{Rules: rules}, + }, + }) + } + + var err error + var options []byte + if workflowOptions != nil { + options, err = json.Marshal(workflowOptions) + require.NoError(t, err) + } + + return &tabletmanagerdatapb.ReadVReplicationWorkflowResponse{ + Workflow: request.Workflow, + Options: string(options), + WorkflowType: workflowType, + Streams: streams, + }, nil + } +} diff --git a/go/vt/vtctl/workflow/state.go b/go/vt/vtctl/workflow/state.go index 927f5a9db56..9d2d1f23def 100644 --- a/go/vt/vtctl/workflow/state.go +++ b/go/vt/vtctl/workflow/state.go @@ -61,6 +61,7 @@ type State struct { SourceKeyspace string TargetKeyspace string WorkflowType Type + IsReverse bool ReplicaCellsSwitched []string ReplicaCellsNotSwitched []string diff --git a/go/vt/vtctl/workflow/switcher.go b/go/vt/vtctl/workflow/switcher.go index aa41655aab8..3fbd1c507e2 100644 --- a/go/vt/vtctl/workflow/switcher.go +++ b/go/vt/vtctl/workflow/switcher.go @@ -161,3 +161,7 @@ func (r *switcher) resetSequences(ctx context.Context) error { func (r *switcher) initializeTargetSequences(ctx context.Context, sequencesByBackingTable map[string]*sequenceMetadata) error { return r.ts.initializeTargetSequences(ctx, sequencesByBackingTable) } + +func (r *switcher) mirrorTableTraffic(ctx context.Context, types []topodatapb.TabletType, percent float32) error { + return r.ts.mirrorTableTraffic(ctx, types, percent) +} diff --git a/go/vt/vtctl/workflow/switcher_dry_run.go b/go/vt/vtctl/workflow/switcher_dry_run.go index 03faa4c4ca2..2ea788ed95c 100644 --- a/go/vt/vtctl/workflow/switcher_dry_run.go +++ b/go/vt/vtctl/workflow/switcher_dry_run.go @@ -63,6 +63,16 @@ func (dr *switcherDryRun) deleteKeyspaceRoutingRules(ctx context.Context) error return nil } +func (dr *switcherDryRun) mirrorTableTraffic(ctx context.Context, types []topodatapb.TabletType, percent float32) error { + var tabletTypes []string + for _, servedType := range types { + tabletTypes = append(tabletTypes, servedType.String()) + } + dr.drLog.Logf("Mirroring %f percent of traffic from keyspace %s to keyspace %s for tablet types [%s]", + percent, dr.ts.SourceKeyspaceName(), dr.ts.TargetKeyspaceName(), strings.Join(tabletTypes, ",")) + return nil +} + func (dr *switcherDryRun) switchKeyspaceReads(ctx context.Context, types []topodatapb.TabletType) error { var tabletTypes []string for _, servedType := range types { diff --git a/go/vt/vtctl/workflow/switcher_interface.go b/go/vt/vtctl/workflow/switcher_interface.go index 0780aaf484c..9dea0af30a1 100644 --- a/go/vt/vtctl/workflow/switcher_interface.go +++ b/go/vt/vtctl/workflow/switcher_interface.go @@ -34,6 +34,7 @@ type iswitcher interface { createJournals(ctx context.Context, sourceWorkflows []string) error allowTargetWrites(ctx context.Context) error changeRouting(ctx context.Context) error + mirrorTableTraffic(ctx context.Context, types []topodatapb.TabletType, percent float32) error streamMigraterfinalize(ctx context.Context, ts *trafficSwitcher, workflows []string) error startReverseVReplication(ctx context.Context) error switchKeyspaceReads(ctx context.Context, types []topodatapb.TabletType) error diff --git a/go/vt/vtctl/workflow/traffic_switcher.go b/go/vt/vtctl/workflow/traffic_switcher.go index 9ea1c8b609b..d6c64384b11 100644 --- a/go/vt/vtctl/workflow/traffic_switcher.go +++ b/go/vt/vtctl/workflow/traffic_switcher.go @@ -346,7 +346,7 @@ func (ts *trafficSwitcher) getSourceAndTargetShardsNames() ([]string, []string) return sourceShards, targetShards } -// isPartialMoveTables returns true if whe workflow is MoveTables, has the same +// isPartialMoveTables returns true if the workflow is MoveTables, has the same // number of shards, is not covering the entire shard range, and has one-to-one // shards in source and target. func (ts *trafficSwitcher) isPartialMoveTables(sourceShards, targetShards []string) (bool, error) { @@ -1637,3 +1637,50 @@ func (ts *trafficSwitcher) IsMultiTenantMigration() bool { } return false } + +func (ts *trafficSwitcher) mirrorTableTraffic(ctx context.Context, types []topodatapb.TabletType, percent float32) error { + log.Infof("mirrorTableTraffic") + + mrs, err := topotools.GetMirrorRules(ctx, ts.TopoServer()) + if err != nil { + return err + } + + var numExisting int + for _, table := range ts.tables { + for _, tabletType := range types { + fromTable := fmt.Sprintf("%s.%s", ts.SourceKeyspaceName(), table) + if tabletType != topodatapb.TabletType_PRIMARY { + fromTable = fmt.Sprintf("%s@%s", fromTable, topoproto.TabletTypeLString(tabletType)) + } + toTable := fmt.Sprintf("%s.%s", ts.TargetKeyspaceName(), table) + + if _, ok := mrs[fromTable]; !ok { + mrs[fromTable] = make(map[string]float32) + } + + if _, ok := mrs[fromTable][toTable]; ok { + numExisting++ + } + + if percent == 0 { + // When percent is 0, remove mirror rule if it exists. + if _, ok := mrs[fromTable][toTable]; ok { + delete(mrs, fromTable) + } + } else { + mrs[fromTable][toTable] = percent + } + } + } + + if numExisting > 0 && numExisting != (len(types)*len(ts.tables)) { + return vterrors.Errorf(vtrpcpb.Code_ALREADY_EXISTS, "wrong number of pre-existing mirror rules") + } + + if err := topotools.SaveMirrorRules(ctx, ts.TopoServer(), mrs); err != nil { + return err + } + + return ts.TopoServer().RebuildSrvVSchema(ctx, nil) +} diff --git a/proto/vschema.proto b/proto/vschema.proto index dd327f863dc..f0d12278fcd 100644 --- a/proto/vschema.proto +++ b/proto/vschema.proto @@ -153,6 +153,7 @@ message SrvVSchema { RoutingRules routing_rules = 2; // table routing rules ShardRoutingRules shard_routing_rules = 3; KeyspaceRoutingRules keyspace_routing_rules = 4; + MirrorRules mirror_rules = 5; // mirror rules } // ShardRoutingRules specify the shard routing rules for the VSchema. @@ -176,3 +177,17 @@ message KeyspaceRoutingRule { string to_keyspace = 2; } +// MirrorRules specify the high level mirror rules for the VSchema. +message MirrorRules { + // rules should ideally be a map. However protos dont't allow + // repeated fields as elements of a map. So, we use a list + // instead. + repeated MirrorRule rules = 1; +} + +// MirrorRule specifies a mirror rule. +message MirrorRule { + string from_table = 1; + string to_table = 2; + float percent = 3; +} diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 4e59384f2e2..68b8cff4794 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -1959,3 +1959,38 @@ message WorkflowUpdateResponse { string summary = 1; repeated TabletInfo details = 2; } + +message ApplyMirrorRulesRequest { + vschema.MirrorRules mirror_rules = 1; + // SkipRebuild, if set, will cause ApplyRoutingRules to skip rebuilding the + // SrvVSchema objects in each cell in RebuildCells. + bool skip_rebuild = 2; + // RebuildCells limits the SrvVSchema rebuild to the specified cells. If not + // provided the SrvVSchema will be rebuilt in every cell in the topology. + // + // Ignored if SkipRebuild is set. + repeated string rebuild_cells = 3; +} + +message ApplyMirrorRulesResponse { +} + +message GetMirrorRulesRequest { +} + +message GetMirrorRulesResponse { + vschema.MirrorRules mirror_rules = 1; +} + +message WorkflowMirrorTrafficRequest { + string keyspace = 1; + string workflow = 2; + repeated topodata.TabletType tablet_types = 3; + float percent = 4; +} + +message WorkflowMirrorTrafficResponse { + string summary = 1; + string start_state = 2; + string current_state = 3; +} diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 8abc37dab80..59309a9bc5d 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -360,4 +360,9 @@ service Vtctld { // WorkflowUpdate updates the configuration of a vreplication workflow // using the provided updated parameters. rpc WorkflowUpdate(vtctldata.WorkflowUpdateRequest) returns (vtctldata.WorkflowUpdateResponse) {}; + // ApplyMirrorRules applies the VSchema routing rules. + rpc ApplyMirrorRules(vtctldata.ApplyMirrorRulesRequest) returns (vtctldata.ApplyMirrorRulesResponse) {}; + // GetMirrorRules returns the VSchema routing rules. + rpc GetMirrorRules(vtctldata.GetMirrorRulesRequest) returns (vtctldata.GetMirrorRulesResponse) {}; + rpc WorkflowMirrorTraffic(vtctldata.WorkflowMirrorTrafficRequest) returns (vtctldata.WorkflowMirrorTrafficResponse) {}; } diff --git a/proto/vttest.proto b/proto/vttest.proto index b48107044d7..fdabe7c40f5 100644 --- a/proto/vttest.proto +++ b/proto/vttest.proto @@ -94,4 +94,7 @@ message VTTestTopology { // routing rules for the topology. vschema.RoutingRules routing_rules = 3; + + // mirror rules for the topology. + vschema.MirrorRules mirror_rules = 4; } diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index d6ec9baec6d..3b1f8797b36 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -43944,6 +43944,9 @@ export namespace vschema { /** SrvVSchema keyspace_routing_rules */ keyspace_routing_rules?: (vschema.IKeyspaceRoutingRules|null); + + /** SrvVSchema mirror_rules */ + mirror_rules?: (vschema.IMirrorRules|null); } /** Represents a SrvVSchema. */ @@ -43967,6 +43970,9 @@ export namespace vschema { /** SrvVSchema keyspace_routing_rules. */ public keyspace_routing_rules?: (vschema.IKeyspaceRoutingRules|null); + /** SrvVSchema mirror_rules. */ + public mirror_rules?: (vschema.IMirrorRules|null); + /** * Creates a new SrvVSchema instance using the specified properties. * @param [properties] Properties to set @@ -44450,6 +44456,212 @@ export namespace vschema { */ public static getTypeUrl(typeUrlPrefix?: string): string; } + + /** Properties of a MirrorRules. */ + interface IMirrorRules { + + /** MirrorRules rules */ + rules?: (vschema.IMirrorRule[]|null); + } + + /** Represents a MirrorRules. */ + class MirrorRules implements IMirrorRules { + + /** + * Constructs a new MirrorRules. + * @param [properties] Properties to set + */ + constructor(properties?: vschema.IMirrorRules); + + /** MirrorRules rules. */ + public rules: vschema.IMirrorRule[]; + + /** + * Creates a new MirrorRules instance using the specified properties. + * @param [properties] Properties to set + * @returns MirrorRules instance + */ + public static create(properties?: vschema.IMirrorRules): vschema.MirrorRules; + + /** + * Encodes the specified MirrorRules message. Does not implicitly {@link vschema.MirrorRules.verify|verify} messages. + * @param message MirrorRules message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vschema.IMirrorRules, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MirrorRules message, length delimited. Does not implicitly {@link vschema.MirrorRules.verify|verify} messages. + * @param message MirrorRules message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vschema.IMirrorRules, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MirrorRules message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MirrorRules + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vschema.MirrorRules; + + /** + * Decodes a MirrorRules message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MirrorRules + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vschema.MirrorRules; + + /** + * Verifies a MirrorRules message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MirrorRules message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MirrorRules + */ + public static fromObject(object: { [k: string]: any }): vschema.MirrorRules; + + /** + * Creates a plain object from a MirrorRules message. Also converts values to other types if specified. + * @param message MirrorRules + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vschema.MirrorRules, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MirrorRules to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for MirrorRules + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a MirrorRule. */ + interface IMirrorRule { + + /** MirrorRule from_table */ + from_table?: (string|null); + + /** MirrorRule to_table */ + to_table?: (string|null); + + /** MirrorRule percent */ + percent?: (number|null); + } + + /** Represents a MirrorRule. */ + class MirrorRule implements IMirrorRule { + + /** + * Constructs a new MirrorRule. + * @param [properties] Properties to set + */ + constructor(properties?: vschema.IMirrorRule); + + /** MirrorRule from_table. */ + public from_table: string; + + /** MirrorRule to_table. */ + public to_table: string; + + /** MirrorRule percent. */ + public percent: number; + + /** + * Creates a new MirrorRule instance using the specified properties. + * @param [properties] Properties to set + * @returns MirrorRule instance + */ + public static create(properties?: vschema.IMirrorRule): vschema.MirrorRule; + + /** + * Encodes the specified MirrorRule message. Does not implicitly {@link vschema.MirrorRule.verify|verify} messages. + * @param message MirrorRule message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vschema.IMirrorRule, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MirrorRule message, length delimited. Does not implicitly {@link vschema.MirrorRule.verify|verify} messages. + * @param message MirrorRule message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vschema.IMirrorRule, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MirrorRule message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MirrorRule + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vschema.MirrorRule; + + /** + * Decodes a MirrorRule message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MirrorRule + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vschema.MirrorRule; + + /** + * Verifies a MirrorRule message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a MirrorRule message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MirrorRule + */ + public static fromObject(object: { [k: string]: any }): vschema.MirrorRule; + + /** + * Creates a plain object from a MirrorRule message. Also converts values to other types if specified. + * @param message MirrorRule + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vschema.MirrorRule, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MirrorRule to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for MirrorRule + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } } /** Namespace vtctldata. */ @@ -71868,4 +72080,616 @@ export namespace vtctldata { public static getTypeUrl(typeUrlPrefix?: string): string; } } + + /** Properties of an ApplyMirrorRulesRequest. */ + interface IApplyMirrorRulesRequest { + + /** ApplyMirrorRulesRequest mirror_rules */ + mirror_rules?: (vschema.IMirrorRules|null); + + /** ApplyMirrorRulesRequest skip_rebuild */ + skip_rebuild?: (boolean|null); + + /** ApplyMirrorRulesRequest rebuild_cells */ + rebuild_cells?: (string[]|null); + } + + /** Represents an ApplyMirrorRulesRequest. */ + class ApplyMirrorRulesRequest implements IApplyMirrorRulesRequest { + + /** + * Constructs a new ApplyMirrorRulesRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IApplyMirrorRulesRequest); + + /** ApplyMirrorRulesRequest mirror_rules. */ + public mirror_rules?: (vschema.IMirrorRules|null); + + /** ApplyMirrorRulesRequest skip_rebuild. */ + public skip_rebuild: boolean; + + /** ApplyMirrorRulesRequest rebuild_cells. */ + public rebuild_cells: string[]; + + /** + * Creates a new ApplyMirrorRulesRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns ApplyMirrorRulesRequest instance + */ + public static create(properties?: vtctldata.IApplyMirrorRulesRequest): vtctldata.ApplyMirrorRulesRequest; + + /** + * Encodes the specified ApplyMirrorRulesRequest message. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. + * @param message ApplyMirrorRulesRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IApplyMirrorRulesRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ApplyMirrorRulesRequest message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. + * @param message ApplyMirrorRulesRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IApplyMirrorRulesRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ApplyMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ApplyMirrorRulesRequest; + + /** + * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ApplyMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ApplyMirrorRulesRequest; + + /** + * Verifies an ApplyMirrorRulesRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ApplyMirrorRulesRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ApplyMirrorRulesRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ApplyMirrorRulesRequest; + + /** + * Creates a plain object from an ApplyMirrorRulesRequest message. Also converts values to other types if specified. + * @param message ApplyMirrorRulesRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ApplyMirrorRulesRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ApplyMirrorRulesRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for ApplyMirrorRulesRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of an ApplyMirrorRulesResponse. */ + interface IApplyMirrorRulesResponse { + } + + /** Represents an ApplyMirrorRulesResponse. */ + class ApplyMirrorRulesResponse implements IApplyMirrorRulesResponse { + + /** + * Constructs a new ApplyMirrorRulesResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IApplyMirrorRulesResponse); + + /** + * Creates a new ApplyMirrorRulesResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns ApplyMirrorRulesResponse instance + */ + public static create(properties?: vtctldata.IApplyMirrorRulesResponse): vtctldata.ApplyMirrorRulesResponse; + + /** + * Encodes the specified ApplyMirrorRulesResponse message. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. + * @param message ApplyMirrorRulesResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IApplyMirrorRulesResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ApplyMirrorRulesResponse message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. + * @param message ApplyMirrorRulesResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IApplyMirrorRulesResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ApplyMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ApplyMirrorRulesResponse; + + /** + * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ApplyMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ApplyMirrorRulesResponse; + + /** + * Verifies an ApplyMirrorRulesResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ApplyMirrorRulesResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ApplyMirrorRulesResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ApplyMirrorRulesResponse; + + /** + * Creates a plain object from an ApplyMirrorRulesResponse message. Also converts values to other types if specified. + * @param message ApplyMirrorRulesResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ApplyMirrorRulesResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ApplyMirrorRulesResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for ApplyMirrorRulesResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a GetMirrorRulesRequest. */ + interface IGetMirrorRulesRequest { + } + + /** Represents a GetMirrorRulesRequest. */ + class GetMirrorRulesRequest implements IGetMirrorRulesRequest { + + /** + * Constructs a new GetMirrorRulesRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IGetMirrorRulesRequest); + + /** + * Creates a new GetMirrorRulesRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns GetMirrorRulesRequest instance + */ + public static create(properties?: vtctldata.IGetMirrorRulesRequest): vtctldata.GetMirrorRulesRequest; + + /** + * Encodes the specified GetMirrorRulesRequest message. Does not implicitly {@link vtctldata.GetMirrorRulesRequest.verify|verify} messages. + * @param message GetMirrorRulesRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IGetMirrorRulesRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified GetMirrorRulesRequest message, length delimited. Does not implicitly {@link vtctldata.GetMirrorRulesRequest.verify|verify} messages. + * @param message GetMirrorRulesRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IGetMirrorRulesRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a GetMirrorRulesRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns GetMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.GetMirrorRulesRequest; + + /** + * Decodes a GetMirrorRulesRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns GetMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.GetMirrorRulesRequest; + + /** + * Verifies a GetMirrorRulesRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a GetMirrorRulesRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns GetMirrorRulesRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.GetMirrorRulesRequest; + + /** + * Creates a plain object from a GetMirrorRulesRequest message. Also converts values to other types if specified. + * @param message GetMirrorRulesRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.GetMirrorRulesRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this GetMirrorRulesRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for GetMirrorRulesRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a GetMirrorRulesResponse. */ + interface IGetMirrorRulesResponse { + + /** GetMirrorRulesResponse mirror_rules */ + mirror_rules?: (vschema.IMirrorRules|null); + } + + /** Represents a GetMirrorRulesResponse. */ + class GetMirrorRulesResponse implements IGetMirrorRulesResponse { + + /** + * Constructs a new GetMirrorRulesResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IGetMirrorRulesResponse); + + /** GetMirrorRulesResponse mirror_rules. */ + public mirror_rules?: (vschema.IMirrorRules|null); + + /** + * Creates a new GetMirrorRulesResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns GetMirrorRulesResponse instance + */ + public static create(properties?: vtctldata.IGetMirrorRulesResponse): vtctldata.GetMirrorRulesResponse; + + /** + * Encodes the specified GetMirrorRulesResponse message. Does not implicitly {@link vtctldata.GetMirrorRulesResponse.verify|verify} messages. + * @param message GetMirrorRulesResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IGetMirrorRulesResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified GetMirrorRulesResponse message, length delimited. Does not implicitly {@link vtctldata.GetMirrorRulesResponse.verify|verify} messages. + * @param message GetMirrorRulesResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IGetMirrorRulesResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a GetMirrorRulesResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns GetMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.GetMirrorRulesResponse; + + /** + * Decodes a GetMirrorRulesResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns GetMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.GetMirrorRulesResponse; + + /** + * Verifies a GetMirrorRulesResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a GetMirrorRulesResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns GetMirrorRulesResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.GetMirrorRulesResponse; + + /** + * Creates a plain object from a GetMirrorRulesResponse message. Also converts values to other types if specified. + * @param message GetMirrorRulesResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.GetMirrorRulesResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this GetMirrorRulesResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for GetMirrorRulesResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a WorkflowMirrorTrafficRequest. */ + interface IWorkflowMirrorTrafficRequest { + + /** WorkflowMirrorTrafficRequest keyspace */ + keyspace?: (string|null); + + /** WorkflowMirrorTrafficRequest workflow */ + workflow?: (string|null); + + /** WorkflowMirrorTrafficRequest tablet_types */ + tablet_types?: (topodata.TabletType[]|null); + + /** WorkflowMirrorTrafficRequest percent */ + percent?: (number|null); + } + + /** Represents a WorkflowMirrorTrafficRequest. */ + class WorkflowMirrorTrafficRequest implements IWorkflowMirrorTrafficRequest { + + /** + * Constructs a new WorkflowMirrorTrafficRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IWorkflowMirrorTrafficRequest); + + /** WorkflowMirrorTrafficRequest keyspace. */ + public keyspace: string; + + /** WorkflowMirrorTrafficRequest workflow. */ + public workflow: string; + + /** WorkflowMirrorTrafficRequest tablet_types. */ + public tablet_types: topodata.TabletType[]; + + /** WorkflowMirrorTrafficRequest percent. */ + public percent: number; + + /** + * Creates a new WorkflowMirrorTrafficRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns WorkflowMirrorTrafficRequest instance + */ + public static create(properties?: vtctldata.IWorkflowMirrorTrafficRequest): vtctldata.WorkflowMirrorTrafficRequest; + + /** + * Encodes the specified WorkflowMirrorTrafficRequest message. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficRequest.verify|verify} messages. + * @param message WorkflowMirrorTrafficRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IWorkflowMirrorTrafficRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WorkflowMirrorTrafficRequest message, length delimited. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficRequest.verify|verify} messages. + * @param message WorkflowMirrorTrafficRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IWorkflowMirrorTrafficRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WorkflowMirrorTrafficRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WorkflowMirrorTrafficRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.WorkflowMirrorTrafficRequest; + + /** + * Decodes a WorkflowMirrorTrafficRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WorkflowMirrorTrafficRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.WorkflowMirrorTrafficRequest; + + /** + * Verifies a WorkflowMirrorTrafficRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WorkflowMirrorTrafficRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WorkflowMirrorTrafficRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.WorkflowMirrorTrafficRequest; + + /** + * Creates a plain object from a WorkflowMirrorTrafficRequest message. Also converts values to other types if specified. + * @param message WorkflowMirrorTrafficRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.WorkflowMirrorTrafficRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WorkflowMirrorTrafficRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for WorkflowMirrorTrafficRequest + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + + /** Properties of a WorkflowMirrorTrafficResponse. */ + interface IWorkflowMirrorTrafficResponse { + + /** WorkflowMirrorTrafficResponse summary */ + summary?: (string|null); + + /** WorkflowMirrorTrafficResponse start_state */ + start_state?: (string|null); + + /** WorkflowMirrorTrafficResponse current_state */ + current_state?: (string|null); + } + + /** Represents a WorkflowMirrorTrafficResponse. */ + class WorkflowMirrorTrafficResponse implements IWorkflowMirrorTrafficResponse { + + /** + * Constructs a new WorkflowMirrorTrafficResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IWorkflowMirrorTrafficResponse); + + /** WorkflowMirrorTrafficResponse summary. */ + public summary: string; + + /** WorkflowMirrorTrafficResponse start_state. */ + public start_state: string; + + /** WorkflowMirrorTrafficResponse current_state. */ + public current_state: string; + + /** + * Creates a new WorkflowMirrorTrafficResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns WorkflowMirrorTrafficResponse instance + */ + public static create(properties?: vtctldata.IWorkflowMirrorTrafficResponse): vtctldata.WorkflowMirrorTrafficResponse; + + /** + * Encodes the specified WorkflowMirrorTrafficResponse message. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficResponse.verify|verify} messages. + * @param message WorkflowMirrorTrafficResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IWorkflowMirrorTrafficResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified WorkflowMirrorTrafficResponse message, length delimited. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficResponse.verify|verify} messages. + * @param message WorkflowMirrorTrafficResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IWorkflowMirrorTrafficResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a WorkflowMirrorTrafficResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns WorkflowMirrorTrafficResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.WorkflowMirrorTrafficResponse; + + /** + * Decodes a WorkflowMirrorTrafficResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns WorkflowMirrorTrafficResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.WorkflowMirrorTrafficResponse; + + /** + * Verifies a WorkflowMirrorTrafficResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a WorkflowMirrorTrafficResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns WorkflowMirrorTrafficResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.WorkflowMirrorTrafficResponse; + + /** + * Creates a plain object from a WorkflowMirrorTrafficResponse message. Also converts values to other types if specified. + * @param message WorkflowMirrorTrafficResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.WorkflowMirrorTrafficResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this WorkflowMirrorTrafficResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for WorkflowMirrorTrafficResponse + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } } diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index f827b6ee594..c76ebd68740 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -107448,6 +107448,7 @@ export const vschema = $root.vschema = (() => { * @property {vschema.IRoutingRules|null} [routing_rules] SrvVSchema routing_rules * @property {vschema.IShardRoutingRules|null} [shard_routing_rules] SrvVSchema shard_routing_rules * @property {vschema.IKeyspaceRoutingRules|null} [keyspace_routing_rules] SrvVSchema keyspace_routing_rules + * @property {vschema.IMirrorRules|null} [mirror_rules] SrvVSchema mirror_rules */ /** @@ -107498,6 +107499,14 @@ export const vschema = $root.vschema = (() => { */ SrvVSchema.prototype.keyspace_routing_rules = null; + /** + * SrvVSchema mirror_rules. + * @member {vschema.IMirrorRules|null|undefined} mirror_rules + * @memberof vschema.SrvVSchema + * @instance + */ + SrvVSchema.prototype.mirror_rules = null; + /** * Creates a new SrvVSchema instance using the specified properties. * @function create @@ -107533,6 +107542,8 @@ export const vschema = $root.vschema = (() => { $root.vschema.ShardRoutingRules.encode(message.shard_routing_rules, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim(); if (message.keyspace_routing_rules != null && Object.hasOwnProperty.call(message, "keyspace_routing_rules")) $root.vschema.KeyspaceRoutingRules.encode(message.keyspace_routing_rules, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.mirror_rules != null && Object.hasOwnProperty.call(message, "mirror_rules")) + $root.vschema.MirrorRules.encode(message.mirror_rules, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); return writer; }; @@ -107602,6 +107613,10 @@ export const vschema = $root.vschema = (() => { message.keyspace_routing_rules = $root.vschema.KeyspaceRoutingRules.decode(reader, reader.uint32()); break; } + case 5: { + message.mirror_rules = $root.vschema.MirrorRules.decode(reader, reader.uint32()); + break; + } default: reader.skipType(tag & 7); break; @@ -107662,6 +107677,11 @@ export const vschema = $root.vschema = (() => { if (error) return "keyspace_routing_rules." + error; } + if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) { + let error = $root.vschema.MirrorRules.verify(message.mirror_rules); + if (error) + return "mirror_rules." + error; + } return null; }; @@ -107702,6 +107722,11 @@ export const vschema = $root.vschema = (() => { throw TypeError(".vschema.SrvVSchema.keyspace_routing_rules: object expected"); message.keyspace_routing_rules = $root.vschema.KeyspaceRoutingRules.fromObject(object.keyspace_routing_rules); } + if (object.mirror_rules != null) { + if (typeof object.mirror_rules !== "object") + throw TypeError(".vschema.SrvVSchema.mirror_rules: object expected"); + message.mirror_rules = $root.vschema.MirrorRules.fromObject(object.mirror_rules); + } return message; }; @@ -107724,6 +107749,7 @@ export const vschema = $root.vschema = (() => { object.routing_rules = null; object.shard_routing_rules = null; object.keyspace_routing_rules = null; + object.mirror_rules = null; } let keys2; if (message.keyspaces && (keys2 = Object.keys(message.keyspaces)).length) { @@ -107737,6 +107763,8 @@ export const vschema = $root.vschema = (() => { object.shard_routing_rules = $root.vschema.ShardRoutingRules.toObject(message.shard_routing_rules, options); if (message.keyspace_routing_rules != null && message.hasOwnProperty("keyspace_routing_rules")) object.keyspace_routing_rules = $root.vschema.KeyspaceRoutingRules.toObject(message.keyspace_routing_rules, options); + if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) + object.mirror_rules = $root.vschema.MirrorRules.toObject(message.mirror_rules, options); return object; }; @@ -108694,6 +108722,480 @@ export const vschema = $root.vschema = (() => { return KeyspaceRoutingRule; })(); + vschema.MirrorRules = (function() { + + /** + * Properties of a MirrorRules. + * @memberof vschema + * @interface IMirrorRules + * @property {Array.|null} [rules] MirrorRules rules + */ + + /** + * Constructs a new MirrorRules. + * @memberof vschema + * @classdesc Represents a MirrorRules. + * @implements IMirrorRules + * @constructor + * @param {vschema.IMirrorRules=} [properties] Properties to set + */ + function MirrorRules(properties) { + this.rules = []; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MirrorRules rules. + * @member {Array.} rules + * @memberof vschema.MirrorRules + * @instance + */ + MirrorRules.prototype.rules = $util.emptyArray; + + /** + * Creates a new MirrorRules instance using the specified properties. + * @function create + * @memberof vschema.MirrorRules + * @static + * @param {vschema.IMirrorRules=} [properties] Properties to set + * @returns {vschema.MirrorRules} MirrorRules instance + */ + MirrorRules.create = function create(properties) { + return new MirrorRules(properties); + }; + + /** + * Encodes the specified MirrorRules message. Does not implicitly {@link vschema.MirrorRules.verify|verify} messages. + * @function encode + * @memberof vschema.MirrorRules + * @static + * @param {vschema.IMirrorRules} message MirrorRules message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MirrorRules.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.rules != null && message.rules.length) + for (let i = 0; i < message.rules.length; ++i) + $root.vschema.MirrorRule.encode(message.rules[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified MirrorRules message, length delimited. Does not implicitly {@link vschema.MirrorRules.verify|verify} messages. + * @function encodeDelimited + * @memberof vschema.MirrorRules + * @static + * @param {vschema.IMirrorRules} message MirrorRules message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MirrorRules.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MirrorRules message from the specified reader or buffer. + * @function decode + * @memberof vschema.MirrorRules + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vschema.MirrorRules} MirrorRules + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MirrorRules.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vschema.MirrorRules(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (!(message.rules && message.rules.length)) + message.rules = []; + message.rules.push($root.vschema.MirrorRule.decode(reader, reader.uint32())); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MirrorRules message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vschema.MirrorRules + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vschema.MirrorRules} MirrorRules + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MirrorRules.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MirrorRules message. + * @function verify + * @memberof vschema.MirrorRules + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MirrorRules.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.rules != null && message.hasOwnProperty("rules")) { + if (!Array.isArray(message.rules)) + return "rules: array expected"; + for (let i = 0; i < message.rules.length; ++i) { + let error = $root.vschema.MirrorRule.verify(message.rules[i]); + if (error) + return "rules." + error; + } + } + return null; + }; + + /** + * Creates a MirrorRules message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vschema.MirrorRules + * @static + * @param {Object.} object Plain object + * @returns {vschema.MirrorRules} MirrorRules + */ + MirrorRules.fromObject = function fromObject(object) { + if (object instanceof $root.vschema.MirrorRules) + return object; + let message = new $root.vschema.MirrorRules(); + if (object.rules) { + if (!Array.isArray(object.rules)) + throw TypeError(".vschema.MirrorRules.rules: array expected"); + message.rules = []; + for (let i = 0; i < object.rules.length; ++i) { + if (typeof object.rules[i] !== "object") + throw TypeError(".vschema.MirrorRules.rules: object expected"); + message.rules[i] = $root.vschema.MirrorRule.fromObject(object.rules[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a MirrorRules message. Also converts values to other types if specified. + * @function toObject + * @memberof vschema.MirrorRules + * @static + * @param {vschema.MirrorRules} message MirrorRules + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MirrorRules.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.arrays || options.defaults) + object.rules = []; + if (message.rules && message.rules.length) { + object.rules = []; + for (let j = 0; j < message.rules.length; ++j) + object.rules[j] = $root.vschema.MirrorRule.toObject(message.rules[j], options); + } + return object; + }; + + /** + * Converts this MirrorRules to JSON. + * @function toJSON + * @memberof vschema.MirrorRules + * @instance + * @returns {Object.} JSON object + */ + MirrorRules.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for MirrorRules + * @function getTypeUrl + * @memberof vschema.MirrorRules + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + MirrorRules.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vschema.MirrorRules"; + }; + + return MirrorRules; + })(); + + vschema.MirrorRule = (function() { + + /** + * Properties of a MirrorRule. + * @memberof vschema + * @interface IMirrorRule + * @property {string|null} [from_table] MirrorRule from_table + * @property {string|null} [to_table] MirrorRule to_table + * @property {number|null} [percent] MirrorRule percent + */ + + /** + * Constructs a new MirrorRule. + * @memberof vschema + * @classdesc Represents a MirrorRule. + * @implements IMirrorRule + * @constructor + * @param {vschema.IMirrorRule=} [properties] Properties to set + */ + function MirrorRule(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * MirrorRule from_table. + * @member {string} from_table + * @memberof vschema.MirrorRule + * @instance + */ + MirrorRule.prototype.from_table = ""; + + /** + * MirrorRule to_table. + * @member {string} to_table + * @memberof vschema.MirrorRule + * @instance + */ + MirrorRule.prototype.to_table = ""; + + /** + * MirrorRule percent. + * @member {number} percent + * @memberof vschema.MirrorRule + * @instance + */ + MirrorRule.prototype.percent = 0; + + /** + * Creates a new MirrorRule instance using the specified properties. + * @function create + * @memberof vschema.MirrorRule + * @static + * @param {vschema.IMirrorRule=} [properties] Properties to set + * @returns {vschema.MirrorRule} MirrorRule instance + */ + MirrorRule.create = function create(properties) { + return new MirrorRule(properties); + }; + + /** + * Encodes the specified MirrorRule message. Does not implicitly {@link vschema.MirrorRule.verify|verify} messages. + * @function encode + * @memberof vschema.MirrorRule + * @static + * @param {vschema.IMirrorRule} message MirrorRule message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MirrorRule.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.from_table != null && Object.hasOwnProperty.call(message, "from_table")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.from_table); + if (message.to_table != null && Object.hasOwnProperty.call(message, "to_table")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.to_table); + if (message.percent != null && Object.hasOwnProperty.call(message, "percent")) + writer.uint32(/* id 3, wireType 5 =*/29).float(message.percent); + return writer; + }; + + /** + * Encodes the specified MirrorRule message, length delimited. Does not implicitly {@link vschema.MirrorRule.verify|verify} messages. + * @function encodeDelimited + * @memberof vschema.MirrorRule + * @static + * @param {vschema.IMirrorRule} message MirrorRule message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MirrorRule.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MirrorRule message from the specified reader or buffer. + * @function decode + * @memberof vschema.MirrorRule + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vschema.MirrorRule} MirrorRule + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MirrorRule.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vschema.MirrorRule(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.from_table = reader.string(); + break; + } + case 2: { + message.to_table = reader.string(); + break; + } + case 3: { + message.percent = reader.float(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MirrorRule message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vschema.MirrorRule + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vschema.MirrorRule} MirrorRule + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MirrorRule.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MirrorRule message. + * @function verify + * @memberof vschema.MirrorRule + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MirrorRule.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.from_table != null && message.hasOwnProperty("from_table")) + if (!$util.isString(message.from_table)) + return "from_table: string expected"; + if (message.to_table != null && message.hasOwnProperty("to_table")) + if (!$util.isString(message.to_table)) + return "to_table: string expected"; + if (message.percent != null && message.hasOwnProperty("percent")) + if (typeof message.percent !== "number") + return "percent: number expected"; + return null; + }; + + /** + * Creates a MirrorRule message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vschema.MirrorRule + * @static + * @param {Object.} object Plain object + * @returns {vschema.MirrorRule} MirrorRule + */ + MirrorRule.fromObject = function fromObject(object) { + if (object instanceof $root.vschema.MirrorRule) + return object; + let message = new $root.vschema.MirrorRule(); + if (object.from_table != null) + message.from_table = String(object.from_table); + if (object.to_table != null) + message.to_table = String(object.to_table); + if (object.percent != null) + message.percent = Number(object.percent); + return message; + }; + + /** + * Creates a plain object from a MirrorRule message. Also converts values to other types if specified. + * @function toObject + * @memberof vschema.MirrorRule + * @static + * @param {vschema.MirrorRule} message MirrorRule + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MirrorRule.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.from_table = ""; + object.to_table = ""; + object.percent = 0; + } + if (message.from_table != null && message.hasOwnProperty("from_table")) + object.from_table = message.from_table; + if (message.to_table != null && message.hasOwnProperty("to_table")) + object.to_table = message.to_table; + if (message.percent != null && message.hasOwnProperty("percent")) + object.percent = options.json && !isFinite(message.percent) ? String(message.percent) : message.percent; + return object; + }; + + /** + * Converts this MirrorRule to JSON. + * @function toJSON + * @memberof vschema.MirrorRule + * @instance + * @returns {Object.} JSON object + */ + MirrorRule.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for MirrorRule + * @function getTypeUrl + * @memberof vschema.MirrorRule + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + MirrorRule.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vschema.MirrorRule"; + }; + + return MirrorRule; + })(); + return vschema; })(); @@ -175383,6 +175885,1448 @@ export const vtctldata = $root.vtctldata = (() => { return WorkflowUpdateResponse; })(); + vtctldata.ApplyMirrorRulesRequest = (function() { + + /** + * Properties of an ApplyMirrorRulesRequest. + * @memberof vtctldata + * @interface IApplyMirrorRulesRequest + * @property {vschema.IMirrorRules|null} [mirror_rules] ApplyMirrorRulesRequest mirror_rules + * @property {boolean|null} [skip_rebuild] ApplyMirrorRulesRequest skip_rebuild + * @property {Array.|null} [rebuild_cells] ApplyMirrorRulesRequest rebuild_cells + */ + + /** + * Constructs a new ApplyMirrorRulesRequest. + * @memberof vtctldata + * @classdesc Represents an ApplyMirrorRulesRequest. + * @implements IApplyMirrorRulesRequest + * @constructor + * @param {vtctldata.IApplyMirrorRulesRequest=} [properties] Properties to set + */ + function ApplyMirrorRulesRequest(properties) { + this.rebuild_cells = []; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ApplyMirrorRulesRequest mirror_rules. + * @member {vschema.IMirrorRules|null|undefined} mirror_rules + * @memberof vtctldata.ApplyMirrorRulesRequest + * @instance + */ + ApplyMirrorRulesRequest.prototype.mirror_rules = null; + + /** + * ApplyMirrorRulesRequest skip_rebuild. + * @member {boolean} skip_rebuild + * @memberof vtctldata.ApplyMirrorRulesRequest + * @instance + */ + ApplyMirrorRulesRequest.prototype.skip_rebuild = false; + + /** + * ApplyMirrorRulesRequest rebuild_cells. + * @member {Array.} rebuild_cells + * @memberof vtctldata.ApplyMirrorRulesRequest + * @instance + */ + ApplyMirrorRulesRequest.prototype.rebuild_cells = $util.emptyArray; + + /** + * Creates a new ApplyMirrorRulesRequest instance using the specified properties. + * @function create + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {vtctldata.IApplyMirrorRulesRequest=} [properties] Properties to set + * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest instance + */ + ApplyMirrorRulesRequest.create = function create(properties) { + return new ApplyMirrorRulesRequest(properties); + }; + + /** + * Encodes the specified ApplyMirrorRulesRequest message. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {vtctldata.IApplyMirrorRulesRequest} message ApplyMirrorRulesRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyMirrorRulesRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.mirror_rules != null && Object.hasOwnProperty.call(message, "mirror_rules")) + $root.vschema.MirrorRules.encode(message.mirror_rules, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + if (message.skip_rebuild != null && Object.hasOwnProperty.call(message, "skip_rebuild")) + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.skip_rebuild); + if (message.rebuild_cells != null && message.rebuild_cells.length) + for (let i = 0; i < message.rebuild_cells.length; ++i) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.rebuild_cells[i]); + return writer; + }; + + /** + * Encodes the specified ApplyMirrorRulesRequest message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {vtctldata.IApplyMirrorRulesRequest} message ApplyMirrorRulesRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyMirrorRulesRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyMirrorRulesRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ApplyMirrorRulesRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.mirror_rules = $root.vschema.MirrorRules.decode(reader, reader.uint32()); + break; + } + case 2: { + message.skip_rebuild = reader.bool(); + break; + } + case 3: { + if (!(message.rebuild_cells && message.rebuild_cells.length)) + message.rebuild_cells = []; + message.rebuild_cells.push(reader.string()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyMirrorRulesRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ApplyMirrorRulesRequest message. + * @function verify + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ApplyMirrorRulesRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) { + let error = $root.vschema.MirrorRules.verify(message.mirror_rules); + if (error) + return "mirror_rules." + error; + } + if (message.skip_rebuild != null && message.hasOwnProperty("skip_rebuild")) + if (typeof message.skip_rebuild !== "boolean") + return "skip_rebuild: boolean expected"; + if (message.rebuild_cells != null && message.hasOwnProperty("rebuild_cells")) { + if (!Array.isArray(message.rebuild_cells)) + return "rebuild_cells: array expected"; + for (let i = 0; i < message.rebuild_cells.length; ++i) + if (!$util.isString(message.rebuild_cells[i])) + return "rebuild_cells: string[] expected"; + } + return null; + }; + + /** + * Creates an ApplyMirrorRulesRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest + */ + ApplyMirrorRulesRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ApplyMirrorRulesRequest) + return object; + let message = new $root.vtctldata.ApplyMirrorRulesRequest(); + if (object.mirror_rules != null) { + if (typeof object.mirror_rules !== "object") + throw TypeError(".vtctldata.ApplyMirrorRulesRequest.mirror_rules: object expected"); + message.mirror_rules = $root.vschema.MirrorRules.fromObject(object.mirror_rules); + } + if (object.skip_rebuild != null) + message.skip_rebuild = Boolean(object.skip_rebuild); + if (object.rebuild_cells) { + if (!Array.isArray(object.rebuild_cells)) + throw TypeError(".vtctldata.ApplyMirrorRulesRequest.rebuild_cells: array expected"); + message.rebuild_cells = []; + for (let i = 0; i < object.rebuild_cells.length; ++i) + message.rebuild_cells[i] = String(object.rebuild_cells[i]); + } + return message; + }; + + /** + * Creates a plain object from an ApplyMirrorRulesRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {vtctldata.ApplyMirrorRulesRequest} message ApplyMirrorRulesRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ApplyMirrorRulesRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.arrays || options.defaults) + object.rebuild_cells = []; + if (options.defaults) { + object.mirror_rules = null; + object.skip_rebuild = false; + } + if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) + object.mirror_rules = $root.vschema.MirrorRules.toObject(message.mirror_rules, options); + if (message.skip_rebuild != null && message.hasOwnProperty("skip_rebuild")) + object.skip_rebuild = message.skip_rebuild; + if (message.rebuild_cells && message.rebuild_cells.length) { + object.rebuild_cells = []; + for (let j = 0; j < message.rebuild_cells.length; ++j) + object.rebuild_cells[j] = message.rebuild_cells[j]; + } + return object; + }; + + /** + * Converts this ApplyMirrorRulesRequest to JSON. + * @function toJSON + * @memberof vtctldata.ApplyMirrorRulesRequest + * @instance + * @returns {Object.} JSON object + */ + ApplyMirrorRulesRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ApplyMirrorRulesRequest + * @function getTypeUrl + * @memberof vtctldata.ApplyMirrorRulesRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ApplyMirrorRulesRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.ApplyMirrorRulesRequest"; + }; + + return ApplyMirrorRulesRequest; + })(); + + vtctldata.ApplyMirrorRulesResponse = (function() { + + /** + * Properties of an ApplyMirrorRulesResponse. + * @memberof vtctldata + * @interface IApplyMirrorRulesResponse + */ + + /** + * Constructs a new ApplyMirrorRulesResponse. + * @memberof vtctldata + * @classdesc Represents an ApplyMirrorRulesResponse. + * @implements IApplyMirrorRulesResponse + * @constructor + * @param {vtctldata.IApplyMirrorRulesResponse=} [properties] Properties to set + */ + function ApplyMirrorRulesResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new ApplyMirrorRulesResponse instance using the specified properties. + * @function create + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {vtctldata.IApplyMirrorRulesResponse=} [properties] Properties to set + * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse instance + */ + ApplyMirrorRulesResponse.create = function create(properties) { + return new ApplyMirrorRulesResponse(properties); + }; + + /** + * Encodes the specified ApplyMirrorRulesResponse message. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {vtctldata.IApplyMirrorRulesResponse} message ApplyMirrorRulesResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyMirrorRulesResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified ApplyMirrorRulesResponse message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {vtctldata.IApplyMirrorRulesResponse} message ApplyMirrorRulesResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyMirrorRulesResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyMirrorRulesResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ApplyMirrorRulesResponse(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyMirrorRulesResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ApplyMirrorRulesResponse message. + * @function verify + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ApplyMirrorRulesResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates an ApplyMirrorRulesResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse + */ + ApplyMirrorRulesResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ApplyMirrorRulesResponse) + return object; + return new $root.vtctldata.ApplyMirrorRulesResponse(); + }; + + /** + * Creates a plain object from an ApplyMirrorRulesResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {vtctldata.ApplyMirrorRulesResponse} message ApplyMirrorRulesResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ApplyMirrorRulesResponse.toObject = function toObject() { + return {}; + }; + + /** + * Converts this ApplyMirrorRulesResponse to JSON. + * @function toJSON + * @memberof vtctldata.ApplyMirrorRulesResponse + * @instance + * @returns {Object.} JSON object + */ + ApplyMirrorRulesResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for ApplyMirrorRulesResponse + * @function getTypeUrl + * @memberof vtctldata.ApplyMirrorRulesResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + ApplyMirrorRulesResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.ApplyMirrorRulesResponse"; + }; + + return ApplyMirrorRulesResponse; + })(); + + vtctldata.GetMirrorRulesRequest = (function() { + + /** + * Properties of a GetMirrorRulesRequest. + * @memberof vtctldata + * @interface IGetMirrorRulesRequest + */ + + /** + * Constructs a new GetMirrorRulesRequest. + * @memberof vtctldata + * @classdesc Represents a GetMirrorRulesRequest. + * @implements IGetMirrorRulesRequest + * @constructor + * @param {vtctldata.IGetMirrorRulesRequest=} [properties] Properties to set + */ + function GetMirrorRulesRequest(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new GetMirrorRulesRequest instance using the specified properties. + * @function create + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {vtctldata.IGetMirrorRulesRequest=} [properties] Properties to set + * @returns {vtctldata.GetMirrorRulesRequest} GetMirrorRulesRequest instance + */ + GetMirrorRulesRequest.create = function create(properties) { + return new GetMirrorRulesRequest(properties); + }; + + /** + * Encodes the specified GetMirrorRulesRequest message. Does not implicitly {@link vtctldata.GetMirrorRulesRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {vtctldata.IGetMirrorRulesRequest} message GetMirrorRulesRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetMirrorRulesRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified GetMirrorRulesRequest message, length delimited. Does not implicitly {@link vtctldata.GetMirrorRulesRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {vtctldata.IGetMirrorRulesRequest} message GetMirrorRulesRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetMirrorRulesRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a GetMirrorRulesRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.GetMirrorRulesRequest} GetMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetMirrorRulesRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.GetMirrorRulesRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a GetMirrorRulesRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.GetMirrorRulesRequest} GetMirrorRulesRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetMirrorRulesRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a GetMirrorRulesRequest message. + * @function verify + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + GetMirrorRulesRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a GetMirrorRulesRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.GetMirrorRulesRequest} GetMirrorRulesRequest + */ + GetMirrorRulesRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.GetMirrorRulesRequest) + return object; + return new $root.vtctldata.GetMirrorRulesRequest(); + }; + + /** + * Creates a plain object from a GetMirrorRulesRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {vtctldata.GetMirrorRulesRequest} message GetMirrorRulesRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + GetMirrorRulesRequest.toObject = function toObject() { + return {}; + }; + + /** + * Converts this GetMirrorRulesRequest to JSON. + * @function toJSON + * @memberof vtctldata.GetMirrorRulesRequest + * @instance + * @returns {Object.} JSON object + */ + GetMirrorRulesRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for GetMirrorRulesRequest + * @function getTypeUrl + * @memberof vtctldata.GetMirrorRulesRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + GetMirrorRulesRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.GetMirrorRulesRequest"; + }; + + return GetMirrorRulesRequest; + })(); + + vtctldata.GetMirrorRulesResponse = (function() { + + /** + * Properties of a GetMirrorRulesResponse. + * @memberof vtctldata + * @interface IGetMirrorRulesResponse + * @property {vschema.IMirrorRules|null} [mirror_rules] GetMirrorRulesResponse mirror_rules + */ + + /** + * Constructs a new GetMirrorRulesResponse. + * @memberof vtctldata + * @classdesc Represents a GetMirrorRulesResponse. + * @implements IGetMirrorRulesResponse + * @constructor + * @param {vtctldata.IGetMirrorRulesResponse=} [properties] Properties to set + */ + function GetMirrorRulesResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * GetMirrorRulesResponse mirror_rules. + * @member {vschema.IMirrorRules|null|undefined} mirror_rules + * @memberof vtctldata.GetMirrorRulesResponse + * @instance + */ + GetMirrorRulesResponse.prototype.mirror_rules = null; + + /** + * Creates a new GetMirrorRulesResponse instance using the specified properties. + * @function create + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {vtctldata.IGetMirrorRulesResponse=} [properties] Properties to set + * @returns {vtctldata.GetMirrorRulesResponse} GetMirrorRulesResponse instance + */ + GetMirrorRulesResponse.create = function create(properties) { + return new GetMirrorRulesResponse(properties); + }; + + /** + * Encodes the specified GetMirrorRulesResponse message. Does not implicitly {@link vtctldata.GetMirrorRulesResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {vtctldata.IGetMirrorRulesResponse} message GetMirrorRulesResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetMirrorRulesResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.mirror_rules != null && Object.hasOwnProperty.call(message, "mirror_rules")) + $root.vschema.MirrorRules.encode(message.mirror_rules, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified GetMirrorRulesResponse message, length delimited. Does not implicitly {@link vtctldata.GetMirrorRulesResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {vtctldata.IGetMirrorRulesResponse} message GetMirrorRulesResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + GetMirrorRulesResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a GetMirrorRulesResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.GetMirrorRulesResponse} GetMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetMirrorRulesResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.GetMirrorRulesResponse(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.mirror_rules = $root.vschema.MirrorRules.decode(reader, reader.uint32()); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a GetMirrorRulesResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.GetMirrorRulesResponse} GetMirrorRulesResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + GetMirrorRulesResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a GetMirrorRulesResponse message. + * @function verify + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + GetMirrorRulesResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) { + let error = $root.vschema.MirrorRules.verify(message.mirror_rules); + if (error) + return "mirror_rules." + error; + } + return null; + }; + + /** + * Creates a GetMirrorRulesResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.GetMirrorRulesResponse} GetMirrorRulesResponse + */ + GetMirrorRulesResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.GetMirrorRulesResponse) + return object; + let message = new $root.vtctldata.GetMirrorRulesResponse(); + if (object.mirror_rules != null) { + if (typeof object.mirror_rules !== "object") + throw TypeError(".vtctldata.GetMirrorRulesResponse.mirror_rules: object expected"); + message.mirror_rules = $root.vschema.MirrorRules.fromObject(object.mirror_rules); + } + return message; + }; + + /** + * Creates a plain object from a GetMirrorRulesResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {vtctldata.GetMirrorRulesResponse} message GetMirrorRulesResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + GetMirrorRulesResponse.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) + object.mirror_rules = null; + if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) + object.mirror_rules = $root.vschema.MirrorRules.toObject(message.mirror_rules, options); + return object; + }; + + /** + * Converts this GetMirrorRulesResponse to JSON. + * @function toJSON + * @memberof vtctldata.GetMirrorRulesResponse + * @instance + * @returns {Object.} JSON object + */ + GetMirrorRulesResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for GetMirrorRulesResponse + * @function getTypeUrl + * @memberof vtctldata.GetMirrorRulesResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + GetMirrorRulesResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.GetMirrorRulesResponse"; + }; + + return GetMirrorRulesResponse; + })(); + + vtctldata.WorkflowMirrorTrafficRequest = (function() { + + /** + * Properties of a WorkflowMirrorTrafficRequest. + * @memberof vtctldata + * @interface IWorkflowMirrorTrafficRequest + * @property {string|null} [keyspace] WorkflowMirrorTrafficRequest keyspace + * @property {string|null} [workflow] WorkflowMirrorTrafficRequest workflow + * @property {Array.|null} [tablet_types] WorkflowMirrorTrafficRequest tablet_types + * @property {number|null} [percent] WorkflowMirrorTrafficRequest percent + */ + + /** + * Constructs a new WorkflowMirrorTrafficRequest. + * @memberof vtctldata + * @classdesc Represents a WorkflowMirrorTrafficRequest. + * @implements IWorkflowMirrorTrafficRequest + * @constructor + * @param {vtctldata.IWorkflowMirrorTrafficRequest=} [properties] Properties to set + */ + function WorkflowMirrorTrafficRequest(properties) { + this.tablet_types = []; + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WorkflowMirrorTrafficRequest keyspace. + * @member {string} keyspace + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @instance + */ + WorkflowMirrorTrafficRequest.prototype.keyspace = ""; + + /** + * WorkflowMirrorTrafficRequest workflow. + * @member {string} workflow + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @instance + */ + WorkflowMirrorTrafficRequest.prototype.workflow = ""; + + /** + * WorkflowMirrorTrafficRequest tablet_types. + * @member {Array.} tablet_types + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @instance + */ + WorkflowMirrorTrafficRequest.prototype.tablet_types = $util.emptyArray; + + /** + * WorkflowMirrorTrafficRequest percent. + * @member {number} percent + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @instance + */ + WorkflowMirrorTrafficRequest.prototype.percent = 0; + + /** + * Creates a new WorkflowMirrorTrafficRequest instance using the specified properties. + * @function create + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {vtctldata.IWorkflowMirrorTrafficRequest=} [properties] Properties to set + * @returns {vtctldata.WorkflowMirrorTrafficRequest} WorkflowMirrorTrafficRequest instance + */ + WorkflowMirrorTrafficRequest.create = function create(properties) { + return new WorkflowMirrorTrafficRequest(properties); + }; + + /** + * Encodes the specified WorkflowMirrorTrafficRequest message. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {vtctldata.IWorkflowMirrorTrafficRequest} message WorkflowMirrorTrafficRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WorkflowMirrorTrafficRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.keyspace); + if (message.workflow != null && Object.hasOwnProperty.call(message, "workflow")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.workflow); + if (message.tablet_types != null && message.tablet_types.length) { + writer.uint32(/* id 3, wireType 2 =*/26).fork(); + for (let i = 0; i < message.tablet_types.length; ++i) + writer.int32(message.tablet_types[i]); + writer.ldelim(); + } + if (message.percent != null && Object.hasOwnProperty.call(message, "percent")) + writer.uint32(/* id 4, wireType 5 =*/37).float(message.percent); + return writer; + }; + + /** + * Encodes the specified WorkflowMirrorTrafficRequest message, length delimited. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {vtctldata.IWorkflowMirrorTrafficRequest} message WorkflowMirrorTrafficRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WorkflowMirrorTrafficRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WorkflowMirrorTrafficRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.WorkflowMirrorTrafficRequest} WorkflowMirrorTrafficRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WorkflowMirrorTrafficRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.WorkflowMirrorTrafficRequest(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.keyspace = reader.string(); + break; + } + case 2: { + message.workflow = reader.string(); + break; + } + case 3: { + if (!(message.tablet_types && message.tablet_types.length)) + message.tablet_types = []; + if ((tag & 7) === 2) { + let end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) + message.tablet_types.push(reader.int32()); + } else + message.tablet_types.push(reader.int32()); + break; + } + case 4: { + message.percent = reader.float(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WorkflowMirrorTrafficRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.WorkflowMirrorTrafficRequest} WorkflowMirrorTrafficRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WorkflowMirrorTrafficRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WorkflowMirrorTrafficRequest message. + * @function verify + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WorkflowMirrorTrafficRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + if (!$util.isString(message.keyspace)) + return "keyspace: string expected"; + if (message.workflow != null && message.hasOwnProperty("workflow")) + if (!$util.isString(message.workflow)) + return "workflow: string expected"; + if (message.tablet_types != null && message.hasOwnProperty("tablet_types")) { + if (!Array.isArray(message.tablet_types)) + return "tablet_types: array expected"; + for (let i = 0; i < message.tablet_types.length; ++i) + switch (message.tablet_types[i]) { + default: + return "tablet_types: enum value[] expected"; + case 0: + case 1: + case 1: + case 2: + case 3: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + break; + } + } + if (message.percent != null && message.hasOwnProperty("percent")) + if (typeof message.percent !== "number") + return "percent: number expected"; + return null; + }; + + /** + * Creates a WorkflowMirrorTrafficRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.WorkflowMirrorTrafficRequest} WorkflowMirrorTrafficRequest + */ + WorkflowMirrorTrafficRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.WorkflowMirrorTrafficRequest) + return object; + let message = new $root.vtctldata.WorkflowMirrorTrafficRequest(); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.workflow != null) + message.workflow = String(object.workflow); + if (object.tablet_types) { + if (!Array.isArray(object.tablet_types)) + throw TypeError(".vtctldata.WorkflowMirrorTrafficRequest.tablet_types: array expected"); + message.tablet_types = []; + for (let i = 0; i < object.tablet_types.length; ++i) + switch (object.tablet_types[i]) { + default: + if (typeof object.tablet_types[i] === "number") { + message.tablet_types[i] = object.tablet_types[i]; + break; + } + case "UNKNOWN": + case 0: + message.tablet_types[i] = 0; + break; + case "PRIMARY": + case 1: + message.tablet_types[i] = 1; + break; + case "MASTER": + case 1: + message.tablet_types[i] = 1; + break; + case "REPLICA": + case 2: + message.tablet_types[i] = 2; + break; + case "RDONLY": + case 3: + message.tablet_types[i] = 3; + break; + case "BATCH": + case 3: + message.tablet_types[i] = 3; + break; + case "SPARE": + case 4: + message.tablet_types[i] = 4; + break; + case "EXPERIMENTAL": + case 5: + message.tablet_types[i] = 5; + break; + case "BACKUP": + case 6: + message.tablet_types[i] = 6; + break; + case "RESTORE": + case 7: + message.tablet_types[i] = 7; + break; + case "DRAINED": + case 8: + message.tablet_types[i] = 8; + break; + } + } + if (object.percent != null) + message.percent = Number(object.percent); + return message; + }; + + /** + * Creates a plain object from a WorkflowMirrorTrafficRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {vtctldata.WorkflowMirrorTrafficRequest} message WorkflowMirrorTrafficRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WorkflowMirrorTrafficRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.arrays || options.defaults) + object.tablet_types = []; + if (options.defaults) { + object.keyspace = ""; + object.workflow = ""; + object.percent = 0; + } + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.workflow != null && message.hasOwnProperty("workflow")) + object.workflow = message.workflow; + if (message.tablet_types && message.tablet_types.length) { + object.tablet_types = []; + for (let j = 0; j < message.tablet_types.length; ++j) + object.tablet_types[j] = options.enums === String ? $root.topodata.TabletType[message.tablet_types[j]] === undefined ? message.tablet_types[j] : $root.topodata.TabletType[message.tablet_types[j]] : message.tablet_types[j]; + } + if (message.percent != null && message.hasOwnProperty("percent")) + object.percent = options.json && !isFinite(message.percent) ? String(message.percent) : message.percent; + return object; + }; + + /** + * Converts this WorkflowMirrorTrafficRequest to JSON. + * @function toJSON + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @instance + * @returns {Object.} JSON object + */ + WorkflowMirrorTrafficRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for WorkflowMirrorTrafficRequest + * @function getTypeUrl + * @memberof vtctldata.WorkflowMirrorTrafficRequest + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + WorkflowMirrorTrafficRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.WorkflowMirrorTrafficRequest"; + }; + + return WorkflowMirrorTrafficRequest; + })(); + + vtctldata.WorkflowMirrorTrafficResponse = (function() { + + /** + * Properties of a WorkflowMirrorTrafficResponse. + * @memberof vtctldata + * @interface IWorkflowMirrorTrafficResponse + * @property {string|null} [summary] WorkflowMirrorTrafficResponse summary + * @property {string|null} [start_state] WorkflowMirrorTrafficResponse start_state + * @property {string|null} [current_state] WorkflowMirrorTrafficResponse current_state + */ + + /** + * Constructs a new WorkflowMirrorTrafficResponse. + * @memberof vtctldata + * @classdesc Represents a WorkflowMirrorTrafficResponse. + * @implements IWorkflowMirrorTrafficResponse + * @constructor + * @param {vtctldata.IWorkflowMirrorTrafficResponse=} [properties] Properties to set + */ + function WorkflowMirrorTrafficResponse(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * WorkflowMirrorTrafficResponse summary. + * @member {string} summary + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @instance + */ + WorkflowMirrorTrafficResponse.prototype.summary = ""; + + /** + * WorkflowMirrorTrafficResponse start_state. + * @member {string} start_state + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @instance + */ + WorkflowMirrorTrafficResponse.prototype.start_state = ""; + + /** + * WorkflowMirrorTrafficResponse current_state. + * @member {string} current_state + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @instance + */ + WorkflowMirrorTrafficResponse.prototype.current_state = ""; + + /** + * Creates a new WorkflowMirrorTrafficResponse instance using the specified properties. + * @function create + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {vtctldata.IWorkflowMirrorTrafficResponse=} [properties] Properties to set + * @returns {vtctldata.WorkflowMirrorTrafficResponse} WorkflowMirrorTrafficResponse instance + */ + WorkflowMirrorTrafficResponse.create = function create(properties) { + return new WorkflowMirrorTrafficResponse(properties); + }; + + /** + * Encodes the specified WorkflowMirrorTrafficResponse message. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {vtctldata.IWorkflowMirrorTrafficResponse} message WorkflowMirrorTrafficResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WorkflowMirrorTrafficResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.summary != null && Object.hasOwnProperty.call(message, "summary")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.summary); + if (message.start_state != null && Object.hasOwnProperty.call(message, "start_state")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.start_state); + if (message.current_state != null && Object.hasOwnProperty.call(message, "current_state")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.current_state); + return writer; + }; + + /** + * Encodes the specified WorkflowMirrorTrafficResponse message, length delimited. Does not implicitly {@link vtctldata.WorkflowMirrorTrafficResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {vtctldata.IWorkflowMirrorTrafficResponse} message WorkflowMirrorTrafficResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + WorkflowMirrorTrafficResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a WorkflowMirrorTrafficResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.WorkflowMirrorTrafficResponse} WorkflowMirrorTrafficResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WorkflowMirrorTrafficResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.WorkflowMirrorTrafficResponse(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.summary = reader.string(); + break; + } + case 2: { + message.start_state = reader.string(); + break; + } + case 3: { + message.current_state = reader.string(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a WorkflowMirrorTrafficResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.WorkflowMirrorTrafficResponse} WorkflowMirrorTrafficResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + WorkflowMirrorTrafficResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a WorkflowMirrorTrafficResponse message. + * @function verify + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + WorkflowMirrorTrafficResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.summary != null && message.hasOwnProperty("summary")) + if (!$util.isString(message.summary)) + return "summary: string expected"; + if (message.start_state != null && message.hasOwnProperty("start_state")) + if (!$util.isString(message.start_state)) + return "start_state: string expected"; + if (message.current_state != null && message.hasOwnProperty("current_state")) + if (!$util.isString(message.current_state)) + return "current_state: string expected"; + return null; + }; + + /** + * Creates a WorkflowMirrorTrafficResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.WorkflowMirrorTrafficResponse} WorkflowMirrorTrafficResponse + */ + WorkflowMirrorTrafficResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.WorkflowMirrorTrafficResponse) + return object; + let message = new $root.vtctldata.WorkflowMirrorTrafficResponse(); + if (object.summary != null) + message.summary = String(object.summary); + if (object.start_state != null) + message.start_state = String(object.start_state); + if (object.current_state != null) + message.current_state = String(object.current_state); + return message; + }; + + /** + * Creates a plain object from a WorkflowMirrorTrafficResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {vtctldata.WorkflowMirrorTrafficResponse} message WorkflowMirrorTrafficResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + WorkflowMirrorTrafficResponse.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.summary = ""; + object.start_state = ""; + object.current_state = ""; + } + if (message.summary != null && message.hasOwnProperty("summary")) + object.summary = message.summary; + if (message.start_state != null && message.hasOwnProperty("start_state")) + object.start_state = message.start_state; + if (message.current_state != null && message.hasOwnProperty("current_state")) + object.current_state = message.current_state; + return object; + }; + + /** + * Converts this WorkflowMirrorTrafficResponse to JSON. + * @function toJSON + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @instance + * @returns {Object.} JSON object + */ + WorkflowMirrorTrafficResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for WorkflowMirrorTrafficResponse + * @function getTypeUrl + * @memberof vtctldata.WorkflowMirrorTrafficResponse + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + WorkflowMirrorTrafficResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/vtctldata.WorkflowMirrorTrafficResponse"; + }; + + return WorkflowMirrorTrafficResponse; + })(); + return vtctldata; })(); From c9430d07d308b84fa66750fbfdb4edc67c1932fd Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 28 May 2024 16:19:45 -0400 Subject: [PATCH 02/27] cr: rename var, extract common test code to helper fn Signed-off-by: Max Englander --- go/cmd/vtctldclient/command/mirror_rules.go | 8 +-- .../movetables_mirrortraffic_test.go | 51 ++++--------------- .../vreplication_vtctldclient_cli_test.go | 24 +++++++++ 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/go/cmd/vtctldclient/command/mirror_rules.go b/go/cmd/vtctldclient/command/mirror_rules.go index 50acaf8be75..e0192a39684 100644 --- a/go/cmd/vtctldclient/command/mirror_rules.go +++ b/go/cmd/vtctldclient/command/mirror_rules.go @@ -81,13 +81,13 @@ func commandApplyMirrorRules(cmd *cobra.Command, args []string) error { rulesBytes = []byte(applyMirrorRulesOptions.Rules) } - rr := &vschemapb.MirrorRules{} - if err := json2.Unmarshal(rulesBytes, &rr); err != nil { + mr := &vschemapb.MirrorRules{} + if err := json2.Unmarshal(rulesBytes, &mr); err != nil { return err } // Round-trip so when we display the result it's readable. - data, err := cli.MarshalJSON(rr) + data, err := cli.MarshalJSON(mr) if err != nil { return err } @@ -110,7 +110,7 @@ func commandApplyMirrorRules(cmd *cobra.Command, args []string) error { } _, err = client.ApplyMirrorRules(commandCtx, &vtctldatapb.ApplyMirrorRulesRequest{ - MirrorRules: rr, + MirrorRules: mr, SkipRebuild: applyMirrorRulesOptions.SkipRebuild, RebuildCells: applyMirrorRulesOptions.Cells, }) diff --git a/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go b/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go index 1c6d24ef721..dfab72d9582 100644 --- a/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go +++ b/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go @@ -1,5 +1,5 @@ /* -Copyright 2022 The Vitess Authors. +Copyright 2024 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,15 +17,10 @@ limitations under the License. package vreplication import ( - "fmt" "testing" - "github.com/stretchr/testify/require" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vschemapb "vitess.io/vitess/go/vt/proto/vschema" - "vitess.io/vitess/go/vt/topo/topoproto" ) func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { @@ -36,6 +31,7 @@ func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { sourceKeyspace := "product" targetKeyspace := "customer" workflowName := "wf1" + tables := []string{"customer", "loadtest", "customer2"} _ = setupMinimalCustomerKeyspace(t) @@ -58,28 +54,11 @@ func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { mt.MirrorTraffic() confirmMirrorRulesExist(t) - // Each table should have a mirror rule for each serving type. - mirrorRules := getMirrorRules(t) - require.Len(t, mirrorRules.Rules, 9) - fromTableToRule := make(map[string]*vschemapb.MirrorRule) - for _, rule := range mirrorRules.Rules { - fromTableToRule[rule.FromTable] = rule - } - for _, table := range []string{"customer", "loadtest", "customer2"} { - for _, tabletType := range []topodatapb.TabletType{ - topodatapb.TabletType_PRIMARY, - topodatapb.TabletType_REPLICA, - topodatapb.TabletType_RDONLY, - } { - fromTable := fmt.Sprintf("%s.%s", sourceKeyspace, table) - if tabletType != topodatapb.TabletType_PRIMARY { - fromTable = fmt.Sprintf("%s@%s", fromTable, topoproto.TabletTypeLString(tabletType)) - } - require.Contains(t, fromTableToRule, fromTable) - require.Equal(t, fmt.Sprintf("%s.%s", targetKeyspace, table), fromTableToRule[fromTable].ToTable) - require.Equal(t, float32(25), fromTableToRule[fromTable].Percent) - } - } + expectMirrorRules(t, sourceKeyspace, targetKeyspace, tables, []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + }, 25) lg := newLoadGenerator(t, vc) go func() { @@ -90,19 +69,9 @@ func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { mt.SwitchReads() confirmMirrorRulesExist(t) - // Each table should only have a mirror rule for primary serving type. - mirrorRules = getMirrorRules(t) - require.Len(t, mirrorRules.Rules, 3) - fromTableToRule = make(map[string]*vschemapb.MirrorRule) - for _, rule := range mirrorRules.Rules { - fromTableToRule[rule.FromTable] = rule - } - for _, table := range []string{"customer", "loadtest", "customer2"} { - fromTable := fmt.Sprintf("%s.%s", sourceKeyspace, table) - require.Contains(t, fromTableToRule, fromTable) - require.Equal(t, fmt.Sprintf("%s.%s", targetKeyspace, table), fromTableToRule[fromTable].ToTable) - require.Equal(t, float32(25), fromTableToRule[fromTable].Percent) - } + expectMirrorRules(t, sourceKeyspace, targetKeyspace, tables, []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + }, 25) mt.SwitchWrites() confirmNoMirrorRules(t) diff --git a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go index 90822a2835c..d8d3d9f00d9 100644 --- a/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go +++ b/go/test/endtoend/vreplication/vreplication_vtctldclient_cli_test.go @@ -34,6 +34,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + "vitess.io/vitess/go/vt/topo/topoproto" ) // TestVtctldclientCLI tests the vreplication vtctldclient CLI commands, primarily to check that non-standard flags @@ -409,6 +410,29 @@ func confirmMirrorRulesExist(t *testing.T) { require.NotZero(t, len(mirrorRulesResponse.Rules)) } +func expectMirrorRules(t *testing.T, sourceKeyspace, targetKeyspace string, tables []string, tabletTypes []topodatapb.TabletType, percent float32) { + t.Helper() + + // Each table should have a mirror rule for each serving type. + mirrorRules := getMirrorRules(t) + require.Len(t, mirrorRules.Rules, len(tables)*len(tabletTypes)) + fromTableToRule := make(map[string]*vschemapb.MirrorRule) + for _, rule := range mirrorRules.Rules { + fromTableToRule[rule.FromTable] = rule + } + for _, table := range tables { + for _, tabletType := range tabletTypes { + fromTable := fmt.Sprintf("%s.%s", sourceKeyspace, table) + if tabletType != topodatapb.TabletType_PRIMARY { + fromTable = fmt.Sprintf("%s@%s", fromTable, topoproto.TabletTypeLString(tabletType)) + } + require.Contains(t, fromTableToRule, fromTable) + require.Equal(t, fmt.Sprintf("%s.%s", targetKeyspace, table), fromTableToRule[fromTable].ToTable) + require.Equal(t, percent, fromTableToRule[fromTable].Percent) + } + } +} + func getRoutingRules(t *testing.T) *vschemapb.RoutingRules { routingRules, err := vc.VtctldClient.ExecuteCommandWithOutput("GetRoutingRules") require.NoError(t, err) From a9dbf341efde943ea5add97b2c49cbafea442e3b Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 18 Jun 2024 16:16:49 -0400 Subject: [PATCH 03/27] update tests Signed-off-by: Max Englander --- go/test/endtoend/vreplication/vreplication_test_env.go | 2 ++ go/vt/vtctl/workflow/server_test.go | 4 ++++ go/vt/vtctl/workflow/switcher_dry_run.go | 1 + 3 files changed, 7 insertions(+) diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index 6073cfac6ab..751faf497ad 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -17,6 +17,7 @@ limitations under the License. package vreplication var dryRunResultsSwitchWritesCustomerShard = []string{ + "Mirroring 0.000000 percent of traffic from keyspace product to keyspace customer for tablet types [PRIMARY]", "Lock keyspace product", "Lock keyspace customer", "/Stop writes on keyspace product for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order]: [keyspace:product;shard:0;position:", @@ -35,6 +36,7 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ } var dryRunResultsReadCustomerShard = []string{ + "Mirroring 0.000000 percent of traffic from keyspace product to keyspace customer for tablet types [RDONLY,REPLICA]", "Lock keyspace product", "Switch reads for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order] to keyspace customer for tablet types [RDONLY,REPLICA]", "Routing rules for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order] will be updated", diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go index 32ae6ce48d5..fa81b7555fe 100644 --- a/go/vt/vtctl/workflow/server_test.go +++ b/go/vt/vtctl/workflow/server_test.go @@ -689,10 +689,12 @@ func TestMoveTablesTrafficSwitchingDryRun(t *testing.T) { DryRun: true, }, want: []string{ + fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [REPLICA,RDONLY]", sourceKeyspaceName, targetKeyspaceName), fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), fmt.Sprintf("Switch reads for tables [%s] to keyspace %s for tablet types [REPLICA,RDONLY]", tablesStr, targetKeyspaceName), fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), fmt.Sprintf("Unlock keyspace %s", sourceKeyspaceName), + fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [PRIMARY]", sourceKeyspaceName, targetKeyspaceName), fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), fmt.Sprintf("Stop writes on keyspace %s for tables [%s]: [keyspace:%s;shard:-80;position:%s,keyspace:%s;shard:80-;position:%s]", @@ -728,10 +730,12 @@ func TestMoveTablesTrafficSwitchingDryRun(t *testing.T) { DryRun: true, }, want: []string{ + fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [REPLICA,RDONLY]", targetKeyspaceName, sourceKeyspaceName), fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), fmt.Sprintf("Switch reads for tables [%s] to keyspace %s for tablet types [REPLICA,RDONLY]", tablesStr, targetKeyspaceName), fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), fmt.Sprintf("Unlock keyspace %s", targetKeyspaceName), + fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [PRIMARY]", targetKeyspaceName, sourceKeyspaceName), fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), fmt.Sprintf("Stop writes on keyspace %s for tables [%s]: [keyspace:%s;shard:-80;position:%s,keyspace:%s;shard:80-;position:%s]", diff --git a/go/vt/vtctl/workflow/switcher_dry_run.go b/go/vt/vtctl/workflow/switcher_dry_run.go index ab3ad6e5e02..d96af1d276f 100644 --- a/go/vt/vtctl/workflow/switcher_dry_run.go +++ b/go/vt/vtctl/workflow/switcher_dry_run.go @@ -70,6 +70,7 @@ func (dr *switcherDryRun) mirrorTableTraffic(ctx context.Context, types []topoda } dr.drLog.Logf("Mirroring %f percent of traffic from keyspace %s to keyspace %s for tablet types [%s]", percent, dr.ts.SourceKeyspaceName(), dr.ts.TargetKeyspaceName(), strings.Join(tabletTypes, ",")) + return nil } From a0cffe5275d3981687b8cc8b6bb2891adf2dc91d Mon Sep 17 00:00:00 2001 From: Max Englander Date: Fri, 21 Jun 2024 14:18:16 -0400 Subject: [PATCH 04/27] Update go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go Co-authored-by: Deepthi Sigireddi Signed-off-by: Max Englander --- .../vtctldclient/command/vreplication/common/mirrortraffic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go b/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go index 601af477c95..f12970fbbfc 100644 --- a/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go +++ b/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go @@ -31,7 +31,7 @@ import ( func GetMirrorTrafficCommand(opts *SubCommandsOpts) *cobra.Command { cmd := &cobra.Command{ Use: "mirrortraffic", - Short: fmt.Sprintf("Mirror traffic for a %s VReplication workflow.", opts.SubCommand), + Short: fmt.Sprintf("Mirror traffic for a %s MoveTables workflow.", opts.SubCommand), Example: fmt.Sprintf(`vtctldclient --server localhost:15999 %s --workflow %s --target-keyspace customer mirrortraffic --percent 50.0`, opts.SubCommand, opts.Workflow), DisableFlagsInUseLine: true, Aliases: []string{"MirrorTraffic"}, From 859b4218a9ac35349ee97722cbbc9d5ac9dbe2c1 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Fri, 21 Jun 2024 14:21:10 -0400 Subject: [PATCH 05/27] Update go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go Co-authored-by: Deepthi Sigireddi Signed-off-by: Max Englander --- .../vtctldclient/command/vreplication/common/mirrortraffic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go b/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go index f12970fbbfc..68f0cfbc68c 100644 --- a/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go +++ b/go/cmd/vtctldclient/command/vreplication/common/mirrortraffic.go @@ -32,7 +32,7 @@ func GetMirrorTrafficCommand(opts *SubCommandsOpts) *cobra.Command { cmd := &cobra.Command{ Use: "mirrortraffic", Short: fmt.Sprintf("Mirror traffic for a %s MoveTables workflow.", opts.SubCommand), - Example: fmt.Sprintf(`vtctldclient --server localhost:15999 %s --workflow %s --target-keyspace customer mirrortraffic --percent 50.0`, opts.SubCommand, opts.Workflow), + Example: fmt.Sprintf(`vtctldclient --server localhost:15999 %s --workflow %s --target-keyspace customer mirrortraffic --percent 5.0`, opts.SubCommand, opts.Workflow), DisableFlagsInUseLine: true, Aliases: []string{"MirrorTraffic"}, Args: cobra.NoArgs, From 71b9a008952a81fa325249efdf5658a92991c92d Mon Sep 17 00:00:00 2001 From: Max Englander Date: Fri, 21 Jun 2024 19:14:43 -0400 Subject: [PATCH 06/27] cr: test repeat calls to mirror traffic Signed-off-by: Max Englander --- .../movetables_mirrortraffic_test.go | 37 +++++++++++++++++-- .../vreplication/vreplication_test_env.go | 4 +- go/vt/vtctl/workflow/server.go | 16 +++++++- go/vt/vtctl/workflow/server_test.go | 20 +++++----- go/vt/vtctl/workflow/switcher_dry_run.go | 2 +- 5 files changed, 60 insertions(+), 19 deletions(-) diff --git a/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go b/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go index dfab72d9582..54e648de6b4 100644 --- a/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go +++ b/go/test/endtoend/vreplication/movetables_mirrortraffic_test.go @@ -35,7 +35,7 @@ func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { _ = setupMinimalCustomerKeyspace(t) - mt := newMoveTables(vc, &moveTablesWorkflow{ + mtwf := &moveTablesWorkflow{ workflowInfo: &workflowInfo{ vc: vc, workflowName: workflowName, @@ -44,22 +44,45 @@ func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { sourceKeyspace: sourceKeyspace, tables: "customer,loadtest,customer2", mirrorFlags: []string{"--percent", "25"}, - }, flavor) + } + mt := newMoveTables(vc, mtwf, flavor) + // Mirror rules do not exist by default. mt.Create() confirmNoMirrorRules(t) waitForWorkflowState(t, vc, ksWorkflow, binlogdatapb.VReplicationWorkflowState_Running.String()) + // Mirror rules can be created after a MoveTables workflow is created. mt.MirrorTraffic() confirmMirrorRulesExist(t) - expectMirrorRules(t, sourceKeyspace, targetKeyspace, tables, []topodatapb.TabletType{ topodatapb.TabletType_PRIMARY, topodatapb.TabletType_REPLICA, topodatapb.TabletType_RDONLY, }, 25) + // Mirror rules can be adjusted after mirror rules are in place. + mtwf.mirrorFlags[1] = "50" + mt.MirrorTraffic() + confirmMirrorRulesExist(t) + expectMirrorRules(t, sourceKeyspace, targetKeyspace, tables, []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + }, 50) + + // Mirror rules can be adjusted multiple times after mirror rules are in + // place. + mtwf.mirrorFlags[1] = "75" + mt.MirrorTraffic() + confirmMirrorRulesExist(t) + expectMirrorRules(t, sourceKeyspace, targetKeyspace, tables, []topodatapb.TabletType{ + topodatapb.TabletType_PRIMARY, + topodatapb.TabletType_REPLICA, + topodatapb.TabletType_RDONLY, + }, 75) + lg := newLoadGenerator(t, vc) go func() { lg.start() @@ -69,10 +92,16 @@ func testMoveTablesMirrorTraffic(t *testing.T, flavor workflowFlavor) { mt.SwitchReads() confirmMirrorRulesExist(t) + // Mirror rules can be adjusted for writes after reads have been switched. + mtwf.mirrorFlags[1] = "100" + mtwf.mirrorFlags = append(mtwf.mirrorFlags, "--tablet-types", "primary") + mt.MirrorTraffic() + confirmMirrorRulesExist(t) expectMirrorRules(t, sourceKeyspace, targetKeyspace, tables, []topodatapb.TabletType{ topodatapb.TabletType_PRIMARY, - }, 25) + }, 100) + // Mirror rules are removed after writes are switched. mt.SwitchWrites() confirmNoMirrorRules(t) } diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index 751faf497ad..238242f0e65 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -17,7 +17,7 @@ limitations under the License. package vreplication var dryRunResultsSwitchWritesCustomerShard = []string{ - "Mirroring 0.000000 percent of traffic from keyspace product to keyspace customer for tablet types [PRIMARY]", + "Mirroring 0.00 percent of traffic from keyspace product to keyspace customer for tablet types [PRIMARY]", "Lock keyspace product", "Lock keyspace customer", "/Stop writes on keyspace product for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order]: [keyspace:product;shard:0;position:", @@ -36,7 +36,7 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ } var dryRunResultsReadCustomerShard = []string{ - "Mirroring 0.000000 percent of traffic from keyspace product to keyspace customer for tablet types [RDONLY,REPLICA]", + "Mirroring 0.00 percent of traffic from keyspace product to keyspace customer for tablet types [RDONLY,REPLICA]", "Lock keyspace product", "Switch reads for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order] to keyspace customer for tablet types [RDONLY,REPLICA]", "Routing rules for tables [Lead,Lead-1,blüb_tbl,customer,db_order_test,geom_tbl,json_tbl,loadtest,reftable,vdiff_order] will be updated", diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 70fd969bbdd..0a00ee9a0bf 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -4091,8 +4091,20 @@ func (s *Server) WorkflowMirrorTraffic(ctx context.Context, req *vtctldatapb.Wor // Don't allow traffic to be mirrored if any traffic has been switched over // to the target keyspace. - if len(startState.RdonlyCellsSwitched) > 0 || len(startState.ReplicaCellsSwitched) > 0 || startState.WritesSwitched { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot mirror traffic for workflow %s at this time: traffic is switched", startState.Workflow) + var cannotSwitchTabletTypes []string + for _, tt := range req.TabletTypes { + if tt == topodatapb.TabletType_RDONLY && len(startState.RdonlyCellsSwitched) > 0 { + cannotSwitchTabletTypes = append(cannotSwitchTabletTypes, "rdonly") + } + if tt == topodatapb.TabletType_REPLICA && len(startState.ReplicaCellsSwitched) > 0 { + cannotSwitchTabletTypes = append(cannotSwitchTabletTypes, "replica") + } + if tt == topodatapb.TabletType_PRIMARY && startState.WritesSwitched { + cannotSwitchTabletTypes = append(cannotSwitchTabletTypes, "primary") + } + } + if len(cannotSwitchTabletTypes) > 0 { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "cannot mirror [%s] traffic for workflow %s at this time: traffic for those tablet types is switched", strings.Join(cannotSwitchTabletTypes, ","), startState.Workflow) } if err := s.mirrorTraffic(ctx, req, ts, startState); err != nil { diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go index fa81b7555fe..f2b9f6b2496 100644 --- a/go/vt/vtctl/workflow/server_test.go +++ b/go/vt/vtctl/workflow/server_test.go @@ -689,12 +689,12 @@ func TestMoveTablesTrafficSwitchingDryRun(t *testing.T) { DryRun: true, }, want: []string{ - fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [REPLICA,RDONLY]", sourceKeyspaceName, targetKeyspaceName), + fmt.Sprintf("Mirroring 0.00 percent of traffic from keyspace %s to keyspace %s for tablet types [REPLICA,RDONLY]", sourceKeyspaceName, targetKeyspaceName), fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), fmt.Sprintf("Switch reads for tables [%s] to keyspace %s for tablet types [REPLICA,RDONLY]", tablesStr, targetKeyspaceName), fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), fmt.Sprintf("Unlock keyspace %s", sourceKeyspaceName), - fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [PRIMARY]", sourceKeyspaceName, targetKeyspaceName), + fmt.Sprintf("Mirroring 0.00 percent of traffic from keyspace %s to keyspace %s for tablet types [PRIMARY]", sourceKeyspaceName, targetKeyspaceName), fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), fmt.Sprintf("Stop writes on keyspace %s for tables [%s]: [keyspace:%s;shard:-80;position:%s,keyspace:%s;shard:80-;position:%s]", @@ -730,12 +730,12 @@ func TestMoveTablesTrafficSwitchingDryRun(t *testing.T) { DryRun: true, }, want: []string{ - fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [REPLICA,RDONLY]", targetKeyspaceName, sourceKeyspaceName), + fmt.Sprintf("Mirroring 0.00 percent of traffic from keyspace %s to keyspace %s for tablet types [REPLICA,RDONLY]", targetKeyspaceName, sourceKeyspaceName), fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), fmt.Sprintf("Switch reads for tables [%s] to keyspace %s for tablet types [REPLICA,RDONLY]", tablesStr, targetKeyspaceName), fmt.Sprintf("Routing rules for tables [%s] will be updated", tablesStr), fmt.Sprintf("Unlock keyspace %s", targetKeyspaceName), - fmt.Sprintf("Mirroring 0.000000 percent of traffic from keyspace %s to keyspace %s for tablet types [PRIMARY]", targetKeyspaceName, sourceKeyspaceName), + fmt.Sprintf("Mirroring 0.00 percent of traffic from keyspace %s to keyspace %s for tablet types [PRIMARY]", targetKeyspaceName, sourceKeyspaceName), fmt.Sprintf("Lock keyspace %s", targetKeyspaceName), fmt.Sprintf("Lock keyspace %s", sourceKeyspaceName), fmt.Sprintf("Stop writes on keyspace %s for tables [%s]: [keyspace:%s;shard:-80;position:%s,keyspace:%s;shard:80-;position:%s]", @@ -891,7 +891,7 @@ func TestMirrorTraffic(t *testing.T) { wantMirrorRules: make(map[string]map[string]float32), }, { - name: "cannot mirror traffic after switch rdonly traffic", + name: "cannot mirror rdonly traffic after switch rdonly traffic", req: &vtctldatapb.WorkflowMirrorTrafficRequest{ Keyspace: targetKs, Workflow: workflow, @@ -902,11 +902,11 @@ func TestMirrorTraffic(t *testing.T) { fmt.Sprintf("%s.%s@rdonly", targetKs, table1): {fmt.Sprintf("%s.%s@rdonly", targetKs, table1)}, fmt.Sprintf("%s.%s@rdonly", targetKs, table2): {fmt.Sprintf("%s.%s@rdonly", targetKs, table2)}, }, - wantErr: "cannot mirror traffic for workflow src2target at this time: traffic is switched", + wantErr: "cannot mirror [rdonly] traffic for workflow src2target at this time: traffic for those tablet types is switched", wantMirrorRules: make(map[string]map[string]float32), }, { - name: "cannot mirror traffic after switch replica traffic", + name: "cannot mirror replica traffic after switch replica traffic", req: &vtctldatapb.WorkflowMirrorTrafficRequest{ Keyspace: targetKs, Workflow: workflow, @@ -917,11 +917,11 @@ func TestMirrorTraffic(t *testing.T) { fmt.Sprintf("%s.%s@replica", targetKs, table1): {fmt.Sprintf("%s.%s@replica", targetKs, table1)}, fmt.Sprintf("%s.%s@replica", targetKs, table2): {fmt.Sprintf("%s.%s@replica", targetKs, table2)}, }, - wantErr: "cannot mirror traffic for workflow src2target at this time: traffic is switched", + wantErr: "cannot mirror [replica] traffic for workflow src2target at this time: traffic for those tablet types is switched", wantMirrorRules: make(map[string]map[string]float32), }, { - name: "cannot mirror traffic after switch traffic", + name: "cannot mirror write traffic after switch traffic", req: &vtctldatapb.WorkflowMirrorTrafficRequest{ Keyspace: targetKs, Workflow: workflow, @@ -932,7 +932,7 @@ func TestMirrorTraffic(t *testing.T) { table1: {fmt.Sprintf("%s.%s", targetKs, table1)}, table2: {fmt.Sprintf("%s.%s", targetKs, table2)}, }, - wantErr: "cannot mirror traffic for workflow src2target at this time: traffic is switched", + wantErr: "cannot mirror [primary] traffic for workflow src2target at this time: traffic for those tablet types is switched", wantMirrorRules: make(map[string]map[string]float32), }, { diff --git a/go/vt/vtctl/workflow/switcher_dry_run.go b/go/vt/vtctl/workflow/switcher_dry_run.go index d96af1d276f..55c843b07cb 100644 --- a/go/vt/vtctl/workflow/switcher_dry_run.go +++ b/go/vt/vtctl/workflow/switcher_dry_run.go @@ -68,7 +68,7 @@ func (dr *switcherDryRun) mirrorTableTraffic(ctx context.Context, types []topoda for _, servedType := range types { tabletTypes = append(tabletTypes, servedType.String()) } - dr.drLog.Logf("Mirroring %f percent of traffic from keyspace %s to keyspace %s for tablet types [%s]", + dr.drLog.Logf("Mirroring %.2f percent of traffic from keyspace %s to keyspace %s for tablet types [%s]", percent, dr.ts.SourceKeyspaceName(), dr.ts.TargetKeyspaceName(), strings.Join(tabletTypes, ",")) return nil From 446445c16b051aeabb38185d64e50807329dbe26 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Mon, 24 Jun 2024 16:43:51 -0400 Subject: [PATCH 07/27] cr: remove ApplyMirrorRules vtctldclient command Signed-off-by: Max Englander --- changelog/21.0/21.0.0/summary.md | 24 +- go/cmd/vtctldclient/command/mirror_rules.go | 113 +- go/flags/endtoend/vtctldclient.txt | 1 - go/vt/proto/vtctldata/vtctldata.pb.go | 992 ++++++++---------- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 358 ------- go/vt/proto/vtctlservice/vtctlservice.pb.go | 528 +++++----- .../vtctlservice/vtctlservice_grpc.pb.go | 38 - go/vt/vtctl/grpcvtctldclient/client_gen.go | 9 - go/vt/vtctl/grpcvtctldserver/server.go | 45 +- go/vt/vtctl/localvtctldclient/client_gen.go | 5 - proto/vtctldata.proto | 15 - proto/vtctlservice.proto | 2 - web/vtadmin/src/proto/vtadmin.d.ts | 200 ---- web/vtadmin/src/proto/vtadmin.js | 447 -------- 14 files changed, 697 insertions(+), 2080 deletions(-) diff --git a/changelog/21.0/21.0.0/summary.md b/changelog/21.0/21.0.0/summary.md index 8aad7edb677..6c98665abc8 100644 --- a/changelog/21.0/21.0.0/summary.md +++ b/changelog/21.0/21.0.0/summary.md @@ -38,29 +38,7 @@ The following metrics that were deprecated in the previous release, have now bee Traffic mirroring is intended to help reduce some of the uncertainty inherent to `MoveTables SwitchTraffic`. When traffic mirroring is enabled, VTGate will mirror a percentage of traffic from one keyspace to another. -Mirror rules may be enabled through `vtctldclient` in two ways: - - * With `ApplyMirrorRules`. - * With `MoveTables MirrorTraffic`, which uses `ApplyMirrorRules` under the hood. - -Example with `ApplyMirrorRules`: - -```bash -$ vtctldclient --server :15999 ApplyMirrorRules --rules "$(cat < logutil.Event + 303, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event 6, // 1: vtctldata.MaterializeSettings.table_settings:type_name -> vtctldata.TableMaterializeSettings 0, // 2: vtctldata.MaterializeSettings.materialization_intent:type_name -> vtctldata.MaterializationIntent - 306, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 304, // 3: vtctldata.MaterializeSettings.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference 11, // 4: vtctldata.MaterializeSettings.workflow_options:type_name -> vtctldata.WorkflowOptions - 307, // 5: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace + 305, // 5: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace 2, // 6: vtctldata.SchemaMigration.strategy:type_name -> vtctldata.SchemaMigration.Strategy - 308, // 7: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time - 308, // 8: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time - 308, // 9: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time - 308, // 10: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time - 308, // 11: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time - 308, // 12: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time - 308, // 13: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time + 306, // 7: vtctldata.SchemaMigration.added_at:type_name -> vttime.Time + 306, // 8: vtctldata.SchemaMigration.requested_at:type_name -> vttime.Time + 306, // 9: vtctldata.SchemaMigration.ready_at:type_name -> vttime.Time + 306, // 10: vtctldata.SchemaMigration.started_at:type_name -> vttime.Time + 306, // 11: vtctldata.SchemaMigration.liveness_timestamp:type_name -> vttime.Time + 306, // 12: vtctldata.SchemaMigration.completed_at:type_name -> vttime.Time + 306, // 13: vtctldata.SchemaMigration.cleaned_up_at:type_name -> vttime.Time 3, // 14: vtctldata.SchemaMigration.status:type_name -> vtctldata.SchemaMigration.Status - 309, // 15: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias - 310, // 16: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration - 308, // 17: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time - 308, // 18: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time - 308, // 19: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time - 308, // 20: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time - 311, // 21: vtctldata.Shard.shard:type_name -> topodata.Shard - 256, // 22: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation - 256, // 23: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation - 255, // 24: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry + 307, // 15: vtctldata.SchemaMigration.tablet:type_name -> topodata.TabletAlias + 308, // 16: vtctldata.SchemaMigration.artifact_retention:type_name -> vttime.Duration + 306, // 17: vtctldata.SchemaMigration.last_throttled_at:type_name -> vttime.Time + 306, // 18: vtctldata.SchemaMigration.cancelled_at:type_name -> vttime.Time + 306, // 19: vtctldata.SchemaMigration.reviewed_at:type_name -> vttime.Time + 306, // 20: vtctldata.SchemaMigration.ready_to_complete_at:type_name -> vttime.Time + 309, // 21: vtctldata.Shard.shard:type_name -> topodata.Shard + 254, // 22: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation + 254, // 23: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation + 253, // 24: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry 11, // 25: vtctldata.Workflow.options:type_name -> vtctldata.WorkflowOptions - 312, // 26: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 313, // 27: vtctldata.ApplyKeyspaceRoutingRulesRequest.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 313, // 28: vtctldata.ApplyKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 314, // 29: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules - 315, // 30: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 310, // 31: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration - 316, // 32: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID - 262, // 33: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry - 317, // 34: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace - 317, // 35: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 263, // 36: vtctldata.ApplyVSchemaResponse.unknown_vindex_params:type_name -> vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry - 309, // 37: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 38: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 305, // 39: vtctldata.BackupResponse.event:type_name -> logutil.Event - 265, // 40: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry - 309, // 41: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias - 318, // 42: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType - 319, // 43: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet - 319, // 44: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet - 309, // 45: vtctldata.CheckThrottlerRequest.tablet_alias:type_name -> topodata.TabletAlias - 267, // 46: vtctldata.CheckThrottlerResponse.metrics:type_name -> vtctldata.CheckThrottlerResponse.MetricsEntry - 268, // 47: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry - 269, // 48: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry - 320, // 49: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType - 308, // 50: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time + 310, // 26: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 311, // 27: vtctldata.ApplyKeyspaceRoutingRulesRequest.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 311, // 28: vtctldata.ApplyKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 312, // 29: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules + 313, // 30: vtctldata.ApplyShardRoutingRulesRequest.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 308, // 31: vtctldata.ApplySchemaRequest.wait_replicas_timeout:type_name -> vttime.Duration + 314, // 32: vtctldata.ApplySchemaRequest.caller_id:type_name -> vtrpc.CallerID + 260, // 33: vtctldata.ApplySchemaResponse.rows_affected_by_shard:type_name -> vtctldata.ApplySchemaResponse.RowsAffectedByShardEntry + 315, // 34: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace + 315, // 35: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 261, // 36: vtctldata.ApplyVSchemaResponse.unknown_vindex_params:type_name -> vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry + 307, // 37: vtctldata.BackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 38: vtctldata.BackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 303, // 39: vtctldata.BackupResponse.event:type_name -> logutil.Event + 263, // 40: vtctldata.CancelSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CancelSchemaMigrationResponse.RowsAffectedByShardEntry + 307, // 41: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias + 316, // 42: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType + 317, // 43: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet + 317, // 44: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet + 307, // 45: vtctldata.CheckThrottlerRequest.tablet_alias:type_name -> topodata.TabletAlias + 265, // 46: vtctldata.CheckThrottlerResponse.metrics:type_name -> vtctldata.CheckThrottlerResponse.MetricsEntry + 266, // 47: vtctldata.CleanupSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CleanupSchemaMigrationResponse.RowsAffectedByShardEntry + 267, // 48: vtctldata.CompleteSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.CompleteSchemaMigrationResponse.RowsAffectedByShardEntry + 318, // 49: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType + 306, // 50: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time 8, // 51: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace 8, // 52: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace 10, // 53: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard 10, // 54: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard - 309, // 55: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 309, // 56: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 309, // 57: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias - 310, // 58: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 309, // 59: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 305, // 60: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event - 309, // 61: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias - 321, // 62: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult - 309, // 63: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 321, // 64: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult - 309, // 65: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias - 322, // 66: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest - 323, // 67: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse - 309, // 68: vtctldata.ExecuteMultiFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias - 321, // 69: vtctldata.ExecuteMultiFetchAsDBAResponse.results:type_name -> query.QueryResult - 270, // 70: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - 271, // 71: vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry - 324, // 72: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo - 312, // 73: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 272, // 74: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry - 309, // 75: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias - 325, // 76: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus + 307, // 55: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 307, // 56: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 307, // 57: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias + 308, // 58: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 307, // 59: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 303, // 60: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event + 307, // 61: vtctldata.ExecuteFetchAsAppRequest.tablet_alias:type_name -> topodata.TabletAlias + 319, // 62: vtctldata.ExecuteFetchAsAppResponse.result:type_name -> query.QueryResult + 307, // 63: vtctldata.ExecuteFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 319, // 64: vtctldata.ExecuteFetchAsDBAResponse.result:type_name -> query.QueryResult + 307, // 65: vtctldata.ExecuteHookRequest.tablet_alias:type_name -> topodata.TabletAlias + 320, // 66: vtctldata.ExecuteHookRequest.tablet_hook_request:type_name -> tabletmanagerdata.ExecuteHookRequest + 321, // 67: vtctldata.ExecuteHookResponse.hook_result:type_name -> tabletmanagerdata.ExecuteHookResponse + 307, // 68: vtctldata.ExecuteMultiFetchAsDBARequest.tablet_alias:type_name -> topodata.TabletAlias + 319, // 69: vtctldata.ExecuteMultiFetchAsDBAResponse.results:type_name -> query.QueryResult + 268, // 70: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + 269, // 71: vtctldata.ForceCutOverSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.ForceCutOverSchemaMigrationResponse.RowsAffectedByShardEntry + 322, // 72: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo + 310, // 73: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 270, // 74: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry + 307, // 75: vtctldata.GetFullStatusRequest.tablet_alias:type_name -> topodata.TabletAlias + 323, // 76: vtctldata.GetFullStatusResponse.status:type_name -> replicationdata.FullStatus 8, // 77: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace 8, // 78: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 309, // 79: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias - 326, // 80: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions - 313, // 81: vtctldata.GetKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules - 314, // 82: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules - 309, // 83: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 327, // 84: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition + 307, // 79: vtctldata.GetPermissionsRequest.tablet_alias:type_name -> topodata.TabletAlias + 324, // 80: vtctldata.GetPermissionsResponse.permissions:type_name -> tabletmanagerdata.Permissions + 311, // 81: vtctldata.GetKeyspaceRoutingRulesResponse.keyspace_routing_rules:type_name -> vschema.KeyspaceRoutingRules + 312, // 82: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules + 307, // 83: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 325, // 84: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition 3, // 85: vtctldata.GetSchemaMigrationsRequest.status:type_name -> vtctldata.SchemaMigration.Status - 310, // 86: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration + 308, // 86: vtctldata.GetSchemaMigrationsRequest.recent:type_name -> vttime.Duration 1, // 87: vtctldata.GetSchemaMigrationsRequest.order:type_name -> vtctldata.QueryOrdering 9, // 88: vtctldata.GetSchemaMigrationsResponse.migrations:type_name -> vtctldata.SchemaMigration - 273, // 89: vtctldata.GetShardReplicationResponse.shard_replication_by_cell:type_name -> vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry + 271, // 89: vtctldata.GetShardReplicationResponse.shard_replication_by_cell:type_name -> vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry 10, // 90: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard - 315, // 91: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules - 274, // 92: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry - 276, // 93: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - 328, // 94: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule - 329, // 95: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema - 277, // 96: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - 309, // 97: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 319, // 98: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet - 309, // 99: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 318, // 100: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType - 319, // 101: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet - 309, // 102: vtctldata.GetThrottlerStatusRequest.tablet_alias:type_name -> topodata.TabletAlias - 279, // 103: vtctldata.GetThrottlerStatusResponse.aggregated_metrics:type_name -> vtctldata.GetThrottlerStatusResponse.AggregatedMetricsEntry - 280, // 104: vtctldata.GetThrottlerStatusResponse.metric_thresholds:type_name -> vtctldata.GetThrottlerStatusResponse.MetricThresholdsEntry - 282, // 105: vtctldata.GetThrottlerStatusResponse.metrics_health:type_name -> vtctldata.GetThrottlerStatusResponse.MetricsHealthEntry - 283, // 106: vtctldata.GetThrottlerStatusResponse.throttled_apps:type_name -> vtctldata.GetThrottlerStatusResponse.ThrottledAppsEntry - 284, // 107: vtctldata.GetThrottlerStatusResponse.app_checked_metrics:type_name -> vtctldata.GetThrottlerStatusResponse.AppCheckedMetricsEntry - 286, // 108: vtctldata.GetThrottlerStatusResponse.recent_apps:type_name -> vtctldata.GetThrottlerStatusResponse.RecentAppsEntry + 313, // 91: vtctldata.GetShardRoutingRulesResponse.shard_routing_rules:type_name -> vschema.ShardRoutingRules + 272, // 92: vtctldata.GetSrvKeyspaceNamesResponse.names:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry + 274, // 93: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + 326, // 94: vtctldata.UpdateThrottlerConfigRequest.throttled_app:type_name -> topodata.ThrottledAppRule + 327, // 95: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema + 275, // 96: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + 307, // 97: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 317, // 98: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet + 307, // 99: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 316, // 100: vtctldata.GetTabletsRequest.tablet_type:type_name -> topodata.TabletType + 317, // 101: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet + 307, // 102: vtctldata.GetThrottlerStatusRequest.tablet_alias:type_name -> topodata.TabletAlias + 277, // 103: vtctldata.GetThrottlerStatusResponse.aggregated_metrics:type_name -> vtctldata.GetThrottlerStatusResponse.AggregatedMetricsEntry + 278, // 104: vtctldata.GetThrottlerStatusResponse.metric_thresholds:type_name -> vtctldata.GetThrottlerStatusResponse.MetricThresholdsEntry + 280, // 105: vtctldata.GetThrottlerStatusResponse.metrics_health:type_name -> vtctldata.GetThrottlerStatusResponse.MetricsHealthEntry + 281, // 106: vtctldata.GetThrottlerStatusResponse.throttled_apps:type_name -> vtctldata.GetThrottlerStatusResponse.ThrottledAppsEntry + 282, // 107: vtctldata.GetThrottlerStatusResponse.app_checked_metrics:type_name -> vtctldata.GetThrottlerStatusResponse.AppCheckedMetricsEntry + 284, // 108: vtctldata.GetThrottlerStatusResponse.recent_apps:type_name -> vtctldata.GetThrottlerStatusResponse.RecentAppsEntry 118, // 109: vtctldata.GetTopologyPathResponse.cell:type_name -> vtctldata.TopologyCell - 309, // 110: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias - 317, // 111: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 307, // 110: vtctldata.GetVersionRequest.tablet_alias:type_name -> topodata.TabletAlias + 315, // 111: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace 12, // 112: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow - 309, // 113: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias - 310, // 114: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration - 305, // 115: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event - 287, // 116: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry - 317, // 117: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace - 318, // 118: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType - 306, // 119: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 307, // 113: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias + 308, // 114: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration + 303, // 115: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event + 285, // 116: vtctldata.LaunchSchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.LaunchSchemaMigrationResponse.RowsAffectedByShardEntry + 315, // 117: vtctldata.LookupVindexCreateRequest.vindex:type_name -> vschema.Keyspace + 316, // 118: vtctldata.LookupVindexCreateRequest.tablet_types:type_name -> topodata.TabletType + 304, // 119: vtctldata.LookupVindexCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference 7, // 120: vtctldata.MaterializeCreateRequest.settings:type_name -> vtctldata.MaterializeSettings - 318, // 121: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType - 306, // 122: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 318, // 123: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType - 306, // 124: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 316, // 121: vtctldata.MigrateCreateRequest.tablet_types:type_name -> topodata.TabletType + 304, // 122: vtctldata.MigrateCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 316, // 123: vtctldata.MoveTablesCreateRequest.tablet_types:type_name -> topodata.TabletType + 304, // 124: vtctldata.MoveTablesCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference 11, // 125: vtctldata.MoveTablesCreateRequest.workflow_options:type_name -> vtctldata.WorkflowOptions - 288, // 126: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo - 309, // 127: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 128: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 309, // 129: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias - 310, // 130: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 310, // 131: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration - 309, // 132: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 305, // 133: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 309, // 134: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 135: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 305, // 136: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event - 305, // 137: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event - 309, // 138: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 309, // 139: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 318, // 140: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType - 306, // 141: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 309, // 142: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias - 308, // 143: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time - 308, // 144: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time - 309, // 145: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias - 305, // 146: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event - 289, // 147: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry - 309, // 148: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias - 307, // 149: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace - 307, // 150: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace - 311, // 151: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard - 318, // 152: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType - 311, // 153: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard - 309, // 154: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 155: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias - 330, // 156: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError - 290, // 157: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 291, // 158: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 309, // 159: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 160: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 310, // 161: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration - 331, // 162: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange - 311, // 163: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard - 311, // 164: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard - 309, // 165: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 166: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias - 309, // 167: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 309, // 168: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 309, // 169: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 312, // 170: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 312, // 171: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 332, // 172: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 332, // 173: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias - 292, // 174: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry - 293, // 175: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry - 294, // 176: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry - 295, // 177: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry - 296, // 178: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry - 318, // 179: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType - 306, // 180: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 310, // 181: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration - 310, // 182: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration - 310, // 183: vtctldata.VDiffCreateRequest.max_diff_duration:type_name -> vttime.Duration - 297, // 184: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry - 298, // 185: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo - 302, // 186: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry - 303, // 187: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry - 318, // 188: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType - 310, // 189: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration - 310, // 190: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration - 333, // 191: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest - 304, // 192: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo - 334, // 193: vtctldata.ApplyMirrorRulesRequest.mirror_rules:type_name -> vschema.MirrorRules - 334, // 194: vtctldata.GetMirrorRulesResponse.mirror_rules:type_name -> vschema.MirrorRules - 318, // 195: vtctldata.WorkflowMirrorTrafficRequest.tablet_types:type_name -> topodata.TabletType - 257, // 196: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream - 258, // 197: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 335, // 198: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 309, // 199: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 336, // 200: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 308, // 201: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 308, // 202: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time - 259, // 203: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 260, // 204: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log - 261, // 205: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus - 318, // 206: vtctldata.Workflow.Stream.tablet_types:type_name -> topodata.TabletType - 306, // 207: vtctldata.Workflow.Stream.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference - 308, // 208: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time - 308, // 209: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time - 308, // 210: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time - 264, // 211: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry.value:type_name -> vtctldata.ApplyVSchemaResponse.ParamList - 266, // 212: vtctldata.CheckThrottlerResponse.MetricsEntry.value:type_name -> vtctldata.CheckThrottlerResponse.Metric - 10, // 213: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 332, // 214: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 337, // 215: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry.value:type_name -> topodata.ShardReplication - 275, // 216: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList - 338, // 217: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 329, // 218: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 278, // 219: vtctldata.GetThrottlerStatusResponse.AggregatedMetricsEntry.value:type_name -> vtctldata.GetThrottlerStatusResponse.MetricResult - 308, // 220: vtctldata.GetThrottlerStatusResponse.MetricHealth.last_healthy_at:type_name -> vttime.Time - 281, // 221: vtctldata.GetThrottlerStatusResponse.MetricsHealthEntry.value:type_name -> vtctldata.GetThrottlerStatusResponse.MetricHealth - 328, // 222: vtctldata.GetThrottlerStatusResponse.ThrottledAppsEntry.value:type_name -> topodata.ThrottledAppRule - 308, // 223: vtctldata.GetThrottlerStatusResponse.RecentApp.checked_at:type_name -> vttime.Time - 285, // 224: vtctldata.GetThrottlerStatusResponse.RecentAppsEntry.value:type_name -> vtctldata.GetThrottlerStatusResponse.RecentApp - 309, // 225: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 339, // 226: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 319, // 227: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 220, // 228: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse - 224, // 229: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 224, // 230: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 224, // 231: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 224, // 232: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse - 340, // 233: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse - 309, // 234: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 309, // 235: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias - 300, // 236: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState - 299, // 237: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState - 301, // 238: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams - 309, // 239: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias - 240, // [240:240] is the sub-list for method output_type - 240, // [240:240] is the sub-list for method input_type - 240, // [240:240] is the sub-list for extension type_name - 240, // [240:240] is the sub-list for extension extendee - 0, // [0:240] is the sub-list for field type_name + 286, // 126: vtctldata.MoveTablesCreateResponse.details:type_name -> vtctldata.MoveTablesCreateResponse.TabletInfo + 307, // 127: vtctldata.PingTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 128: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 307, // 129: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias + 308, // 130: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 308, // 131: vtctldata.PlannedReparentShardRequest.tolerable_replication_lag:type_name -> vttime.Duration + 307, // 132: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 303, // 133: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 307, // 134: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 135: vtctldata.ReloadSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 303, // 136: vtctldata.ReloadSchemaKeyspaceResponse.events:type_name -> logutil.Event + 303, // 137: vtctldata.ReloadSchemaShardResponse.events:type_name -> logutil.Event + 307, // 138: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 307, // 139: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 316, // 140: vtctldata.ReshardCreateRequest.tablet_types:type_name -> topodata.TabletType + 304, // 141: vtctldata.ReshardCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 307, // 142: vtctldata.RestoreFromBackupRequest.tablet_alias:type_name -> topodata.TabletAlias + 306, // 143: vtctldata.RestoreFromBackupRequest.backup_time:type_name -> vttime.Time + 306, // 144: vtctldata.RestoreFromBackupRequest.restore_to_timestamp:type_name -> vttime.Time + 307, // 145: vtctldata.RestoreFromBackupResponse.tablet_alias:type_name -> topodata.TabletAlias + 303, // 146: vtctldata.RestoreFromBackupResponse.event:type_name -> logutil.Event + 287, // 147: vtctldata.RetrySchemaMigrationResponse.rows_affected_by_shard:type_name -> vtctldata.RetrySchemaMigrationResponse.RowsAffectedByShardEntry + 307, // 148: vtctldata.RunHealthCheckRequest.tablet_alias:type_name -> topodata.TabletAlias + 305, // 149: vtctldata.SetKeyspaceDurabilityPolicyResponse.keyspace:type_name -> topodata.Keyspace + 305, // 150: vtctldata.SetKeyspaceShardingInfoResponse.keyspace:type_name -> topodata.Keyspace + 309, // 151: vtctldata.SetShardIsPrimaryServingResponse.shard:type_name -> topodata.Shard + 316, // 152: vtctldata.SetShardTabletControlRequest.tablet_type:type_name -> topodata.TabletType + 309, // 153: vtctldata.SetShardTabletControlResponse.shard:type_name -> topodata.Shard + 307, // 154: vtctldata.SetWritableRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 155: vtctldata.ShardReplicationAddRequest.tablet_alias:type_name -> topodata.TabletAlias + 328, // 156: vtctldata.ShardReplicationFixResponse.error:type_name -> topodata.ShardReplicationError + 288, // 157: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 289, // 158: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 307, // 159: vtctldata.ShardReplicationRemoveRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 160: vtctldata.SleepTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 308, // 161: vtctldata.SleepTabletRequest.duration:type_name -> vttime.Duration + 329, // 162: vtctldata.SourceShardAddRequest.key_range:type_name -> topodata.KeyRange + 309, // 163: vtctldata.SourceShardAddResponse.shard:type_name -> topodata.Shard + 309, // 164: vtctldata.SourceShardDeleteResponse.shard:type_name -> topodata.Shard + 307, // 165: vtctldata.StartReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 166: vtctldata.StopReplicationRequest.tablet_alias:type_name -> topodata.TabletAlias + 307, // 167: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 307, // 168: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 307, // 169: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 310, // 170: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 310, // 171: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 330, // 172: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 330, // 173: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 290, // 174: vtctldata.ValidateResponse.results_by_keyspace:type_name -> vtctldata.ValidateResponse.ResultsByKeyspaceEntry + 291, // 175: vtctldata.ValidateKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry + 292, // 176: vtctldata.ValidateSchemaKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry + 293, // 177: vtctldata.ValidateVersionKeyspaceResponse.results_by_shard:type_name -> vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry + 294, // 178: vtctldata.ValidateVSchemaResponse.results_by_shard:type_name -> vtctldata.ValidateVSchemaResponse.ResultsByShardEntry + 316, // 179: vtctldata.VDiffCreateRequest.tablet_types:type_name -> topodata.TabletType + 304, // 180: vtctldata.VDiffCreateRequest.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 308, // 181: vtctldata.VDiffCreateRequest.filtered_replication_wait_time:type_name -> vttime.Duration + 308, // 182: vtctldata.VDiffCreateRequest.wait_update_interval:type_name -> vttime.Duration + 308, // 183: vtctldata.VDiffCreateRequest.max_diff_duration:type_name -> vttime.Duration + 295, // 184: vtctldata.VDiffShowResponse.tablet_responses:type_name -> vtctldata.VDiffShowResponse.TabletResponsesEntry + 296, // 185: vtctldata.WorkflowDeleteResponse.details:type_name -> vtctldata.WorkflowDeleteResponse.TabletInfo + 300, // 186: vtctldata.WorkflowStatusResponse.table_copy_state:type_name -> vtctldata.WorkflowStatusResponse.TableCopyStateEntry + 301, // 187: vtctldata.WorkflowStatusResponse.shard_streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamsEntry + 316, // 188: vtctldata.WorkflowSwitchTrafficRequest.tablet_types:type_name -> topodata.TabletType + 308, // 189: vtctldata.WorkflowSwitchTrafficRequest.max_replication_lag_allowed:type_name -> vttime.Duration + 308, // 190: vtctldata.WorkflowSwitchTrafficRequest.timeout:type_name -> vttime.Duration + 331, // 191: vtctldata.WorkflowUpdateRequest.tablet_request:type_name -> tabletmanagerdata.UpdateVReplicationWorkflowRequest + 302, // 192: vtctldata.WorkflowUpdateResponse.details:type_name -> vtctldata.WorkflowUpdateResponse.TabletInfo + 332, // 193: vtctldata.GetMirrorRulesResponse.mirror_rules:type_name -> vschema.MirrorRules + 316, // 194: vtctldata.WorkflowMirrorTrafficRequest.tablet_types:type_name -> topodata.TabletType + 255, // 195: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream + 256, // 196: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream + 333, // 197: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 307, // 198: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 334, // 199: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 306, // 200: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 306, // 201: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 257, // 202: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState + 258, // 203: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 259, // 204: vtctldata.Workflow.Stream.throttler_status:type_name -> vtctldata.Workflow.Stream.ThrottlerStatus + 316, // 205: vtctldata.Workflow.Stream.tablet_types:type_name -> topodata.TabletType + 304, // 206: vtctldata.Workflow.Stream.tablet_selection_preference:type_name -> tabletmanagerdata.TabletSelectionPreference + 306, // 207: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 306, // 208: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 306, // 209: vtctldata.Workflow.Stream.ThrottlerStatus.time_throttled:type_name -> vttime.Time + 262, // 210: vtctldata.ApplyVSchemaResponse.UnknownVindexParamsEntry.value:type_name -> vtctldata.ApplyVSchemaResponse.ParamList + 264, // 211: vtctldata.CheckThrottlerResponse.MetricsEntry.value:type_name -> vtctldata.CheckThrottlerResponse.Metric + 10, // 212: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 330, // 213: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 335, // 214: vtctldata.GetShardReplicationResponse.ShardReplicationByCellEntry.value:type_name -> topodata.ShardReplication + 273, // 215: vtctldata.GetSrvKeyspaceNamesResponse.NamesEntry.value:type_name -> vtctldata.GetSrvKeyspaceNamesResponse.NameList + 336, // 216: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 327, // 217: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 276, // 218: vtctldata.GetThrottlerStatusResponse.AggregatedMetricsEntry.value:type_name -> vtctldata.GetThrottlerStatusResponse.MetricResult + 306, // 219: vtctldata.GetThrottlerStatusResponse.MetricHealth.last_healthy_at:type_name -> vttime.Time + 279, // 220: vtctldata.GetThrottlerStatusResponse.MetricsHealthEntry.value:type_name -> vtctldata.GetThrottlerStatusResponse.MetricHealth + 326, // 221: vtctldata.GetThrottlerStatusResponse.ThrottledAppsEntry.value:type_name -> topodata.ThrottledAppRule + 306, // 222: vtctldata.GetThrottlerStatusResponse.RecentApp.checked_at:type_name -> vttime.Time + 283, // 223: vtctldata.GetThrottlerStatusResponse.RecentAppsEntry.value:type_name -> vtctldata.GetThrottlerStatusResponse.RecentApp + 307, // 224: vtctldata.MoveTablesCreateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 337, // 225: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 317, // 226: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 220, // 227: vtctldata.ValidateResponse.ResultsByKeyspaceEntry.value:type_name -> vtctldata.ValidateKeyspaceResponse + 224, // 228: vtctldata.ValidateKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 224, // 229: vtctldata.ValidateSchemaKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 224, // 230: vtctldata.ValidateVersionKeyspaceResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 224, // 231: vtctldata.ValidateVSchemaResponse.ResultsByShardEntry.value:type_name -> vtctldata.ValidateShardResponse + 338, // 232: vtctldata.VDiffShowResponse.TabletResponsesEntry.value:type_name -> tabletmanagerdata.VDiffResponse + 307, // 233: vtctldata.WorkflowDeleteResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 307, // 234: vtctldata.WorkflowStatusResponse.ShardStreamState.tablet:type_name -> topodata.TabletAlias + 298, // 235: vtctldata.WorkflowStatusResponse.ShardStreams.streams:type_name -> vtctldata.WorkflowStatusResponse.ShardStreamState + 297, // 236: vtctldata.WorkflowStatusResponse.TableCopyStateEntry.value:type_name -> vtctldata.WorkflowStatusResponse.TableCopyState + 299, // 237: vtctldata.WorkflowStatusResponse.ShardStreamsEntry.value:type_name -> vtctldata.WorkflowStatusResponse.ShardStreams + 307, // 238: vtctldata.WorkflowUpdateResponse.TabletInfo.tablet:type_name -> topodata.TabletAlias + 239, // [239:239] is the sub-list for method output_type + 239, // [239:239] is the sub-list for method input_type + 239, // [239:239] is the sub-list for extension type_name + 239, // [239:239] is the sub-list for extension extendee + 0, // [0:239] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } @@ -23340,30 +23218,6 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[245].Exporter = func(v any, i int) any { - switch v := v.(*ApplyMirrorRulesRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vtctldata_proto_msgTypes[246].Exporter = func(v any, i int) any { - switch v := v.(*ApplyMirrorRulesResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vtctldata_proto_msgTypes[247].Exporter = func(v any, i int) any { switch v := v.(*GetMirrorRulesRequest); i { case 0: return &v.state @@ -23375,7 +23229,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[248].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[246].Exporter = func(v any, i int) any { switch v := v.(*GetMirrorRulesResponse); i { case 0: return &v.state @@ -23387,7 +23241,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[249].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[247].Exporter = func(v any, i int) any { switch v := v.(*WorkflowMirrorTrafficRequest); i { case 0: return &v.state @@ -23399,7 +23253,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[250].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[248].Exporter = func(v any, i int) any { switch v := v.(*WorkflowMirrorTrafficResponse); i { case 0: return &v.state @@ -23411,7 +23265,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[252].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[250].Exporter = func(v any, i int) any { switch v := v.(*Workflow_ReplicationLocation); i { case 0: return &v.state @@ -23423,7 +23277,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[253].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[251].Exporter = func(v any, i int) any { switch v := v.(*Workflow_ShardStream); i { case 0: return &v.state @@ -23435,7 +23289,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[254].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[252].Exporter = func(v any, i int) any { switch v := v.(*Workflow_Stream); i { case 0: return &v.state @@ -23447,7 +23301,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[255].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[253].Exporter = func(v any, i int) any { switch v := v.(*Workflow_Stream_CopyState); i { case 0: return &v.state @@ -23459,7 +23313,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[256].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[254].Exporter = func(v any, i int) any { switch v := v.(*Workflow_Stream_Log); i { case 0: return &v.state @@ -23471,7 +23325,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[257].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[255].Exporter = func(v any, i int) any { switch v := v.(*Workflow_Stream_ThrottlerStatus); i { case 0: return &v.state @@ -23483,7 +23337,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[260].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[258].Exporter = func(v any, i int) any { switch v := v.(*ApplyVSchemaResponse_ParamList); i { case 0: return &v.state @@ -23495,7 +23349,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[262].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[260].Exporter = func(v any, i int) any { switch v := v.(*CheckThrottlerResponse_Metric); i { case 0: return &v.state @@ -23507,7 +23361,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[271].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[269].Exporter = func(v any, i int) any { switch v := v.(*GetSrvKeyspaceNamesResponse_NameList); i { case 0: return &v.state @@ -23519,7 +23373,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[274].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[272].Exporter = func(v any, i int) any { switch v := v.(*GetThrottlerStatusResponse_MetricResult); i { case 0: return &v.state @@ -23531,7 +23385,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[277].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[275].Exporter = func(v any, i int) any { switch v := v.(*GetThrottlerStatusResponse_MetricHealth); i { case 0: return &v.state @@ -23543,7 +23397,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[281].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[279].Exporter = func(v any, i int) any { switch v := v.(*GetThrottlerStatusResponse_RecentApp); i { case 0: return &v.state @@ -23555,7 +23409,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[284].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[282].Exporter = func(v any, i int) any { switch v := v.(*MoveTablesCreateResponse_TabletInfo); i { case 0: return &v.state @@ -23567,7 +23421,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[294].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[292].Exporter = func(v any, i int) any { switch v := v.(*WorkflowDeleteResponse_TabletInfo); i { case 0: return &v.state @@ -23579,7 +23433,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[295].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[293].Exporter = func(v any, i int) any { switch v := v.(*WorkflowStatusResponse_TableCopyState); i { case 0: return &v.state @@ -23591,7 +23445,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[296].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[294].Exporter = func(v any, i int) any { switch v := v.(*WorkflowStatusResponse_ShardStreamState); i { case 0: return &v.state @@ -23603,7 +23457,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[297].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[295].Exporter = func(v any, i int) any { switch v := v.(*WorkflowStatusResponse_ShardStreams); i { case 0: return &v.state @@ -23615,7 +23469,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[300].Exporter = func(v any, i int) any { + file_vtctldata_proto_msgTypes[298].Exporter = func(v any, i int) any { switch v := v.(*WorkflowUpdateResponse_TabletInfo); i { case 0: return &v.state @@ -23634,7 +23488,7 @@ func file_vtctldata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vtctldata_proto_rawDesc, NumEnums: 4, - NumMessages: 301, + NumMessages: 299, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go index 405ac6c53d9..cd52155d618 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -5792,46 +5792,6 @@ func (m *WorkflowUpdateResponse) CloneMessageVT() proto.Message { return m.CloneVT() } -func (m *ApplyMirrorRulesRequest) CloneVT() *ApplyMirrorRulesRequest { - if m == nil { - return (*ApplyMirrorRulesRequest)(nil) - } - r := &ApplyMirrorRulesRequest{ - MirrorRules: m.MirrorRules.CloneVT(), - SkipRebuild: m.SkipRebuild, - } - if rhs := m.RebuildCells; rhs != nil { - tmpContainer := make([]string, len(rhs)) - copy(tmpContainer, rhs) - r.RebuildCells = tmpContainer - } - if len(m.unknownFields) > 0 { - r.unknownFields = make([]byte, len(m.unknownFields)) - copy(r.unknownFields, m.unknownFields) - } - return r -} - -func (m *ApplyMirrorRulesRequest) CloneMessageVT() proto.Message { - return m.CloneVT() -} - -func (m *ApplyMirrorRulesResponse) CloneVT() *ApplyMirrorRulesResponse { - if m == nil { - return (*ApplyMirrorRulesResponse)(nil) - } - r := &ApplyMirrorRulesResponse{} - if len(m.unknownFields) > 0 { - r.unknownFields = make([]byte, len(m.unknownFields)) - copy(r.unknownFields, m.unknownFields) - } - return r -} - -func (m *ApplyMirrorRulesResponse) CloneMessageVT() proto.Message { - return m.CloneVT() -} - func (m *GetMirrorRulesRequest) CloneVT() *GetMirrorRulesRequest { if m == nil { return (*GetMirrorRulesRequest)(nil) @@ -21347,101 +21307,6 @@ func (m *WorkflowUpdateResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error return len(dAtA) - i, nil } -func (m *ApplyMirrorRulesRequest) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplyMirrorRulesRequest) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *ApplyMirrorRulesRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if len(m.RebuildCells) > 0 { - for iNdEx := len(m.RebuildCells) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.RebuildCells[iNdEx]) - copy(dAtA[i:], m.RebuildCells[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.RebuildCells[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if m.SkipRebuild { - i-- - if m.SkipRebuild { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x10 - } - if m.MirrorRules != nil { - size, err := m.MirrorRules.MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ApplyMirrorRulesResponse) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ApplyMirrorRulesResponse) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *ApplyMirrorRulesResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - return len(dAtA) - i, nil -} - func (m *GetMirrorRulesRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -27492,39 +27357,6 @@ func (m *WorkflowUpdateResponse) SizeVT() (n int) { return n } -func (m *ApplyMirrorRulesRequest) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.MirrorRules != nil { - l = m.MirrorRules.SizeVT() - n += 1 + l + sov(uint64(l)) - } - if m.SkipRebuild { - n += 2 - } - if len(m.RebuildCells) > 0 { - for _, s := range m.RebuildCells { - l = len(s) - n += 1 + l + sov(uint64(l)) - } - } - n += len(m.unknownFields) - return n -} - -func (m *ApplyMirrorRulesResponse) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += len(m.unknownFields) - return n -} - func (m *GetMirrorRulesRequest) SizeVT() (n int) { if m == nil { return 0 @@ -65947,196 +65779,6 @@ func (m *WorkflowUpdateResponse) UnmarshalVT(dAtA []byte) error { } return nil } -func (m *ApplyMirrorRulesRequest) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplyMirrorRulesRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplyMirrorRulesRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MirrorRules", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.MirrorRules == nil { - m.MirrorRules = &vschema.MirrorRules{} - } - if err := m.MirrorRules.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SkipRebuild", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.SkipRebuild = bool(v != 0) - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RebuildCells", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RebuildCells = append(m.RebuildCells, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ApplyMirrorRulesResponse) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ApplyMirrorRulesResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ApplyMirrorRulesResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *GetMirrorRulesRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 318a01b7bf4..e5ff978e853 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -51,7 +51,7 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0xbe, 0x58, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, + 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0xdf, 0x57, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x12, 0x4e, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, @@ -741,28 +741,22 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x4d, 0x69, 0x72, 0x72, 0x6f, - 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, - 0x65, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, - 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, - 0x69, 0x63, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, - 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x76, 0x69, 0x74, 0x65, 0x73, - 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, - 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x15, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, + 0x66, 0x69, 0x63, 0x12, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, + 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x76, 0x69, 0x74, 0x65, + 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, + 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_vtctlservice_proto_goTypes = []any{ @@ -884,126 +878,124 @@ var file_vtctlservice_proto_goTypes = []any{ (*vtctldata.WorkflowStatusRequest)(nil), // 115: vtctldata.WorkflowStatusRequest (*vtctldata.WorkflowSwitchTrafficRequest)(nil), // 116: vtctldata.WorkflowSwitchTrafficRequest (*vtctldata.WorkflowUpdateRequest)(nil), // 117: vtctldata.WorkflowUpdateRequest - (*vtctldata.ApplyMirrorRulesRequest)(nil), // 118: vtctldata.ApplyMirrorRulesRequest - (*vtctldata.GetMirrorRulesRequest)(nil), // 119: vtctldata.GetMirrorRulesRequest - (*vtctldata.WorkflowMirrorTrafficRequest)(nil), // 120: vtctldata.WorkflowMirrorTrafficRequest - (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 121: vtctldata.ExecuteVtctlCommandResponse - (*vtctldata.AddCellInfoResponse)(nil), // 122: vtctldata.AddCellInfoResponse - (*vtctldata.AddCellsAliasResponse)(nil), // 123: vtctldata.AddCellsAliasResponse - (*vtctldata.ApplyRoutingRulesResponse)(nil), // 124: vtctldata.ApplyRoutingRulesResponse - (*vtctldata.ApplySchemaResponse)(nil), // 125: vtctldata.ApplySchemaResponse - (*vtctldata.ApplyKeyspaceRoutingRulesResponse)(nil), // 126: vtctldata.ApplyKeyspaceRoutingRulesResponse - (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 127: vtctldata.ApplyShardRoutingRulesResponse - (*vtctldata.ApplyVSchemaResponse)(nil), // 128: vtctldata.ApplyVSchemaResponse - (*vtctldata.BackupResponse)(nil), // 129: vtctldata.BackupResponse - (*vtctldata.CancelSchemaMigrationResponse)(nil), // 130: vtctldata.CancelSchemaMigrationResponse - (*vtctldata.ChangeTabletTypeResponse)(nil), // 131: vtctldata.ChangeTabletTypeResponse - (*vtctldata.CheckThrottlerResponse)(nil), // 132: vtctldata.CheckThrottlerResponse - (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 133: vtctldata.CleanupSchemaMigrationResponse - (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 134: vtctldata.CompleteSchemaMigrationResponse - (*vtctldata.CreateKeyspaceResponse)(nil), // 135: vtctldata.CreateKeyspaceResponse - (*vtctldata.CreateShardResponse)(nil), // 136: vtctldata.CreateShardResponse - (*vtctldata.DeleteCellInfoResponse)(nil), // 137: vtctldata.DeleteCellInfoResponse - (*vtctldata.DeleteCellsAliasResponse)(nil), // 138: vtctldata.DeleteCellsAliasResponse - (*vtctldata.DeleteKeyspaceResponse)(nil), // 139: vtctldata.DeleteKeyspaceResponse - (*vtctldata.DeleteShardsResponse)(nil), // 140: vtctldata.DeleteShardsResponse - (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 141: vtctldata.DeleteSrvVSchemaResponse - (*vtctldata.DeleteTabletsResponse)(nil), // 142: vtctldata.DeleteTabletsResponse - (*vtctldata.EmergencyReparentShardResponse)(nil), // 143: vtctldata.EmergencyReparentShardResponse - (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 144: vtctldata.ExecuteFetchAsAppResponse - (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 145: vtctldata.ExecuteFetchAsDBAResponse - (*vtctldata.ExecuteHookResponse)(nil), // 146: vtctldata.ExecuteHookResponse - (*vtctldata.ExecuteMultiFetchAsDBAResponse)(nil), // 147: vtctldata.ExecuteMultiFetchAsDBAResponse - (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 148: vtctldata.FindAllShardsInKeyspaceResponse - (*vtctldata.ForceCutOverSchemaMigrationResponse)(nil), // 149: vtctldata.ForceCutOverSchemaMigrationResponse - (*vtctldata.GetBackupsResponse)(nil), // 150: vtctldata.GetBackupsResponse - (*vtctldata.GetCellInfoResponse)(nil), // 151: vtctldata.GetCellInfoResponse - (*vtctldata.GetCellInfoNamesResponse)(nil), // 152: vtctldata.GetCellInfoNamesResponse - (*vtctldata.GetCellsAliasesResponse)(nil), // 153: vtctldata.GetCellsAliasesResponse - (*vtctldata.GetFullStatusResponse)(nil), // 154: vtctldata.GetFullStatusResponse - (*vtctldata.GetKeyspaceResponse)(nil), // 155: vtctldata.GetKeyspaceResponse - (*vtctldata.GetKeyspacesResponse)(nil), // 156: vtctldata.GetKeyspacesResponse - (*vtctldata.GetKeyspaceRoutingRulesResponse)(nil), // 157: vtctldata.GetKeyspaceRoutingRulesResponse - (*vtctldata.GetPermissionsResponse)(nil), // 158: vtctldata.GetPermissionsResponse - (*vtctldata.GetRoutingRulesResponse)(nil), // 159: vtctldata.GetRoutingRulesResponse - (*vtctldata.GetSchemaResponse)(nil), // 160: vtctldata.GetSchemaResponse - (*vtctldata.GetSchemaMigrationsResponse)(nil), // 161: vtctldata.GetSchemaMigrationsResponse - (*vtctldata.GetShardReplicationResponse)(nil), // 162: vtctldata.GetShardReplicationResponse - (*vtctldata.GetShardResponse)(nil), // 163: vtctldata.GetShardResponse - (*vtctldata.GetShardRoutingRulesResponse)(nil), // 164: vtctldata.GetShardRoutingRulesResponse - (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 165: vtctldata.GetSrvKeyspaceNamesResponse - (*vtctldata.GetSrvKeyspacesResponse)(nil), // 166: vtctldata.GetSrvKeyspacesResponse - (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 167: vtctldata.UpdateThrottlerConfigResponse - (*vtctldata.GetSrvVSchemaResponse)(nil), // 168: vtctldata.GetSrvVSchemaResponse - (*vtctldata.GetSrvVSchemasResponse)(nil), // 169: vtctldata.GetSrvVSchemasResponse - (*vtctldata.GetTabletResponse)(nil), // 170: vtctldata.GetTabletResponse - (*vtctldata.GetTabletsResponse)(nil), // 171: vtctldata.GetTabletsResponse - (*vtctldata.GetThrottlerStatusResponse)(nil), // 172: vtctldata.GetThrottlerStatusResponse - (*vtctldata.GetTopologyPathResponse)(nil), // 173: vtctldata.GetTopologyPathResponse - (*vtctldata.GetVersionResponse)(nil), // 174: vtctldata.GetVersionResponse - (*vtctldata.GetVSchemaResponse)(nil), // 175: vtctldata.GetVSchemaResponse - (*vtctldata.GetWorkflowsResponse)(nil), // 176: vtctldata.GetWorkflowsResponse - (*vtctldata.InitShardPrimaryResponse)(nil), // 177: vtctldata.InitShardPrimaryResponse - (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 178: vtctldata.LaunchSchemaMigrationResponse - (*vtctldata.LookupVindexCreateResponse)(nil), // 179: vtctldata.LookupVindexCreateResponse - (*vtctldata.LookupVindexExternalizeResponse)(nil), // 180: vtctldata.LookupVindexExternalizeResponse - (*vtctldata.MaterializeCreateResponse)(nil), // 181: vtctldata.MaterializeCreateResponse - (*vtctldata.WorkflowStatusResponse)(nil), // 182: vtctldata.WorkflowStatusResponse - (*vtctldata.MountRegisterResponse)(nil), // 183: vtctldata.MountRegisterResponse - (*vtctldata.MountUnregisterResponse)(nil), // 184: vtctldata.MountUnregisterResponse - (*vtctldata.MountShowResponse)(nil), // 185: vtctldata.MountShowResponse - (*vtctldata.MountListResponse)(nil), // 186: vtctldata.MountListResponse - (*vtctldata.MoveTablesCompleteResponse)(nil), // 187: vtctldata.MoveTablesCompleteResponse - (*vtctldata.PingTabletResponse)(nil), // 188: vtctldata.PingTabletResponse - (*vtctldata.PlannedReparentShardResponse)(nil), // 189: vtctldata.PlannedReparentShardResponse - (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 190: vtctldata.RebuildKeyspaceGraphResponse - (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 191: vtctldata.RebuildVSchemaGraphResponse - (*vtctldata.RefreshStateResponse)(nil), // 192: vtctldata.RefreshStateResponse - (*vtctldata.RefreshStateByShardResponse)(nil), // 193: vtctldata.RefreshStateByShardResponse - (*vtctldata.ReloadSchemaResponse)(nil), // 194: vtctldata.ReloadSchemaResponse - (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 195: vtctldata.ReloadSchemaKeyspaceResponse - (*vtctldata.ReloadSchemaShardResponse)(nil), // 196: vtctldata.ReloadSchemaShardResponse - (*vtctldata.RemoveBackupResponse)(nil), // 197: vtctldata.RemoveBackupResponse - (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 198: vtctldata.RemoveKeyspaceCellResponse - (*vtctldata.RemoveShardCellResponse)(nil), // 199: vtctldata.RemoveShardCellResponse - (*vtctldata.ReparentTabletResponse)(nil), // 200: vtctldata.ReparentTabletResponse - (*vtctldata.RestoreFromBackupResponse)(nil), // 201: vtctldata.RestoreFromBackupResponse - (*vtctldata.RetrySchemaMigrationResponse)(nil), // 202: vtctldata.RetrySchemaMigrationResponse - (*vtctldata.RunHealthCheckResponse)(nil), // 203: vtctldata.RunHealthCheckResponse - (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 204: vtctldata.SetKeyspaceDurabilityPolicyResponse - (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 205: vtctldata.SetShardIsPrimaryServingResponse - (*vtctldata.SetShardTabletControlResponse)(nil), // 206: vtctldata.SetShardTabletControlResponse - (*vtctldata.SetWritableResponse)(nil), // 207: vtctldata.SetWritableResponse - (*vtctldata.ShardReplicationAddResponse)(nil), // 208: vtctldata.ShardReplicationAddResponse - (*vtctldata.ShardReplicationFixResponse)(nil), // 209: vtctldata.ShardReplicationFixResponse - (*vtctldata.ShardReplicationPositionsResponse)(nil), // 210: vtctldata.ShardReplicationPositionsResponse - (*vtctldata.ShardReplicationRemoveResponse)(nil), // 211: vtctldata.ShardReplicationRemoveResponse - (*vtctldata.SleepTabletResponse)(nil), // 212: vtctldata.SleepTabletResponse - (*vtctldata.SourceShardAddResponse)(nil), // 213: vtctldata.SourceShardAddResponse - (*vtctldata.SourceShardDeleteResponse)(nil), // 214: vtctldata.SourceShardDeleteResponse - (*vtctldata.StartReplicationResponse)(nil), // 215: vtctldata.StartReplicationResponse - (*vtctldata.StopReplicationResponse)(nil), // 216: vtctldata.StopReplicationResponse - (*vtctldata.TabletExternallyReparentedResponse)(nil), // 217: vtctldata.TabletExternallyReparentedResponse - (*vtctldata.UpdateCellInfoResponse)(nil), // 218: vtctldata.UpdateCellInfoResponse - (*vtctldata.UpdateCellsAliasResponse)(nil), // 219: vtctldata.UpdateCellsAliasResponse - (*vtctldata.ValidateResponse)(nil), // 220: vtctldata.ValidateResponse - (*vtctldata.ValidateKeyspaceResponse)(nil), // 221: vtctldata.ValidateKeyspaceResponse - (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 222: vtctldata.ValidateSchemaKeyspaceResponse - (*vtctldata.ValidateShardResponse)(nil), // 223: vtctldata.ValidateShardResponse - (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 224: vtctldata.ValidateVersionKeyspaceResponse - (*vtctldata.ValidateVersionShardResponse)(nil), // 225: vtctldata.ValidateVersionShardResponse - (*vtctldata.ValidateVSchemaResponse)(nil), // 226: vtctldata.ValidateVSchemaResponse - (*vtctldata.VDiffCreateResponse)(nil), // 227: vtctldata.VDiffCreateResponse - (*vtctldata.VDiffDeleteResponse)(nil), // 228: vtctldata.VDiffDeleteResponse - (*vtctldata.VDiffResumeResponse)(nil), // 229: vtctldata.VDiffResumeResponse - (*vtctldata.VDiffShowResponse)(nil), // 230: vtctldata.VDiffShowResponse - (*vtctldata.VDiffStopResponse)(nil), // 231: vtctldata.VDiffStopResponse - (*vtctldata.WorkflowDeleteResponse)(nil), // 232: vtctldata.WorkflowDeleteResponse - (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 233: vtctldata.WorkflowSwitchTrafficResponse - (*vtctldata.WorkflowUpdateResponse)(nil), // 234: vtctldata.WorkflowUpdateResponse - (*vtctldata.ApplyMirrorRulesResponse)(nil), // 235: vtctldata.ApplyMirrorRulesResponse - (*vtctldata.GetMirrorRulesResponse)(nil), // 236: vtctldata.GetMirrorRulesResponse - (*vtctldata.WorkflowMirrorTrafficResponse)(nil), // 237: vtctldata.WorkflowMirrorTrafficResponse + (*vtctldata.GetMirrorRulesRequest)(nil), // 118: vtctldata.GetMirrorRulesRequest + (*vtctldata.WorkflowMirrorTrafficRequest)(nil), // 119: vtctldata.WorkflowMirrorTrafficRequest + (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 120: vtctldata.ExecuteVtctlCommandResponse + (*vtctldata.AddCellInfoResponse)(nil), // 121: vtctldata.AddCellInfoResponse + (*vtctldata.AddCellsAliasResponse)(nil), // 122: vtctldata.AddCellsAliasResponse + (*vtctldata.ApplyRoutingRulesResponse)(nil), // 123: vtctldata.ApplyRoutingRulesResponse + (*vtctldata.ApplySchemaResponse)(nil), // 124: vtctldata.ApplySchemaResponse + (*vtctldata.ApplyKeyspaceRoutingRulesResponse)(nil), // 125: vtctldata.ApplyKeyspaceRoutingRulesResponse + (*vtctldata.ApplyShardRoutingRulesResponse)(nil), // 126: vtctldata.ApplyShardRoutingRulesResponse + (*vtctldata.ApplyVSchemaResponse)(nil), // 127: vtctldata.ApplyVSchemaResponse + (*vtctldata.BackupResponse)(nil), // 128: vtctldata.BackupResponse + (*vtctldata.CancelSchemaMigrationResponse)(nil), // 129: vtctldata.CancelSchemaMigrationResponse + (*vtctldata.ChangeTabletTypeResponse)(nil), // 130: vtctldata.ChangeTabletTypeResponse + (*vtctldata.CheckThrottlerResponse)(nil), // 131: vtctldata.CheckThrottlerResponse + (*vtctldata.CleanupSchemaMigrationResponse)(nil), // 132: vtctldata.CleanupSchemaMigrationResponse + (*vtctldata.CompleteSchemaMigrationResponse)(nil), // 133: vtctldata.CompleteSchemaMigrationResponse + (*vtctldata.CreateKeyspaceResponse)(nil), // 134: vtctldata.CreateKeyspaceResponse + (*vtctldata.CreateShardResponse)(nil), // 135: vtctldata.CreateShardResponse + (*vtctldata.DeleteCellInfoResponse)(nil), // 136: vtctldata.DeleteCellInfoResponse + (*vtctldata.DeleteCellsAliasResponse)(nil), // 137: vtctldata.DeleteCellsAliasResponse + (*vtctldata.DeleteKeyspaceResponse)(nil), // 138: vtctldata.DeleteKeyspaceResponse + (*vtctldata.DeleteShardsResponse)(nil), // 139: vtctldata.DeleteShardsResponse + (*vtctldata.DeleteSrvVSchemaResponse)(nil), // 140: vtctldata.DeleteSrvVSchemaResponse + (*vtctldata.DeleteTabletsResponse)(nil), // 141: vtctldata.DeleteTabletsResponse + (*vtctldata.EmergencyReparentShardResponse)(nil), // 142: vtctldata.EmergencyReparentShardResponse + (*vtctldata.ExecuteFetchAsAppResponse)(nil), // 143: vtctldata.ExecuteFetchAsAppResponse + (*vtctldata.ExecuteFetchAsDBAResponse)(nil), // 144: vtctldata.ExecuteFetchAsDBAResponse + (*vtctldata.ExecuteHookResponse)(nil), // 145: vtctldata.ExecuteHookResponse + (*vtctldata.ExecuteMultiFetchAsDBAResponse)(nil), // 146: vtctldata.ExecuteMultiFetchAsDBAResponse + (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 147: vtctldata.FindAllShardsInKeyspaceResponse + (*vtctldata.ForceCutOverSchemaMigrationResponse)(nil), // 148: vtctldata.ForceCutOverSchemaMigrationResponse + (*vtctldata.GetBackupsResponse)(nil), // 149: vtctldata.GetBackupsResponse + (*vtctldata.GetCellInfoResponse)(nil), // 150: vtctldata.GetCellInfoResponse + (*vtctldata.GetCellInfoNamesResponse)(nil), // 151: vtctldata.GetCellInfoNamesResponse + (*vtctldata.GetCellsAliasesResponse)(nil), // 152: vtctldata.GetCellsAliasesResponse + (*vtctldata.GetFullStatusResponse)(nil), // 153: vtctldata.GetFullStatusResponse + (*vtctldata.GetKeyspaceResponse)(nil), // 154: vtctldata.GetKeyspaceResponse + (*vtctldata.GetKeyspacesResponse)(nil), // 155: vtctldata.GetKeyspacesResponse + (*vtctldata.GetKeyspaceRoutingRulesResponse)(nil), // 156: vtctldata.GetKeyspaceRoutingRulesResponse + (*vtctldata.GetPermissionsResponse)(nil), // 157: vtctldata.GetPermissionsResponse + (*vtctldata.GetRoutingRulesResponse)(nil), // 158: vtctldata.GetRoutingRulesResponse + (*vtctldata.GetSchemaResponse)(nil), // 159: vtctldata.GetSchemaResponse + (*vtctldata.GetSchemaMigrationsResponse)(nil), // 160: vtctldata.GetSchemaMigrationsResponse + (*vtctldata.GetShardReplicationResponse)(nil), // 161: vtctldata.GetShardReplicationResponse + (*vtctldata.GetShardResponse)(nil), // 162: vtctldata.GetShardResponse + (*vtctldata.GetShardRoutingRulesResponse)(nil), // 163: vtctldata.GetShardRoutingRulesResponse + (*vtctldata.GetSrvKeyspaceNamesResponse)(nil), // 164: vtctldata.GetSrvKeyspaceNamesResponse + (*vtctldata.GetSrvKeyspacesResponse)(nil), // 165: vtctldata.GetSrvKeyspacesResponse + (*vtctldata.UpdateThrottlerConfigResponse)(nil), // 166: vtctldata.UpdateThrottlerConfigResponse + (*vtctldata.GetSrvVSchemaResponse)(nil), // 167: vtctldata.GetSrvVSchemaResponse + (*vtctldata.GetSrvVSchemasResponse)(nil), // 168: vtctldata.GetSrvVSchemasResponse + (*vtctldata.GetTabletResponse)(nil), // 169: vtctldata.GetTabletResponse + (*vtctldata.GetTabletsResponse)(nil), // 170: vtctldata.GetTabletsResponse + (*vtctldata.GetThrottlerStatusResponse)(nil), // 171: vtctldata.GetThrottlerStatusResponse + (*vtctldata.GetTopologyPathResponse)(nil), // 172: vtctldata.GetTopologyPathResponse + (*vtctldata.GetVersionResponse)(nil), // 173: vtctldata.GetVersionResponse + (*vtctldata.GetVSchemaResponse)(nil), // 174: vtctldata.GetVSchemaResponse + (*vtctldata.GetWorkflowsResponse)(nil), // 175: vtctldata.GetWorkflowsResponse + (*vtctldata.InitShardPrimaryResponse)(nil), // 176: vtctldata.InitShardPrimaryResponse + (*vtctldata.LaunchSchemaMigrationResponse)(nil), // 177: vtctldata.LaunchSchemaMigrationResponse + (*vtctldata.LookupVindexCreateResponse)(nil), // 178: vtctldata.LookupVindexCreateResponse + (*vtctldata.LookupVindexExternalizeResponse)(nil), // 179: vtctldata.LookupVindexExternalizeResponse + (*vtctldata.MaterializeCreateResponse)(nil), // 180: vtctldata.MaterializeCreateResponse + (*vtctldata.WorkflowStatusResponse)(nil), // 181: vtctldata.WorkflowStatusResponse + (*vtctldata.MountRegisterResponse)(nil), // 182: vtctldata.MountRegisterResponse + (*vtctldata.MountUnregisterResponse)(nil), // 183: vtctldata.MountUnregisterResponse + (*vtctldata.MountShowResponse)(nil), // 184: vtctldata.MountShowResponse + (*vtctldata.MountListResponse)(nil), // 185: vtctldata.MountListResponse + (*vtctldata.MoveTablesCompleteResponse)(nil), // 186: vtctldata.MoveTablesCompleteResponse + (*vtctldata.PingTabletResponse)(nil), // 187: vtctldata.PingTabletResponse + (*vtctldata.PlannedReparentShardResponse)(nil), // 188: vtctldata.PlannedReparentShardResponse + (*vtctldata.RebuildKeyspaceGraphResponse)(nil), // 189: vtctldata.RebuildKeyspaceGraphResponse + (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 190: vtctldata.RebuildVSchemaGraphResponse + (*vtctldata.RefreshStateResponse)(nil), // 191: vtctldata.RefreshStateResponse + (*vtctldata.RefreshStateByShardResponse)(nil), // 192: vtctldata.RefreshStateByShardResponse + (*vtctldata.ReloadSchemaResponse)(nil), // 193: vtctldata.ReloadSchemaResponse + (*vtctldata.ReloadSchemaKeyspaceResponse)(nil), // 194: vtctldata.ReloadSchemaKeyspaceResponse + (*vtctldata.ReloadSchemaShardResponse)(nil), // 195: vtctldata.ReloadSchemaShardResponse + (*vtctldata.RemoveBackupResponse)(nil), // 196: vtctldata.RemoveBackupResponse + (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 197: vtctldata.RemoveKeyspaceCellResponse + (*vtctldata.RemoveShardCellResponse)(nil), // 198: vtctldata.RemoveShardCellResponse + (*vtctldata.ReparentTabletResponse)(nil), // 199: vtctldata.ReparentTabletResponse + (*vtctldata.RestoreFromBackupResponse)(nil), // 200: vtctldata.RestoreFromBackupResponse + (*vtctldata.RetrySchemaMigrationResponse)(nil), // 201: vtctldata.RetrySchemaMigrationResponse + (*vtctldata.RunHealthCheckResponse)(nil), // 202: vtctldata.RunHealthCheckResponse + (*vtctldata.SetKeyspaceDurabilityPolicyResponse)(nil), // 203: vtctldata.SetKeyspaceDurabilityPolicyResponse + (*vtctldata.SetShardIsPrimaryServingResponse)(nil), // 204: vtctldata.SetShardIsPrimaryServingResponse + (*vtctldata.SetShardTabletControlResponse)(nil), // 205: vtctldata.SetShardTabletControlResponse + (*vtctldata.SetWritableResponse)(nil), // 206: vtctldata.SetWritableResponse + (*vtctldata.ShardReplicationAddResponse)(nil), // 207: vtctldata.ShardReplicationAddResponse + (*vtctldata.ShardReplicationFixResponse)(nil), // 208: vtctldata.ShardReplicationFixResponse + (*vtctldata.ShardReplicationPositionsResponse)(nil), // 209: vtctldata.ShardReplicationPositionsResponse + (*vtctldata.ShardReplicationRemoveResponse)(nil), // 210: vtctldata.ShardReplicationRemoveResponse + (*vtctldata.SleepTabletResponse)(nil), // 211: vtctldata.SleepTabletResponse + (*vtctldata.SourceShardAddResponse)(nil), // 212: vtctldata.SourceShardAddResponse + (*vtctldata.SourceShardDeleteResponse)(nil), // 213: vtctldata.SourceShardDeleteResponse + (*vtctldata.StartReplicationResponse)(nil), // 214: vtctldata.StartReplicationResponse + (*vtctldata.StopReplicationResponse)(nil), // 215: vtctldata.StopReplicationResponse + (*vtctldata.TabletExternallyReparentedResponse)(nil), // 216: vtctldata.TabletExternallyReparentedResponse + (*vtctldata.UpdateCellInfoResponse)(nil), // 217: vtctldata.UpdateCellInfoResponse + (*vtctldata.UpdateCellsAliasResponse)(nil), // 218: vtctldata.UpdateCellsAliasResponse + (*vtctldata.ValidateResponse)(nil), // 219: vtctldata.ValidateResponse + (*vtctldata.ValidateKeyspaceResponse)(nil), // 220: vtctldata.ValidateKeyspaceResponse + (*vtctldata.ValidateSchemaKeyspaceResponse)(nil), // 221: vtctldata.ValidateSchemaKeyspaceResponse + (*vtctldata.ValidateShardResponse)(nil), // 222: vtctldata.ValidateShardResponse + (*vtctldata.ValidateVersionKeyspaceResponse)(nil), // 223: vtctldata.ValidateVersionKeyspaceResponse + (*vtctldata.ValidateVersionShardResponse)(nil), // 224: vtctldata.ValidateVersionShardResponse + (*vtctldata.ValidateVSchemaResponse)(nil), // 225: vtctldata.ValidateVSchemaResponse + (*vtctldata.VDiffCreateResponse)(nil), // 226: vtctldata.VDiffCreateResponse + (*vtctldata.VDiffDeleteResponse)(nil), // 227: vtctldata.VDiffDeleteResponse + (*vtctldata.VDiffResumeResponse)(nil), // 228: vtctldata.VDiffResumeResponse + (*vtctldata.VDiffShowResponse)(nil), // 229: vtctldata.VDiffShowResponse + (*vtctldata.VDiffStopResponse)(nil), // 230: vtctldata.VDiffStopResponse + (*vtctldata.WorkflowDeleteResponse)(nil), // 231: vtctldata.WorkflowDeleteResponse + (*vtctldata.WorkflowSwitchTrafficResponse)(nil), // 232: vtctldata.WorkflowSwitchTrafficResponse + (*vtctldata.WorkflowUpdateResponse)(nil), // 233: vtctldata.WorkflowUpdateResponse + (*vtctldata.GetMirrorRulesResponse)(nil), // 234: vtctldata.GetMirrorRulesResponse + (*vtctldata.WorkflowMirrorTrafficResponse)(nil), // 235: vtctldata.WorkflowMirrorTrafficResponse } var file_vtctlservice_proto_depIdxs = []int32{ 0, // 0: vtctlservice.Vtctl.ExecuteVtctlCommand:input_type -> vtctldata.ExecuteVtctlCommandRequest @@ -1124,132 +1116,130 @@ var file_vtctlservice_proto_depIdxs = []int32{ 115, // 115: vtctlservice.Vtctld.WorkflowStatus:input_type -> vtctldata.WorkflowStatusRequest 116, // 116: vtctlservice.Vtctld.WorkflowSwitchTraffic:input_type -> vtctldata.WorkflowSwitchTrafficRequest 117, // 117: vtctlservice.Vtctld.WorkflowUpdate:input_type -> vtctldata.WorkflowUpdateRequest - 118, // 118: vtctlservice.Vtctld.ApplyMirrorRules:input_type -> vtctldata.ApplyMirrorRulesRequest - 119, // 119: vtctlservice.Vtctld.GetMirrorRules:input_type -> vtctldata.GetMirrorRulesRequest - 120, // 120: vtctlservice.Vtctld.WorkflowMirrorTraffic:input_type -> vtctldata.WorkflowMirrorTrafficRequest - 121, // 121: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse - 122, // 122: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse - 123, // 123: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse - 124, // 124: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse - 125, // 125: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse - 126, // 126: vtctlservice.Vtctld.ApplyKeyspaceRoutingRules:output_type -> vtctldata.ApplyKeyspaceRoutingRulesResponse - 127, // 127: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse - 128, // 128: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse - 129, // 129: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse - 129, // 130: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse - 130, // 131: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse - 131, // 132: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse - 132, // 133: vtctlservice.Vtctld.CheckThrottler:output_type -> vtctldata.CheckThrottlerResponse - 133, // 134: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse - 134, // 135: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse - 135, // 136: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse - 136, // 137: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse - 137, // 138: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse - 138, // 139: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse - 139, // 140: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse - 140, // 141: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse - 141, // 142: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse - 142, // 143: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse - 143, // 144: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse - 144, // 145: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse - 145, // 146: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse - 146, // 147: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse - 147, // 148: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:output_type -> vtctldata.ExecuteMultiFetchAsDBAResponse - 148, // 149: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse - 149, // 150: vtctlservice.Vtctld.ForceCutOverSchemaMigration:output_type -> vtctldata.ForceCutOverSchemaMigrationResponse - 150, // 151: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse - 151, // 152: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse - 152, // 153: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse - 153, // 154: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse - 154, // 155: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse - 155, // 156: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse - 156, // 157: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse - 157, // 158: vtctlservice.Vtctld.GetKeyspaceRoutingRules:output_type -> vtctldata.GetKeyspaceRoutingRulesResponse - 158, // 159: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse - 159, // 160: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse - 160, // 161: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse - 161, // 162: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse - 162, // 163: vtctlservice.Vtctld.GetShardReplication:output_type -> vtctldata.GetShardReplicationResponse - 163, // 164: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse - 164, // 165: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse - 165, // 166: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse - 166, // 167: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse - 167, // 168: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse - 168, // 169: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse - 169, // 170: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse - 170, // 171: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse - 171, // 172: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse - 172, // 173: vtctlservice.Vtctld.GetThrottlerStatus:output_type -> vtctldata.GetThrottlerStatusResponse - 173, // 174: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse - 174, // 175: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse - 175, // 176: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse - 176, // 177: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse - 177, // 178: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse - 178, // 179: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse - 179, // 180: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse - 180, // 181: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse - 181, // 182: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse - 182, // 183: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse - 183, // 184: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse - 184, // 185: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse - 185, // 186: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse - 186, // 187: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse - 182, // 188: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse - 187, // 189: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse - 188, // 190: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse - 189, // 191: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse - 190, // 192: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse - 191, // 193: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse - 192, // 194: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse - 193, // 195: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse - 194, // 196: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse - 195, // 197: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse - 196, // 198: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse - 197, // 199: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse - 198, // 200: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse - 199, // 201: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse - 200, // 202: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse - 182, // 203: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse - 201, // 204: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse - 202, // 205: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse - 203, // 206: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse - 204, // 207: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse - 205, // 208: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse - 206, // 209: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse - 207, // 210: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse - 208, // 211: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse - 209, // 212: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse - 210, // 213: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse - 211, // 214: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse - 212, // 215: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse - 213, // 216: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse - 214, // 217: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse - 215, // 218: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse - 216, // 219: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse - 217, // 220: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse - 218, // 221: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse - 219, // 222: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse - 220, // 223: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse - 221, // 224: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse - 222, // 225: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse - 223, // 226: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse - 224, // 227: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse - 225, // 228: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse - 226, // 229: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse - 227, // 230: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse - 228, // 231: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse - 229, // 232: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse - 230, // 233: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse - 231, // 234: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse - 232, // 235: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse - 182, // 236: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse - 233, // 237: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse - 234, // 238: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse - 235, // 239: vtctlservice.Vtctld.ApplyMirrorRules:output_type -> vtctldata.ApplyMirrorRulesResponse - 236, // 240: vtctlservice.Vtctld.GetMirrorRules:output_type -> vtctldata.GetMirrorRulesResponse - 237, // 241: vtctlservice.Vtctld.WorkflowMirrorTraffic:output_type -> vtctldata.WorkflowMirrorTrafficResponse - 121, // [121:242] is the sub-list for method output_type - 0, // [0:121] is the sub-list for method input_type + 118, // 118: vtctlservice.Vtctld.GetMirrorRules:input_type -> vtctldata.GetMirrorRulesRequest + 119, // 119: vtctlservice.Vtctld.WorkflowMirrorTraffic:input_type -> vtctldata.WorkflowMirrorTrafficRequest + 120, // 120: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse + 121, // 121: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse + 122, // 122: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse + 123, // 123: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse + 124, // 124: vtctlservice.Vtctld.ApplySchema:output_type -> vtctldata.ApplySchemaResponse + 125, // 125: vtctlservice.Vtctld.ApplyKeyspaceRoutingRules:output_type -> vtctldata.ApplyKeyspaceRoutingRulesResponse + 126, // 126: vtctlservice.Vtctld.ApplyShardRoutingRules:output_type -> vtctldata.ApplyShardRoutingRulesResponse + 127, // 127: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse + 128, // 128: vtctlservice.Vtctld.Backup:output_type -> vtctldata.BackupResponse + 128, // 129: vtctlservice.Vtctld.BackupShard:output_type -> vtctldata.BackupResponse + 129, // 130: vtctlservice.Vtctld.CancelSchemaMigration:output_type -> vtctldata.CancelSchemaMigrationResponse + 130, // 131: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse + 131, // 132: vtctlservice.Vtctld.CheckThrottler:output_type -> vtctldata.CheckThrottlerResponse + 132, // 133: vtctlservice.Vtctld.CleanupSchemaMigration:output_type -> vtctldata.CleanupSchemaMigrationResponse + 133, // 134: vtctlservice.Vtctld.CompleteSchemaMigration:output_type -> vtctldata.CompleteSchemaMigrationResponse + 134, // 135: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse + 135, // 136: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse + 136, // 137: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse + 137, // 138: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse + 138, // 139: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse + 139, // 140: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse + 140, // 141: vtctlservice.Vtctld.DeleteSrvVSchema:output_type -> vtctldata.DeleteSrvVSchemaResponse + 141, // 142: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse + 142, // 143: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse + 143, // 144: vtctlservice.Vtctld.ExecuteFetchAsApp:output_type -> vtctldata.ExecuteFetchAsAppResponse + 144, // 145: vtctlservice.Vtctld.ExecuteFetchAsDBA:output_type -> vtctldata.ExecuteFetchAsDBAResponse + 145, // 146: vtctlservice.Vtctld.ExecuteHook:output_type -> vtctldata.ExecuteHookResponse + 146, // 147: vtctlservice.Vtctld.ExecuteMultiFetchAsDBA:output_type -> vtctldata.ExecuteMultiFetchAsDBAResponse + 147, // 148: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse + 148, // 149: vtctlservice.Vtctld.ForceCutOverSchemaMigration:output_type -> vtctldata.ForceCutOverSchemaMigrationResponse + 149, // 150: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse + 150, // 151: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse + 151, // 152: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse + 152, // 153: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse + 153, // 154: vtctlservice.Vtctld.GetFullStatus:output_type -> vtctldata.GetFullStatusResponse + 154, // 155: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse + 155, // 156: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse + 156, // 157: vtctlservice.Vtctld.GetKeyspaceRoutingRules:output_type -> vtctldata.GetKeyspaceRoutingRulesResponse + 157, // 158: vtctlservice.Vtctld.GetPermissions:output_type -> vtctldata.GetPermissionsResponse + 158, // 159: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse + 159, // 160: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse + 160, // 161: vtctlservice.Vtctld.GetSchemaMigrations:output_type -> vtctldata.GetSchemaMigrationsResponse + 161, // 162: vtctlservice.Vtctld.GetShardReplication:output_type -> vtctldata.GetShardReplicationResponse + 162, // 163: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse + 163, // 164: vtctlservice.Vtctld.GetShardRoutingRules:output_type -> vtctldata.GetShardRoutingRulesResponse + 164, // 165: vtctlservice.Vtctld.GetSrvKeyspaceNames:output_type -> vtctldata.GetSrvKeyspaceNamesResponse + 165, // 166: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse + 166, // 167: vtctlservice.Vtctld.UpdateThrottlerConfig:output_type -> vtctldata.UpdateThrottlerConfigResponse + 167, // 168: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse + 168, // 169: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse + 169, // 170: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse + 170, // 171: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse + 171, // 172: vtctlservice.Vtctld.GetThrottlerStatus:output_type -> vtctldata.GetThrottlerStatusResponse + 172, // 173: vtctlservice.Vtctld.GetTopologyPath:output_type -> vtctldata.GetTopologyPathResponse + 173, // 174: vtctlservice.Vtctld.GetVersion:output_type -> vtctldata.GetVersionResponse + 174, // 175: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse + 175, // 176: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse + 176, // 177: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse + 177, // 178: vtctlservice.Vtctld.LaunchSchemaMigration:output_type -> vtctldata.LaunchSchemaMigrationResponse + 178, // 179: vtctlservice.Vtctld.LookupVindexCreate:output_type -> vtctldata.LookupVindexCreateResponse + 179, // 180: vtctlservice.Vtctld.LookupVindexExternalize:output_type -> vtctldata.LookupVindexExternalizeResponse + 180, // 181: vtctlservice.Vtctld.MaterializeCreate:output_type -> vtctldata.MaterializeCreateResponse + 181, // 182: vtctlservice.Vtctld.MigrateCreate:output_type -> vtctldata.WorkflowStatusResponse + 182, // 183: vtctlservice.Vtctld.MountRegister:output_type -> vtctldata.MountRegisterResponse + 183, // 184: vtctlservice.Vtctld.MountUnregister:output_type -> vtctldata.MountUnregisterResponse + 184, // 185: vtctlservice.Vtctld.MountShow:output_type -> vtctldata.MountShowResponse + 185, // 186: vtctlservice.Vtctld.MountList:output_type -> vtctldata.MountListResponse + 181, // 187: vtctlservice.Vtctld.MoveTablesCreate:output_type -> vtctldata.WorkflowStatusResponse + 186, // 188: vtctlservice.Vtctld.MoveTablesComplete:output_type -> vtctldata.MoveTablesCompleteResponse + 187, // 189: vtctlservice.Vtctld.PingTablet:output_type -> vtctldata.PingTabletResponse + 188, // 190: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse + 189, // 191: vtctlservice.Vtctld.RebuildKeyspaceGraph:output_type -> vtctldata.RebuildKeyspaceGraphResponse + 190, // 192: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse + 191, // 193: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse + 192, // 194: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse + 193, // 195: vtctlservice.Vtctld.ReloadSchema:output_type -> vtctldata.ReloadSchemaResponse + 194, // 196: vtctlservice.Vtctld.ReloadSchemaKeyspace:output_type -> vtctldata.ReloadSchemaKeyspaceResponse + 195, // 197: vtctlservice.Vtctld.ReloadSchemaShard:output_type -> vtctldata.ReloadSchemaShardResponse + 196, // 198: vtctlservice.Vtctld.RemoveBackup:output_type -> vtctldata.RemoveBackupResponse + 197, // 199: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse + 198, // 200: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse + 199, // 201: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse + 181, // 202: vtctlservice.Vtctld.ReshardCreate:output_type -> vtctldata.WorkflowStatusResponse + 200, // 203: vtctlservice.Vtctld.RestoreFromBackup:output_type -> vtctldata.RestoreFromBackupResponse + 201, // 204: vtctlservice.Vtctld.RetrySchemaMigration:output_type -> vtctldata.RetrySchemaMigrationResponse + 202, // 205: vtctlservice.Vtctld.RunHealthCheck:output_type -> vtctldata.RunHealthCheckResponse + 203, // 206: vtctlservice.Vtctld.SetKeyspaceDurabilityPolicy:output_type -> vtctldata.SetKeyspaceDurabilityPolicyResponse + 204, // 207: vtctlservice.Vtctld.SetShardIsPrimaryServing:output_type -> vtctldata.SetShardIsPrimaryServingResponse + 205, // 208: vtctlservice.Vtctld.SetShardTabletControl:output_type -> vtctldata.SetShardTabletControlResponse + 206, // 209: vtctlservice.Vtctld.SetWritable:output_type -> vtctldata.SetWritableResponse + 207, // 210: vtctlservice.Vtctld.ShardReplicationAdd:output_type -> vtctldata.ShardReplicationAddResponse + 208, // 211: vtctlservice.Vtctld.ShardReplicationFix:output_type -> vtctldata.ShardReplicationFixResponse + 209, // 212: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse + 210, // 213: vtctlservice.Vtctld.ShardReplicationRemove:output_type -> vtctldata.ShardReplicationRemoveResponse + 211, // 214: vtctlservice.Vtctld.SleepTablet:output_type -> vtctldata.SleepTabletResponse + 212, // 215: vtctlservice.Vtctld.SourceShardAdd:output_type -> vtctldata.SourceShardAddResponse + 213, // 216: vtctlservice.Vtctld.SourceShardDelete:output_type -> vtctldata.SourceShardDeleteResponse + 214, // 217: vtctlservice.Vtctld.StartReplication:output_type -> vtctldata.StartReplicationResponse + 215, // 218: vtctlservice.Vtctld.StopReplication:output_type -> vtctldata.StopReplicationResponse + 216, // 219: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse + 217, // 220: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse + 218, // 221: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse + 219, // 222: vtctlservice.Vtctld.Validate:output_type -> vtctldata.ValidateResponse + 220, // 223: vtctlservice.Vtctld.ValidateKeyspace:output_type -> vtctldata.ValidateKeyspaceResponse + 221, // 224: vtctlservice.Vtctld.ValidateSchemaKeyspace:output_type -> vtctldata.ValidateSchemaKeyspaceResponse + 222, // 225: vtctlservice.Vtctld.ValidateShard:output_type -> vtctldata.ValidateShardResponse + 223, // 226: vtctlservice.Vtctld.ValidateVersionKeyspace:output_type -> vtctldata.ValidateVersionKeyspaceResponse + 224, // 227: vtctlservice.Vtctld.ValidateVersionShard:output_type -> vtctldata.ValidateVersionShardResponse + 225, // 228: vtctlservice.Vtctld.ValidateVSchema:output_type -> vtctldata.ValidateVSchemaResponse + 226, // 229: vtctlservice.Vtctld.VDiffCreate:output_type -> vtctldata.VDiffCreateResponse + 227, // 230: vtctlservice.Vtctld.VDiffDelete:output_type -> vtctldata.VDiffDeleteResponse + 228, // 231: vtctlservice.Vtctld.VDiffResume:output_type -> vtctldata.VDiffResumeResponse + 229, // 232: vtctlservice.Vtctld.VDiffShow:output_type -> vtctldata.VDiffShowResponse + 230, // 233: vtctlservice.Vtctld.VDiffStop:output_type -> vtctldata.VDiffStopResponse + 231, // 234: vtctlservice.Vtctld.WorkflowDelete:output_type -> vtctldata.WorkflowDeleteResponse + 181, // 235: vtctlservice.Vtctld.WorkflowStatus:output_type -> vtctldata.WorkflowStatusResponse + 232, // 236: vtctlservice.Vtctld.WorkflowSwitchTraffic:output_type -> vtctldata.WorkflowSwitchTrafficResponse + 233, // 237: vtctlservice.Vtctld.WorkflowUpdate:output_type -> vtctldata.WorkflowUpdateResponse + 234, // 238: vtctlservice.Vtctld.GetMirrorRules:output_type -> vtctldata.GetMirrorRulesResponse + 235, // 239: vtctlservice.Vtctld.WorkflowMirrorTraffic:output_type -> vtctldata.WorkflowMirrorTrafficResponse + 120, // [120:240] is the sub-list for method output_type + 0, // [0:120] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go index a4a8b70f779..56cef8d1dcd 100644 --- a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go @@ -464,8 +464,6 @@ type VtctldClient interface { // WorkflowUpdate updates the configuration of a vreplication workflow // using the provided updated parameters. WorkflowUpdate(ctx context.Context, in *vtctldata.WorkflowUpdateRequest, opts ...grpc.CallOption) (*vtctldata.WorkflowUpdateResponse, error) - // ApplyMirrorRules applies the VSchema routing rules. - ApplyMirrorRules(ctx context.Context, in *vtctldata.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.ApplyMirrorRulesResponse, error) // GetMirrorRules returns the VSchema routing rules. GetMirrorRules(ctx context.Context, in *vtctldata.GetMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.GetMirrorRulesResponse, error) WorkflowMirrorTraffic(ctx context.Context, in *vtctldata.WorkflowMirrorTrafficRequest, opts ...grpc.CallOption) (*vtctldata.WorkflowMirrorTrafficResponse, error) @@ -1601,15 +1599,6 @@ func (c *vtctldClient) WorkflowUpdate(ctx context.Context, in *vtctldata.Workflo return out, nil } -func (c *vtctldClient) ApplyMirrorRules(ctx context.Context, in *vtctldata.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.ApplyMirrorRulesResponse, error) { - out := new(vtctldata.ApplyMirrorRulesResponse) - err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/ApplyMirrorRules", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *vtctldClient) GetMirrorRules(ctx context.Context, in *vtctldata.GetMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldata.GetMirrorRulesResponse, error) { out := new(vtctldata.GetMirrorRulesResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/GetMirrorRules", in, out, opts...) @@ -1960,8 +1949,6 @@ type VtctldServer interface { // WorkflowUpdate updates the configuration of a vreplication workflow // using the provided updated parameters. WorkflowUpdate(context.Context, *vtctldata.WorkflowUpdateRequest) (*vtctldata.WorkflowUpdateResponse, error) - // ApplyMirrorRules applies the VSchema routing rules. - ApplyMirrorRules(context.Context, *vtctldata.ApplyMirrorRulesRequest) (*vtctldata.ApplyMirrorRulesResponse, error) // GetMirrorRules returns the VSchema routing rules. GetMirrorRules(context.Context, *vtctldata.GetMirrorRulesRequest) (*vtctldata.GetMirrorRulesResponse, error) WorkflowMirrorTraffic(context.Context, *vtctldata.WorkflowMirrorTrafficRequest) (*vtctldata.WorkflowMirrorTrafficResponse, error) @@ -2323,9 +2310,6 @@ func (UnimplementedVtctldServer) WorkflowSwitchTraffic(context.Context, *vtctlda func (UnimplementedVtctldServer) WorkflowUpdate(context.Context, *vtctldata.WorkflowUpdateRequest) (*vtctldata.WorkflowUpdateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method WorkflowUpdate not implemented") } -func (UnimplementedVtctldServer) ApplyMirrorRules(context.Context, *vtctldata.ApplyMirrorRulesRequest) (*vtctldata.ApplyMirrorRulesResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ApplyMirrorRules not implemented") -} func (UnimplementedVtctldServer) GetMirrorRules(context.Context, *vtctldata.GetMirrorRulesRequest) (*vtctldata.GetMirrorRulesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetMirrorRules not implemented") } @@ -4460,24 +4444,6 @@ func _Vtctld_WorkflowUpdate_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } -func _Vtctld_ApplyMirrorRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(vtctldata.ApplyMirrorRulesRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(VtctldServer).ApplyMirrorRules(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/vtctlservice.Vtctld/ApplyMirrorRules", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(VtctldServer).ApplyMirrorRules(ctx, req.(*vtctldata.ApplyMirrorRulesRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Vtctld_GetMirrorRules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.GetMirrorRulesRequest) if err := dec(in); err != nil { @@ -4977,10 +4943,6 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "WorkflowUpdate", Handler: _Vtctld_WorkflowUpdate_Handler, }, - { - MethodName: "ApplyMirrorRules", - Handler: _Vtctld_ApplyMirrorRules_Handler, - }, { MethodName: "GetMirrorRules", Handler: _Vtctld_GetMirrorRules_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index 9093893a4c8..2153d2c94f4 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -56,15 +56,6 @@ func (client *gRPCVtctldClient) ApplyKeyspaceRoutingRules(ctx context.Context, i return client.c.ApplyKeyspaceRoutingRules(ctx, in, opts...) } -// ApplyMirrorRules is part of the vtctlservicepb.VtctldClient interface. -func (client *gRPCVtctldClient) ApplyMirrorRules(ctx context.Context, in *vtctldatapb.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyMirrorRulesResponse, error) { - if client.c == nil { - return nil, status.Error(codes.Unavailable, connClosedMsg) - } - - return client.c.ApplyMirrorRules(ctx, in, opts...) -} - // ApplyRoutingRules is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) ApplyRoutingRules(ctx context.Context, in *vtctldatapb.ApplyRoutingRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyRoutingRulesResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index e03d3a00b97..65f99c43694 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -291,7 +291,6 @@ func (s *VtctldServer) ApplySchema(ctx context.Context, req *vtctldatapb.ApplySc schemamanager.NewPlainController(req.Sql, req.Keyspace), executor, ) - if err != nil { return nil, err } @@ -464,7 +463,6 @@ func (s *VtctldServer) BackupShard(req *vtctldatapb.BackupShardRequest, stream v span.Annotate("incremental_from_pos", req.IncrementalFromPos) tablets, stats, err := reparentutil.ShardReplicationStatuses(ctx, s.ts, s.tmc, req.Keyspace, req.Shard) - // Instead of return on err directly, only return err when no tablets for backup at all if err != nil { tablets = reparentutil.GetBackupCandidates(tablets, stats) @@ -517,7 +515,8 @@ func (s *VtctldServer) BackupShard(req *vtctldatapb.BackupShardRequest, stream v func (s *VtctldServer) backupTablet(ctx context.Context, tablet *topodatapb.Tablet, req *vtctldatapb.BackupRequest, stream interface { Send(resp *vtctldatapb.BackupResponse) error -}) error { +}, +) error { r := &tabletmanagerdatapb.BackupRequest{ Concurrency: req.Concurrency, AllowPrimary: req.AllowPrimary, @@ -1898,7 +1897,6 @@ func (s *VtctldServer) GetSrvKeyspaces(ctx context.Context, req *vtctldatapb.Get for _, cell := range cells { var srvKeyspace *topodatapb.SrvKeyspace srvKeyspace, err = s.ts.GetSrvKeyspace(ctx, cell, req.Keyspace) - if err != nil { if !topo.IsErrType(err, topo.NoNode) { return nil, err @@ -2036,7 +2034,6 @@ func (s *VtctldServer) GetSrvVSchemas(ctx context.Context, req *vtctldatapb.GetS for _, cell := range cells { var sv *vschemapb.SrvVSchema sv, err = s.ts.GetSrvVSchema(ctx, cell) - if err != nil { if !topo.IsErrType(err, topo.NoNode) { return nil, err @@ -3289,6 +3286,7 @@ func (s *VtctldServer) ReshardCreate(ctx context.Context, req *vtctldatapb.Resha resp, err = s.ws.ReshardCreate(ctx, req) return resp, err } + func (s *VtctldServer) RestoreFromBackup(req *vtctldatapb.RestoreFromBackupRequest, stream vtctlservicepb.Vtctld_RestoreFromBackupServer) (err error) { span, ctx := trace.NewSpan(stream.Context(), "VtctldServer.RestoreFromBackup") defer span.Finish() @@ -4119,7 +4117,6 @@ func (s *VtctldServer) UpdateCellInfo(ctx context.Context, req *vtctldatapb.Upda return nil }) - if err != nil { return nil, err } @@ -4150,7 +4147,6 @@ func (s *VtctldServer) UpdateCellsAlias(ctx context.Context, req *vtctldatapb.Up ca.Cells = req.CellsAlias.Cells return nil }) - if err != nil { return nil, err } @@ -5060,35 +5056,6 @@ func (s *VtctldServer) WorkflowUpdate(ctx context.Context, req *vtctldatapb.Work return resp, err } -// ApplyMirrorRules is part of the vtctlservicepb.VtctldServer interface. -func (s *VtctldServer) ApplyMirrorRules(ctx context.Context, req *vtctldatapb.ApplyMirrorRulesRequest) (resp *vtctldatapb.ApplyMirrorRulesResponse, err error) { - span, ctx := trace.NewSpan(ctx, "VtctldServer.ApplyMirrorRules") - defer span.Finish() - - defer panicHandler(&err) - - span.Annotate("skip_rebuild", req.SkipRebuild) - span.Annotate("rebuild_cells", strings.Join(req.RebuildCells, ",")) - - if err = s.ts.SaveMirrorRules(ctx, req.MirrorRules); err != nil { - return nil, err - } - - resp = &vtctldatapb.ApplyMirrorRulesResponse{} - - if req.SkipRebuild { - log.Warningf("Skipping rebuild of SrvVSchema, will need to run RebuildVSchemaGraph for changes to take effect") - return resp, nil - } - - if err = s.ts.RebuildSrvVSchema(ctx, req.RebuildCells); err != nil { - err = vterrors.Wrapf(err, "RebuildSrvVSchema(%v) failed: %v", req.RebuildCells, err) - return nil, err - } - - return resp, nil -} - // GetMirrorRules is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) GetMirrorRules(ctx context.Context, req *vtctldatapb.GetMirrorRulesRequest) (resp *vtctldatapb.GetMirrorRulesResponse, err error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.GetMirrorRules") @@ -5211,8 +5178,10 @@ var getVersionFromTabletDebugVars = func(tabletAddr string) (string, error) { return version, nil } -var versionFuncMu sync.Mutex -var getVersionFromTablet = getVersionFromTabletDebugVars +var ( + versionFuncMu sync.Mutex + getVersionFromTablet = getVersionFromTabletDebugVars +) func SetVersionFunc(versionFunc func(string) (string, error)) { versionFuncMu.Lock() diff --git a/go/vt/vtctl/localvtctldclient/client_gen.go b/go/vt/vtctl/localvtctldclient/client_gen.go index 5083fef9b9d..2738c771be3 100644 --- a/go/vt/vtctl/localvtctldclient/client_gen.go +++ b/go/vt/vtctl/localvtctldclient/client_gen.go @@ -44,11 +44,6 @@ func (client *localVtctldClient) ApplyKeyspaceRoutingRules(ctx context.Context, return client.s.ApplyKeyspaceRoutingRules(ctx, in) } -// ApplyMirrorRules is part of the vtctlservicepb.VtctldClient interface. -func (client *localVtctldClient) ApplyMirrorRules(ctx context.Context, in *vtctldatapb.ApplyMirrorRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyMirrorRulesResponse, error) { - return client.s.ApplyMirrorRules(ctx, in) -} - // ApplyRoutingRules is part of the vtctlservicepb.VtctldClient interface. func (client *localVtctldClient) ApplyRoutingRules(ctx context.Context, in *vtctldatapb.ApplyRoutingRulesRequest, opts ...grpc.CallOption) (*vtctldatapb.ApplyRoutingRulesResponse, error) { return client.s.ApplyRoutingRules(ctx, in) diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 9af23619170..398357c0423 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -2081,21 +2081,6 @@ message WorkflowUpdateResponse { repeated TabletInfo details = 2; } -message ApplyMirrorRulesRequest { - vschema.MirrorRules mirror_rules = 1; - // SkipRebuild, if set, will cause ApplyRoutingRules to skip rebuilding the - // SrvVSchema objects in each cell in RebuildCells. - bool skip_rebuild = 2; - // RebuildCells limits the SrvVSchema rebuild to the specified cells. If not - // provided the SrvVSchema will be rebuilt in every cell in the topology. - // - // Ignored if SkipRebuild is set. - repeated string rebuild_cells = 3; -} - -message ApplyMirrorRulesResponse { -} - message GetMirrorRulesRequest { } diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index bf98ef44f0c..672374038b5 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -364,8 +364,6 @@ service Vtctld { // WorkflowUpdate updates the configuration of a vreplication workflow // using the provided updated parameters. rpc WorkflowUpdate(vtctldata.WorkflowUpdateRequest) returns (vtctldata.WorkflowUpdateResponse) {}; - // ApplyMirrorRules applies the VSchema routing rules. - rpc ApplyMirrorRules(vtctldata.ApplyMirrorRulesRequest) returns (vtctldata.ApplyMirrorRulesResponse) {}; // GetMirrorRules returns the VSchema routing rules. rpc GetMirrorRules(vtctldata.GetMirrorRulesRequest) returns (vtctldata.GetMirrorRulesResponse) {}; rpc WorkflowMirrorTraffic(vtctldata.WorkflowMirrorTrafficRequest) returns (vtctldata.WorkflowMirrorTrafficResponse) {}; diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 7ceb71ecf12..67b1fca3d05 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -74189,206 +74189,6 @@ export namespace vtctldata { } } - /** Properties of an ApplyMirrorRulesRequest. */ - interface IApplyMirrorRulesRequest { - - /** ApplyMirrorRulesRequest mirror_rules */ - mirror_rules?: (vschema.IMirrorRules|null); - - /** ApplyMirrorRulesRequest skip_rebuild */ - skip_rebuild?: (boolean|null); - - /** ApplyMirrorRulesRequest rebuild_cells */ - rebuild_cells?: (string[]|null); - } - - /** Represents an ApplyMirrorRulesRequest. */ - class ApplyMirrorRulesRequest implements IApplyMirrorRulesRequest { - - /** - * Constructs a new ApplyMirrorRulesRequest. - * @param [properties] Properties to set - */ - constructor(properties?: vtctldata.IApplyMirrorRulesRequest); - - /** ApplyMirrorRulesRequest mirror_rules. */ - public mirror_rules?: (vschema.IMirrorRules|null); - - /** ApplyMirrorRulesRequest skip_rebuild. */ - public skip_rebuild: boolean; - - /** ApplyMirrorRulesRequest rebuild_cells. */ - public rebuild_cells: string[]; - - /** - * Creates a new ApplyMirrorRulesRequest instance using the specified properties. - * @param [properties] Properties to set - * @returns ApplyMirrorRulesRequest instance - */ - public static create(properties?: vtctldata.IApplyMirrorRulesRequest): vtctldata.ApplyMirrorRulesRequest; - - /** - * Encodes the specified ApplyMirrorRulesRequest message. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. - * @param message ApplyMirrorRulesRequest message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: vtctldata.IApplyMirrorRulesRequest, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ApplyMirrorRulesRequest message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. - * @param message ApplyMirrorRulesRequest message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: vtctldata.IApplyMirrorRulesRequest, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ApplyMirrorRulesRequest - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ApplyMirrorRulesRequest; - - /** - * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ApplyMirrorRulesRequest - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ApplyMirrorRulesRequest; - - /** - * Verifies an ApplyMirrorRulesRequest message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an ApplyMirrorRulesRequest message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ApplyMirrorRulesRequest - */ - public static fromObject(object: { [k: string]: any }): vtctldata.ApplyMirrorRulesRequest; - - /** - * Creates a plain object from an ApplyMirrorRulesRequest message. Also converts values to other types if specified. - * @param message ApplyMirrorRulesRequest - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: vtctldata.ApplyMirrorRulesRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ApplyMirrorRulesRequest to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - - /** - * Gets the default type url for ApplyMirrorRulesRequest - * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns The default type url - */ - public static getTypeUrl(typeUrlPrefix?: string): string; - } - - /** Properties of an ApplyMirrorRulesResponse. */ - interface IApplyMirrorRulesResponse { - } - - /** Represents an ApplyMirrorRulesResponse. */ - class ApplyMirrorRulesResponse implements IApplyMirrorRulesResponse { - - /** - * Constructs a new ApplyMirrorRulesResponse. - * @param [properties] Properties to set - */ - constructor(properties?: vtctldata.IApplyMirrorRulesResponse); - - /** - * Creates a new ApplyMirrorRulesResponse instance using the specified properties. - * @param [properties] Properties to set - * @returns ApplyMirrorRulesResponse instance - */ - public static create(properties?: vtctldata.IApplyMirrorRulesResponse): vtctldata.ApplyMirrorRulesResponse; - - /** - * Encodes the specified ApplyMirrorRulesResponse message. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. - * @param message ApplyMirrorRulesResponse message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encode(message: vtctldata.IApplyMirrorRulesResponse, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Encodes the specified ApplyMirrorRulesResponse message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. - * @param message ApplyMirrorRulesResponse message or plain object to encode - * @param [writer] Writer to encode to - * @returns Writer - */ - public static encodeDelimited(message: vtctldata.IApplyMirrorRulesResponse, writer?: $protobuf.Writer): $protobuf.Writer; - - /** - * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer. - * @param reader Reader or buffer to decode from - * @param [length] Message length if known beforehand - * @returns ApplyMirrorRulesResponse - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ApplyMirrorRulesResponse; - - /** - * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer, length delimited. - * @param reader Reader or buffer to decode from - * @returns ApplyMirrorRulesResponse - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ApplyMirrorRulesResponse; - - /** - * Verifies an ApplyMirrorRulesResponse message. - * @param message Plain object to verify - * @returns `null` if valid, otherwise the reason why it is not - */ - public static verify(message: { [k: string]: any }): (string|null); - - /** - * Creates an ApplyMirrorRulesResponse message from a plain object. Also converts values to their respective internal types. - * @param object Plain object - * @returns ApplyMirrorRulesResponse - */ - public static fromObject(object: { [k: string]: any }): vtctldata.ApplyMirrorRulesResponse; - - /** - * Creates a plain object from an ApplyMirrorRulesResponse message. Also converts values to other types if specified. - * @param message ApplyMirrorRulesResponse - * @param [options] Conversion options - * @returns Plain object - */ - public static toObject(message: vtctldata.ApplyMirrorRulesResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; - - /** - * Converts this ApplyMirrorRulesResponse to JSON. - * @returns JSON object - */ - public toJSON(): { [k: string]: any }; - - /** - * Gets the default type url for ApplyMirrorRulesResponse - * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns The default type url - */ - public static getTypeUrl(typeUrlPrefix?: string): string; - } - /** Properties of a GetMirrorRulesRequest. */ interface IGetMirrorRulesRequest { } diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index cc8f781dc2f..f36e43dadec 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -181849,453 +181849,6 @@ export const vtctldata = $root.vtctldata = (() => { return WorkflowUpdateResponse; })(); - vtctldata.ApplyMirrorRulesRequest = (function() { - - /** - * Properties of an ApplyMirrorRulesRequest. - * @memberof vtctldata - * @interface IApplyMirrorRulesRequest - * @property {vschema.IMirrorRules|null} [mirror_rules] ApplyMirrorRulesRequest mirror_rules - * @property {boolean|null} [skip_rebuild] ApplyMirrorRulesRequest skip_rebuild - * @property {Array.|null} [rebuild_cells] ApplyMirrorRulesRequest rebuild_cells - */ - - /** - * Constructs a new ApplyMirrorRulesRequest. - * @memberof vtctldata - * @classdesc Represents an ApplyMirrorRulesRequest. - * @implements IApplyMirrorRulesRequest - * @constructor - * @param {vtctldata.IApplyMirrorRulesRequest=} [properties] Properties to set - */ - function ApplyMirrorRulesRequest(properties) { - this.rebuild_cells = []; - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * ApplyMirrorRulesRequest mirror_rules. - * @member {vschema.IMirrorRules|null|undefined} mirror_rules - * @memberof vtctldata.ApplyMirrorRulesRequest - * @instance - */ - ApplyMirrorRulesRequest.prototype.mirror_rules = null; - - /** - * ApplyMirrorRulesRequest skip_rebuild. - * @member {boolean} skip_rebuild - * @memberof vtctldata.ApplyMirrorRulesRequest - * @instance - */ - ApplyMirrorRulesRequest.prototype.skip_rebuild = false; - - /** - * ApplyMirrorRulesRequest rebuild_cells. - * @member {Array.} rebuild_cells - * @memberof vtctldata.ApplyMirrorRulesRequest - * @instance - */ - ApplyMirrorRulesRequest.prototype.rebuild_cells = $util.emptyArray; - - /** - * Creates a new ApplyMirrorRulesRequest instance using the specified properties. - * @function create - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {vtctldata.IApplyMirrorRulesRequest=} [properties] Properties to set - * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest instance - */ - ApplyMirrorRulesRequest.create = function create(properties) { - return new ApplyMirrorRulesRequest(properties); - }; - - /** - * Encodes the specified ApplyMirrorRulesRequest message. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. - * @function encode - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {vtctldata.IApplyMirrorRulesRequest} message ApplyMirrorRulesRequest message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ApplyMirrorRulesRequest.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.mirror_rules != null && Object.hasOwnProperty.call(message, "mirror_rules")) - $root.vschema.MirrorRules.encode(message.mirror_rules, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); - if (message.skip_rebuild != null && Object.hasOwnProperty.call(message, "skip_rebuild")) - writer.uint32(/* id 2, wireType 0 =*/16).bool(message.skip_rebuild); - if (message.rebuild_cells != null && message.rebuild_cells.length) - for (let i = 0; i < message.rebuild_cells.length; ++i) - writer.uint32(/* id 3, wireType 2 =*/26).string(message.rebuild_cells[i]); - return writer; - }; - - /** - * Encodes the specified ApplyMirrorRulesRequest message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesRequest.verify|verify} messages. - * @function encodeDelimited - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {vtctldata.IApplyMirrorRulesRequest} message ApplyMirrorRulesRequest message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ApplyMirrorRulesRequest.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer. - * @function decode - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ApplyMirrorRulesRequest.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ApplyMirrorRulesRequest(); - while (reader.pos < end) { - let tag = reader.uint32(); - switch (tag >>> 3) { - case 1: { - message.mirror_rules = $root.vschema.MirrorRules.decode(reader, reader.uint32()); - break; - } - case 2: { - message.skip_rebuild = reader.bool(); - break; - } - case 3: { - if (!(message.rebuild_cells && message.rebuild_cells.length)) - message.rebuild_cells = []; - message.rebuild_cells.push(reader.string()); - break; - } - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an ApplyMirrorRulesRequest message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ApplyMirrorRulesRequest.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an ApplyMirrorRulesRequest message. - * @function verify - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ApplyMirrorRulesRequest.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) { - let error = $root.vschema.MirrorRules.verify(message.mirror_rules); - if (error) - return "mirror_rules." + error; - } - if (message.skip_rebuild != null && message.hasOwnProperty("skip_rebuild")) - if (typeof message.skip_rebuild !== "boolean") - return "skip_rebuild: boolean expected"; - if (message.rebuild_cells != null && message.hasOwnProperty("rebuild_cells")) { - if (!Array.isArray(message.rebuild_cells)) - return "rebuild_cells: array expected"; - for (let i = 0; i < message.rebuild_cells.length; ++i) - if (!$util.isString(message.rebuild_cells[i])) - return "rebuild_cells: string[] expected"; - } - return null; - }; - - /** - * Creates an ApplyMirrorRulesRequest message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {Object.} object Plain object - * @returns {vtctldata.ApplyMirrorRulesRequest} ApplyMirrorRulesRequest - */ - ApplyMirrorRulesRequest.fromObject = function fromObject(object) { - if (object instanceof $root.vtctldata.ApplyMirrorRulesRequest) - return object; - let message = new $root.vtctldata.ApplyMirrorRulesRequest(); - if (object.mirror_rules != null) { - if (typeof object.mirror_rules !== "object") - throw TypeError(".vtctldata.ApplyMirrorRulesRequest.mirror_rules: object expected"); - message.mirror_rules = $root.vschema.MirrorRules.fromObject(object.mirror_rules); - } - if (object.skip_rebuild != null) - message.skip_rebuild = Boolean(object.skip_rebuild); - if (object.rebuild_cells) { - if (!Array.isArray(object.rebuild_cells)) - throw TypeError(".vtctldata.ApplyMirrorRulesRequest.rebuild_cells: array expected"); - message.rebuild_cells = []; - for (let i = 0; i < object.rebuild_cells.length; ++i) - message.rebuild_cells[i] = String(object.rebuild_cells[i]); - } - return message; - }; - - /** - * Creates a plain object from an ApplyMirrorRulesRequest message. Also converts values to other types if specified. - * @function toObject - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {vtctldata.ApplyMirrorRulesRequest} message ApplyMirrorRulesRequest - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ApplyMirrorRulesRequest.toObject = function toObject(message, options) { - if (!options) - options = {}; - let object = {}; - if (options.arrays || options.defaults) - object.rebuild_cells = []; - if (options.defaults) { - object.mirror_rules = null; - object.skip_rebuild = false; - } - if (message.mirror_rules != null && message.hasOwnProperty("mirror_rules")) - object.mirror_rules = $root.vschema.MirrorRules.toObject(message.mirror_rules, options); - if (message.skip_rebuild != null && message.hasOwnProperty("skip_rebuild")) - object.skip_rebuild = message.skip_rebuild; - if (message.rebuild_cells && message.rebuild_cells.length) { - object.rebuild_cells = []; - for (let j = 0; j < message.rebuild_cells.length; ++j) - object.rebuild_cells[j] = message.rebuild_cells[j]; - } - return object; - }; - - /** - * Converts this ApplyMirrorRulesRequest to JSON. - * @function toJSON - * @memberof vtctldata.ApplyMirrorRulesRequest - * @instance - * @returns {Object.} JSON object - */ - ApplyMirrorRulesRequest.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * Gets the default type url for ApplyMirrorRulesRequest - * @function getTypeUrl - * @memberof vtctldata.ApplyMirrorRulesRequest - * @static - * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns {string} The default type url - */ - ApplyMirrorRulesRequest.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/vtctldata.ApplyMirrorRulesRequest"; - }; - - return ApplyMirrorRulesRequest; - })(); - - vtctldata.ApplyMirrorRulesResponse = (function() { - - /** - * Properties of an ApplyMirrorRulesResponse. - * @memberof vtctldata - * @interface IApplyMirrorRulesResponse - */ - - /** - * Constructs a new ApplyMirrorRulesResponse. - * @memberof vtctldata - * @classdesc Represents an ApplyMirrorRulesResponse. - * @implements IApplyMirrorRulesResponse - * @constructor - * @param {vtctldata.IApplyMirrorRulesResponse=} [properties] Properties to set - */ - function ApplyMirrorRulesResponse(properties) { - if (properties) - for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } - - /** - * Creates a new ApplyMirrorRulesResponse instance using the specified properties. - * @function create - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {vtctldata.IApplyMirrorRulesResponse=} [properties] Properties to set - * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse instance - */ - ApplyMirrorRulesResponse.create = function create(properties) { - return new ApplyMirrorRulesResponse(properties); - }; - - /** - * Encodes the specified ApplyMirrorRulesResponse message. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. - * @function encode - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {vtctldata.IApplyMirrorRulesResponse} message ApplyMirrorRulesResponse message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ApplyMirrorRulesResponse.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - return writer; - }; - - /** - * Encodes the specified ApplyMirrorRulesResponse message, length delimited. Does not implicitly {@link vtctldata.ApplyMirrorRulesResponse.verify|verify} messages. - * @function encodeDelimited - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {vtctldata.IApplyMirrorRulesResponse} message ApplyMirrorRulesResponse message or plain object to encode - * @param {$protobuf.Writer} [writer] Writer to encode to - * @returns {$protobuf.Writer} Writer - */ - ApplyMirrorRulesResponse.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - /** - * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer. - * @function decode - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @param {number} [length] Message length if known beforehand - * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ApplyMirrorRulesResponse.decode = function decode(reader, length) { - if (!(reader instanceof $Reader)) - reader = $Reader.create(reader); - let end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ApplyMirrorRulesResponse(); - while (reader.pos < end) { - let tag = reader.uint32(); - switch (tag >>> 3) { - default: - reader.skipType(tag & 7); - break; - } - } - return message; - }; - - /** - * Decodes an ApplyMirrorRulesResponse message from the specified reader or buffer, length delimited. - * @function decodeDelimited - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from - * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse - * @throws {Error} If the payload is not a reader or valid buffer - * @throws {$protobuf.util.ProtocolError} If required fields are missing - */ - ApplyMirrorRulesResponse.decodeDelimited = function decodeDelimited(reader) { - if (!(reader instanceof $Reader)) - reader = new $Reader(reader); - return this.decode(reader, reader.uint32()); - }; - - /** - * Verifies an ApplyMirrorRulesResponse message. - * @function verify - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {Object.} message Plain object to verify - * @returns {string|null} `null` if valid, otherwise the reason why it is not - */ - ApplyMirrorRulesResponse.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - return null; - }; - - /** - * Creates an ApplyMirrorRulesResponse message from a plain object. Also converts values to their respective internal types. - * @function fromObject - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {Object.} object Plain object - * @returns {vtctldata.ApplyMirrorRulesResponse} ApplyMirrorRulesResponse - */ - ApplyMirrorRulesResponse.fromObject = function fromObject(object) { - if (object instanceof $root.vtctldata.ApplyMirrorRulesResponse) - return object; - return new $root.vtctldata.ApplyMirrorRulesResponse(); - }; - - /** - * Creates a plain object from an ApplyMirrorRulesResponse message. Also converts values to other types if specified. - * @function toObject - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {vtctldata.ApplyMirrorRulesResponse} message ApplyMirrorRulesResponse - * @param {$protobuf.IConversionOptions} [options] Conversion options - * @returns {Object.} Plain object - */ - ApplyMirrorRulesResponse.toObject = function toObject() { - return {}; - }; - - /** - * Converts this ApplyMirrorRulesResponse to JSON. - * @function toJSON - * @memberof vtctldata.ApplyMirrorRulesResponse - * @instance - * @returns {Object.} JSON object - */ - ApplyMirrorRulesResponse.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - /** - * Gets the default type url for ApplyMirrorRulesResponse - * @function getTypeUrl - * @memberof vtctldata.ApplyMirrorRulesResponse - * @static - * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") - * @returns {string} The default type url - */ - ApplyMirrorRulesResponse.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/vtctldata.ApplyMirrorRulesResponse"; - }; - - return ApplyMirrorRulesResponse; - })(); - vtctldata.GetMirrorRulesRequest = (function() { /** From 2a786e52dadbef030f5bb1b64e7488456a38e116 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Fri, 21 Jun 2024 19:32:22 -0400 Subject: [PATCH 08/27] add support for vtgate traffic mirroring (query serving) Signed-off-by: Max Englander --- go/test/vschemawrapper/vschema_wrapper.go | 14 + go/vt/vtgate/bench_test.go | 1 - go/vt/vtgate/endtoend/main_test.go | 72 ++++ go/vt/vtgate/endtoend/mirror_test.go | 180 ++++++++ go/vt/vtgate/endtoend/schema.sql | 12 +- go/vt/vtgate/endtoend/vstream_test.go | 10 +- go/vt/vtgate/engine/cached_size.go | 38 +- go/vt/vtgate/engine/fake_vcursor_test.go | 27 ++ go/vt/vtgate/engine/mirror.go | 219 ++++++++++ go/vt/vtgate/engine/mirror_test.go | 382 +++++++++++++++++ go/vt/vtgate/engine/plan.go | 14 +- go/vt/vtgate/engine/primitive.go | 3 + go/vt/vtgate/executor_select_test.go | 57 +++ go/vt/vtgate/logstats/logstats.go | 11 +- go/vt/vtgate/logstats/logstats_test.go | 6 +- go/vt/vtgate/planbuilder/builder.go | 116 ++++- go/vt/vtgate/planbuilder/ddl.go | 2 +- go/vt/vtgate/planbuilder/operators/delete.go | 9 +- go/vt/vtgate/planbuilder/operators/helpers.go | 74 ++-- go/vt/vtgate/planbuilder/operators/insert.go | 9 +- go/vt/vtgate/planbuilder/operators/route.go | 6 +- go/vt/vtgate/planbuilder/operators/table.go | 9 +- go/vt/vtgate/planbuilder/operators/update.go | 9 +- go/vt/vtgate/planbuilder/operators/vindex.go | 9 +- go/vt/vtgate/planbuilder/plan_test.go | 41 ++ .../planbuilder/plancontext/mirror_vschema.go | 265 ++++++++++++ .../vtgate/planbuilder/plancontext/vschema.go | 4 + go/vt/vtgate/planbuilder/select.go | 12 +- .../planbuilder/single_sharded_shortcut.go | 2 +- .../planbuilder/testdata/mirror_cases.json | 397 ++++++++++++++++++ .../testdata/vschemas/mirror_schema.json | 99 +++++ go/vt/vtgate/planbuilder/vexplain.go | 7 +- go/vt/vtgate/sandbox_test.go | 13 + go/vt/vtgate/vcursor_impl.go | 50 ++- go/vt/vtgate/vindexes/vschema.go | 260 +++++++++++- go/vt/vtgate/vindexes/vschema_test.go | 287 ++++++++++++- go/vt/vtgate/vschema_manager_test.go | 4 + .../tabletserver/vstreamer/engine_test.go | 1 + 38 files changed, 2631 insertions(+), 100 deletions(-) create mode 100644 go/vt/vtgate/endtoend/mirror_test.go create mode 100644 go/vt/vtgate/engine/mirror.go create mode 100644 go/vt/vtgate/engine/mirror_test.go create mode 100644 go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go create mode 100644 go/vt/vtgate/planbuilder/testdata/mirror_cases.json create mode 100644 go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json diff --git a/go/test/vschemawrapper/vschema_wrapper.go b/go/test/vschemawrapper/vschema_wrapper.go index 4d1c424dda8..e7214783595 100644 --- a/go/test/vschemawrapper/vschema_wrapper.go +++ b/go/test/vschemawrapper/vschema_wrapper.go @@ -342,3 +342,17 @@ func (vw *VSchemaWrapper) FindRoutedShard(keyspace, shard string) (string, error func (vw *VSchemaWrapper) IsViewsEnabled() bool { return vw.EnableViews } + +// FindMirrorRule finds the mirror rule for the requested keyspace, table +// name, and the tablet type in the VSchema. +func (vs *VSchemaWrapper) FindMirrorRule(tab sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { + destKeyspace, destTabletType, dest, err := topoproto.ParseDestination(tab.Qualifier.String(), topodatapb.TabletType_PRIMARY) + if err != nil { + return nil, "", destTabletType, nil, err + } + mirrorRule, err := vs.V.FindMirrorRule(destKeyspace, tab.Name.String(), destTabletType) + if err != nil { + return nil, "", destTabletType, nil, err + } + return mirrorRule, destKeyspace, destTabletType, dest, err +} diff --git a/go/vt/vtgate/bench_test.go b/go/vt/vtgate/bench_test.go index 5c64c7e3473..5da1af896d0 100644 --- a/go/vt/vtgate/bench_test.go +++ b/go/vt/vtgate/bench_test.go @@ -54,7 +54,6 @@ func init() { fmt.Fprintf(buf, " and v%d = '%d%s'", i, i, baseval.String()) } benchQuery = buf.String() - // fmt.Printf("len: %d\n", len(benchQuery)) } func BenchmarkWithNormalizer(b *testing.B) { diff --git a/go/vt/vtgate/endtoend/main_test.go b/go/vt/vtgate/endtoend/main_test.go index b471786b78e..8f8cfb4b5a3 100644 --- a/go/vt/vtgate/endtoend/main_test.go +++ b/go/vt/vtgate/endtoend/main_test.go @@ -166,6 +166,18 @@ var ( Type: sqltypes.Char, }}, }, + "mirror_tbl1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + }, + "mirror_tbl2": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + }, }, } @@ -175,6 +187,11 @@ create table t1_copy_all_ks2( id2 bigint, primary key(id1) ) Engine=InnoDB; + +create table mirror_tbl1( + id bigint not null, + primary key(id) +) Engine=InnoDB; ` vschema2 = &vschemapb.Keyspace{ @@ -191,6 +208,48 @@ create table t1_copy_all_ks2( Name: "hash", }}, }, + "mirror_tbl1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + }, + }, + } + + schema3 = ` +create table t1_copy_all_ks3( + id1 bigint, + id2 bigint, + primary key(id1) +) Engine=InnoDB; + +create table mirror_tbl2( + id bigint not null, + primary key(id) +) Engine=InnoDB; +` + + vschema3 = &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "hash": { + Type: "hash", + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1_copy_all_ks3": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id1", + Name: "hash", + }}, + }, + "mirror_tbl2": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Column: "id", + Name: "hash", + }}, + }, }, } ) @@ -218,6 +277,14 @@ func TestMain(m *testing.M) { Name: "80-", }}, }, + { + Name: "ks3", + Shards: []*vttestpb.Shard{{ + Name: "-80", + }, { + Name: "80-", + }}, + }, }, } if err := cfg.InitSchemas("ks", Schema, vschema); err != nil { @@ -231,6 +298,11 @@ func TestMain(m *testing.M) { os.RemoveAll(cfg.SchemaDir) return 1 } + if err := cfg.InitSchemas("ks3", schema3, vschema3); err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + os.RemoveAll(cfg.SchemaDir) + return 1 + } cluster = &vttest.LocalCluster{ Config: cfg, diff --git a/go/vt/vtgate/endtoend/mirror_test.go b/go/vt/vtgate/endtoend/mirror_test.go new file mode 100644 index 00000000000..26175d1a8a8 --- /dev/null +++ b/go/vt/vtgate/endtoend/mirror_test.go @@ -0,0 +1,180 @@ +package endtoend + +import ( + "bytes" + "context" + "fmt" + "math/rand" + osExec "os/exec" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" +) + +var mirrorInitOnce sync.Once + +func BenchmarkMirror(b *testing.B) { + const numRows = 10000 + + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + if err != nil { + b.Fatal(err) + } + defer conn.Close() + + var query bytes.Buffer + + mirrorInitOnce.Do(func() { + b.Logf("seeding database for benchmark...") + + for i := 0; i < numRows; i++ { + query.Reset() + query.WriteString(fmt.Sprintf("INSERT INTO ks.mirror_tbl1(id) VALUES(%d)", i)) + _, err = conn.ExecuteFetch(query.String(), -1, false) + if err != nil { + b.Fatal(err) + } + + query.Reset() + query.WriteString(fmt.Sprintf("INSERT INTO ks2.mirror_tbl1(id) VALUES(%d)", i)) + _, err = conn.ExecuteFetch(query.String(), -1, false) + if err != nil { + b.Fatal(err) + } + + query.Reset() + query.WriteString(fmt.Sprintf("INSERT INTO ks.mirror_tbl2(id) VALUES(%d)", i)) + _, err = conn.ExecuteFetch(query.String(), -1, false) + if err != nil { + b.Fatal(err) + } + + query.Reset() + query.WriteString(fmt.Sprintf("INSERT INTO ks3.mirror_tbl2(id) VALUES(%d)", i)) + _, err = conn.ExecuteFetch(query.String(), -1, false) + if err != nil { + b.Fatal(err) + } + } + + b.Logf("finished (inserted %d rows)", numRows) + }) + + testCases := []struct { + name string + run func(*testing.B, *rand.Rand) + }{ + { + name: "point select, { ks => ks1 }.tbl1", + run: func(b *testing.B, rnd *rand.Rand) { + for i := 0; i < b.N; i++ { + id := rnd.Intn(numRows) + query.Reset() + _, _ = fmt.Fprintf( + &query, + "SELECT t1.id, t2.id FROM ks.mirror_tbl1 AS t1, ks.mirror_tbl2 AS t2 WHERE t1.id = %d AND t2.id = %d", + id, id, + ) + _, err := conn.ExecuteFetch(query.String(), 1, false) + if err != nil { + b.Error(err) + } + } + }, + }, + { + name: "point select, { ks => ks2 }.tbl1, { ks => ks3 }.tbl2", + run: func(b *testing.B, rnd *rand.Rand) { + for i := 0; i < b.N; i++ { + id := rnd.Intn(numRows) + query.Reset() + _, _ = fmt.Fprintf( + &query, + "SELECT t1.id, t2.id FROM ks.mirror_tbl1 AS t1, ks.mirror_tbl2 AS t2 WHERE t1.id = %d AND t2.id = %d", + id, id, + ) + _, err := conn.ExecuteFetch(query.String(), 1, false) + if err != nil { + b.Error(err) + } + } + }, + }, + } + + // Each time this BenchmarkMirror runs, use a different source of + // random-ness. But use the same source of randomness across test cases and + // mirror percentages sub-tests. + randSeed := time.Now().UnixNano() + + for _, tc := range testCases { + b.Run(tc.name, func(b *testing.B) { + b.Run("mirror 0%", func(b *testing.B) { + mirrorTraffic(b, 0) + b.ResetTimer() + tc.run(b, rand.New(rand.NewSource(randSeed))) + }) + + b.Run("mirror 1%", func(b *testing.B) { + mirrorTraffic(b, 1) + b.ResetTimer() + tc.run(b, rand.New(rand.NewSource(randSeed))) + }) + + b.Run("mirror 5%", func(b *testing.B) { + mirrorTraffic(b, 5) + b.ResetTimer() + tc.run(b, rand.New(rand.NewSource(randSeed))) + }) + + b.Run("mirror 10%", func(b *testing.B) { + mirrorTraffic(b, 10) + b.ResetTimer() + tc.run(b, rand.New(rand.NewSource(randSeed))) + }) + + b.Run("mirror 25%", func(b *testing.B) { + mirrorTraffic(b, 25) + b.ResetTimer() + tc.run(b, rand.New(rand.NewSource(randSeed))) + }) + + b.Run("mirror 50%", func(b *testing.B) { + mirrorTraffic(b, 50) + b.ResetTimer() + tc.run(b, rand.New(rand.NewSource(randSeed))) + }) + + b.Run("mirror 100%", func(b *testing.B) { + mirrorTraffic(b, 100) + b.ResetTimer() + tc.run(b, rand.New(rand.NewSource(randSeed))) + }) + }) + } +} + +func mirrorTraffic(b *testing.B, percent float32) { + server := fmt.Sprintf("localhost:%v", cluster.VTProcess().PortGrpc) + rules := fmt.Sprintf(`{ + "rules": [ + { + "from_table": "ks.mirror_tbl1", + "to_table": "ks2.mirror_tbl1", + "percent": %f + }, + { + "from_table": "ks.mirror_tbl2", + "to_table": "ks3.mirror_tbl2", + "percent": %f + } + ] + }`, percent, percent) + _, err := osExec.Command("vtctldclient", "--server", server, "ApplyMirrorRules", "--rules", rules).CombinedOutput() + require.NoError(b, err) +} diff --git a/go/vt/vtgate/endtoend/schema.sql b/go/vt/vtgate/endtoend/schema.sql index d543d130c14..4713c9057cf 100644 --- a/go/vt/vtgate/endtoend/schema.sql +++ b/go/vt/vtgate/endtoend/schema.sql @@ -79,4 +79,14 @@ create table oltp_test( c char(120) default '' not null, pad char(60) default '' not null, primary key (id) -) Engine=InnoDB; \ No newline at end of file +) Engine=InnoDB; + +create table mirror_tbl1( + id bigint not null, + primary key(id) +) Engine=InnoDB; + +create table mirror_tbl2( + id bigint not null, + primary key(id) +) Engine=InnoDB; diff --git a/go/vt/vtgate/endtoend/vstream_test.go b/go/vt/vtgate/endtoend/vstream_test.go index 246d17f88b5..1381b9448bd 100644 --- a/go/vt/vtgate/endtoend/vstream_test.go +++ b/go/vt/vtgate/endtoend/vstream_test.go @@ -279,6 +279,11 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { require.NoError(t, err) } + _, err = conn.ExecuteFetch("insert into t1_copy_all_ks3(id1,id2) values(30,30), (40,40)", 1, false) + if err != nil { + require.NoError(t, err) + } + filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ Match: "/t1_copy_all.*/", @@ -303,6 +308,7 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { // copy phase operations in the vstream. expectedKs1EventNum := 2 /* num shards */ * (9 /* begin/field/vgtid:pos/4 rowevents avg/vgitd: lastpk/commit) */ + 3 /* begin/vgtid/commit for completed table */ + 1 /* copy operation completed */) expectedKs2EventNum := 2 /* num shards */ * (6 /* begin/field/vgtid:pos/1 rowevents avg/vgitd: lastpk/commit) */ + 3 /* begin/vgtid/commit for completed table */ + 1 /* copy operation completed */) + expectedKs3EventNum := 2 /* num shards */ * (6 /* begin/field/vgtid:pos/1 rowevents avg/vgitd: lastpk/commit) */ + 3 /* begin/vgtid/commit for completed table */ + 1 /* copy operation completed */) expectedFullyCopyCompletedNum := 1 cases := []struct { @@ -316,12 +322,14 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { shardGtid: &binlogdatapb.ShardGtid{ Keyspace: "/.*", }, - expectedEventNum: expectedKs1EventNum + expectedKs2EventNum + expectedFullyCopyCompletedNum, + expectedEventNum: expectedKs1EventNum + expectedKs2EventNum + expectedKs3EventNum + expectedFullyCopyCompletedNum, expectedCompletedEvents: []string{ `type:COPY_COMPLETED keyspace:"ks" shard:"-80"`, `type:COPY_COMPLETED keyspace:"ks" shard:"80-"`, `type:COPY_COMPLETED keyspace:"ks2" shard:"-80"`, `type:COPY_COMPLETED keyspace:"ks2" shard:"80-"`, + `type:COPY_COMPLETED keyspace:"ks3" shard:"-80"`, + `type:COPY_COMPLETED keyspace:"ks3" shard:"80-"`, `type:COPY_COMPLETED`, }, }, diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index e65ff61a9f6..500587d0754 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -731,6 +731,24 @@ func (cached *MergeSort) CachedSize(alloc bool) int64 { } return size } +func (cached *Mirror) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(32) + } + // field Primitive vitess.io/vitess/go/vt/vtgate/engine.Primitive + if cc, ok := cached.Primitive.(cachedObject); ok { + size += cc.CachedSize(true) + } + // field Target vitess.io/vitess/go/vt/vtgate/engine.MirrorTarget + if cc, ok := cached.Target.(cachedObject); ok { + size += cc.CachedSize(true) + } + return size +} func (cached *NonLiteralUpdateInfo) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -795,6 +813,20 @@ func (cached *OrderedAggregate) CachedSize(alloc bool) int64 { } return size } +func (cached *PercentMirrorTarget) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(24) + } + // field Primitive vitess.io/vitess/go/vt/vtgate/engine.Primitive + if cc, ok := cached.Primitive.(cachedObject); ok { + size += cc.CachedSize(true) + } + return size +} func (cached *Plan) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -818,11 +850,11 @@ func (cached *Plan) CachedSize(alloc bool) int64 { size += elem.CachedSize(true) } } - // field TablesUsed []string + // field TablesUsed vitess.io/vitess/go/vt/sqlparser.TableNames { - size += hack.RuntimeAllocSize(int64(cap(cached.TablesUsed)) * int64(16)) + size += hack.RuntimeAllocSize(int64(cap(cached.TablesUsed)) * int64(32)) for _, elem := range cached.TablesUsed { - size += hack.RuntimeAllocSize(int64(len(elem))) + size += elem.CachedSize(false) } } return size diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 1ba0abfa2ef..1a4d76bdc03 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -112,6 +112,10 @@ func (t *noopVCursor) CloneForReplicaWarming(ctx context.Context) VCursor { panic("implement me") } +func (t *noopVCursor) CloneForMirroring(ctx context.Context) VCursor { + panic("implement me") +} + func (t *noopVCursor) SetExec(ctx context.Context, name string, value string) error { panic("implement me") } @@ -421,6 +425,10 @@ type loggingVCursor struct { shardSession []*srvtopo.ResolvedShard parser *sqlparser.Parser + + handleMirrorClonesFn func(context.Context) VCursor + onExecuteMultiShardFn func(context.Context, Primitive, []*srvtopo.ResolvedShard, []*querypb.BoundQuery, bool, bool) + onStreamExecuteMultiFn func(context.Context, Primitive, string, []*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, bool, bool, func(*sqltypes.Result) error) } func (f *loggingVCursor) HasCreatedTempTable() { @@ -536,6 +544,13 @@ func (f *loggingVCursor) CloneForReplicaWarming(ctx context.Context) VCursor { return f } +func (f *loggingVCursor) CloneForMirroring(ctx context.Context) VCursor { + if f.handleMirrorClonesFn != nil { + return f.handleMirrorClonesFn(ctx) + } + panic("no mirror clones available") +} + func (f *loggingVCursor) Execute(ctx context.Context, method string, query string, bindvars map[string]*querypb.BindVariable, rollbackOnError bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error) { name := "Unknown" switch co { @@ -553,7 +568,12 @@ func (f *loggingVCursor) Execute(ctx context.Context, method string, query strin } func (f *loggingVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { + f.mu.Lock() + defer f.mu.Unlock() f.log = append(f.log, fmt.Sprintf("ExecuteMultiShard %v%v %v", printResolvedShardQueries(rss, queries), rollbackOnError, canAutocommit)) + if f.onExecuteMultiShardFn != nil { + f.onExecuteMultiShardFn(ctx, primitive, rss, queries, rollbackOnError, canAutocommit) + } res, err := f.nextResult() if err != nil { return nil, []error{err} @@ -574,6 +594,9 @@ func (f *loggingVCursor) ExecuteStandalone(ctx context.Context, primitive Primit func (f *loggingVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error { f.mu.Lock() f.log = append(f.log, fmt.Sprintf("StreamExecuteMulti %s %s", query, printResolvedShardsBindVars(rss, bindVars))) + if f.onStreamExecuteMultiFn != nil { + f.onStreamExecuteMultiFn(ctx, primitive, query, rss, bindVars, rollbackOnError, autocommit, callback) + } r, err := f.nextResult() f.mu.Unlock() if err != nil { @@ -725,6 +748,8 @@ func (f *loggingVCursor) ResolveDestinationsMultiCol(ctx context.Context, keyspa func (f *loggingVCursor) ExpectLog(t *testing.T, want []string) { t.Helper() + f.mu.Lock() + defer f.mu.Unlock() if len(f.log) == 0 && len(want) == 0 { return } @@ -742,6 +767,8 @@ func (f *loggingVCursor) ExpectWarnings(t *testing.T, want []*querypb.QueryWarni } func (f *loggingVCursor) Rewind() { + f.mu.Lock() + defer f.mu.Unlock() f.curShardForKsid = 0 f.curResult = 0 f.log = nil diff --git a/go/vt/vtgate/engine/mirror.go b/go/vt/vtgate/engine/mirror.go new file mode 100644 index 00000000000..2cfc447c7a0 --- /dev/null +++ b/go/vt/vtgate/engine/mirror.go @@ -0,0 +1,219 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + "math/rand" + "time" + + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" +) + +type ( + // Mirror represents the instructions to execute an authoritative source, + // and compare the results of that execution to those of one or more + // non-authoritative mirroring targets. + Mirror struct { + Primitive Primitive + Target MirrorTarget + } + + // MirrorTarget contains the Primitive for mirroring a query to the + // non-authoritative target of the Mirror primitive. + MirrorTarget interface { + Primitive + Accept() bool + } + + // PercentMirrorTarget contains the Primitive to mirror to, an will + // Accept() an execution based if a random dice-roll is less than Percent. + PercentMirrorTarget struct { + Percent float32 + Primitive Primitive + } +) + +const ( + // maxMirrorTargetLag limits how long a mirror target may continue + // executing after the main primitive has finished. + maxMirrorTargetLag = 100 * time.Millisecond +) + +var ( + _ Primitive = (*Mirror)(nil) + _ Primitive = (MirrorTarget)(nil) + _ Primitive = (*PercentMirrorTarget)(nil) + _ MirrorTarget = (*PercentMirrorTarget)(nil) +) + +// NewMirror creates a Mirror. +func NewMirror(primitive Primitive, target MirrorTarget) *Mirror { + return &Mirror{primitive, target} +} + +// NewPercentMirrorTarget creates a percentage-based Mirror target. +func NewPercentMirrorTarget(percent float32, primitive Primitive) *PercentMirrorTarget { + return &PercentMirrorTarget{percent, primitive} +} + +func (m *Mirror) RouteType() string { + return "Mirror" +} + +func (m *Mirror) GetKeyspaceName() string { + return m.Primitive.GetKeyspaceName() +} + +func (m *Mirror) GetTableName() string { + return m.Primitive.GetTableName() +} + +func (m *Mirror) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return m.Primitive.GetFields(ctx, vcursor, bindVars) +} + +func (m *Mirror) NeedsTransaction() bool { + return m.Primitive.NeedsTransaction() +} + +func (m *Mirror) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { + var mirrorCh chan any + var mirrorCtxCancel func() + + if m.Target.Accept() { + mirrorCh = make(chan any) + + var mirrorCtx context.Context + mirrorCtx, mirrorCtxCancel = context.WithCancel(ctx) + defer mirrorCtxCancel() + + go func(target Primitive, vcursor VCursor) { + defer close(mirrorCh) + _, _ = target.TryExecute(mirrorCtx, vcursor, bindVars, wantfields) + }(m.Target, vcursor.CloneForMirroring(mirrorCtx)) + } + + r, err := m.Primitive.TryExecute(ctx, vcursor, bindVars, wantfields) + + if mirrorCh != nil { + select { + case <-mirrorCh: + case <-time.After(maxMirrorTargetLag): + mirrorCtxCancel() + } + } + + return r, err +} + +func (m *Mirror) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + var mirrorCn chan any + var mirrorCtxCancel func() + + if m.Target.Accept() { + mirrorCn = make(chan any) + + var mirrorCtx context.Context + mirrorCtx, mirrorCtxCancel = context.WithCancel(ctx) + defer mirrorCtxCancel() + + go func(target Primitive, vcursor VCursor) { + defer close(mirrorCn) + _ = target.TryStreamExecute(mirrorCtx, vcursor, bindVars, wantfields, func(_ *sqltypes.Result) error { + return nil + }) + }(m.Target, vcursor.CloneForMirroring(mirrorCtx)) + } + + err := m.Primitive.TryStreamExecute(ctx, vcursor, bindVars, wantfields, callback) + + if mirrorCn != nil { + select { + case <-mirrorCn: + case <-time.After(maxMirrorTargetLag): + mirrorCtxCancel() + } + } + + return err +} + +// Inputs is a slice containing the inputs to this Primitive. +// The returned map has additional information about the inputs, that is used in the description. +func (m *Mirror) Inputs() ([]Primitive, []map[string]any) { + return []Primitive{m.Primitive, m.Target}, nil +} + +// description is the description, sans the inputs, of this Primitive. +// to get the plan description with all children, use PrimitiveToPlanDescription() +func (m *Mirror) description() PrimitiveDescription { + return PrimitiveDescription{ + OperatorType: "Mirror", + } +} + +func (m *PercentMirrorTarget) RouteType() string { + return "PercentMirrorTarget" +} + +func (m *PercentMirrorTarget) GetKeyspaceName() string { + return m.Primitive.GetKeyspaceName() +} + +func (m *PercentMirrorTarget) GetTableName() string { + return m.Primitive.GetTableName() +} + +func (m *PercentMirrorTarget) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return m.Primitive.GetFields(ctx, vcursor, bindVars) +} + +func (m *PercentMirrorTarget) NeedsTransaction() bool { + return m.Primitive.NeedsTransaction() +} + +func (m *PercentMirrorTarget) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { + return m.Primitive.TryExecute(ctx, vcursor, bindVars, wantfields) +} + +func (m *PercentMirrorTarget) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + return m.Primitive.TryStreamExecute(ctx, vcursor, bindVars, wantfields, callback) +} + +// Inputs is a slice containing the inputs to this Primitive. +// The returned map has additional information about the inputs, that is used in the description. +func (m *PercentMirrorTarget) Inputs() ([]Primitive, []map[string]any) { + return []Primitive{m.Primitive}, nil +} + +// description is the description, sans the inputs, of this Primitive. +// to get the plan description with all children, use PrimitiveToPlanDescription() +func (m *PercentMirrorTarget) description() PrimitiveDescription { + return PrimitiveDescription{ + OperatorType: "MirrorTarget", + Variant: "Percent", + Other: map[string]any{ + "Percent": m.Percent, + }, + } +} + +func (m *PercentMirrorTarget) Accept() bool { + return m.Percent >= (rand.Float32() * 100.0) +} diff --git a/go/vt/vtgate/engine/mirror_test.go b/go/vt/vtgate/engine/mirror_test.go new file mode 100644 index 00000000000..2777b6c35b2 --- /dev/null +++ b/go/vt/vtgate/engine/mirror_test.go @@ -0,0 +1,382 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + "fmt" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/vtgate/evalengine" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +func TestMirror(t *testing.T) { + vindex, _ := vindexes.CreateVindex("xxhash", "xxhash_vdx", nil) + + primitive := NewRoute( + Unsharded, + &vindexes.Keyspace{ + Name: "ks1", + }, + "select f.bar from foo f where f.id = 1", + "select 1 from foo f where f.id = 1 and 1 != 1", + ) + + mirrorPrimitive1 := NewRoute( + EqualUnique, + &vindexes.Keyspace{ + Name: "ks2", + Sharded: true, + }, + "select f.bar from foo f where f.id = 1", + "select 1 from foo f where f.id = 1 and 1 != 1", + ) + mirrorPrimitive1.Vindex = vindex.(vindexes.SingleColumn) + mirrorPrimitive1.Values = []evalengine.Expr{ + evalengine.NewLiteralInt(1), + } + + mirror := &Mirror{ + Primitive: primitive, + Target: &PercentMirrorTarget{ + Percent: 100, + Primitive: mirrorPrimitive1, + }, + } + + mirrorVC := &loggingVCursor{ + shards: []string{"-20", "20-"}, + ksShardMap: map[string][]string{ + "ks2": {"-20", "20-"}, + }, + results: []*sqltypes.Result{ + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "bar", + "varchar", + ), + "hello", + ), + }, + } + + vc := &loggingVCursor{ + shards: []string{"0"}, + ksShardMap: map[string][]string{ + "ks1": {"0"}, + }, + results: []*sqltypes.Result{ + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "bar", + "varchar", + ), + "hello", + ), + }, + handleMirrorClonesFn: func(ctx context.Context) VCursor { + return mirrorVC + }, + } + + t.Run("TryExecute success", func(t *testing.T) { + defer func() { + vc.Rewind() + mirrorVC.Rewind() + }() + + want := vc.results[0] + res, err := mirror.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, true) + require.Equal(t, want, res) + require.NoError(t, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "ExecuteMultiShard ks1.0: select f.bar from foo f where f.id = 1 {} false false", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "ExecuteMultiShard ks2.-20: select f.bar from foo f where f.id = 1 {} false false", + }) + }) + + t.Run("TryExecute return primitive error", func(t *testing.T) { + results := vc.results + + defer func() { + vc.Rewind() + vc.results = results + vc.resultErr = nil + mirrorVC.Rewind() + }() + + vc.results = nil + vc.resultErr = fmt.Errorf("return me") + + ctx := context.Background() + res, err := mirror.TryExecute(ctx, vc, map[string]*querypb.BindVariable{}, true) + require.Nil(t, res) + require.Error(t, err) + require.Equal(t, vc.resultErr, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "ExecuteMultiShard ks1.0: select f.bar from foo f where f.id = 1 {} false false", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "ExecuteMultiShard ks2.-20: select f.bar from foo f where f.id = 1 {} false false", + }) + }) + + t.Run("TryExecute ignore mirror target error", func(t *testing.T) { + results := mirrorVC.results + + defer func() { + vc.Rewind() + mirrorVC.Rewind() + mirrorVC.results = results + mirrorVC.resultErr = nil + }() + + mirrorVC.results = nil + mirrorVC.resultErr = fmt.Errorf("ignore me") + + want := vc.results[0] + res, err := mirror.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, true) + require.Equal(t, res, want) + require.NoError(t, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "ExecuteMultiShard ks1.0: select f.bar from foo f where f.id = 1 {} false false", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "ExecuteMultiShard ks2.-20: select f.bar from foo f where f.id = 1 {} false false", + }) + }) + + t.Run("TryExecute slow mirror target", func(t *testing.T) { + defer func() { + vc.Rewind() + vc.onExecuteMultiShardFn = nil + mirrorVC.Rewind() + mirrorVC.onExecuteMultiShardFn = nil + }() + + primitiveLatency := maxMirrorTargetLag * 2 + vc.onExecuteMultiShardFn = func(ctx context.Context, _ Primitive, _ []*srvtopo.ResolvedShard, _ []*querypb.BoundQuery, _ bool, _ bool) { + time.Sleep(primitiveLatency) + select { + case <-ctx.Done(): + require.Fail(t, "primitive context done") + default: + } + } + + var wg sync.WaitGroup + defer wg.Wait() + wg.Add(1) + mirrorVC.onExecuteMultiShardFn = func(ctx context.Context, _ Primitive, _ []*srvtopo.ResolvedShard, _ []*querypb.BoundQuery, _ bool, _ bool) { + defer wg.Done() + time.Sleep(primitiveLatency + (2 * maxMirrorTargetLag)) + select { + case <-ctx.Done(): + default: + require.Fail(t, "mirror target context not done") + } + } + + want := vc.results[0] + res, err := mirror.TryExecute(context.Background(), vc, map[string]*querypb.BindVariable{}, true) + require.Equal(t, res, want) + require.NoError(t, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "ExecuteMultiShard ks1.0: select f.bar from foo f where f.id = 1 {} false false", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "ExecuteMultiShard ks2.-20: select f.bar from foo f where f.id = 1 {} false false", + }) + }) + + t.Run("TryStreamExecute success", func(t *testing.T) { + defer func() { + vc.Rewind() + mirrorVC.Rewind() + }() + + want := vc.results[0] + err := mirror.TryStreamExecute( + context.Background(), + vc, + map[string]*querypb.BindVariable{}, + true, + func(result *sqltypes.Result) error { + require.Equal(t, want, result) + return nil + }, + ) + require.NoError(t, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks1.0: {} ", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks2.-20: {} ", + }) + }) + + t.Run("TryStreamExecute return primitive error", func(t *testing.T) { + results := vc.results + + defer func() { + vc.Rewind() + vc.results = results + vc.resultErr = nil + mirrorVC.Rewind() + }() + + vc.results = nil + vc.resultErr = fmt.Errorf("return me") + + err := mirror.TryStreamExecute( + context.Background(), + vc, + map[string]*querypb.BindVariable{}, + true, + func(result *sqltypes.Result) error { + require.Nil(t, result) + return nil + }, + ) + require.Error(t, err) + require.Equal(t, vc.resultErr, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks1.0: {} ", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks2.-20: {} ", + }) + }) + + t.Run("TryStreamExecute ignore mirror target error", func(t *testing.T) { + results := mirrorVC.results + + defer func() { + vc.Rewind() + mirrorVC.Rewind() + mirrorVC.results = results + mirrorVC.resultErr = nil + }() + + mirrorVC.results = nil + mirrorVC.resultErr = fmt.Errorf("ignore me") + + want := vc.results[0] + err := mirror.TryStreamExecute( + context.Background(), + vc, + map[string]*querypb.BindVariable{}, + true, + func(result *sqltypes.Result) error { + require.Equal(t, want, result) + return nil + }, + ) + require.NoError(t, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks1.0: {} ", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks2.-20: {} ", + }) + }) + + t.Run("TryStreamExecute slow mirror target", func(t *testing.T) { + defer func() { + vc.Rewind() + vc.onStreamExecuteMultiFn = nil + mirrorVC.Rewind() + mirrorVC.onStreamExecuteMultiFn = nil + }() + + primitiveLatency := maxMirrorTargetLag * 2 + vc.onStreamExecuteMultiFn = func(ctx context.Context, _ Primitive, _ string, _ []*srvtopo.ResolvedShard, _ []map[string]*querypb.BindVariable, _ bool, _ bool, _ func(*sqltypes.Result) error) { + time.Sleep(primitiveLatency) + select { + case <-ctx.Done(): + require.Fail(t, "primitive context done") + default: + } + } + + var wg sync.WaitGroup + defer wg.Wait() + wg.Add(1) + mirrorVC.onStreamExecuteMultiFn = func(ctx context.Context, _ Primitive, _ string, _ []*srvtopo.ResolvedShard, _ []map[string]*querypb.BindVariable, _ bool, _ bool, _ func(*sqltypes.Result) error) { + defer wg.Done() + time.Sleep(primitiveLatency + (2 * maxMirrorTargetLag)) + select { + case <-ctx.Done(): + default: + require.Fail(t, "mirror target context not done") + } + } + + want := vc.results[0] + err := mirror.TryStreamExecute( + context.Background(), + vc, + map[string]*querypb.BindVariable{}, + true, + func(result *sqltypes.Result) error { + require.Equal(t, want, result) + return nil + }, + ) + require.NoError(t, err) + + vc.ExpectLog(t, []string{ + "ResolveDestinations ks1 [] Destinations:DestinationAllShards()", + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks1.0: {} ", + }) + mirrorVC.ExpectLog(t, []string{ + `ResolveDestinations ks2 [type:INT64 value:"1"] Destinations:DestinationKeyspaceID(d46405367612b4b7)`, + "StreamExecuteMulti select f.bar from foo f where f.id = 1 ks2.-20: {} ", + }) + }) +} diff --git a/go/vt/vtgate/engine/plan.go b/go/vt/vtgate/engine/plan.go index 769c69aaa06..8de1ed808d5 100644 --- a/go/vt/vtgate/engine/plan.go +++ b/go/vt/vtgate/engine/plan.go @@ -19,6 +19,7 @@ package engine import ( "bytes" "encoding/json" + "fmt" "sync/atomic" "time" @@ -37,7 +38,7 @@ type Plan struct { Instructions Primitive // Instructions contains the instructions needed to fulfil the query. BindVarNeeds *sqlparser.BindVarNeeds // Stores BindVars needed to be provided as part of expression rewriting Warnings []*query.QueryWarning // Warnings that need to be yielded every time this query runs - TablesUsed []string // TablesUsed is the list of tables that this plan will query + TablesUsed sqlparser.TableNames // TablesUsed is the list of tables that this plan will query ExecCount uint64 // Count of times this plan was executed ExecTime uint64 // Total execution time @@ -76,6 +77,15 @@ func (p *Plan) MarshalJSON() ([]byte, error) { instructions = &description } + tablesUsed := make([]string, len(p.TablesUsed)) + for i, table := range p.TablesUsed { + if table.Qualifier.NotEmpty() { + tablesUsed[i] = fmt.Sprintf("%s.%s", table.Qualifier.String(), table.Name.String()) + } else { + tablesUsed[i] = table.Name.String() + } + } + marshalPlan := struct { QueryType string Original string `json:",omitempty"` @@ -97,7 +107,7 @@ func (p *Plan) MarshalJSON() ([]byte, error) { RowsAffected: atomic.LoadUint64(&p.RowsAffected), RowsReturned: atomic.LoadUint64(&p.RowsReturned), Errors: atomic.LoadUint64(&p.Errors), - TablesUsed: p.TablesUsed, + TablesUsed: tablesUsed, } b := new(bytes.Buffer) diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index 1c0e7de7a19..99b14e4a5af 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -131,6 +131,9 @@ type ( // CloneForReplicaWarming clones the VCursor for re-use in warming queries to replicas CloneForReplicaWarming(ctx context.Context) VCursor + + // CloneForMirroring clones the VCursor for re-use in mirroring queries to other keyspaces + CloneForMirroring(ctx context.Context) VCursor } // SessionActions gives primitives ability to interact with the session state diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index bd24907af9b..d88cb9e8e44 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -4335,3 +4335,60 @@ func TestStreamJoinQuery(t *testing.T) { utils.MustMatch(t, wantResult.Rows[idx], result.Rows[idx], "mismatched on: ", strconv.Itoa(idx)) } } + +func BenchmarkSelectMirror(b *testing.B) { + ctx := context.Background() + cell := "aa" + sql := fmt.Sprintf("select id from %s.user where id = 1", KsTestUnsharded) + + currentSandboxMirrorRules := sandboxMirrorRules + b.Cleanup(func() { + setSandboxMirrorRules(currentSandboxMirrorRules) + }) + + // Don't use createExecutorEnv. Doesn't work with benchmarks because of + // utils.EnsureNoLeak. + createBenchmarkExecutor := func(b *testing.B) (context.Context, *Executor) { + ctx, cancel := context.WithCancel(ctx) + b.Cleanup(cancel) + hc := discovery.NewFakeHealthCheck(nil) + u := createSandbox(KsTestUnsharded) + s := createSandbox(KsTestSharded) + s.VSchema = executorVSchema + u.VSchema = unshardedVSchema + serv := newSandboxForCells(ctx, []string{cell}) + resolver := newTestResolver(ctx, hc, serv, cell) + shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"} + for _, shard := range shards { + hc.AddTestTablet(cell, shard, 1, KsTestSharded, shard, topodatapb.TabletType_PRIMARY, true, 1, nil) + } + hc.AddTestTablet(cell, "0", 1, KsTestUnsharded, "0", topodatapb.TabletType_PRIMARY, true, 1, nil) + return ctx, createExecutor(ctx, serv, cell, resolver) + } + + for _, percent := range []float32{0, 1, 5, 10, 25, 50, 100} { + b.Run(fmt.Sprintf("mirror %.2f%%", percent), func(b *testing.B) { + setSandboxMirrorRules(fmt.Sprintf(`{ + "rules": [ + { + "from_table": "%s.user", + "to_table": "%s.user", + "percent": %.2f + } + ] + }`, KsTestUnsharded, KsTestSharded, percent)) + + ctx, executor := createBenchmarkExecutor(b) + session := &vtgatepb.Session{ + TargetString: "@primary", + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + executorExec(ctx, executor, session, sql, nil) + } + b.StopTimer() + }) + } +} diff --git a/go/vt/vtgate/logstats/logstats.go b/go/vt/vtgate/logstats/logstats.go index 8f8ba41e3cd..dd32d1aa5a6 100644 --- a/go/vt/vtgate/logstats/logstats.go +++ b/go/vt/vtgate/logstats/logstats.go @@ -28,6 +28,8 @@ import ( "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/callerid" "vitess.io/vitess/go/vt/callinfo" + "vitess.io/vitess/go/vt/sqlparser" + querypb "vitess.io/vitess/go/vt/proto/query" ) @@ -48,7 +50,7 @@ type LogStats struct { ExecuteTime time.Duration CommitTime time.Duration Error error - TablesUsed []string + TablesUsed []sqlparser.TableName SessionUUID string CachedPlan bool ActiveKeyspace string // ActiveKeyspace is the selected keyspace `use ks` @@ -174,9 +176,12 @@ func (stats *LogStats) Logf(w io.Writer, params url.Values) error { log.Key("Cached Plan") log.Bool(stats.CachedPlan) log.Key("TablesUsed") - log.Strings(stats.TablesUsed) + tablesUsed := make([]string, len(stats.TablesUsed)) + for i, table := range stats.TablesUsed { + tablesUsed[i] = sqlparser.String(table) + } + log.Strings(tablesUsed) log.Key("ActiveKeyspace") log.String(stats.ActiveKeyspace) - return log.Flush(w) } diff --git a/go/vt/vtgate/logstats/logstats_test.go b/go/vt/vtgate/logstats/logstats_test.go index ae3c01e0f0b..c66aecdf01b 100644 --- a/go/vt/vtgate/logstats/logstats_test.go +++ b/go/vt/vtgate/logstats/logstats_test.go @@ -40,6 +40,7 @@ import ( "vitess.io/vitess/go/vt/callinfo" "vitess.io/vitess/go/vt/callinfo/fakecallinfo" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/sqlparser" ) func TestMain(m *testing.M) { @@ -62,7 +63,10 @@ func TestLogStatsFormat(t *testing.T) { logStats := NewLogStats(context.Background(), "test", "sql1", "suuid", nil) logStats.StartTime = time.Date(2017, time.January, 1, 1, 2, 3, 0, time.UTC) logStats.EndTime = time.Date(2017, time.January, 1, 1, 2, 4, 1234, time.UTC) - logStats.TablesUsed = []string{"ks1.tbl1", "ks2.tbl2"} + logStats.TablesUsed = []sqlparser.TableName{ + sqlparser.NewTableNameWithQualifier("tbl1", "ks1"), + sqlparser.NewTableNameWithQualifier("tbl2", "ks2"), + } logStats.TabletType = "PRIMARY" logStats.ActiveKeyspace = "db" params := map[string][]string{"full": {}} diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 5d1d4ecd622..ee4907be922 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -49,13 +50,13 @@ var ( type ( planResult struct { primitive engine.Primitive - tables []string + tables sqlparser.TableNames } stmtPlanner func(sqlparser.Statement, *sqlparser.ReservedVars, plancontext.VSchema) (*planResult, error) ) -func newPlanResult(prim engine.Primitive, tablesUsed ...string) *planResult { +func newPlanResult(prim engine.Primitive, tablesUsed ...sqlparser.TableName) *planResult { return &planResult{primitive: prim, tables: tablesUsed} } @@ -100,7 +101,7 @@ func BuildFromStmt(ctx context.Context, query string, stmt sqlparser.Statement, } var primitive engine.Primitive - var tablesUsed []string + var tablesUsed []sqlparser.TableName if planResult != nil { primitive = planResult.primitive tablesUsed = planResult.tables @@ -151,9 +152,83 @@ func buildRoutePlan(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVa return f(stmt, reservedVars, vschema) } +func buildRoutePlanWithMirroring(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, f func(statement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, schema plancontext.VSchema) (*planResult, error)) (*planResult, error) { + // Building a plan changes the statement, so clone it before we create the + // original plan. + // + // TODO(maxeng): find a way to avoid this work unless all tables have a + // mirror rule. At present, we don't know which tables to check until we + // plan the original statement. + mirrorStmt := sqlparser.CloneStatement(stmt) + + plan, err := buildRoutePlan(stmt, reservedVars, vschema, f) + if err != nil { + return nil, err + } + + // Avoid mirroring work unless all tables have a mirror rule. + mirrorRules := make(map[sqlparser.TableName]*vindexes.MirrorRule) + for _, table := range plan.tables { + mirrorRule, _, _, _, err := vschema.FindMirrorRule(table) + if err != nil || mirrorRule == nil { + break + } + // Forbid self-mirroring. + if mirrorRule.Table.Keyspace.Name == table.Qualifier.String() { + break + } + mirrorRules[table] = mirrorRule + } + if len(mirrorRules) == 0 || len(mirrorRules) != len(plan.tables) { + return plan, nil + } + + // Set up a vschema for mirroring. + mirrorVSchema := plancontext.ForMirroring(vschema) + + // Use the smallest mirror percent. + var i int + var percent float32 + for _, mirrorRule := range mirrorRules { + if i == 0 || mirrorRule.Percent < percent { + percent = mirrorRule.Percent + } + i++ + } + + // Create plan with cloned statement and mirrored vschema. + target, err := buildRoutePlan(mirrorStmt, reservedVars, mirrorVSchema, f) + if err != nil { + // We don't want to return the error here. Mirroring is meant to be + // best effort, and should not stand in the way of production work. + // + // TODO(maxeng): log an error or increase a metric. + return plan, nil + } + + // Build a new planResult from the original plan and mirror target plan. + tables := make(sqlparser.TableNames, len(plan.tables)+len(target.tables)) + copy(tables, plan.tables) + copy(tables[len(plan.tables):], target.tables) + operators.SortTableNames(tables) + return &planResult{ + engine.NewMirror( + plan.primitive, + engine.NewPercentMirrorTarget(percent, target.primitive), + ), + tables, + }, nil +} + func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { switch stmt := stmt.(type) { - case *sqlparser.Select, *sqlparser.Insert, *sqlparser.Update, *sqlparser.Delete: + case *sqlparser.Select: + configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) + if err != nil { + return nil, err + } + return buildRoutePlanWithMirroring(stmt, reservedVars, vschema, configuredPlanner) + case *sqlparser.Insert, *sqlparser.Update, *sqlparser.Delete: configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) if err != nil { return nil, err @@ -164,7 +239,7 @@ func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Stat if err != nil { return nil, err } - return buildRoutePlan(stmt, reservedVars, vschema, configuredPlanner) + return buildRoutePlanWithMirroring(stmt, reservedVars, vschema, configuredPlanner) case sqlparser.DDLStatement: return buildGeneralDDLPlan(ctx, query, stmt, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) case *sqlparser.AlterMigration: @@ -265,7 +340,7 @@ func buildAnalyzePlan(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, vsche TargetDestination: dest, Query: sqlparser.String(analyzeStmt), } - return newPlanResult(prim, sqlparser.String(analyzeStmt.Table)), nil + return newPlanResult(prim, analyzeStmt.Table), nil } func buildDBDDLPlan(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { @@ -337,7 +412,7 @@ func buildVSchemaDDLPlan(stmt *sqlparser.AlterVschema, vschema plancontext.VSche return newPlanResult(&engine.AlterVSchema{ Keyspace: keyspace, AlterVschemaDDL: stmt, - }, singleTable(keyspace.Name, stmt.Table.Name.String())), nil + }, sqlparser.NewTableNameWithQualifier(stmt.Table.Name.String(), keyspace.Name)), nil } func buildFlushPlan(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*planResult, error) { @@ -397,7 +472,7 @@ func buildFlushTables(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*plan if tbl == nil { return nil, vindexes.NotFoundError{TableName: tab.Name.String()} } - tc.addTable(tbl.Keyspace.Name, tbl.Name.String()) + tc.addTable(sqlparser.NewTableNameWithQualifier(tbl.Name.String(), tbl.Keyspace.Name)) ksTab = tbl.Keyspace stmt.TableNames[i] = sqlparser.TableName{ Name: tbl.Name, @@ -441,28 +516,23 @@ func buildFlushTables(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*plan } type tableCollector struct { - tables map[string]any + tables map[sqlparser.TableName]any } -func (tc *tableCollector) addTable(ks, tbl string) { +func (tc *tableCollector) addTable(t sqlparser.TableName) { if tc.tables == nil { - tc.tables = map[string]any{} + tc.tables = map[sqlparser.TableName]any{} } - tc.tables[fmt.Sprintf("%s.%s", ks, tbl)] = nil + tc.tables[t] = nil } -func (tc *tableCollector) addASTTable(ks string, tbl sqlparser.TableName) { - tc.addTable(ks, tbl.Name.String()) -} - -func (tc *tableCollector) getTables() []string { - tableNames := make([]string, 0, len(tc.tables)) - for tbl := range tc.tables { - tableNames = append(tableNames, tbl) +func (tc *tableCollector) getTables() []sqlparser.TableName { + tables := make([]sqlparser.TableName, 0, len(tc.tables)) + for t := range tc.tables { + tables = append(tables, t) } - - sort.Strings(tableNames) - return tableNames + operators.SortTableNames(tables) + return tables } func newFlushStmt(stmt *sqlparser.Flush, tables sqlparser.TableNames) *sqlparser.Flush { diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index 4c4b3791c20..eddab9b3a4b 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -74,7 +74,7 @@ func buildGeneralDDLPlan(ctx context.Context, sql string, ddlStatement sqlparser } tc := &tableCollector{} for _, tbl := range ddlStatement.AffectedTables() { - tc.addASTTable(normalDDLPlan.Keyspace.Name, tbl) + tc.addTable(sqlparser.NewTableNameWithQualifier(tbl.Name.String(), normalDDLPlan.Keyspace.Name)) } return newPlanResult(eddl, tc.getTables()...), nil diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index 5bbf5218bd7..797ca3c7977 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -33,6 +33,11 @@ type Delete struct { noPredicates } +var ( + _ Operator = (*Delete)(nil) + _ TableUser = (*Delete)(nil) +) + // Clone implements the Operator interface func (d *Delete) Clone(inputs []Operator) Operator { newD := *d @@ -55,8 +60,8 @@ func (d *Delete) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -func (d *Delete) TablesUsed() []string { - return SingleQualifiedIdentifier(d.Target.VTable.Keyspace, d.Target.VTable.Name) +func (d *Delete) TablesUsed() []sqlparser.TableName { + return SingleTableName(d.Target.VTable.Keyspace, d.Target.VTable.Name) } func (d *Delete) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/helpers.go b/go/vt/vtgate/planbuilder/operators/helpers.go index 31d9bcfd279..3f23ca1b43c 100644 --- a/go/vt/vtgate/planbuilder/operators/helpers.go +++ b/go/vt/vtgate/planbuilder/operators/helpers.go @@ -17,8 +17,8 @@ limitations under the License. package operators import ( - "fmt" - "sort" + "slices" + "strings" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -82,15 +82,15 @@ func TableID(op Operator) (result semantics.TableSet) { // TableUser is used to signal that this operator directly interacts with one or more tables type TableUser interface { - TablesUsed() []string + TablesUsed() []sqlparser.TableName } -func TablesUsed(op Operator) []string { - addString, collect := collectSortedUniqueStrings() +func TablesUsed(op Operator) []sqlparser.TableName { + addTableName, collect := collectSortedUniqueTableNames() _ = Visit(op, func(this Operator) error { if tbl, ok := this.(TableUser); ok { for _, u := range tbl.TablesUsed() { - addString(u) + addTableName(u) } } return nil @@ -116,53 +116,59 @@ func CostOf(op Operator) (cost int) { return } -func QualifiedIdentifier(ks *vindexes.Keyspace, i sqlparser.IdentifierCS) string { - return QualifiedString(ks, i.String()) -} - -func QualifiedString(ks *vindexes.Keyspace, s string) string { - return fmt.Sprintf("%s.%s", ks.Name, s) -} - -func QualifiedTableName(ks *vindexes.Keyspace, t sqlparser.TableName) string { - return QualifiedIdentifier(ks, t.Name) -} - -func QualifiedTableNames(ks *vindexes.Keyspace, ts []sqlparser.TableName) []string { - add, collect := collectSortedUniqueStrings() +func QualifiedTableNames(ks *vindexes.Keyspace, ts []sqlparser.TableName) []sqlparser.TableName { + add, collect := collectSortedUniqueTableNames() for _, t := range ts { - add(QualifiedTableName(ks, t)) + add(sqlparser.NewTableNameWithQualifier(t.Name.String(), ks.Name)) } return collect() } -func QualifiedTables(ks *vindexes.Keyspace, vts []*vindexes.Table) []string { - add, collect := collectSortedUniqueStrings() +func QualifiedTables(ks *vindexes.Keyspace, vts []*vindexes.Table) []sqlparser.TableName { + add, collect := collectSortedUniqueTableNames() for _, vt := range vts { - add(QualifiedIdentifier(ks, vt.Name)) + add(sqlparser.NewTableNameWithQualifier(vt.Name.String(), ks.Name)) } return collect() } -func SingleQualifiedIdentifier(ks *vindexes.Keyspace, i sqlparser.IdentifierCS) []string { - return SingleQualifiedString(ks, i.String()) +func SingleTableName(ks *vindexes.Keyspace, i sqlparser.IdentifierCS) []sqlparser.TableName { + return []sqlparser.TableName{sqlparser.NewTableNameWithQualifier(i.String(), ks.Name)} } -func SingleQualifiedString(ks *vindexes.Keyspace, s string) []string { - return []string{QualifiedString(ks, s)} +func SortTableNames(ts []sqlparser.TableName) { + slices.SortFunc[[]sqlparser.TableName, sqlparser.TableName](ts, func(a, b sqlparser.TableName) int { + if a.Qualifier.NotEmpty() && b.Qualifier.NotEmpty() { + if cq := strings.Compare(a.Qualifier.String(), b.Qualifier.String()); cq != 0 { + return cq + } + return strings.Compare(a.Name.String(), b.Name.String()) + } + if a.Qualifier.NotEmpty() { + return strings.Compare(a.Qualifier.String(), b.Name.String()) + } + if b.Qualifier.NotEmpty() { + return strings.Compare(a.Name.String(), b.Qualifier.String()) + } + return strings.Compare(a.Name.String(), b.Name.String()) + }) } -func collectSortedUniqueStrings() (add func(string), collect func() []string) { - uniq := make(map[string]any) - add = func(v string) { +func collectSortedUniqueTableNames() (add func(sqlparser.TableName), collect func() []sqlparser.TableName) { + uniq := make(map[sqlparser.TableName]any) + + add = func(v sqlparser.TableName) { uniq[v] = nil } - collect = func() []string { - sorted := make([]string, 0, len(uniq)) + + collect = func() []sqlparser.TableName { + sorted := make([]sqlparser.TableName, 0, len(uniq)) for v := range uniq { sorted = append(sorted, v) } - sort.Strings(sorted) + + SortTableNames(sorted) + return sorted } diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index 6832dc363d5..1a129946812 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -82,7 +82,10 @@ func (i *Insert) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -var _ Operator = (*Insert)(nil) +var ( + _ Operator = (*Insert)(nil) + _ TableUser = (*Insert)(nil) +) func (i *Insert) Clone([]Operator) Operator { return &Insert{ @@ -96,8 +99,8 @@ func (i *Insert) Clone([]Operator) Operator { } } -func (i *Insert) TablesUsed() []string { - return SingleQualifiedIdentifier(i.VTable.Keyspace, i.VTable.Name) +func (i *Insert) TablesUsed() []sqlparser.TableName { + return SingleTableName(i.VTable.Keyspace, i.VTable.Name) } func (i *Insert) Statement() sqlparser.Statement { diff --git a/go/vt/vtgate/planbuilder/operators/route.go b/go/vt/vtgate/planbuilder/operators/route.go index feeb091a725..e215b52132a 100644 --- a/go/vt/vtgate/planbuilder/operators/route.go +++ b/go/vt/vtgate/planbuilder/operators/route.go @@ -762,11 +762,11 @@ func (r *Route) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { // TablesUsed returns tables used by MergedWith routes, which are not included // in Inputs() and thus not a part of the operator tree -func (r *Route) TablesUsed() []string { - addString, collect := collectSortedUniqueStrings() +func (r *Route) TablesUsed() []sqlparser.TableName { + addTable, collect := collectSortedUniqueTableNames() for _, mw := range r.MergedWith { for _, u := range TablesUsed(mw) { - addString(u) + addTable(u) } } return collect() diff --git a/go/vt/vtgate/planbuilder/operators/table.go b/go/vt/vtgate/planbuilder/operators/table.go index 3ecd4982ece..e1e4493df30 100644 --- a/go/vt/vtgate/planbuilder/operators/table.go +++ b/go/vt/vtgate/planbuilder/operators/table.go @@ -41,6 +41,11 @@ type ( } ) +var ( + _ Operator = (*Table)(nil) + _ TableUser = (*Table)(nil) +) + // Clone implements the Operator interface func (to *Table) Clone([]Operator) Operator { var columns []*sqlparser.ColName @@ -107,11 +112,11 @@ func (to *Table) AddCol(col *sqlparser.ColName) { to.Columns = append(to.Columns, col) } -func (to *Table) TablesUsed() []string { +func (to *Table) TablesUsed() []sqlparser.TableName { if sqlparser.SystemSchema(to.QTable.Table.Qualifier.String()) { return nil } - return SingleQualifiedIdentifier(to.VTable.Keyspace, to.VTable.Name) + return SingleTableName(to.VTable.Keyspace, to.VTable.Name) } func addColumn(ctx *plancontext.PlanningContext, op ColNameColumns, e sqlparser.Expr) int { diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index e843155246c..40cc8a68574 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -58,6 +58,11 @@ type ( } ) +var ( + _ Operator = (*Update)(nil) + _ TableUser = (*Update)(nil) +) + func (u *Update) Inputs() []Operator { if u.Source == nil { return nil @@ -89,8 +94,8 @@ func (u *Update) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -func (u *Update) TablesUsed() []string { - return SingleQualifiedIdentifier(u.Target.VTable.Keyspace, u.Target.VTable.Name) +func (u *Update) TablesUsed() []sqlparser.TableName { + return SingleTableName(u.Target.VTable.Keyspace, u.Target.VTable.Name) } func (u *Update) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/vindex.go b/go/vt/vtgate/planbuilder/operators/vindex.go index fd907fdad27..ce56554d568 100644 --- a/go/vt/vtgate/planbuilder/operators/vindex.go +++ b/go/vt/vtgate/planbuilder/operators/vindex.go @@ -50,6 +50,11 @@ type ( const wrongWhereCond = "WHERE clause for vindex function must be of the form id = or id in(,...)" +var ( + _ Operator = (*Vindex)(nil) + _ TableUser = (*Vindex)(nil) +) + // Introduces implements the Operator interface func (v *Vindex) introducesTableID() semantics.TableSet { return v.Solved @@ -164,8 +169,8 @@ func (v *Vindex) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.E // TablesUsed implements the Operator interface. // It is not keyspace-qualified. -func (v *Vindex) TablesUsed() []string { - return []string{v.Table.Table.Name.String()} +func (v *Vindex) TablesUsed() []sqlparser.TableName { + return []sqlparser.TableName{sqlparser.NewTableName(v.Table.Table.Name.String())} } func (v *Vindex) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index f49994d37b2..7c2f20a4d3a 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -591,6 +591,18 @@ func (s *planTestSuite) TestOtherPlanningFromFile() { s.testFile("other_admin_cases.json", vschema, false) } +func (s *planTestSuite) TestMirrorPlanning() { + vschema := &vschemawrapper.VSchemaWrapper{ + V: loadSchema(s.T(), "vschemas/mirror_schema.json", true), + TabletType_: topodatapb.TabletType_PRIMARY, + SysVarEnabled: true, + TestBuilder: TestBuilder, + Env: vtenv.NewTestEnv(), + } + + s.testFile("mirror_cases.json", vschema, false) +} + func loadSchema(t testing.TB, filename string, setCollation bool) *vindexes.VSchema { formal, err := vindexes.LoadFormal(locateFile(filename)) require.NoError(t, err) @@ -839,6 +851,35 @@ func BenchmarkSelectVsDML(b *testing.B) { }) } +func BenchmarkBaselineVsMirrored(b *testing.B) { + baseline := loadSchema(b, "vschemas/mirror_schema.json", true) + baseline.MirrorRules = map[string]*vindexes.MirrorRule{} + baselineVschema := &vschemawrapper.VSchemaWrapper{ + V: baseline, + SysVarEnabled: true, + Version: Gen4, + Env: vtenv.NewTestEnv(), + } + + mirroredSchema := loadSchema(b, "vschemas/mirror_schema.json", true) + mirroredVschema := &vschemawrapper.VSchemaWrapper{ + V: mirroredSchema, + SysVarEnabled: true, + Version: Gen4, + Env: vtenv.NewTestEnv(), + } + + cases := readJSONTests("mirror_cases.json") + + b.Run("Baseline", func(b *testing.B) { + benchmarkPlanner(b, Gen4, cases, baselineVschema) + }) + + b.Run("Mirrored", func(b *testing.B) { + benchmarkPlanner(b, Gen4, cases, mirroredVschema) + }) +} + func benchmarkPlanner(b *testing.B, version plancontext.PlannerVersion, testCases []planTest, vschema *vschemawrapper.VSchemaWrapper) { b.ReportAllocs() for n := 0; n < b.N; n++ { diff --git a/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go b/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go new file mode 100644 index 00000000000..e957c282fb8 --- /dev/null +++ b/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go @@ -0,0 +1,265 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package plancontext + +import ( + "context" + + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/vt/key" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtenv" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vtgate/semantics" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +// mirrorVSchema is a wrapper which returns mirrored versions of values +// return by the wrapped vschema. +// +// For example, if the wrapped VSchema defines any mirror rules from ks1 to +// ks2, calls to FindTable for which the wrapped VSchema returns tables in +// ks1 will return tables in ks2. +// +// The returned VSchema cannot be reflected back again by passing it to +// ForMirroring. This restriction allows the returned VSchema to be used in +// recursive planning calls without creating an infinite loop. +type mirrorVSchema struct { + vschema VSchema +} + +// FindTable finds and returns the table with the requested name. +// +// mirrorVSchema returns a mirrored version of the value returned by the underlying VSchema. +// If the underlying VSchema returns a table t1 in ks1, and there is exists a +// routing rule from ks1 to ks2, and ks2 has a table t1, then mirrorVSchema +// returns ks2.t1. +// +// If no table with the requested name can be found, or not mirror rule is +// defined on the keyspace of the found table, or no table is found in the +// target keyspace defined by the mirror rule, then nil is returned. +func (m *mirrorVSchema) FindTable(tablename sqlparser.TableName) (*vindexes.Table, string, topodatapb.TabletType, key.Destination, error) { + mirrorRule, destKeyspace, destTabletType, dest, err := m.vschema.FindMirrorRule(tablename) + if err != nil { + return nil, "", destTabletType, nil, err + } + return mirrorRule.Table, destKeyspace, destTabletType, dest, err +} + +func (m *mirrorVSchema) FindView(name sqlparser.TableName) sqlparser.SelectStatement { + // TODO(maxeng): we don't have all the information we need here to mirror + // views. May need to expose a new method on VSchema interface, such as + // ParseDestinationTarget + return nil +} + +// FindTableOrVindex returns a routed table or vindex. +// +// mirrorVSchema returns a mirrored version of the value returned by the +// underlying VSchema. If the underlying VSchema returns a table t1 in ks1, +// and there is exists a mirror rule from ks1.t1 to ks2.t1, then mirrorVSchema +// returns ks2.t1. Vindexes are not mirrored. +func (m *mirrorVSchema) FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) { + fromTable, vindex, destKeyspace, destTabletType, dest, err := m.vschema.FindTableOrVindex(tablename) + if err != nil { + return nil, vindex, "", destTabletType, nil, err + } + mirrorRule, err := m.GetVSchema().FindMirrorRule(fromTable.Keyspace.Name, fromTable.Name.String(), destTabletType) + if err != nil { + return nil, vindex, "", destTabletType, nil, err + } + // If mirror rule not found, just use the table we initially found. + if mirrorRule == nil { + return fromTable, vindex, destKeyspace, destTabletType, dest, nil + } + return mirrorRule.Table, vindex, destKeyspace, destTabletType, dest, err +} + +func (m *mirrorVSchema) DefaultKeyspace() (*vindexes.Keyspace, error) { + return m.vschema.DefaultKeyspace() +} + +func (m *mirrorVSchema) TargetString() string { + return m.vschema.TargetString() +} + +func (m *mirrorVSchema) Destination() key.Destination { + return m.vschema.Destination() +} + +func (m *mirrorVSchema) TabletType() topodatapb.TabletType { + return m.vschema.TabletType() +} + +func (m *mirrorVSchema) TargetDestination(qualifier string) (key.Destination, *vindexes.Keyspace, topodatapb.TabletType, error) { + return m.vschema.TargetDestination(qualifier) +} + +func (m *mirrorVSchema) AnyKeyspace() (*vindexes.Keyspace, error) { + return m.vschema.AnyKeyspace() +} + +func (m *mirrorVSchema) FirstSortedKeyspace() (*vindexes.Keyspace, error) { + return m.vschema.FirstSortedKeyspace() +} + +func (m *mirrorVSchema) SysVarSetEnabled() bool { + return m.vschema.SysVarSetEnabled() +} + +func (m *mirrorVSchema) KeyspaceExists(keyspace string) bool { + return m.vschema.KeyspaceExists(keyspace) +} + +func (m *mirrorVSchema) AllKeyspace() ([]*vindexes.Keyspace, error) { + return m.vschema.AllKeyspace() +} + +func (m *mirrorVSchema) FindKeyspace(keyspace string) (*vindexes.Keyspace, error) { + return m.vschema.FindKeyspace(keyspace) +} + +func (m *mirrorVSchema) GetSemTable() *semantics.SemTable { + return m.vschema.GetSemTable() +} + +func (m *mirrorVSchema) Planner() PlannerVersion { + return m.vschema.Planner() +} + +func (m *mirrorVSchema) SetPlannerVersion(pv PlannerVersion) { + m.vschema.SetPlannerVersion(pv) +} + +func (m *mirrorVSchema) ConnCollation() collations.ID { + return m.vschema.ConnCollation() +} + +func (m *mirrorVSchema) Environment() *vtenv.Environment { + return m.vschema.Environment() +} + +// ErrorIfShardedF will return an error if the keyspace is sharded, +// and produce a warning if the vtgate if configured to do so +func (m *mirrorVSchema) ErrorIfShardedF(keyspace *vindexes.Keyspace, warn string, errFmt string, params ...any) error { + return m.vschema.ErrorIfShardedF(keyspace, warn, errFmt, params...) +} + +// WarnUnshardedOnly is used when a feature is only supported in unsharded mode. +// This will let the user know that they are using something +// that could become a problem if they move to a sharded keyspace +func (m *mirrorVSchema) WarnUnshardedOnly(format string, params ...any) { + m.vschema.WarnUnshardedOnly(format, params...) +} + +// PlannerWarning records warning created during planning. +func (m *mirrorVSchema) PlannerWarning(message string) { + m.vschema.PlannerWarning(message) +} + +// ForeignKeyMode returns the foreign_key flag value +func (m *mirrorVSchema) ForeignKeyMode(keyspace string) (vschemapb.Keyspace_ForeignKeyMode, error) { + return m.vschema.ForeignKeyMode(keyspace) +} + +// KeyspaceError returns any error in the keyspace vschema. +func (m *mirrorVSchema) KeyspaceError(keyspace string) error { + return m.vschema.KeyspaceError(keyspace) +} + +func (m *mirrorVSchema) GetForeignKeyChecksState() *bool { + return m.vschema.GetForeignKeyChecksState() +} + +// GetVSchema returns the latest cached vindexes.VSchema +func (m *mirrorVSchema) GetVSchema() *vindexes.VSchema { + return m.vschema.GetVSchema() +} + +func (m *mirrorVSchema) GetSrvVschema() *vschemapb.SrvVSchema { + return m.vschema.GetSrvVschema() +} + +// FindRoutedShard looks up shard routing rules for a shard +func (m *mirrorVSchema) FindRoutedShard(keyspace string, shard string) (string, error) { + return m.vschema.FindRoutedShard(keyspace, shard) +} + +// IsShardRoutingEnabled returns true if partial shard routing is enabled +func (m *mirrorVSchema) IsShardRoutingEnabled() bool { + return m.vschema.IsShardRoutingEnabled() +} + +// IsViewsEnabled returns true if Vitess manages the views. +func (m *mirrorVSchema) IsViewsEnabled() bool { + return m.vschema.IsViewsEnabled() +} + +// GetUDV returns user defined value from the variable passed. +func (m *mirrorVSchema) GetUDV(name string) *querypb.BindVariable { + return m.vschema.GetUDV(name) +} + +// PlanPrepareStatement plans the prepared statement. +func (m *mirrorVSchema) PlanPrepareStatement(ctx context.Context, query string) (*engine.Plan, sqlparser.Statement, error) { + return m.vschema.PlanPrepareStatement(ctx, query) +} + +// ClearPrepareData clears the prepared data from the session. +func (m *mirrorVSchema) ClearPrepareData(stmtName string) { + m.vschema.ClearPrepareData(stmtName) +} + +// GetPrepareData returns the prepared data for the statement from the session. +func (m *mirrorVSchema) GetPrepareData(stmtName string) *vtgatepb.PrepareData { + return m.vschema.GetPrepareData(stmtName) +} + +// StorePrepareData stores the prepared data in the session. +func (m *mirrorVSchema) StorePrepareData(name string, v *vtgatepb.PrepareData) { + m.vschema.StorePrepareData(name, v) +} + +// GetAggregateUDFs returns the list of aggregate UDFs. +func (m *mirrorVSchema) GetAggregateUDFs() []string { + return m.vschema.GetAggregateUDFs() +} + +// FindMirrorRule finds the mirror rule for the requested table name and +// VSchema tablet type. +func (m *mirrorVSchema) FindMirrorRule(name sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { + return nil, "", topodatapb.TabletType_UNKNOWN, nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "[BUG] refusing to perform chained traffic mirroring") +} + +// ForMirroring returns a wrapper which returns mirrored versions of values +// return by the wrapped vschema. +// +// For example, if the underlying VSchema defines any mirror rules from ks1 to +// ks2, calls to FindTable for which the wrapped VSchema returns tables in +// ks1 will return tables in ks2. +// +// The returned VSchema cannot be reflected back again by passing it to +// ForMirroring. This restriction prevents infinite mirroring loops. +func ForMirroring(vschema VSchema) VSchema { + return &mirrorVSchema{vschema} +} diff --git a/go/vt/vtgate/planbuilder/plancontext/vschema.go b/go/vt/vtgate/planbuilder/plancontext/vschema.go index 8ac4c57bfd7..64712fd2b66 100644 --- a/go/vt/vtgate/planbuilder/plancontext/vschema.go +++ b/go/vt/vtgate/planbuilder/plancontext/vschema.go @@ -96,6 +96,10 @@ type VSchema interface { // GetAggregateUDFs returns the list of aggregate UDFs. GetAggregateUDFs() []string + + // FindMirrorRule finds the mirror rule for the requested keyspace, table + // name, and the tablet type in the VSchema. + FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) } // PlannerNameToVersion returns the numerical representation of the planner diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index 01dfd8aa387..9880f32e500 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -45,12 +45,12 @@ func gen4SelectStmtPlanner( return nil, err } if p != nil { - used := "dual" + used := sqlparser.NewTableName("dual") keyspace, ksErr := vschema.DefaultKeyspace() if ksErr == nil { // we are just getting the ks to log the correct table use. // no need to fail this if we can't find the default keyspace - used = keyspace.Name + ".dual" + used = sqlparser.NewTableNameWithQualifier("dual", keyspace.Name) } return newPlanResult(p, used), nil } @@ -62,7 +62,7 @@ func gen4SelectStmtPlanner( sel.SQLCalcFoundRows = false } - getPlan := func(selStatement sqlparser.SelectStatement) (engine.Primitive, []string, error) { + getPlan := func(selStatement sqlparser.SelectStatement) (engine.Primitive, []sqlparser.TableName, error) { return newBuildSelectPlan(selStatement, reservedVars, vschema, plannerVersion) } @@ -123,7 +123,7 @@ func buildSQLCalcFoundRowsPlan( sel *sqlparser.Select, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, -) (engine.Primitive, []string, error) { +) (engine.Primitive, []sqlparser.TableName, error) { limitPlan, _, err := newBuildSelectPlan(sel, reservedVars, vschema, Gen4) if err != nil { return nil, nil, err @@ -180,7 +180,7 @@ func buildSQLCalcFoundRowsPlan( }, tablesUsed, nil } -func gen4PredicateRewrite(stmt sqlparser.Statement, getPlan func(selStatement sqlparser.SelectStatement) (engine.Primitive, []string, error)) (engine.Primitive, []string) { +func gen4PredicateRewrite(stmt sqlparser.Statement, getPlan func(selStatement sqlparser.SelectStatement) (engine.Primitive, []sqlparser.TableName, error)) (engine.Primitive, []sqlparser.TableName) { rewritten, isSel := sqlparser.RewritePredicate(stmt).(sqlparser.SelectStatement) if !isSel { // Fail-safe code, should never happen @@ -199,7 +199,7 @@ func newBuildSelectPlan( reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, version querypb.ExecuteOptions_PlannerVersion, -) (plan engine.Primitive, tablesUsed []string, err error) { +) (plan engine.Primitive, tablesUsed []sqlparser.TableName, err error) { ctx, err := plancontext.CreatePlanningContext(selStmt, reservedVars, vschema, version) if err != nil { return nil, nil, err diff --git a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go index 5d877cd341d..ad6329f4f0a 100644 --- a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go +++ b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go @@ -28,7 +28,7 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) -func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, ks *vindexes.Keyspace) (engine.Primitive, []string, error) { +func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, ks *vindexes.Keyspace) (engine.Primitive, []sqlparser.TableName, error) { // this method is used when the query we are handling has all tables in the same unsharded keyspace sqlparser.SafeRewrite(stmt, nil, func(cursor *sqlparser.Cursor) bool { switch node := cursor.Node().(type) { diff --git a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json new file mode 100644 index 00000000000..c8014721d5f --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json @@ -0,0 +1,397 @@ +[ + { + "comment": "select unsharded, qualified, table mirrored to unsharded table", + "query": "select t1.id from unsharded_src1.t1 where t1.id = 1", + "plan": { + "QueryType": "SELECT", + "Original": "select t1.id from unsharded_src1.t1 where t1.id = 1", + "Instructions": { + "OperatorType": "Mirror", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1 where t1.id = 1", + "Table": "t1" + }, + { + "OperatorType": "MirrorTarget", + "Variant": "Percent", + "Percent": 50, + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1 where t1.id = 1", + "Table": "t1" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_dst1.t1", + "unsharded_src1.t1" + ] + } + }, + { + "comment": "select unsharded, qualified, table mirrored to sharded table", + "query": "select t1.id from unsharded_src1.t1 where t1.id = 1", + "plan": { + "QueryType": "SELECT", + "Original": "select t1.id from unsharded_src1.t1 where t1.id = 1", + "Instructions": { + "OperatorType": "Mirror", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1 where t1.id = 1", + "Table": "t1" + }, + { + "OperatorType": "MirrorTarget", + "Variant": "Percent", + "Percent": 50, + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1 where t1.id = 1", + "Table": "t1" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_dst1.t1", + "unsharded_src1.t1" + ] + } + }, + { + "comment": "select two unsharded, qualified, tables, one mirrored to unsharded table, other to sharded table", + "query": "select t1.id, t2.id from unsharded_src1.t1, unsharded_src1.t2 where t1.id = t2.id", + "plan": { + "QueryType": "SELECT", + "Original": "select t1.id, t2.id from unsharded_src1.t1, unsharded_src1.t2 where t1.id = t2.id", + "Instructions": { + "OperatorType": "Mirror", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "FieldQuery": "select t1.id, t2.id from t1, t2 where 1 != 1", + "Query": "select t1.id, t2.id from t1, t2 where t1.id = t2.id", + "Table": "t1, t2" + }, + { + "OperatorType": "MirrorTarget", + "Variant": "Percent", + "Percent": 50, + "Inputs": [ + { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:0,R:0", + "JoinVars": { + "t1_id": 0 + }, + "TableName": "t1_t1", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1", + "Table": "t1" + }, + { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_dst1", + "Sharded": true + }, + "FieldQuery": "select t2.id from t1 as t2 where 1 != 1", + "Query": "select t2.id from t1 as t2 where t2.id = :t1_id", + "Table": "t1", + "Values": [ + ":t1_id" + ], + "Vindex": "xxhash" + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "sharded_dst1.t1", + "unsharded_dst1.t1", + "unsharded_src1.t1", + "unsharded_src1.t2" + ] + } + }, + { + "comment": "union of selects from unsharded, qualified, tables, one mirrored to unsharded table, other to sharded table", + "query": "select t1.id from unsharded_src1.t1 union select t2.id from unsharded_src1.t2", + "plan": { + "QueryType": "SELECT", + "Original": "select t1.id from unsharded_src1.t1 union select t2.id from unsharded_src1.t2", + "Instructions": { + "OperatorType": "Mirror", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1 union select t2.id from t2 where 1 != 1", + "Query": "select t1.id from t1 union select t2.id from t2", + "Table": "t1, t2" + }, + { + "OperatorType": "MirrorTarget", + "Variant": "Percent", + "Percent": 50, + "Inputs": [ + { + "OperatorType": "Distinct", + "Collations": [ + "(0:1)" + ], + "ResultColumns": 1, + "Inputs": [ + { + "OperatorType": "Concatenate", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false + }, + "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select t1.id from t1 where 1 != 1) as dt(c0) where 1 != 1", + "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct t1.id from t1) as dt(c0)", + "Table": "t1" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_dst1", + "Sharded": true + }, + "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select t2.id from t1 as t2 where 1 != 1) as dt(c0) where 1 != 1", + "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct t2.id from t1 as t2) as dt(c0)", + "Table": "t1" + } + ] + } + ] + } + ] + } + ] + }, + "TablesUsed": [ + "sharded_dst1.t1", + "unsharded_dst1.t1", + "unsharded_src1.t1", + "unsharded_src1.t2" + ] + } + }, + { + "comment": "inserts are not mirrored", + "query": "insert into unsharded_src1.t1 (id) values(1)", + "plan": { + "QueryType": "INSERT", + "Original": "insert into unsharded_src1.t1 (id) values(1)", + "Instructions": { + "OperatorType": "Insert", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "insert into t1(id) values (1)", + "TableName": "t1" + }, + "TablesUsed": [ + "unsharded_src1.t1" + ] + } + }, + { + "comment": "updates are not mirrored", + "query": "update unsharded_src1.t1 set data = 'a' where id = 1", + "plan": { + "QueryType": "UPDATE", + "Original": "update unsharded_src1.t1 set data = 'a' where id = 1", + "Instructions": { + "OperatorType": "Update", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "update t1 set `data` = 'a' where id = 1", + "Table": "t1" + }, + "TablesUsed": [ + "unsharded_src1.t1" + ] + } + }, + { + "comment": "deletes are not mirrored", + "query": "delete from unsharded_src1.t1 where id = 1", + "plan": { + "QueryType": "DELETE", + "Original": "delete from unsharded_src1.t1 where id = 1", + "Instructions": { + "OperatorType": "Delete", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "TargetTabletType": "PRIMARY", + "Query": "delete from t1 where id = 1", + "Table": "t1" + }, + "TablesUsed": [ + "unsharded_src1.t1" + ] + } + }, + { + "comment": "self-mirror is not allowed", + "query": "select t1.id from unsharded_src1.t3", + "plan": { + "QueryType": "SELECT", + "Original": "select t1.id from unsharded_src1.t3", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t3 where 1 != 1", + "Query": "select t1.id from t3", + "Table": "t3" + }, + "TablesUsed": [ + "unsharded_src1.t3" + ] + } + }, + { + "comment": "chained mirror is not allowed", + "query": "select t2.id from unsharded_src2.t2", + "plan": { + "QueryType": "SELECT", + "Original": "select t2.id from unsharded_src2.t2", + "Instructions": { + "OperatorType": "Mirror", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src2", + "Sharded": false + }, + "FieldQuery": "select t2.id from t2 where 1 != 1", + "Query": "select t2.id from t2", + "Table": "t2" + }, + { + "OperatorType": "MirrorTarget", + "Variant": "Percent", + "Percent": 50, + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst2", + "Sharded": false + }, + "FieldQuery": "select t2.id from t2 where 1 != 1", + "Query": "select t2.id from t2", + "Table": "t2" + } + ] + } + ] + }, + "TablesUsed": [ + "unsharded_dst2.t2", + "unsharded_src2.t2" + ] + } + }, + { + "comment": "circular mirror is not allowed", + "query": "select t1.id from unsharded_src3.t1", + "plan": { + "QueryType": "SELECT", + "Original": "select t1.id from unsharded_src3.t1", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src3", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1", + "Table": "t1" + }, + "TablesUsed": [ + "unsharded_src3.t1" + ] + } + } +] diff --git a/go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json b/go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json new file mode 100644 index 00000000000..faa54a15f08 --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json @@ -0,0 +1,99 @@ +{ + "mirror_rules": { + "rules": [ + { + "from_table": "unsharded_src1.t1", + "to_table": "unsharded_dst1.t1", + "percent": 50 + }, + { + "from_table": "unsharded_src1.t2", + "to_table": "sharded_dst1.t1", + "percent": 50 + }, + { + "from_table": "unsharded_src2.t1", + "to_table": "unsharded_src2.t1", + "percent": 50 + }, + { + "from_table": "unsharded_src2.t2", + "to_table": "unsharded_dst2.t2", + "percent": 50 + }, + { + "from_table": "unsharded_dst2.t2", + "to_table": "unsharded_dst3.t2", + "percent": 50 + }, + { + "from_table": "unsharded_src3.t1", + "to_table": "unsharded_dst4.t1", + "percent": 50 + }, + { + "from_table": "unsharded_dst4.t2", + "to_table": "unsharded_src3.t2", + "percent": 50 + }, + { + "from_table": "sharded_src1.t1", + "to_table": "sharded_dst1.t1", + "percent": 50 + } + + ] + }, + "keyspaces": { + "main": { + "sharded": false, + "tables": {} + }, + "unsharded_src1": { + "sharded": false, + "tables": {} + }, + "unsharded_src2": { + "sharded": false, + "tables": {} + }, + "unsharded_src3": { + "sharded": false, + "tables": {} + }, + "unsharded_dst1": { + "sharded": false, + "tables": {} + }, + "unsharded_dst2": { + "sharded": false, + "tables": {} + }, + "unsharded_dst3": { + "sharded": false, + "tables": {} + }, + "unsharded_dst4": { + "sharded": false, + "tables": {} + }, + "sharded_dst1": { + "sharded": true, + "vindexes": { + "xxhash": { + "type": "xxhash" + } + }, + "tables": { + "t1": { + "columnVindexes": [ + { + "column": "id", + "name": "xxhash" + } + ] + } + } + } + } +} diff --git a/go/vt/vtgate/planbuilder/vexplain.go b/go/vt/vtgate/planbuilder/vexplain.go index 21a35f02967..cc5cf6a10db 100644 --- a/go/vt/vtgate/planbuilder/vexplain.go +++ b/go/vt/vtgate/planbuilder/vexplain.go @@ -27,7 +27,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -79,7 +78,7 @@ func explainTabPlan(explain *sqlparser.ExplainTab, vschema plancontext.VSchema) TargetDestination: destination, Query: sqlparser.String(explain), SingleShardOnly: true, - }, singleTable(keyspace.Name, explain.Table.Name.String())), nil + }, sqlparser.NewTableNameWithQualifier(explain.Table.Name.String(), keyspace.Name)), nil } func buildVExplainVtgatePlan(ctx context.Context, explainStatement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { @@ -148,7 +147,7 @@ func explainPlan(explain *sqlparser.ExplainStmt, reservedVars *sqlparser.Reserve // Remove keyspace qualifier from columns and tables. sqlparser.RemoveKeyspace(explain.Statement) - var tables []string + var tables []sqlparser.TableName for _, table := range ctx.SemTable.Tables { name, err := table.Name() if err != nil { @@ -156,7 +155,7 @@ func explainPlan(explain *sqlparser.ExplainStmt, reservedVars *sqlparser.Reserve // it's OK to ignore errors here continue } - tables = append(tables, operators.QualifiedString(ks, name.Name.String())) + tables = append(tables, sqlparser.NewTableNameWithQualifier(name.Name.String(), ks.Name)) } return newPlanResult(&engine.Send{ diff --git a/go/vt/vtgate/sandbox_test.go b/go/vt/vtgate/sandbox_test.go index dc3c1f103af..e8ae096e062 100644 --- a/go/vt/vtgate/sandbox_test.go +++ b/go/vt/vtgate/sandbox_test.go @@ -48,6 +48,7 @@ const ( func init() { ksToSandbox = make(map[string]*sandbox) + sandboxMirrorRules = `{"rules":[]}` createSandbox(KsTestSharded) createSandbox(KsTestUnsharded) createSandbox(KsTestBadVSchema) @@ -57,6 +58,7 @@ func init() { var sandboxMu sync.Mutex var ksToSandbox map[string]*sandbox +var sandboxMirrorRules string func createSandbox(keyspace string) *sandbox { sandboxMu.Lock() @@ -86,9 +88,20 @@ func getSandboxSrvVSchema() *vschemapb.SrvVSchema { } result.Keyspaces[keyspace] = &vs } + var mrs vschemapb.MirrorRules + if err := json2.Unmarshal([]byte(sandboxMirrorRules), &mrs); err != nil { + panic(err) + } + result.MirrorRules = &mrs return result } +func setSandboxMirrorRules(mirrorRules string) { + sandboxMu.Lock() + defer sandboxMu.Unlock() + sandboxMirrorRules = mirrorRules +} + type sandbox struct { // Use sandmu to access the variables below sandmu sync.Mutex diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 9372012f77d..53c3feeab63 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -250,7 +250,7 @@ func (vc *vcursorImpl) IsShardRoutingEnabled() bool { return enableShardRouting } -// FindTable finds the specified table. If the keyspace what specified in the input, it gets used as qualifier. +// FindTable finds the specified table. If the keyspace was specified in the input, it gets used as qualifier. // Otherwise, the keyspace from the request is used, if one was provided. func (vc *vcursorImpl) FindTable(name sqlparser.TableName) (*vindexes.Table, string, topodatapb.TabletType, key.Destination, error) { destKeyspace, destTabletType, dest, err := vc.executor.ParseDestinationTarget(name.Qualifier.String()) @@ -1079,6 +1079,23 @@ func (vc *vcursorImpl) GetAggregateUDFs() []string { return vc.vschema.GetAggregateUDFs() } +// FindMirrorRule finds the mirror rule for the requested table name and +// VSchema tablet type. +func (vc *vcursorImpl) FindMirrorRule(name sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { + destKeyspace, destTabletType, dest, err := vc.executor.ParseDestinationTarget(name.Qualifier.String()) + if err != nil { + return nil, "", destTabletType, nil, err + } + if destKeyspace == "" { + destKeyspace = vc.keyspace + } + mirrorRule, err := vc.vschema.FindMirrorRule(destKeyspace, name.Name.String(), destTabletType) + if err != nil { + return nil, "", destTabletType, nil, err + } + return mirrorRule, destKeyspace, destTabletType, dest, err +} + // ParseDestinationTarget parses destination target string and sets default keyspace if possible. func parseDestinationTarget(targetString string, vschema *vindexes.VSchema) (string, topodatapb.TabletType, key.Destination, error) { destKeyspace, destTabletType, dest, err := topoprotopb.ParseDestination(targetString, defaultTabletType) @@ -1356,6 +1373,37 @@ func (vc *vcursorImpl) CloneForReplicaWarming(ctx context.Context) engine.VCurso return v } +func (vc *vcursorImpl) CloneForMirroring(ctx context.Context) engine.VCursor { + callerId := callerid.EffectiveCallerIDFromContext(ctx) + immediateCallerId := callerid.ImmediateCallerIDFromContext(ctx) + + clonedCtx := callerid.NewContext(ctx, callerId, immediateCallerId) + + v := &vcursorImpl{ + safeSession: NewAutocommitSession(vc.safeSession.Session), + keyspace: vc.keyspace, + tabletType: vc.tabletType, + destination: vc.destination, + marginComments: vc.marginComments, + executor: vc.executor, + resolver: vc.resolver, + topoServer: vc.topoServer, + logStats: &logstats.LogStats{Ctx: clonedCtx}, + collation: vc.collation, + ignoreMaxMemoryRows: vc.ignoreMaxMemoryRows, + vschema: vc.vschema, + vm: vc.vm, + semTable: vc.semTable, + warnShardedOnly: vc.warnShardedOnly, + warnings: vc.warnings, + pv: vc.pv, + } + + v.marginComments.Trailing += "/* mirror query */" + + return v +} + // UpdateForeignKeyChecksState updates the foreign key checks state of the vcursor. func (vc *vcursorImpl) UpdateForeignKeyChecksState(fkStateFromQuery *bool) { // Initialize the state to unspecified. diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 924a28b309d..4b7ec271393 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -63,6 +63,7 @@ const ( // VSchema represents the denormalized version of SrvVSchema, // used for building routing plans. type VSchema struct { + MirrorRules map[string]*MirrorRule `json:"mirror_rules"` RoutingRules map[string]*RoutingRule `json:"routing_rules"` // globalTables contains the name of all tables in all keyspaces. If the @@ -79,13 +80,34 @@ type VSchema struct { created time.Time } +// MirrorRule represents one mirror rule. +type MirrorRule struct { + Error error + Percent float32 `json:"percent,omitempty"` + Table *Table `json:"table,omitempty"` +} + +// MarshalJSON returns a JSON representation of MirrorRule. +func (mr *MirrorRule) MarshalJSON() ([]byte, error) { + if mr.Error != nil { + return json.Marshal(mr.Error.Error()) + } + return json.Marshal(struct { + Percent float32 + Table *Table + }{ + Percent: mr.Percent, + Table: mr.Table, + }) +} + // RoutingRule represents one routing rule. type RoutingRule struct { Tables []*Table Error error } -// MarshalJSON returns a JSON representation of Column. +// MarshalJSON returns a JSON representation of RoutingRule. func (rr *RoutingRule) MarshalJSON() ([]byte, error) { if rr.Error != nil { return json.Marshal(rr.Error.Error()) @@ -324,6 +346,7 @@ func (source *Source) String() string { // BuildVSchema builds a VSchema from a SrvVSchema. func BuildVSchema(source *vschemapb.SrvVSchema, parser *sqlparser.Parser) (vschema *VSchema) { vschema = &VSchema{ + MirrorRules: make(map[string]*MirrorRule), RoutingRules: make(map[string]*RoutingRule), globalTables: make(map[string]*Table), uniqueVindexes: make(map[string]Vindex), @@ -338,6 +361,7 @@ func BuildVSchema(source *vschemapb.SrvVSchema, parser *sqlparser.Parser) (vsche buildRoutingRule(source, vschema, parser) buildShardRoutingRule(source, vschema) buildKeyspaceRoutingRule(source, vschema) + buildMirrorRule(source, vschema, parser) // Resolve auto-increments after routing rules are built since sequence tables also obey routing rules. resolveAutoIncrement(source, vschema, parser) return vschema @@ -895,7 +919,7 @@ func escapeQualifiedTable(qualifiedTableName string) (string, error) { } func extractTableParts(tableName string, allowUnqualified bool) (string, string, error) { - errMsgFormat := "invalid table name: %s, it must be of the " + errMsgFormat := "invalid table name: '%s', it must be of the " if allowUnqualified { errMsgFormat = errMsgFormat + "unqualified form or the " } @@ -1025,6 +1049,216 @@ func buildKeyspaceRoutingRule(source *vschemapb.SrvVSchema, vschema *VSchema) { vschema.KeyspaceRoutingRules = rulesMap } +func buildMirrorRule(source *vschemapb.SrvVSchema, vschema *VSchema, parser *sqlparser.Parser) { + if source.MirrorRules == nil { + return + } + + // Used to validate no mirror chains exist. + fromTableKeyspaces := make(map[string]string) + toKeyspaces := make(map[string]struct{}) + + for _, rule := range source.MirrorRules.Rules { + toTable := rule.ToTable + + // + // Forbid duplicate FromTables expressions. + // + + if _, ok := vschema.MirrorRules[rule.FromTable]; ok { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_ALREADY_EXISTS, + "from table: duplicate rule for entry '%s'", + rule.FromTable, + ), + } + continue + } + + // + // Parse and validate FromTable. + // + + // Separate tablet-type from rest of FromTable. + fromTableParts := strings.Split(rule.FromTable, "@") + if len(fromTableParts) == 0 { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "from table: invalid table name: '%s'", + rule.FromTable, + ), + } + } + + // Escape and parse the FromTable, without table-type specifier. + fromTable, err := escapeQualifiedTable(fromTableParts[0]) + if err != nil { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "from table: %s", + err.Error(), + ), + } + continue + } + fromKeyspace, fromTableName, err := parser.ParseTable(fromTable) + if err != nil { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "from table: invalid table name: '%s'", + err.Error(), + ), + } + continue + } + + // Find the from table. + _, err = vschema.FindTable(fromKeyspace, fromTableName) + if err != nil { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "from table: %s", + err.Error(), + ), + } + continue + } + + // Validate the table-type, if specified. + if len(fromTableParts) > 1 { + fromTabletTypeSuffix := "@" + strings.Join(fromTableParts[1:], "") + var ok bool + for _, tabletTypeSuffix := range TabletTypeSuffix { + if tabletTypeSuffix == fromTabletTypeSuffix { + ok = true + break + } + } + if !ok { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "from table: invalid tablet type: '%s'", + rule.FromTable, + ), + } + continue + } + } + + // + // Parse and validate ToTable. + // + + // Forbid tablet-type specifier. + toTableParts := strings.Split(toTable, "@") + if len(toTableParts) != 1 || toTableParts[0] == "@" { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "to table: tablet type may not be specified: '%s'", + rule.ToTable, + ), + } + continue + } + + // Escape and parse the table. + toTable, err = escapeQualifiedTable(toTable) + if err != nil { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "to table: %s", + err.Error(), + ), + } + continue + } + toKeyspace, toTableName, err := parser.ParseTable(toTable) + if err != nil { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "to table: invalid table name: '%s'", + rule.ToTable, + ), + } + continue + } + + // Forbid self-mirroring. + if fromKeyspace == toKeyspace { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "to table: cannot reside in same keyspace as from table", + ), + } + continue + } + + // + // Find table in VSchema. + // + + t, err := vschema.FindTable(toKeyspace, toTableName) + if err != nil { + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Error: vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "to table: %s", + err.Error(), + ), + } + continue + } + + // + // Return non-error mirror rule. + // + + vschema.MirrorRules[rule.FromTable] = &MirrorRule{ + Table: t, + Percent: rule.Percent, + } + + // + // Save some info for validating no mirror chains exist + // + + fromTableKeyspaces[rule.FromTable] = fromKeyspace + toKeyspaces[toKeyspace] = struct{}{} + } + + // Forbid mirror chains. Keyspaces which are the target of a mirror rule + // may not be the source of another. + for fromTable, rule := range vschema.MirrorRules { + if rule.Error != nil { + continue + } + fromKeyspace, ok := fromTableKeyspaces[fromTable] + if !ok { + rule.Error = vterrors.Errorf( + vtrpcpb.Code_INTERNAL, + "[BUG] from table: failed to determine keyspace", + ) + continue + } + if _, ok := toKeyspaces[fromKeyspace]; ok { + rule.Error = vterrors.Errorf( + vtrpcpb.Code_INVALID_ARGUMENT, + "mirror chaining is not allowed", + ) + } + } +} + // FindTable returns a pointer to the Table. If a keyspace is specified, only tables // from that keyspace are searched. If the specified keyspace is unsharded // and no tables matched, it's considered valid: FindTable will construct a table @@ -1325,6 +1559,28 @@ func (vschema *VSchema) GetAggregateUDFs() (udfs []string) { return } +// FindMirroredTable finds a mirror rule from the keyspace, table name and +// tablet type. +func (vschema *VSchema) FindMirrorRule(keyspace, tablename string, tabletType topodatapb.TabletType) (*MirrorRule, error) { + qualified := tablename + if keyspace != "" { + qualified = keyspace + "." + tablename + } + fqtn := qualified + TabletTypeSuffix[tabletType] + // First look for a fully qualified table name: keyspace.table@tablet_type. + // Then look for one without tablet type: keyspace.table. + for _, name := range []string{fqtn, qualified} { + mr, ok := vschema.MirrorRules[name] + if ok { + if mr.Error != nil { + return nil, mr.Error + } + return mr, nil + } + } + return nil, nil +} + // ByCost provides the interface needed for ColumnVindexes to // be sorted by cost order. type ByCost []*ColumnVindex diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index 40cba720a0c..1014c752037 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -838,6 +838,7 @@ func TestVSchemaRoutingRules(t *testing.T) { Keyspace: ks2, } want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, RoutingRules: map[string]*RoutingRule{ "rt1": { Error: errors.New("table rt1 has more than one target: [ks1.t1 ks2.t2]"), @@ -852,10 +853,10 @@ func TestVSchemaRoutingRules(t *testing.T) { Error: errors.New("duplicate rule for entry dup"), }, "badname": { - Error: errors.New("invalid table name: t1.t2.t3, it must be of the qualified form . (dots are not allowed in either name)"), + Error: errors.New("invalid table name: 't1.t2.t3', it must be of the qualified form . (dots are not allowed in either name)"), }, "unqualified": { - Error: errors.New("invalid table name: t1, it must be of the qualified form . (dots are not allowed in either name)"), + Error: errors.New("invalid table name: 't1', it must be of the qualified form . (dots are not allowed in either name)"), }, "badkeyspace": { Error: errors.New("VT05003: unknown database 'ks3' in vschema"), @@ -897,6 +898,282 @@ func TestVSchemaRoutingRules(t *testing.T) { assert.Equal(t, string(wantb), string(gotb), string(gotb)) } +func TestVSchemaMirrorRules(t *testing.T) { + input := vschemapb.SrvVSchema{ + MirrorRules: &vschemapb.MirrorRules{ + Rules: []*vschemapb.MirrorRule{ + // Empty FromTable not allowed. + { + FromTable: "", + ToTable: "ks2.ks2t1", + }, + // Invalid FromTable, needs to be .[@]. + { + FromTable: "ks1", + ToTable: "ks2.ks2t1", + }, + // Invalid ToTable, needs to be .
. + { + FromTable: "ks1.ks1t1", + ToTable: "ks2", + }, + // Invalid ToTable, needs to be .
. + { + FromTable: "ks1.ks1t2", + ToTable: "ks2.ks2t2.c", + }, + // OK, unsharded => unsharded. + { + FromTable: "ks1.ks1t3", + ToTable: "ks2.ks2t3", + Percent: 50, + }, + // Invalid ToTable, needs to be .
. + { + FromTable: "ks1.ks1t4", + ToTable: "ks2.ks2t4@replica", + }, + // OK, unsharded@tablet-type => unsharded. + { + FromTable: "ks1.ks1t5@replica", + ToTable: "ks2.ks2t5", + }, + // Invalid FromTable tablet type.. + { + FromTable: "ks1.ks1t6@stone", + ToTable: "ks2.ks2t6", + }, + // OK, sharded => sharded. + { + FromTable: "ks3.ks3t1", + ToTable: "ks4.ks4t1", + Percent: 50, + }, + // OK, unsharded => sharded. + { + FromTable: "ks1.ks1t7", + ToTable: "ks4.ks4t1", + Percent: 50, + }, + // Destination sharded table must be defined in VSchema. + { + FromTable: "ks1.ks1t8", + ToTable: "ks4.ks4t2", + Percent: 50, + }, + // Source sharded table must be defined in VSchema. + { + FromTable: "ks3.ks3t2", + ToTable: "ks4.ks4t1", + Percent: 50, + }, + // Keyspaces that are the target of a rule may not be the + // source of another. + { + FromTable: "ks2.ks2t9", + ToTable: "ks4.ks4t1", + Percent: 50, + }, + }, + }, + RoutingRules: &vschemapb.RoutingRules{}, + Keyspaces: map[string]*vschemapb.Keyspace{ + "ks1": { + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Tables: map[string]*vschemapb.Table{}, + }, + "ks2": { + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Tables: map[string]*vschemapb.Table{}, + }, + "ks3": { + Sharded: true, + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Vindexes: map[string]*vschemapb.Vindex{ + "stfu1": { + Type: "stfu", + }, + }, + Tables: map[string]*vschemapb.Table{ + "ks3t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{ + { + Column: "id", + Name: "stfu1", + }, + }, + }, + }, + }, + "ks4": { + Sharded: true, + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Vindexes: map[string]*vschemapb.Vindex{ + "stfu1": { + Type: "stfu", + }, + }, + Tables: map[string]*vschemapb.Table{ + "ks4t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{ + { + Column: "id", + Name: "stfu1", + }, + }, + }, + }, + }, + }, + } + got := BuildVSchema(&input, sqlparser.NewTestParser()) + + ks1 := &Keyspace{ + Name: "ks1", + Sharded: false, + } + ks2 := &Keyspace{ + Name: "ks2", + Sharded: false, + } + ks3 := &Keyspace{ + Name: "ks3", + Sharded: true, + } + ks4 := &Keyspace{ + Name: "ks4", + Sharded: true, + } + + vindex1 := &stFU{ + name: "stfu1", + } + + ks3t1 := &Table{ + Name: sqlparser.NewIdentifierCS("ks3t1"), + Keyspace: ks3, + ColumnVindexes: []*ColumnVindex{{ + Columns: []sqlparser.IdentifierCI{sqlparser.NewIdentifierCI("id")}, + Type: "stfu", + Name: "stfu1", + Vindex: vindex1, + isUnique: vindex1.IsUnique(), + cost: vindex1.Cost(), + }}, + } + ks3t1.Ordered = []*ColumnVindex{ + ks3t1.ColumnVindexes[0], + } + + ks4t1 := &Table{ + Name: sqlparser.NewIdentifierCS("ks4t1"), + Keyspace: ks4, + ColumnVindexes: []*ColumnVindex{{ + Columns: []sqlparser.IdentifierCI{sqlparser.NewIdentifierCI("id")}, + Type: "stfu", + Name: "stfu1", + Vindex: vindex1, + isUnique: vindex1.IsUnique(), + cost: vindex1.Cost(), + }}, + } + ks4t1.Ordered = []*ColumnVindex{ + ks4t1.ColumnVindexes[0], + } + + want := &VSchema{ + MirrorRules: map[string]*MirrorRule{ + "": { + Error: errors.New("from table: invalid table name: '', it must be of the qualified form . (dots are not allowed in either name)"), + }, + "ks1": { + Error: errors.New("from table: invalid table name: 'ks1', it must be of the qualified form . (dots are not allowed in either name)"), + }, + "ks1.ks1t1": { + Error: errors.New("to table: invalid table name: 'ks2', it must be of the qualified form . (dots are not allowed in either name)"), + }, + "ks1.ks1t2": { + Error: errors.New("to table: invalid table name: 'ks2.ks2t2.c', it must be of the qualified form . (dots are not allowed in either name)"), + }, + "ks1.ks1t3": { + Table: &Table{ + Name: sqlparser.NewIdentifierCS("ks2t3"), + }, + Percent: 50, + }, + "ks1.ks1t4": { + Error: errors.New("to table: tablet type may not be specified: 'ks2.ks2t4@replica'"), + }, + "ks1.ks1t5@replica": { + Table: &Table{ + Name: sqlparser.NewIdentifierCS("ks2t5"), + }, + }, + "ks1.ks1t6@stone": { + Error: errors.New("from table: invalid tablet type: 'ks1.ks1t6@stone'"), + }, + "ks3.ks3t1": { + Table: ks4t1, + Percent: 50, + }, + "ks1.ks1t7": { + Table: ks4t1, + Percent: 50, + }, + "ks1.ks1t8": { + Error: errors.New("to table: table ks4t2 not found"), + }, + "ks3.ks3t2": { + Error: errors.New("from table: table ks3t2 not found"), + }, + "ks2.ks2t9": { + Error: errors.New("mirror chaining is not allowed"), + }, + }, + RoutingRules: map[string]*RoutingRule{}, + Keyspaces: map[string]*KeyspaceSchema{ + "ks1": { + Keyspace: ks1, + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Tables: map[string]*Table{}, + Vindexes: map[string]Vindex{}, + }, + "ks2": { + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Keyspace: ks2, + Tables: map[string]*Table{}, + Vindexes: map[string]Vindex{}, + }, + "ks3": { + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Keyspace: ks3, + Tables: map[string]*Table{ + "ks3t1": ks3t1, + }, + Vindexes: map[string]Vindex{ + "stfu1": vindex1, + }, + }, + "ks4": { + ForeignKeyMode: vschemapb.Keyspace_unmanaged, + Keyspace: ks4, + Tables: map[string]*Table{ + "ks4t1": ks4t1, + }, + Vindexes: map[string]Vindex{ + "stfu1": vindex1, + }, + }, + }, + } + + gotb, err := json.MarshalIndent(got, "", " ") + assert.NoError(t, err) + wantb, err := json.MarshalIndent(want, "", " ") + assert.NoError(t, err) + assert.Equal(t, string(wantb), string(gotb), string(gotb)) +} + func TestChooseVindexForType(t *testing.T) { testcases := []struct { in querypb.Type @@ -1247,6 +1524,7 @@ func TestShardedVSchemaMultiColumnVindex(t *testing.T) { t1.ColumnVindexes[0], } want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, RoutingRules: map[string]*RoutingRule{}, globalTables: map[string]*Table{ "t1": t1, @@ -1323,6 +1601,7 @@ func TestShardedVSchemaNotOwned(t *testing.T) { t1.ColumnVindexes[1], t1.ColumnVindexes[0]} want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, RoutingRules: map[string]*RoutingRule{}, globalTables: map[string]*Table{ "t1": t1, @@ -1430,6 +1709,7 @@ func TestBuildVSchemaDupSeq(t *testing.T) { Keyspace: ksb, Type: "sequence"} want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, RoutingRules: map[string]*RoutingRule{}, globalTables: map[string]*Table{ "t1": nil, @@ -1491,6 +1771,7 @@ func TestBuildVSchemaDupTable(t *testing.T) { Keyspace: ksb, } want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, RoutingRules: map[string]*RoutingRule{}, globalTables: map[string]*Table{ "t1": nil, @@ -1620,6 +1901,7 @@ func TestBuildVSchemaDupVindex(t *testing.T) { t2.ColumnVindexes[0], } want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, RoutingRules: map[string]*RoutingRule{}, globalTables: map[string]*Table{ "t1": nil, @@ -2206,6 +2488,7 @@ func TestSequence(t *testing.T) { t2.ColumnVindexes[0], } want := &VSchema{ + MirrorRules: map[string]*MirrorRule{}, RoutingRules: map[string]*RoutingRule{}, globalTables: map[string]*Table{ "seq": seq, diff --git a/go/vt/vtgate/vschema_manager_test.go b/go/vt/vtgate/vschema_manager_test.go index 32f83f0021a..4dfbf46db0a 100644 --- a/go/vt/vtgate/vschema_manager_test.go +++ b/go/vt/vtgate/vschema_manager_test.go @@ -234,6 +234,7 @@ func TestVSchemaUpdate(t *testing.T) { }, }, expected: &vindexes.VSchema{ + MirrorRules: map[string]*vindexes.MirrorRule{}, RoutingRules: map[string]*vindexes.RoutingRule{}, Keyspaces: map[string]*vindexes.KeyspaceSchema{ "ks": { @@ -456,6 +457,7 @@ func TestVSchemaUDFsUpdate(t *testing.T) { }, nil) utils.MustMatchFn(".globalTables", ".uniqueVindexes")(t, &vindexes.VSchema{ + MirrorRules: map[string]*vindexes.MirrorRule{}, RoutingRules: map[string]*vindexes.RoutingRule{}, Keyspaces: map[string]*vindexes.KeyspaceSchema{ "ks": { @@ -778,6 +780,7 @@ func TestVSchemaUpdateWithFKReferenceToInternalTables(t *testing.T) { }, nil) utils.MustMatchFn(".globalTables", ".uniqueVindexes")(t, &vindexes.VSchema{ + MirrorRules: map[string]*vindexes.MirrorRule{}, RoutingRules: map[string]*vindexes.RoutingRule{}, Keyspaces: map[string]*vindexes.KeyspaceSchema{ "ks": { @@ -827,6 +830,7 @@ func makeTestVSchema(ks string, sharded bool, tbls map[string]*vindexes.Table) * func makeTestEmptyVSchema() *vindexes.VSchema { return &vindexes.VSchema{ + MirrorRules: map[string]*vindexes.MirrorRule{}, RoutingRules: map[string]*vindexes.RoutingRule{}, Keyspaces: map[string]*vindexes.KeyspaceSchema{}, } diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go index b0b31e256cc..56a634ca70e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go @@ -106,6 +106,7 @@ func TestUpdateVSchema(t *testing.T) { expectUpdateCount(t, startCount+1) want := `{ + "mirror_rules": {}, "routing_rules": {}, "keyspaces": { "vttest": { From 8297086a31c4dd9dc3cdceea4f341cc43daccee4 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sat, 13 Jul 2024 10:23:48 -0400 Subject: [PATCH 09/27] cr: require.Error, ctx with timeout, license, lightweight Signed-off-by: Max Englander --- go/vt/vtgate/endtoend/mirror_test.go | 16 ++ go/vt/vtgate/endtoend/vstream_test.go | 34 ++- go/vt/vtgate/engine/cached_size.go | 50 ++--- go/vt/vtgate/engine/mirror.go | 165 +++++--------- go/vt/vtgate/engine/mirror_test.go | 8 +- go/vt/vtgate/planbuilder/builder.go | 9 +- .../planbuilder/testdata/mirror_cases.json | 211 ++++++++---------- 7 files changed, 196 insertions(+), 297 deletions(-) diff --git a/go/vt/vtgate/endtoend/mirror_test.go b/go/vt/vtgate/endtoend/mirror_test.go index 26175d1a8a8..41691f42e22 100644 --- a/go/vt/vtgate/endtoend/mirror_test.go +++ b/go/vt/vtgate/endtoend/mirror_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The Vitess Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package endtoend import ( diff --git a/go/vt/vtgate/endtoend/vstream_test.go b/go/vt/vtgate/endtoend/vstream_test.go index 1381b9448bd..6776c95012a 100644 --- a/go/vt/vtgate/endtoend/vstream_test.go +++ b/go/vt/vtgate/endtoend/vstream_test.go @@ -60,6 +60,7 @@ func initialize(ctx context.Context, t *testing.T) (*vtgateconn.VTGateConn, *mys } return gconn, conn, mconn, close } + func TestVStream(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -186,7 +187,7 @@ func TestVStreamCopyBasic(t *testing.T) { Lastpk: qr, }} var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -264,25 +265,17 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { defer cancel() conn, err := mysql.Connect(ctx, &vtParams) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) defer conn.Close() _, err = conn.ExecuteFetch("insert into t1_copy_all(id1,id2) values(1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8)", 1, false) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) _, err = conn.ExecuteFetch("insert into t1_copy_all_ks2(id1,id2) values(10,10), (20,20)", 1, false) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) _, err = conn.ExecuteFetch("insert into t1_copy_all_ks3(id1,id2) values(30,30), (40,40)", 1, false) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -351,13 +344,11 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { gconn, conn, mconn, closeConnections := initialize(ctx, t) defer closeConnections() - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} vgtid.ShardGtids = []*binlogdatapb.ShardGtid{c.shardGtid} reader, err := gconn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags) _, _ = conn, mconn - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) require.NotNil(t, reader) var evs []*binlogdatapb.VEvent var completedEvs []*binlogdatapb.VEvent @@ -434,7 +425,7 @@ func TestVStreamCopyResume(t *testing.T) { } var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -534,7 +525,7 @@ func TestVStreamCurrent(t *testing.T) { defer closeConnections() var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -588,7 +579,7 @@ func TestVStreamSharded(t *testing.T) { defer closeConnections() var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -673,7 +664,6 @@ func TestVStreamSharded(t *testing.T) { t.Fatalf("remote error: %v\n", err) } } - } // TestVStreamCopyTransactions tests that we are properly wrapping @@ -830,9 +820,11 @@ type VEventSorter []*binlogdatapb.VEvent func (v VEventSorter) Len() int { return len(v) } + func (v VEventSorter) Swap(i, j int) { v[i], v[j] = v[j], v[i] } + func (v VEventSorter) Less(i, j int) bool { valsI := v[i].GetRowEvent().RowChanges[0].After if valsI == nil { diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 09d6764bdc8..a26fd70c03f 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -731,24 +731,6 @@ func (cached *MergeSort) CachedSize(alloc bool) int64 { } return size } -func (cached *Mirror) CachedSize(alloc bool) int64 { - if cached == nil { - return int64(0) - } - size := int64(0) - if alloc { - size += int64(32) - } - // field Primitive vitess.io/vitess/go/vt/vtgate/engine.Primitive - if cc, ok := cached.Primitive.(cachedObject); ok { - size += cc.CachedSize(true) - } - // field Target vitess.io/vitess/go/vt/vtgate/engine.MirrorTarget - if cc, ok := cached.Target.(cachedObject); ok { - size += cc.CachedSize(true) - } - return size -} func (cached *NonLiteralUpdateInfo) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -813,20 +795,6 @@ func (cached *OrderedAggregate) CachedSize(alloc bool) int64 { } return size } -func (cached *PercentMirrorTarget) CachedSize(alloc bool) int64 { - if cached == nil { - return int64(0) - } - size := int64(0) - if alloc { - size += int64(24) - } - // field Primitive vitess.io/vitess/go/vt/vtgate/engine.Primitive - if cc, ok := cached.Primitive.(cachedObject); ok { - size += cc.CachedSize(true) - } - return size -} func (cached *Plan) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -1581,6 +1549,24 @@ func (cached *VitessMetadata) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Value))) return size } +func (cached *percentBasedMirror) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(48) + } + // field primitive vitess.io/vitess/go/vt/vtgate/engine.Primitive + if cc, ok := cached.primitive.(cachedObject); ok { + size += cc.CachedSize(true) + } + // field target vitess.io/vitess/go/vt/vtgate/engine.Primitive + if cc, ok := cached.target.(cachedObject); ok { + size += cc.CachedSize(true) + } + return size +} //go:nocheckptr func (cached *shardRoute) CachedSize(alloc bool) int64 { diff --git a/go/vt/vtgate/engine/mirror.go b/go/vt/vtgate/engine/mirror.go index a7f29707621..40b19ae7181 100644 --- a/go/vt/vtgate/engine/mirror.go +++ b/go/vt/vtgate/engine/mirror.go @@ -26,26 +26,13 @@ import ( ) type ( - // Mirror represents the instructions to execute an authoritative source, - // and compare the results of that execution to those of one or more - // non-authoritative mirroring targets. - Mirror struct { - Primitive Primitive - Target MirrorTarget - } - - // MirrorTarget contains the Primitive for mirroring a query to the - // non-authoritative target of the Mirror primitive. - MirrorTarget interface { - Primitive - Accept() bool - } - - // PercentMirrorTarget contains the Primitive to mirror to, an will - // Accept() an execution based if a random dice-roll is less than Percent. - PercentMirrorTarget struct { - Percent float32 - Primitive Primitive + // percentBasedMirror represents the instructions to execute an + // authoritative primitive and, based on whether a die-roll exceeds a + // percentage, to also execute a target Primitive. + percentBasedMirror struct { + percent float32 + primitive Primitive + target Primitive } ) @@ -55,66 +42,60 @@ const ( maxMirrorTargetLag = 100 * time.Millisecond ) -var ( - _ Primitive = (*Mirror)(nil) - _ Primitive = (MirrorTarget)(nil) - _ Primitive = (*PercentMirrorTarget)(nil) - _ MirrorTarget = (*PercentMirrorTarget)(nil) -) - -// NewMirror creates a Mirror. -func NewMirror(primitive Primitive, target MirrorTarget) *Mirror { - return &Mirror{primitive, target} -} +var _ Primitive = (*percentBasedMirror)(nil) -// NewPercentMirrorTarget creates a percentage-based Mirror target. -func NewPercentMirrorTarget(percent float32, primitive Primitive) *PercentMirrorTarget { - return &PercentMirrorTarget{percent, primitive} +// NewPercentBasedMirror creates a Mirror. +func NewPercentBasedMirror(percentage float32, primitive Primitive, target Primitive) *percentBasedMirror { + return &percentBasedMirror{percentage, primitive, target} } -func (m *Mirror) RouteType() string { +func (m *percentBasedMirror) RouteType() string { return "Mirror" } -func (m *Mirror) GetKeyspaceName() string { - return m.Primitive.GetKeyspaceName() +func (m *percentBasedMirror) GetKeyspaceName() string { + return m.primitive.GetKeyspaceName() } -func (m *Mirror) GetTableName() string { - return m.Primitive.GetTableName() +func (m *percentBasedMirror) GetTableName() string { + return m.primitive.GetTableName() } -func (m *Mirror) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - return m.Primitive.GetFields(ctx, vcursor, bindVars) +func (m *percentBasedMirror) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return m.primitive.GetFields(ctx, vcursor, bindVars) } -func (m *Mirror) NeedsTransaction() bool { - return m.Primitive.NeedsTransaction() +func (m *percentBasedMirror) NeedsTransaction() bool { + return m.primitive.NeedsTransaction() } -func (m *Mirror) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { +func (m *percentBasedMirror) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { var mirrorCh chan any + var mirrorCtx context.Context var mirrorCtxCancel func() - if m.Target.Accept() { + doMirror := m.percentAtLeastDieRoll() + + if doMirror { mirrorCh = make(chan any) - var mirrorCtx context.Context - mirrorCtx, mirrorCtxCancel = context.WithCancel(ctx) + mirrorCtx, mirrorCtxCancel = context.WithTimeout(ctx, maxMirrorTargetLag) defer mirrorCtxCancel() go func(target Primitive, vcursor VCursor) { defer close(mirrorCh) _, _ = target.TryExecute(mirrorCtx, vcursor, bindVars, wantfields) - }(m.Target, vcursor.CloneForMirroring(mirrorCtx)) + }(m.target, vcursor.CloneForMirroring(mirrorCtx)) } - r, err := m.Primitive.TryExecute(ctx, vcursor, bindVars, wantfields) + r, err := m.primitive.TryExecute(ctx, vcursor, bindVars, wantfields) - if mirrorCh != nil { + if doMirror { select { case <-mirrorCh: - case <-time.After(maxMirrorTargetLag): + // Mirroring completed within the allowed time. + case <-mirrorCtx.Done(): + // Mirroring took too long, cancel the mirror context. mirrorCtxCancel() } } @@ -122,31 +103,33 @@ func (m *Mirror) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[s return r, err } -func (m *Mirror) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - var mirrorCn chan any +func (m *percentBasedMirror) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + var mirrorCh chan any + var mirrorCtx context.Context var mirrorCtxCancel func() - if m.Target.Accept() { - mirrorCn = make(chan any) + doMirror := m.percentAtLeastDieRoll() - var mirrorCtx context.Context - mirrorCtx, mirrorCtxCancel = context.WithCancel(ctx) + if doMirror { + mirrorCh = make(chan any) + + mirrorCtx, mirrorCtxCancel = context.WithTimeout(ctx, maxMirrorTargetLag) defer mirrorCtxCancel() go func(target Primitive, vcursor VCursor) { - defer close(mirrorCn) + defer close(mirrorCh) _ = target.TryStreamExecute(mirrorCtx, vcursor, bindVars, wantfields, func(_ *sqltypes.Result) error { return nil }) - }(m.Target, vcursor.CloneForMirroring(mirrorCtx)) + }(m.target, vcursor.CloneForMirroring(mirrorCtx)) } - err := m.Primitive.TryStreamExecute(ctx, vcursor, bindVars, wantfields, callback) + err := m.primitive.TryStreamExecute(ctx, vcursor, bindVars, wantfields, callback) - if mirrorCn != nil { + if doMirror { select { - case <-mirrorCn: - case <-time.After(maxMirrorTargetLag): + case <-mirrorCh: + case <-ctx.Done(): mirrorCtxCancel() } } @@ -156,64 +139,22 @@ func (m *Mirror) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars // Inputs is a slice containing the inputs to this Primitive. // The returned map has additional information about the inputs, that is used in the description. -func (m *Mirror) Inputs() ([]Primitive, []map[string]any) { - return []Primitive{m.Primitive, m.Target}, nil +func (m *percentBasedMirror) Inputs() ([]Primitive, []map[string]any) { + return []Primitive{m.primitive, m.target}, nil } // description is the description, sans the inputs, of this Primitive. // to get the plan description with all children, use PrimitiveToPlanDescription() -func (m *Mirror) description() PrimitiveDescription { +func (m *percentBasedMirror) description() PrimitiveDescription { return PrimitiveDescription{ OperatorType: "Mirror", - } -} - -func (m *PercentMirrorTarget) RouteType() string { - return "PercentMirrorTarget" -} - -func (m *PercentMirrorTarget) GetKeyspaceName() string { - return m.Primitive.GetKeyspaceName() -} - -func (m *PercentMirrorTarget) GetTableName() string { - return m.Primitive.GetTableName() -} - -func (m *PercentMirrorTarget) GetFields(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (*sqltypes.Result, error) { - return m.Primitive.GetFields(ctx, vcursor, bindVars) -} - -func (m *PercentMirrorTarget) NeedsTransaction() bool { - return m.Primitive.NeedsTransaction() -} - -func (m *PercentMirrorTarget) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { - return m.Primitive.TryExecute(ctx, vcursor, bindVars, wantfields) -} - -func (m *PercentMirrorTarget) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - return m.Primitive.TryStreamExecute(ctx, vcursor, bindVars, wantfields, callback) -} - -// Inputs is a slice containing the inputs to this Primitive. -// The returned map has additional information about the inputs, that is used in the description. -func (m *PercentMirrorTarget) Inputs() ([]Primitive, []map[string]any) { - return []Primitive{m.Primitive}, nil -} - -// description is the description, sans the inputs, of this Primitive. -// to get the plan description with all children, use PrimitiveToPlanDescription() -func (m *PercentMirrorTarget) description() PrimitiveDescription { - return PrimitiveDescription{ - OperatorType: "MirrorTarget", - Variant: "Percent", + Variant: "PercentBased", Other: map[string]any{ - "Percent": m.Percent, + "Percent": m.percent, }, } } -func (m *PercentMirrorTarget) Accept() bool { - return m.Percent >= (rand.Float32() * 100.0) +func (m *percentBasedMirror) percentAtLeastDieRoll() bool { + return m.percent >= (rand.Float32() * 100.0) } diff --git a/go/vt/vtgate/engine/mirror_test.go b/go/vt/vtgate/engine/mirror_test.go index 2777b6c35b2..b9e442df32d 100644 --- a/go/vt/vtgate/engine/mirror_test.go +++ b/go/vt/vtgate/engine/mirror_test.go @@ -58,13 +58,7 @@ func TestMirror(t *testing.T) { evalengine.NewLiteralInt(1), } - mirror := &Mirror{ - Primitive: primitive, - Target: &PercentMirrorTarget{ - Percent: 100, - Primitive: mirrorPrimitive1, - }, - } + mirror := NewPercentBasedMirror(100, primitive, mirrorPrimitive1) mirrorVC := &loggingVCursor{ shards: []string{"-20", "20-"}, diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index ee4907be922..1031cd08c67 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -43,9 +43,7 @@ const ( Gen4Left2Right = querypb.ExecuteOptions_Gen4Left2Right ) -var ( - plannerVersions = []plancontext.PlannerVersion{Gen4, Gen4GreedyOnly, Gen4Left2Right} -) +var plannerVersions = []plancontext.PlannerVersion{Gen4, Gen4GreedyOnly, Gen4Left2Right} type ( planResult struct { @@ -212,10 +210,7 @@ func buildRoutePlanWithMirroring(stmt sqlparser.Statement, reservedVars *sqlpars copy(tables[len(plan.tables):], target.tables) operators.SortTableNames(tables) return &planResult{ - engine.NewMirror( - plan.primitive, - engine.NewPercentMirrorTarget(percent, target.primitive), - ), + engine.NewPercentBasedMirror(percent, plan.primitive, target.primitive), tables, }, nil } diff --git a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json index c8014721d5f..061badda9f8 100644 --- a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json @@ -7,6 +7,8 @@ "Original": "select t1.id from unsharded_src1.t1 where t1.id = 1", "Instructions": { "OperatorType": "Mirror", + "Variant": "PercentBased", + "Percent": 50, "Inputs": [ { "OperatorType": "Route", @@ -20,22 +22,15 @@ "Table": "t1" }, { - "OperatorType": "MirrorTarget", - "Variant": "Percent", - "Percent": 50, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "unsharded_dst1", - "Sharded": false - }, - "FieldQuery": "select t1.id from t1 where 1 != 1", - "Query": "select t1.id from t1 where t1.id = 1", - "Table": "t1" - } - ] + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1 where t1.id = 1", + "Table": "t1" } ] }, @@ -53,6 +48,8 @@ "Original": "select t1.id from unsharded_src1.t1 where t1.id = 1", "Instructions": { "OperatorType": "Mirror", + "Variant": "PercentBased", + "Percent": 50, "Inputs": [ { "OperatorType": "Route", @@ -66,22 +63,15 @@ "Table": "t1" }, { - "OperatorType": "MirrorTarget", - "Variant": "Percent", - "Percent": 50, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "unsharded_dst1", - "Sharded": false - }, - "FieldQuery": "select t1.id from t1 where 1 != 1", - "Query": "select t1.id from t1 where t1.id = 1", - "Table": "t1" - } - ] + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false + }, + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1 where t1.id = 1", + "Table": "t1" } ] }, @@ -99,6 +89,8 @@ "Original": "select t1.id, t2.id from unsharded_src1.t1, unsharded_src1.t2 where t1.id = t2.id", "Instructions": { "OperatorType": "Mirror", + "Variant": "PercentBased", + "Percent": 50, "Inputs": [ { "OperatorType": "Route", @@ -112,46 +104,39 @@ "Table": "t1, t2" }, { - "OperatorType": "MirrorTarget", - "Variant": "Percent", - "Percent": 50, + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "L:0,R:0", + "JoinVars": { + "t1_id": 0 + }, + "TableName": "t1_t1", "Inputs": [ { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "L:0,R:0", - "JoinVars": { - "t1_id": 0 + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false }, - "TableName": "t1_t1", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "unsharded_dst1", - "Sharded": false - }, - "FieldQuery": "select t1.id from t1 where 1 != 1", - "Query": "select t1.id from t1", - "Table": "t1" - }, - { - "OperatorType": "Route", - "Variant": "EqualUnique", - "Keyspace": { - "Name": "sharded_dst1", - "Sharded": true - }, - "FieldQuery": "select t2.id from t1 as t2 where 1 != 1", - "Query": "select t2.id from t1 as t2 where t2.id = :t1_id", - "Table": "t1", - "Values": [ - ":t1_id" - ], - "Vindex": "xxhash" - } - ] + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1", + "Table": "t1" + }, + { + "OperatorType": "Route", + "Variant": "EqualUnique", + "Keyspace": { + "Name": "sharded_dst1", + "Sharded": true + }, + "FieldQuery": "select t2.id from t1 as t2 where 1 != 1", + "Query": "select t2.id from t1 as t2 where t2.id = :t1_id", + "Table": "t1", + "Values": [ + ":t1_id" + ], + "Vindex": "xxhash" } ] } @@ -173,6 +158,8 @@ "Original": "select t1.id from unsharded_src1.t1 union select t2.id from unsharded_src1.t2", "Instructions": { "OperatorType": "Mirror", + "Variant": "PercentBased", + "Percent": 50, "Inputs": [ { "OperatorType": "Route", @@ -186,43 +173,36 @@ "Table": "t1, t2" }, { - "OperatorType": "MirrorTarget", - "Variant": "Percent", - "Percent": 50, + "OperatorType": "Distinct", + "Collations": [ + "(0:1)" + ], + "ResultColumns": 1, "Inputs": [ { - "OperatorType": "Distinct", - "Collations": [ - "(0:1)" - ], - "ResultColumns": 1, + "OperatorType": "Concatenate", "Inputs": [ { - "OperatorType": "Concatenate", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "unsharded_dst1", - "Sharded": false - }, - "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select t1.id from t1 where 1 != 1) as dt(c0) where 1 != 1", - "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct t1.id from t1) as dt(c0)", - "Table": "t1" - }, - { - "OperatorType": "Route", - "Variant": "Scatter", - "Keyspace": { - "Name": "sharded_dst1", - "Sharded": true - }, - "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select t2.id from t1 as t2 where 1 != 1) as dt(c0) where 1 != 1", - "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct t2.id from t1 as t2) as dt(c0)", - "Table": "t1" - } - ] + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst1", + "Sharded": false + }, + "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select t1.id from t1 where 1 != 1) as dt(c0) where 1 != 1", + "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct t1.id from t1) as dt(c0)", + "Table": "t1" + }, + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "sharded_dst1", + "Sharded": true + }, + "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select t2.id from t1 as t2 where 1 != 1) as dt(c0) where 1 != 1", + "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct t2.id from t1 as t2) as dt(c0)", + "Table": "t1" } ] } @@ -334,6 +314,8 @@ "Original": "select t2.id from unsharded_src2.t2", "Instructions": { "OperatorType": "Mirror", + "Variant": "PercentBased", + "Percent": 50, "Inputs": [ { "OperatorType": "Route", @@ -347,22 +329,15 @@ "Table": "t2" }, { - "OperatorType": "MirrorTarget", - "Variant": "Percent", - "Percent": 50, - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "Unsharded", - "Keyspace": { - "Name": "unsharded_dst2", - "Sharded": false - }, - "FieldQuery": "select t2.id from t2 where 1 != 1", - "Query": "select t2.id from t2", - "Table": "t2" - } - ] + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_dst2", + "Sharded": false + }, + "FieldQuery": "select t2.id from t2 where 1 != 1", + "Query": "select t2.id from t2", + "Table": "t2" } ] }, From ec7d174c5a643b1723d8b7c45a1979266687fb5e Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sat, 13 Jul 2024 13:36:20 -0400 Subject: [PATCH 10/27] cr: go/vt/vtgate/endtoend => go/test/endtoend/vtgate Signed-off-by: Max Englander --- go/test/endtoend/cluster/cluster_process.go | 6 +- .../queries/benchmark/benchmark_test.go | 186 +++++++++++++++++- .../vtgate/queries/benchmark/main_test.go | 109 +++++++--- ...sharded_schema.sql => sharded_schema1.sql} | 14 +- .../queries/benchmark/sharded_schema2.sql | 5 + .../queries/benchmark/sharded_schema3.sql | 5 + .../vtgate/queries/benchmark/vschema1.json | 34 ++++ .../benchmark/{vschema.json => vschema2.json} | 4 +- .../vtgate/queries/benchmark/vschema3.json | 18 ++ go/vt/vtgate/endtoend/main_test.go | 72 ------- go/vt/vtgate/endtoend/schema.sql | 12 +- go/vt/vtgate/endtoend/vstream_test.go | 38 ++-- 12 files changed, 362 insertions(+), 141 deletions(-) rename go/test/endtoend/vtgate/queries/benchmark/{sharded_schema.sql => sharded_schema1.sql} (58%) create mode 100644 go/test/endtoend/vtgate/queries/benchmark/sharded_schema2.sql create mode 100644 go/test/endtoend/vtgate/queries/benchmark/sharded_schema3.sql create mode 100644 go/test/endtoend/vtgate/queries/benchmark/vschema1.json rename go/test/endtoend/vtgate/queries/benchmark/{vschema.json => vschema2.json} (89%) create mode 100644 go/test/endtoend/vtgate/queries/benchmark/vschema3.json diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index 44636b3cdb6..e3daaacdab3 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -281,7 +281,6 @@ func (cluster *LocalProcessCluster) StartUnshardedKeyspace(keyspace Keyspace, re } func (cluster *LocalProcessCluster) startPartialKeyspace(keyspace Keyspace, shardNames []string, movedShard string, replicaCount int, rdonly bool, customizers ...any) (err error) { - cluster.HasPartialKeyspaces = true routedKeyspace := &Keyspace{ Name: fmt.Sprintf("%s_routed", keyspace.Name), @@ -1131,7 +1130,8 @@ func (cluster *LocalProcessCluster) waitForMySQLProcessToExit(mysqlctlProcessLis // StartVtbackup starts a vtbackup func (cluster *LocalProcessCluster) StartVtbackup(newInitDBFile string, initialBackup bool, - keyspace string, shard string, cell string, extraArgs ...string) error { + keyspace string, shard string, cell string, extraArgs ...string, +) error { log.Info("Starting vtbackup") cluster.VtbackupProcess = *VtbackupProcessInstance( cluster.GetAndReserveTabletUID(), @@ -1146,7 +1146,6 @@ func (cluster *LocalProcessCluster) StartVtbackup(newInitDBFile string, initialB initialBackup) cluster.VtbackupProcess.ExtraArgs = extraArgs return cluster.VtbackupProcess.Setup() - } // GetAndReservePort gives port for required process @@ -1162,7 +1161,6 @@ func (cluster *LocalProcessCluster) GetAndReservePort() int { cluster.nextPortForProcess = cluster.nextPortForProcess + 1 log.Infof("Attempting to reserve port: %v", cluster.nextPortForProcess) ln, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(cluster.nextPortForProcess))) - if err != nil { log.Errorf("Can't listen on port %v: %s, trying next port", cluster.nextPortForProcess, err) continue diff --git a/go/test/endtoend/vtgate/queries/benchmark/benchmark_test.go b/go/test/endtoend/vtgate/queries/benchmark/benchmark_test.go index 9a064c1769a..261364bb52b 100644 --- a/go/test/endtoend/vtgate/queries/benchmark/benchmark_test.go +++ b/go/test/endtoend/vtgate/queries/benchmark/benchmark_test.go @@ -18,12 +18,20 @@ package dml import ( "fmt" + "maps" "math/rand/v2" "strconv" "strings" + "sync" "testing" + "time" + + "github.com/stretchr/testify/require" + mapsx "golang.org/x/exp/maps" + "google.golang.org/protobuf/encoding/protojson" "vitess.io/vitess/go/test/endtoend/utils" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) type testQuery struct { @@ -98,7 +106,7 @@ func BenchmarkShardedTblNoLookup(b *testing.B) { } for _, rows := range []int{1, 10, 100, 500, 1000, 5000, 10000} { insStmt := tq.getInsertQuery(rows) - b.Run(fmt.Sprintf("16-shards-%d-rows", rows), func(b *testing.B) { + b.Run(fmt.Sprintf("4-shards-%d-rows", rows), func(b *testing.B) { for i := 0; i < b.N; i++ { _ = utils.Exec(b, conn, insStmt) } @@ -121,7 +129,7 @@ func BenchmarkShardedTblUpdateIn(b *testing.B) { _ = utils.Exec(b, conn, insStmt) for _, rows := range []int{1, 10, 100, 500, 1000, 5000, 10000} { updStmt := tq.getUpdateQuery(rows) - b.Run(fmt.Sprintf("16-shards-%d-rows", rows), func(b *testing.B) { + b.Run(fmt.Sprintf("4-shards-%d-rows", rows), func(b *testing.B) { for i := 0; i < b.N; i++ { _ = utils.Exec(b, conn, updStmt) } @@ -139,10 +147,182 @@ func BenchmarkShardedTblDeleteIn(b *testing.B) { insStmt := tq.getInsertQuery(rows) _ = utils.Exec(b, conn, insStmt) delStmt := tq.getDeleteQuery(rows) - b.Run(fmt.Sprintf("16-shards-%d-rows", rows), func(b *testing.B) { + b.Run(fmt.Sprintf("4-shards-%d-rows", rows), func(b *testing.B) { for i := 0; i < b.N; i++ { _ = utils.Exec(b, conn, delStmt) } }) } } + +var mirrorInitOnce sync.Once + +func BenchmarkMirror(b *testing.B) { + const numRows = 10000 + + conn, closer := start(b) + defer closer() + + // Each time this BenchmarkMirror runs, use a different source of + // randomness. But use the same source of randomness across test cases and + // mirror percentages sub test cases. + pcg := rand.NewPCG(rand.Uint64(), rand.Uint64()) + + ksTables := map[string]string{ + sKs2: "mirror_tbl1", + sKs3: "mirror_tbl2", + } + targetKeyspaces := mapsx.Keys(ksTables) + + mirrorInitOnce.Do(func() { + b.Logf("seeding database for benchmark...") + + for i := 0; i < numRows; i++ { + _, err := conn.ExecuteFetch( + fmt.Sprintf("INSERT INTO %s.mirror_tbl1(id) VALUES(%d)", sKs1, i), -1, false) + require.NoError(b, err) + + _, err = conn.ExecuteFetch( + fmt.Sprintf("INSERT INTO %s.mirror_tbl2(id) VALUES(%d)", sKs1, i), -1, false) + require.NoError(b, err) + } + + _, err := conn.ExecuteFetch( + fmt.Sprintf("SELECT COUNT(id) FROM %s.%s", sKs1, "mirror_tbl1"), 1, false) + require.NoError(b, err) + + b.Logf("finished (inserted %d rows)", numRows) + + b.Logf("using MoveTables to copy data from source keyspace to target keyspaces") + + // Set up MoveTables workflows, which is (at present) the only way to set up + // mirror rules. + for tks, tbl := range ksTables { + output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput( + "MoveTables", "--target-keyspace", tks, "--workflow", fmt.Sprintf("%s2%s", sKs1, tks), + "create", "--source-keyspace", sKs1, "--tables", tbl) + require.NoError(b, err, output) + } + + // Wait for tables to be copied from source to targets. + pending := make(map[string]string, len(ksTables)) + maps.Copy(pending, ksTables) + for len(pending) > 0 { + for tks := range ksTables { + output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput( + "Workflow", "--keyspace", tks, "show", "--workflow", fmt.Sprintf("%s2%s", sKs1, tks)) + require.NoError(b, err, output) + + var response vtctldatapb.GetWorkflowsResponse + require.NoError(b, protojson.Unmarshal([]byte(output), &response)) + + require.Len(b, response.Workflows, 1) + workflow := response.Workflows[0] + + require.Len(b, workflow.ShardStreams, 4 /*shards*/) + for _, ss := range workflow.ShardStreams { + for _, s := range ss.Streams { + if s.State == "Running" { + delete(pending, tks) + } else { + b.Logf("waiting for workflow %s.%s stream %s=>%s to be running; last state: %s", + workflow.Target, workflow.Name, s.BinlogSource.Shard, s.Shard, s.State) + time.Sleep(1 * time.Second) + } + } + } + } + } + }) + + testCases := []struct { + name string + run func(*testing.B, *rand.Rand) + }{ + { + name: "point select, { sks1 => sks2 }.mirror_tbl1", + run: func(b *testing.B, rnd *rand.Rand) { + for i := 0; i < b.N; i++ { + id := rnd.Int32N(numRows) + _, err := conn.ExecuteFetch(fmt.Sprintf( + "SELECT t1.id FROM %s.mirror_tbl1 AS t1 WHERE t1.id = %d", + sKs1, id, + ), 1, false) + if err != nil { + b.Error(err) + } + } + }, + }, + { + name: "point select, { sks1 => sks2 }.mirror_tbl1, { sks1 => sks3 }.mirror_tbl2", + run: func(b *testing.B, rnd *rand.Rand) { + for i := 0; i < b.N; i++ { + id := rnd.Int32N(numRows) + _, err := conn.ExecuteFetch(fmt.Sprintf( + "SELECT t1.id, t2.id FROM %s.mirror_tbl1 AS t1, %s.mirror_tbl2 AS t2 WHERE t1.id = %d AND t2.id = %d", + sKs1, sKs1, id, id, + ), 1, false) + if err != nil { + b.Error(err) + } + } + }, + }, + } + + for _, tc := range testCases { + b.Run(tc.name, func(b *testing.B) { + b.Run("mirror 0%", func(b *testing.B) { + mirrorTraffic(b, targetKeyspaces, 0) + b.ResetTimer() + tc.run(b, rand.New(pcg)) + }) + + b.Run("mirror 1%", func(b *testing.B) { + mirrorTraffic(b, targetKeyspaces, 1) + b.ResetTimer() + tc.run(b, rand.New(pcg)) + }) + + b.Run("mirror 5%", func(b *testing.B) { + mirrorTraffic(b, targetKeyspaces, 5) + b.ResetTimer() + tc.run(b, rand.New(pcg)) + }) + + b.Run("mirror 10%", func(b *testing.B) { + mirrorTraffic(b, targetKeyspaces, 10) + b.ResetTimer() + tc.run(b, rand.New(pcg)) + }) + + b.Run("mirror 25%", func(b *testing.B) { + mirrorTraffic(b, targetKeyspaces, 25) + b.ResetTimer() + tc.run(b, rand.New(pcg)) + }) + + b.Run("mirror 50%", func(b *testing.B) { + mirrorTraffic(b, targetKeyspaces, 50) + b.ResetTimer() + tc.run(b, rand.New(pcg)) + }) + + b.Run("mirror 100%", func(b *testing.B) { + mirrorTraffic(b, targetKeyspaces, 100) + b.ResetTimer() + tc.run(b, rand.New(pcg)) + }) + }) + } +} + +func mirrorTraffic(b *testing.B, targetKeyspaces []string, percent float32) { + for _, tks := range targetKeyspaces { + output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput( + "MoveTables", "--target-keyspace", tks, "--workflow", fmt.Sprintf("%s2%s", sKs1, tks), + "mirrortraffic", "--percent", fmt.Sprintf("%.02f", percent)) + require.NoError(b, err, output) + } +} diff --git a/go/test/endtoend/vtgate/queries/benchmark/main_test.go b/go/test/endtoend/vtgate/queries/benchmark/main_test.go index 6978d0b9428..82cad2a2ba0 100644 --- a/go/test/endtoend/vtgate/queries/benchmark/main_test.go +++ b/go/test/endtoend/vtgate/queries/benchmark/main_test.go @@ -1,6 +1,7 @@ /* Copyright 2023 The Vitess Authors. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -20,8 +21,10 @@ import ( "context" _ "embed" "flag" + "fmt" "os" "testing" + "time" "github.com/stretchr/testify/require" @@ -34,36 +37,34 @@ var ( clusterInstance *cluster.LocalProcessCluster vtParams mysql.ConnParams mysqlParams mysql.ConnParams - sKs = "sks" - uKs = "uks" + sKs1 = "sks1" + sKs2 = "sks2" + sKs3 = "sks3" cell = "test" - //go:embed sharded_schema.sql - sSchemaSQL string + //go:embed sharded_schema1.sql + sSchemaSQL1 string - //go:embed vschema.json - sVSchema string -) + //go:embed vschema1.json + sVSchema1 string -var ( - shards4 = []string{ - "-40", "40-80", "80-c0", "c0-", - } + //go:embed sharded_schema2.sql + sSchemaSQL2 string - shards8 = []string{ - "-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-", - } + //go:embed vschema2.json + sVSchema2 string - shards16 = []string{ - "-10", "10-20", "20-30", "30-40", "40-50", "50-60", "60-70", "70-80", "80-90", "90-a0", "a0-b0", "b0-c0", "c0-d0", "d0-e0", "e0-f0", "f0-", - } + //go:embed sharded_schema3.sql + sSchemaSQL3 string - shards32 = []string{ - "-05", "05-10", "10-15", "15-20", "20-25", "25-30", "30-35", "35-40", "40-45", "45-50", "50-55", "55-60", "60-65", "65-70", "70-75", "75-80", - "80-85", "85-90", "90-95", "95-a0", "a0-a5", "a5-b0", "b0-b5", "b5-c0", "c0-c5", "c5-d0", "d0-d5", "d5-e0", "e0-e5", "e5-f0", "f0-f5", "f5-", - } + //go:embed vschema3.json + sVSchema3 string ) +var shards4 = []string{ + "-40", "40-80", "80-c0", "c0-", +} + func TestMain(m *testing.M) { defer cluster.PanicHandler(nil) flag.Parse() @@ -78,14 +79,38 @@ func TestMain(m *testing.M) { return 1 } - // Start sharded keyspace - sKeyspace := &cluster.Keyspace{ - Name: sKs, - SchemaSQL: sSchemaSQL, - VSchema: sVSchema, + // Start sharded keyspace 1 + sKeyspace1 := &cluster.Keyspace{ + Name: sKs1, + SchemaSQL: sSchemaSQL1, + VSchema: sVSchema1, + } + + err = clusterInstance.StartKeyspace(*sKeyspace1, shards4, 0, false) + if err != nil { + return 1 + } + + // Start sharded keyspace 2 + sKeyspace2 := &cluster.Keyspace{ + Name: sKs2, + SchemaSQL: sSchemaSQL2, + VSchema: sVSchema2, } - err = clusterInstance.StartKeyspace(*sKeyspace, shards4, 0, false) + err = clusterInstance.StartKeyspace(*sKeyspace2, shards4, 0, false) + if err != nil { + return 1 + } + + // Start sharded keyspace 3 + sKeyspace3 := &cluster.Keyspace{ + Name: sKs3, + SchemaSQL: sSchemaSQL3, + VSchema: sVSchema3, + } + + err = clusterInstance.StartKeyspace(*sKeyspace3, shards4, 0, false) if err != nil { return 1 } @@ -96,7 +121,7 @@ func TestMain(m *testing.M) { return 1 } - vtParams = clusterInstance.GetVTParams(sKs) + vtParams = clusterInstance.GetVTParams("@primary") return m.Run() }() @@ -108,12 +133,38 @@ func start(b *testing.B) (*mysql.Conn, func()) { require.NoError(b, err) deleteAll := func() { - tables := []string{"tbl_no_lkp_vdx"} + tables := []string{ + fmt.Sprintf("%s.tbl_no_lkp_vdx", sKs1), + fmt.Sprintf("%s.mirror_tbl1", sKs1), + fmt.Sprintf("%s.mirror_tbl2", sKs1), + fmt.Sprintf("%s.mirror_tbl1", sKs2), + fmt.Sprintf("%s.mirror_tbl2", sKs3), + } for _, table := range tables { _, _ = utils.ExecAllowError(b, conn, "delete from "+table) } } + // Make sure all keyspaces are serving. + pending := map[string]string{ + sKs1: "mirror_tbl1", + sKs2: "mirror_tbl1", + sKs3: "mirror_tbl2", + } + for len(pending) > 0 { + for ks, tbl := range pending { + _, err := conn.ExecuteFetch( + fmt.Sprintf("SELECT COUNT(id) FROM %s.%s", ks, tbl), 1, false) + if err != nil { + b.Logf("waiting for keyspace %s to be serving; last error: %v", ks, err) + time.Sleep(1 * time.Second) + } else { + delete(pending, ks) + } + } + } + + // Delete any pre-existing data. deleteAll() return conn, func() { diff --git a/go/test/endtoend/vtgate/queries/benchmark/sharded_schema.sql b/go/test/endtoend/vtgate/queries/benchmark/sharded_schema1.sql similarity index 58% rename from go/test/endtoend/vtgate/queries/benchmark/sharded_schema.sql rename to go/test/endtoend/vtgate/queries/benchmark/sharded_schema1.sql index 850b6ffc15a..409ca82e251 100644 --- a/go/test/endtoend/vtgate/queries/benchmark/sharded_schema.sql +++ b/go/test/endtoend/vtgate/queries/benchmark/sharded_schema1.sql @@ -13,4 +13,16 @@ create table tbl_no_lkp_vdx c10 varchar(50), c11 varchar(50), c12 varchar(50) -) Engine = InnoDB; \ No newline at end of file +) Engine = InnoDB; + +create table mirror_tbl1 +( + id bigint not null, + primary key(id) +) Engine = InnoDB; + +create table mirror_tbl2 +( + id bigint not null, + primary key(id) +) Engine = InnoDB; diff --git a/go/test/endtoend/vtgate/queries/benchmark/sharded_schema2.sql b/go/test/endtoend/vtgate/queries/benchmark/sharded_schema2.sql new file mode 100644 index 00000000000..4cba88b68ab --- /dev/null +++ b/go/test/endtoend/vtgate/queries/benchmark/sharded_schema2.sql @@ -0,0 +1,5 @@ +create table mirror_tbl1 +( + id bigint not null, + primary key(id) +) Engine = InnoDB; diff --git a/go/test/endtoend/vtgate/queries/benchmark/sharded_schema3.sql b/go/test/endtoend/vtgate/queries/benchmark/sharded_schema3.sql new file mode 100644 index 00000000000..e7e96f30357 --- /dev/null +++ b/go/test/endtoend/vtgate/queries/benchmark/sharded_schema3.sql @@ -0,0 +1,5 @@ +create table mirror_tbl2 +( + id bigint not null, + primary key(id) +) Engine = InnoDB; diff --git a/go/test/endtoend/vtgate/queries/benchmark/vschema1.json b/go/test/endtoend/vtgate/queries/benchmark/vschema1.json new file mode 100644 index 00000000000..bc5637355f3 --- /dev/null +++ b/go/test/endtoend/vtgate/queries/benchmark/vschema1.json @@ -0,0 +1,34 @@ +{ + "sharded": true, + "vindexes": { + "xxhash": { + "type": "xxhash" + } + }, + "tables": { + "tbl_no_lkp_vdx": { + "column_vindexes": [ + { + "column": "id", + "name": "xxhash" + } + ] + }, + "mirror_tbl1": { + "column_vindexes": [ + { + "column": "id", + "name": "xxhash" + } + ] + }, + "mirror_tbl2": { + "column_vindexes": [ + { + "column": "id", + "name": "xxhash" + } + ] + } + } +} diff --git a/go/test/endtoend/vtgate/queries/benchmark/vschema.json b/go/test/endtoend/vtgate/queries/benchmark/vschema2.json similarity index 89% rename from go/test/endtoend/vtgate/queries/benchmark/vschema.json rename to go/test/endtoend/vtgate/queries/benchmark/vschema2.json index 4970e8b7437..2ae87ad2ae4 100644 --- a/go/test/endtoend/vtgate/queries/benchmark/vschema.json +++ b/go/test/endtoend/vtgate/queries/benchmark/vschema2.json @@ -6,7 +6,7 @@ } }, "tables": { - "tbl_no_lkp_vdx": { + "mirror_tbl1": { "column_vindexes": [ { "column": "id", @@ -15,4 +15,4 @@ ] } } -} \ No newline at end of file +} diff --git a/go/test/endtoend/vtgate/queries/benchmark/vschema3.json b/go/test/endtoend/vtgate/queries/benchmark/vschema3.json new file mode 100644 index 00000000000..6e71d6bc157 --- /dev/null +++ b/go/test/endtoend/vtgate/queries/benchmark/vschema3.json @@ -0,0 +1,18 @@ +{ + "sharded": true, + "vindexes": { + "xxhash": { + "type": "xxhash" + } + }, + "tables": { + "mirror_tbl2": { + "column_vindexes": [ + { + "column": "id", + "name": "xxhash" + } + ] + } + } +} diff --git a/go/vt/vtgate/endtoend/main_test.go b/go/vt/vtgate/endtoend/main_test.go index 8f8cfb4b5a3..b471786b78e 100644 --- a/go/vt/vtgate/endtoend/main_test.go +++ b/go/vt/vtgate/endtoend/main_test.go @@ -166,18 +166,6 @@ var ( Type: sqltypes.Char, }}, }, - "mirror_tbl1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, - }, - "mirror_tbl2": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, - }, }, } @@ -187,11 +175,6 @@ create table t1_copy_all_ks2( id2 bigint, primary key(id1) ) Engine=InnoDB; - -create table mirror_tbl1( - id bigint not null, - primary key(id) -) Engine=InnoDB; ` vschema2 = &vschemapb.Keyspace{ @@ -208,48 +191,6 @@ create table mirror_tbl1( Name: "hash", }}, }, - "mirror_tbl1": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, - }, - }, - } - - schema3 = ` -create table t1_copy_all_ks3( - id1 bigint, - id2 bigint, - primary key(id1) -) Engine=InnoDB; - -create table mirror_tbl2( - id bigint not null, - primary key(id) -) Engine=InnoDB; -` - - vschema3 = &vschemapb.Keyspace{ - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "hash": { - Type: "hash", - }, - }, - Tables: map[string]*vschemapb.Table{ - "t1_copy_all_ks3": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id1", - Name: "hash", - }}, - }, - "mirror_tbl2": { - ColumnVindexes: []*vschemapb.ColumnVindex{{ - Column: "id", - Name: "hash", - }}, - }, }, } ) @@ -277,14 +218,6 @@ func TestMain(m *testing.M) { Name: "80-", }}, }, - { - Name: "ks3", - Shards: []*vttestpb.Shard{{ - Name: "-80", - }, { - Name: "80-", - }}, - }, }, } if err := cfg.InitSchemas("ks", Schema, vschema); err != nil { @@ -298,11 +231,6 @@ func TestMain(m *testing.M) { os.RemoveAll(cfg.SchemaDir) return 1 } - if err := cfg.InitSchemas("ks3", schema3, vschema3); err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.RemoveAll(cfg.SchemaDir) - return 1 - } cluster = &vttest.LocalCluster{ Config: cfg, diff --git a/go/vt/vtgate/endtoend/schema.sql b/go/vt/vtgate/endtoend/schema.sql index 4713c9057cf..d543d130c14 100644 --- a/go/vt/vtgate/endtoend/schema.sql +++ b/go/vt/vtgate/endtoend/schema.sql @@ -79,14 +79,4 @@ create table oltp_test( c char(120) default '' not null, pad char(60) default '' not null, primary key (id) -) Engine=InnoDB; - -create table mirror_tbl1( - id bigint not null, - primary key(id) -) Engine=InnoDB; - -create table mirror_tbl2( - id bigint not null, - primary key(id) -) Engine=InnoDB; +) Engine=InnoDB; \ No newline at end of file diff --git a/go/vt/vtgate/endtoend/vstream_test.go b/go/vt/vtgate/endtoend/vstream_test.go index 6776c95012a..246d17f88b5 100644 --- a/go/vt/vtgate/endtoend/vstream_test.go +++ b/go/vt/vtgate/endtoend/vstream_test.go @@ -60,7 +60,6 @@ func initialize(ctx context.Context, t *testing.T) (*vtgateconn.VTGateConn, *mys } return gconn, conn, mconn, close } - func TestVStream(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -187,7 +186,7 @@ func TestVStreamCopyBasic(t *testing.T) { Lastpk: qr, }} var shardGtids []*binlogdatapb.ShardGtid - vgtid := &binlogdatapb.VGtid{} + var vgtid = &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -265,17 +264,20 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { defer cancel() conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) + if err != nil { + require.NoError(t, err) + } defer conn.Close() _, err = conn.ExecuteFetch("insert into t1_copy_all(id1,id2) values(1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8)", 1, false) - require.NoError(t, err) + if err != nil { + require.NoError(t, err) + } _, err = conn.ExecuteFetch("insert into t1_copy_all_ks2(id1,id2) values(10,10), (20,20)", 1, false) - require.NoError(t, err) - - _, err = conn.ExecuteFetch("insert into t1_copy_all_ks3(id1,id2) values(30,30), (40,40)", 1, false) - require.NoError(t, err) + if err != nil { + require.NoError(t, err) + } filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -301,7 +303,6 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { // copy phase operations in the vstream. expectedKs1EventNum := 2 /* num shards */ * (9 /* begin/field/vgtid:pos/4 rowevents avg/vgitd: lastpk/commit) */ + 3 /* begin/vgtid/commit for completed table */ + 1 /* copy operation completed */) expectedKs2EventNum := 2 /* num shards */ * (6 /* begin/field/vgtid:pos/1 rowevents avg/vgitd: lastpk/commit) */ + 3 /* begin/vgtid/commit for completed table */ + 1 /* copy operation completed */) - expectedKs3EventNum := 2 /* num shards */ * (6 /* begin/field/vgtid:pos/1 rowevents avg/vgitd: lastpk/commit) */ + 3 /* begin/vgtid/commit for completed table */ + 1 /* copy operation completed */) expectedFullyCopyCompletedNum := 1 cases := []struct { @@ -315,14 +316,12 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { shardGtid: &binlogdatapb.ShardGtid{ Keyspace: "/.*", }, - expectedEventNum: expectedKs1EventNum + expectedKs2EventNum + expectedKs3EventNum + expectedFullyCopyCompletedNum, + expectedEventNum: expectedKs1EventNum + expectedKs2EventNum + expectedFullyCopyCompletedNum, expectedCompletedEvents: []string{ `type:COPY_COMPLETED keyspace:"ks" shard:"-80"`, `type:COPY_COMPLETED keyspace:"ks" shard:"80-"`, `type:COPY_COMPLETED keyspace:"ks2" shard:"-80"`, `type:COPY_COMPLETED keyspace:"ks2" shard:"80-"`, - `type:COPY_COMPLETED keyspace:"ks3" shard:"-80"`, - `type:COPY_COMPLETED keyspace:"ks3" shard:"80-"`, `type:COPY_COMPLETED`, }, }, @@ -344,11 +343,13 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { gconn, conn, mconn, closeConnections := initialize(ctx, t) defer closeConnections() - vgtid := &binlogdatapb.VGtid{} + var vgtid = &binlogdatapb.VGtid{} vgtid.ShardGtids = []*binlogdatapb.ShardGtid{c.shardGtid} reader, err := gconn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags) _, _ = conn, mconn - require.NoError(t, err) + if err != nil { + require.NoError(t, err) + } require.NotNil(t, reader) var evs []*binlogdatapb.VEvent var completedEvs []*binlogdatapb.VEvent @@ -425,7 +426,7 @@ func TestVStreamCopyResume(t *testing.T) { } var shardGtids []*binlogdatapb.ShardGtid - vgtid := &binlogdatapb.VGtid{} + var vgtid = &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -525,7 +526,7 @@ func TestVStreamCurrent(t *testing.T) { defer closeConnections() var shardGtids []*binlogdatapb.ShardGtid - vgtid := &binlogdatapb.VGtid{} + var vgtid = &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -579,7 +580,7 @@ func TestVStreamSharded(t *testing.T) { defer closeConnections() var shardGtids []*binlogdatapb.ShardGtid - vgtid := &binlogdatapb.VGtid{} + var vgtid = &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -664,6 +665,7 @@ func TestVStreamSharded(t *testing.T) { t.Fatalf("remote error: %v\n", err) } } + } // TestVStreamCopyTransactions tests that we are properly wrapping @@ -820,11 +822,9 @@ type VEventSorter []*binlogdatapb.VEvent func (v VEventSorter) Len() int { return len(v) } - func (v VEventSorter) Swap(i, j int) { v[i], v[j] = v[j], v[i] } - func (v VEventSorter) Less(i, j int) bool { valsI := v[i].GetRowEvent().RowChanges[0].After if valsI == nil { From 099c6ec2e6c030ef90d1b0c0a74a9edcbd5f31af Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sat, 13 Jul 2024 17:15:12 -0400 Subject: [PATCH 11/27] rm vtg/mirror test Signed-off-by: Max Englander --- go/vt/vtgate/endtoend/mirror_test.go | 196 --------------------------- 1 file changed, 196 deletions(-) delete mode 100644 go/vt/vtgate/endtoend/mirror_test.go diff --git a/go/vt/vtgate/endtoend/mirror_test.go b/go/vt/vtgate/endtoend/mirror_test.go deleted file mode 100644 index 41691f42e22..00000000000 --- a/go/vt/vtgate/endtoend/mirror_test.go +++ /dev/null @@ -1,196 +0,0 @@ -/* -Copyright 2024 The Vitess Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package endtoend - -import ( - "bytes" - "context" - "fmt" - "math/rand" - osExec "os/exec" - "sync" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/mysql" -) - -var mirrorInitOnce sync.Once - -func BenchmarkMirror(b *testing.B) { - const numRows = 10000 - - ctx := context.Background() - conn, err := mysql.Connect(ctx, &vtParams) - if err != nil { - b.Fatal(err) - } - defer conn.Close() - - var query bytes.Buffer - - mirrorInitOnce.Do(func() { - b.Logf("seeding database for benchmark...") - - for i := 0; i < numRows; i++ { - query.Reset() - query.WriteString(fmt.Sprintf("INSERT INTO ks.mirror_tbl1(id) VALUES(%d)", i)) - _, err = conn.ExecuteFetch(query.String(), -1, false) - if err != nil { - b.Fatal(err) - } - - query.Reset() - query.WriteString(fmt.Sprintf("INSERT INTO ks2.mirror_tbl1(id) VALUES(%d)", i)) - _, err = conn.ExecuteFetch(query.String(), -1, false) - if err != nil { - b.Fatal(err) - } - - query.Reset() - query.WriteString(fmt.Sprintf("INSERT INTO ks.mirror_tbl2(id) VALUES(%d)", i)) - _, err = conn.ExecuteFetch(query.String(), -1, false) - if err != nil { - b.Fatal(err) - } - - query.Reset() - query.WriteString(fmt.Sprintf("INSERT INTO ks3.mirror_tbl2(id) VALUES(%d)", i)) - _, err = conn.ExecuteFetch(query.String(), -1, false) - if err != nil { - b.Fatal(err) - } - } - - b.Logf("finished (inserted %d rows)", numRows) - }) - - testCases := []struct { - name string - run func(*testing.B, *rand.Rand) - }{ - { - name: "point select, { ks => ks1 }.tbl1", - run: func(b *testing.B, rnd *rand.Rand) { - for i := 0; i < b.N; i++ { - id := rnd.Intn(numRows) - query.Reset() - _, _ = fmt.Fprintf( - &query, - "SELECT t1.id, t2.id FROM ks.mirror_tbl1 AS t1, ks.mirror_tbl2 AS t2 WHERE t1.id = %d AND t2.id = %d", - id, id, - ) - _, err := conn.ExecuteFetch(query.String(), 1, false) - if err != nil { - b.Error(err) - } - } - }, - }, - { - name: "point select, { ks => ks2 }.tbl1, { ks => ks3 }.tbl2", - run: func(b *testing.B, rnd *rand.Rand) { - for i := 0; i < b.N; i++ { - id := rnd.Intn(numRows) - query.Reset() - _, _ = fmt.Fprintf( - &query, - "SELECT t1.id, t2.id FROM ks.mirror_tbl1 AS t1, ks.mirror_tbl2 AS t2 WHERE t1.id = %d AND t2.id = %d", - id, id, - ) - _, err := conn.ExecuteFetch(query.String(), 1, false) - if err != nil { - b.Error(err) - } - } - }, - }, - } - - // Each time this BenchmarkMirror runs, use a different source of - // random-ness. But use the same source of randomness across test cases and - // mirror percentages sub-tests. - randSeed := time.Now().UnixNano() - - for _, tc := range testCases { - b.Run(tc.name, func(b *testing.B) { - b.Run("mirror 0%", func(b *testing.B) { - mirrorTraffic(b, 0) - b.ResetTimer() - tc.run(b, rand.New(rand.NewSource(randSeed))) - }) - - b.Run("mirror 1%", func(b *testing.B) { - mirrorTraffic(b, 1) - b.ResetTimer() - tc.run(b, rand.New(rand.NewSource(randSeed))) - }) - - b.Run("mirror 5%", func(b *testing.B) { - mirrorTraffic(b, 5) - b.ResetTimer() - tc.run(b, rand.New(rand.NewSource(randSeed))) - }) - - b.Run("mirror 10%", func(b *testing.B) { - mirrorTraffic(b, 10) - b.ResetTimer() - tc.run(b, rand.New(rand.NewSource(randSeed))) - }) - - b.Run("mirror 25%", func(b *testing.B) { - mirrorTraffic(b, 25) - b.ResetTimer() - tc.run(b, rand.New(rand.NewSource(randSeed))) - }) - - b.Run("mirror 50%", func(b *testing.B) { - mirrorTraffic(b, 50) - b.ResetTimer() - tc.run(b, rand.New(rand.NewSource(randSeed))) - }) - - b.Run("mirror 100%", func(b *testing.B) { - mirrorTraffic(b, 100) - b.ResetTimer() - tc.run(b, rand.New(rand.NewSource(randSeed))) - }) - }) - } -} - -func mirrorTraffic(b *testing.B, percent float32) { - server := fmt.Sprintf("localhost:%v", cluster.VTProcess().PortGrpc) - rules := fmt.Sprintf(`{ - "rules": [ - { - "from_table": "ks.mirror_tbl1", - "to_table": "ks2.mirror_tbl1", - "percent": %f - }, - { - "from_table": "ks.mirror_tbl2", - "to_table": "ks3.mirror_tbl2", - "percent": %f - } - ] - }`, percent, percent) - _, err := osExec.Command("vtctldclient", "--server", server, "ApplyMirrorRules", "--rules", rules).CombinedOutput() - require.NoError(b, err) -} From 6f5829b7578be54cdf269201e8b883f3a9bffaff Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sat, 13 Jul 2024 17:31:09 -0400 Subject: [PATCH 12/27] fix test Signed-off-by: Max Englander --- .../vtgate/planbuilder/plancontext/planning_context_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go index 3ab58cba724..ff100273edc 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go @@ -365,4 +365,9 @@ func (v *vschema) GetAggregateUDFs() []string { panic("implement me") } +func (v *vschema) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { + // TODO implement me + panic("implement me") +} + var _ VSchema = (*vschema)(nil) From 2cd623065469d9d2da1f900e769c58236cbb028d Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sun, 14 Jul 2024 01:27:23 -0400 Subject: [PATCH 13/27] checkpoint Signed-off-by: Max Englander --- go/vt/sqlparser/ast_funcs.go | 1 + go/vt/sqlparser/tracked_buffer.go | 39 ++++++++++++- go/vt/vtgate/planbuilder/builder.go | 8 +-- .../planbuilder/operator_transformers.go | 2 - .../planbuilder/operators/SQL_builder.go | 10 ++-- .../plancontext/planning_context.go | 8 +++ go/vt/vtgate/planbuilder/route.go | 34 ++++++++++-- .../planbuilder/single_sharded_shortcut.go | 55 +++++++++++++------ 8 files changed, 119 insertions(+), 38 deletions(-) diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index f4f1e3a5455..758061508ef 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -2734,6 +2734,7 @@ func (node *Select) SetWherePredicate(expr Expr) { Expr: expr, } } + func (node *Delete) GetFrom() []TableExpr { return node.TableExprs } diff --git a/go/vt/sqlparser/tracked_buffer.go b/go/vt/sqlparser/tracked_buffer.go index aec206f3b3d..1b225b0be25 100644 --- a/go/vt/sqlparser/tracked_buffer.go +++ b/go/vt/sqlparser/tracked_buffer.go @@ -25,6 +25,44 @@ import ( // function that can be given to TrackedBuffer for code generation. type NodeFormatter func(buf *TrackedBuffer, node SQLNode) +// DefaultFormatter applies default formatting. +func DefaultFormatter(buf *TrackedBuffer, node SQLNode) { + node.Format(buf) +} + +// Transformer is used to make changes to SQLNode during formatting. +// +// The transformed SQLNode is supplied via a callback, allowing NodeTransformer +// to perform internal book-keeping before and after the transformed SQLNode is +// used. +type NodeTransformer func(SQLNode, func(SQLNode)) + +// ComposeTransformers chains multiple NodeTransformer into a composite. +func ComposeTransformers(transformers ...NodeTransformer) NodeTransformer { + return func(node SQLNode, done func(SQLNode)) { + currentNode := node + wrappedDone := func(newNode SQLNode) { + currentNode = newNode + } + for _, transform := range transformers { + transform(currentNode, wrappedDone) + } + done(currentNode) + } +} + +// TransformFormatter produces a NodeFormatter that produces a transforms and +// then formats a SQLNode. +// +// It can be used to influence formatting without mutating the original SQLNode. +func TransformFormatter(transform NodeTransformer, format NodeFormatter) NodeFormatter { + return func(buf *TrackedBuffer, node SQLNode) { + transform(node, func(transformedNode SQLNode) { + format(buf, transformedNode) + }) + } +} + // TrackedBuffer is used to rebuild a query from the ast. // bindLocations keeps track of locations in the buffer that // use bind variables for efficient future substitutions. @@ -335,7 +373,6 @@ func UnescapedString(node SQLNode) string { buf.SetEscapeNoIdentifier() node.Format(buf) return buf.String() - } // CanonicalString returns a canonical string representation of an SQLNode where all identifiers diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 1031cd08c67..472060ad4f0 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -151,13 +151,7 @@ func buildRoutePlan(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVa } func buildRoutePlanWithMirroring(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, f func(statement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, schema plancontext.VSchema) (*planResult, error)) (*planResult, error) { - // Building a plan changes the statement, so clone it before we create the - // original plan. - // - // TODO(maxeng): find a way to avoid this work unless all tables have a - // mirror rule. At present, we don't know which tables to check until we - // plan the original statement. - mirrorStmt := sqlparser.CloneStatement(stmt) + mirrorStmt := stmt plan, err := buildRoutePlan(stmt, reservedVars, vschema, f) if err != nil { diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 546a9854f26..324467045cd 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -288,7 +288,6 @@ func transformFkVerify(ctx *plancontext.PlanningContext, fkv *operators.FkVerify Verify: verify, Exec: inputLP, }, nil - } func transformAggregator(ctx *plancontext.PlanningContext, op *operators.Aggregator) (engine.Primitive, error) { @@ -451,7 +450,6 @@ func getEvalEngineExpr(ctx *plancontext.PlanningContext, pe *operators.ProjExpr) default: return nil, vterrors.VT13001("project not planned for: %s", pe.String()) } - } // newSimpleProjection creates a simple projections diff --git a/go/vt/vtgate/planbuilder/operators/SQL_builder.go b/go/vt/vtgate/planbuilder/operators/SQL_builder.go index fef4ae2aee4..b7512fbf19d 100644 --- a/go/vt/vtgate/planbuilder/operators/SQL_builder.go +++ b/go/vt/vtgate/planbuilder/operators/SQL_builder.go @@ -40,6 +40,7 @@ type ( func (qb *queryBuilder) asSelectStatement() sqlparser.SelectStatement { return qb.stmt.(sqlparser.SelectStatement) } + func (qb *queryBuilder) asOrderAndLimit() sqlparser.OrderAndLimit { return qb.stmt.(sqlparser.OrderAndLimit) } @@ -214,9 +215,11 @@ type FromStatement interface { SetWherePredicate(sqlparser.Expr) } -var _ FromStatement = (*sqlparser.Select)(nil) -var _ FromStatement = (*sqlparser.Update)(nil) -var _ FromStatement = (*sqlparser.Delete)(nil) +var ( + _ FromStatement = (*sqlparser.Select)(nil) + _ FromStatement = (*sqlparser.Update)(nil) + _ FromStatement = (*sqlparser.Delete)(nil) +) func (qb *queryBuilder) joinWith(other *queryBuilder, onCondition sqlparser.Expr, joinType sqlparser.JoinType) { stmt := qb.stmt.(FromStatement) @@ -292,7 +295,6 @@ func (qb *queryBuilder) sortTables() { sort.Sort(ts) return true, nil }, qb.stmt) - } type tableSorter struct { diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context.go b/go/vt/vtgate/planbuilder/plancontext/planning_context.go index 58be17febab..a3f5be6ef19 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context.go @@ -66,6 +66,10 @@ type PlanningContext struct { // OuterTables contains the tables that are outer to the current query // Used to set the nullable flag on the columns OuterTables semantics.TableSet + + // NodeTransformers are used to influence the formatting of Statement without + // making changes to Statement. + NodeTransformers []sqlparser.NodeTransformer } // CreatePlanningContext initializes a new PlanningContext with the given parameters. @@ -376,3 +380,7 @@ func (ctx *PlanningContext) ContainsAggr(e sqlparser.SQLNode) (hasAggr bool) { }, e) return } + +func (ctx *PlanningContext) AddNodeTransformer(transformer sqlparser.NodeTransformer) { + ctx.NodeTransformers = append(ctx.NodeTransformers, transformer) +} diff --git a/go/vt/vtgate/planbuilder/route.go b/go/vt/vtgate/planbuilder/route.go index e320df14416..138073a4521 100644 --- a/go/vt/vtgate/planbuilder/route.go +++ b/go/vt/vtgate/planbuilder/route.go @@ -26,12 +26,34 @@ import ( ) // WireupRoute returns an engine primitive for the given route. -func WireupRoute(ctx *plancontext.PlanningContext, eroute *engine.Route, sel sqlparser.SelectStatement) (engine.Primitive, error) { - // prepare the queries we will pass down - eroute.Query = sqlparser.String(sel) - buffer := sqlparser.NewTrackedBuffer(sqlparser.FormatImpossibleQuery) - node := buffer.WriteNode(sel) - eroute.FieldQuery = node.ParsedQuery().Query +func WireupRoute( + ctx *plancontext.PlanningContext, + eroute *engine.Route, + sel sqlparser.SelectStatement, +) (engine.Primitive, error) { + var transform sqlparser.NodeTransformer + if len(ctx.NodeTransformers) > 0 { + transform = sqlparser.ComposeTransformers(ctx.NodeTransformers...) + } + + // prepare the query we will pass down + if transform != nil { + qfmt := sqlparser.TransformFormatter(transform, sqlparser.DefaultFormatter) + qbuf := sqlparser.NewTrackedBuffer(qfmt) + qnode := qbuf.WriteNode(sel) + eroute.Query = qnode.ParsedQuery().Query + } else { + eroute.Query = sqlparser.String(sel) + } + + // prepare the field query we will pass down + ffmt := sqlparser.FormatImpossibleQuery + if transform != nil { + ffmt = sqlparser.TransformFormatter(transform, ffmt) + } + fbuf := sqlparser.NewTrackedBuffer(ffmt) + fnode := fbuf.WriteNode(sel) + eroute.FieldQuery = fnode.ParsedQuery().Query // if we have a planable vindex lookup, let's extract it into its own primitive planableVindex, ok := eroute.RoutingParameters.Vindex.(vindexes.LookupPlanable) diff --git a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go index ad6329f4f0a..e16dc908f93 100644 --- a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go +++ b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go @@ -28,19 +28,10 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) +var emptyIdentifier = sqlparser.NewIdentifierCS("") + func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, ks *vindexes.Keyspace) (engine.Primitive, []sqlparser.TableName, error) { - // this method is used when the query we are handling has all tables in the same unsharded keyspace - sqlparser.SafeRewrite(stmt, nil, func(cursor *sqlparser.Cursor) bool { - switch node := cursor.Node().(type) { - case sqlparser.SelectExpr: - removeKeyspaceFromSelectExpr(node) - case sqlparser.TableName: - cursor.Replace(sqlparser.TableName{ - Name: node.Name, - }) - } - return true - }) + ctx.AddNodeTransformer(removeKeyspacesTransformer()) tableNames, err := getTableNames(ctx.SemTable) if err != nil { @@ -53,6 +44,7 @@ func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.Se }, TableName: strings.Join(escapedTableNames(tableNames), ", "), } + prim, err := WireupRoute(ctx, eroute, stmt) if err != nil { return nil, nil, err @@ -99,11 +91,38 @@ func getTableNames(semTable *semantics.SemTable) ([]sqlparser.TableName, error) return tableNames, nil } -func removeKeyspaceFromSelectExpr(expr sqlparser.SelectExpr) { - switch expr := expr.(type) { - case *sqlparser.AliasedExpr: - sqlparser.RemoveKeyspaceInCol(expr.Expr) - case *sqlparser.StarExpr: - expr.TableName.Qualifier = sqlparser.NewIdentifierCS("") +// removeKeyspacesTransformer returns a NodeTransformer that produces +// transformed SQLNode stripped of keyspace information. +func removeKeyspacesTransformer() sqlparser.NodeTransformer { + var inAliasedExpr bool + var inSelectExpr bool + + return func(node sqlparser.SQLNode, done func(node sqlparser.SQLNode)) { + switch node := node.(type) { + case *sqlparser.AliasedExpr: + inAliasedExpr = true + done(node) + inAliasedExpr = false + case *sqlparser.ColName: + if inSelectExpr && inAliasedExpr { + if !node.Qualifier.Qualifier.IsEmpty() { + node := sqlparser.Clone(node) + node.Qualifier.Qualifier = emptyIdentifier + } + } + done(node) + case sqlparser.SelectExpr: + inSelectExpr = true + done(node) + inSelectExpr = false + case sqlparser.TableName: + if !node.Qualifier.IsEmpty() { + node = sqlparser.Clone(node) + node.Qualifier = emptyIdentifier + } + done(node) + default: + done(node) + } } } From 0666e684e1b4ae3015142ccc41b5b3f726b3bbcf Mon Sep 17 00:00:00 2001 From: Max Englander Date: Sun, 14 Jul 2024 20:16:32 -0400 Subject: [PATCH 14/27] revert unintended changes Signed-off-by: Max Englander --- go/test/endtoend/cluster/cluster_process.go | 6 ++++-- go/vt/sqlparser/ast_funcs.go | 1 - go/vt/vtgate/bench_test.go | 1 + go/vt/vtgate/planbuilder/operator_transformers.go | 2 ++ go/vt/vtgate/planbuilder/operators/SQL_builder.go | 10 ++++------ 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index e3daaacdab3..44636b3cdb6 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -281,6 +281,7 @@ func (cluster *LocalProcessCluster) StartUnshardedKeyspace(keyspace Keyspace, re } func (cluster *LocalProcessCluster) startPartialKeyspace(keyspace Keyspace, shardNames []string, movedShard string, replicaCount int, rdonly bool, customizers ...any) (err error) { + cluster.HasPartialKeyspaces = true routedKeyspace := &Keyspace{ Name: fmt.Sprintf("%s_routed", keyspace.Name), @@ -1130,8 +1131,7 @@ func (cluster *LocalProcessCluster) waitForMySQLProcessToExit(mysqlctlProcessLis // StartVtbackup starts a vtbackup func (cluster *LocalProcessCluster) StartVtbackup(newInitDBFile string, initialBackup bool, - keyspace string, shard string, cell string, extraArgs ...string, -) error { + keyspace string, shard string, cell string, extraArgs ...string) error { log.Info("Starting vtbackup") cluster.VtbackupProcess = *VtbackupProcessInstance( cluster.GetAndReserveTabletUID(), @@ -1146,6 +1146,7 @@ func (cluster *LocalProcessCluster) StartVtbackup(newInitDBFile string, initialB initialBackup) cluster.VtbackupProcess.ExtraArgs = extraArgs return cluster.VtbackupProcess.Setup() + } // GetAndReservePort gives port for required process @@ -1161,6 +1162,7 @@ func (cluster *LocalProcessCluster) GetAndReservePort() int { cluster.nextPortForProcess = cluster.nextPortForProcess + 1 log.Infof("Attempting to reserve port: %v", cluster.nextPortForProcess) ln, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(cluster.nextPortForProcess))) + if err != nil { log.Errorf("Can't listen on port %v: %s, trying next port", cluster.nextPortForProcess, err) continue diff --git a/go/vt/sqlparser/ast_funcs.go b/go/vt/sqlparser/ast_funcs.go index 758061508ef..f4f1e3a5455 100644 --- a/go/vt/sqlparser/ast_funcs.go +++ b/go/vt/sqlparser/ast_funcs.go @@ -2734,7 +2734,6 @@ func (node *Select) SetWherePredicate(expr Expr) { Expr: expr, } } - func (node *Delete) GetFrom() []TableExpr { return node.TableExprs } diff --git a/go/vt/vtgate/bench_test.go b/go/vt/vtgate/bench_test.go index 5da1af896d0..5c64c7e3473 100644 --- a/go/vt/vtgate/bench_test.go +++ b/go/vt/vtgate/bench_test.go @@ -54,6 +54,7 @@ func init() { fmt.Fprintf(buf, " and v%d = '%d%s'", i, i, baseval.String()) } benchQuery = buf.String() + // fmt.Printf("len: %d\n", len(benchQuery)) } func BenchmarkWithNormalizer(b *testing.B) { diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 324467045cd..546a9854f26 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -288,6 +288,7 @@ func transformFkVerify(ctx *plancontext.PlanningContext, fkv *operators.FkVerify Verify: verify, Exec: inputLP, }, nil + } func transformAggregator(ctx *plancontext.PlanningContext, op *operators.Aggregator) (engine.Primitive, error) { @@ -450,6 +451,7 @@ func getEvalEngineExpr(ctx *plancontext.PlanningContext, pe *operators.ProjExpr) default: return nil, vterrors.VT13001("project not planned for: %s", pe.String()) } + } // newSimpleProjection creates a simple projections diff --git a/go/vt/vtgate/planbuilder/operators/SQL_builder.go b/go/vt/vtgate/planbuilder/operators/SQL_builder.go index b7512fbf19d..fef4ae2aee4 100644 --- a/go/vt/vtgate/planbuilder/operators/SQL_builder.go +++ b/go/vt/vtgate/planbuilder/operators/SQL_builder.go @@ -40,7 +40,6 @@ type ( func (qb *queryBuilder) asSelectStatement() sqlparser.SelectStatement { return qb.stmt.(sqlparser.SelectStatement) } - func (qb *queryBuilder) asOrderAndLimit() sqlparser.OrderAndLimit { return qb.stmt.(sqlparser.OrderAndLimit) } @@ -215,11 +214,9 @@ type FromStatement interface { SetWherePredicate(sqlparser.Expr) } -var ( - _ FromStatement = (*sqlparser.Select)(nil) - _ FromStatement = (*sqlparser.Update)(nil) - _ FromStatement = (*sqlparser.Delete)(nil) -) +var _ FromStatement = (*sqlparser.Select)(nil) +var _ FromStatement = (*sqlparser.Update)(nil) +var _ FromStatement = (*sqlparser.Delete)(nil) func (qb *queryBuilder) joinWith(other *queryBuilder, onCondition sqlparser.Expr, joinType sqlparser.JoinType) { stmt := qb.stmt.(FromStatement) @@ -295,6 +292,7 @@ func (qb *queryBuilder) sortTables() { sort.Sort(ts) return true, nil }, qb.stmt) + } type tableSorter struct { From c8ada40b13f2c19b018e6ea775034dbf92735df4 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 16 Jul 2024 23:51:15 -0400 Subject: [PATCH 15/27] cr: move mirror planning into operators Signed-off-by: Max Englander --- go/vt/schemadiff/semantics.go | 5 + go/vt/sqlparser/tracked_buffer.go | 39 +------ go/vt/vtgate/engine/cached_size.go | 6 +- go/vt/vtgate/engine/plan.go | 14 +-- go/vt/vtgate/logstats/logstats.go | 11 +- go/vt/vtgate/logstats/logstats_test.go | 6 +- go/vt/vtgate/planbuilder/builder.go | 107 ++++-------------- go/vt/vtgate/planbuilder/ddl.go | 2 +- .../planbuilder/operator_transformers.go | 20 +++- .../planbuilder/operators/SQL_builder.go | 10 +- .../vtgate/planbuilder/operators/ast_to_op.go | 20 +++- go/vt/vtgate/planbuilder/operators/delete.go | 9 +- go/vt/vtgate/planbuilder/operators/helpers.go | 75 ++++++------ go/vt/vtgate/planbuilder/operators/horizon.go | 3 +- go/vt/vtgate/planbuilder/operators/insert.go | 9 +- go/vt/vtgate/planbuilder/operators/mirror.go | 102 +++++++++++++++++ .../planbuilder/operators/plan_query.go | 2 +- .../planbuilder/operators/query_planning.go | 8 +- .../vtgate/planbuilder/operators/rewriters.go | 4 +- go/vt/vtgate/planbuilder/operators/route.go | 6 +- .../planbuilder/operators/route_planning.go | 1 - .../planbuilder/operators/sharded_routing.go | 1 + .../planbuilder/operators/subquery_builder.go | 3 + go/vt/vtgate/planbuilder/operators/table.go | 9 +- go/vt/vtgate/planbuilder/operators/update.go | 9 +- go/vt/vtgate/planbuilder/operators/vindex.go | 9 +- .../planbuilder/plancontext/mirror_vschema.go | 6 +- .../plancontext/planning_context.go | 33 +++++- go/vt/vtgate/planbuilder/route.go | 34 +----- go/vt/vtgate/planbuilder/select.go | 15 ++- .../planbuilder/single_sharded_shortcut.go | 57 ++++------ .../planbuilder/testdata/mirror_cases.json | 7 +- go/vt/vtgate/planbuilder/vexplain.go | 7 +- go/vt/vtgate/semantics/FakeSI.go | 5 + go/vt/vtgate/semantics/analyzer.go | 9 +- go/vt/vtgate/semantics/derived_table.go | 5 + go/vt/vtgate/semantics/info_schema.go | 13 ++- go/vt/vtgate/semantics/real_table.go | 6 + go/vt/vtgate/semantics/semantic_state.go | 54 ++++++++- go/vt/vtgate/semantics/table_collector.go | 4 +- go/vt/vtgate/semantics/vindex_table.go | 5 + go/vt/vtgate/semantics/vtable.go | 5 + 42 files changed, 414 insertions(+), 341 deletions(-) create mode 100644 go/vt/vtgate/planbuilder/operators/mirror.go diff --git a/go/vt/schemadiff/semantics.go b/go/vt/schemadiff/semantics.go index cbba8c79497..3e0aca45a88 100644 --- a/go/vt/schemadiff/semantics.go +++ b/go/vt/schemadiff/semantics.go @@ -79,6 +79,11 @@ func (si *declarativeSchemaInformation) GetForeignKeyChecksState() *bool { return nil } +// FindMirrorRule implements semantics.SchemaInformation. +func (si *declarativeSchemaInformation) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { + return nil, "", topodatapb.TabletType_UNKNOWN, nil, nil +} + // addTable adds a fake table with an empty column list func (si *declarativeSchemaInformation) addTable(tableName string) { tbl := &vindexes.Table{ diff --git a/go/vt/sqlparser/tracked_buffer.go b/go/vt/sqlparser/tracked_buffer.go index 1b225b0be25..aec206f3b3d 100644 --- a/go/vt/sqlparser/tracked_buffer.go +++ b/go/vt/sqlparser/tracked_buffer.go @@ -25,44 +25,6 @@ import ( // function that can be given to TrackedBuffer for code generation. type NodeFormatter func(buf *TrackedBuffer, node SQLNode) -// DefaultFormatter applies default formatting. -func DefaultFormatter(buf *TrackedBuffer, node SQLNode) { - node.Format(buf) -} - -// Transformer is used to make changes to SQLNode during formatting. -// -// The transformed SQLNode is supplied via a callback, allowing NodeTransformer -// to perform internal book-keeping before and after the transformed SQLNode is -// used. -type NodeTransformer func(SQLNode, func(SQLNode)) - -// ComposeTransformers chains multiple NodeTransformer into a composite. -func ComposeTransformers(transformers ...NodeTransformer) NodeTransformer { - return func(node SQLNode, done func(SQLNode)) { - currentNode := node - wrappedDone := func(newNode SQLNode) { - currentNode = newNode - } - for _, transform := range transformers { - transform(currentNode, wrappedDone) - } - done(currentNode) - } -} - -// TransformFormatter produces a NodeFormatter that produces a transforms and -// then formats a SQLNode. -// -// It can be used to influence formatting without mutating the original SQLNode. -func TransformFormatter(transform NodeTransformer, format NodeFormatter) NodeFormatter { - return func(buf *TrackedBuffer, node SQLNode) { - transform(node, func(transformedNode SQLNode) { - format(buf, transformedNode) - }) - } -} - // TrackedBuffer is used to rebuild a query from the ast. // bindLocations keeps track of locations in the buffer that // use bind variables for efficient future substitutions. @@ -373,6 +335,7 @@ func UnescapedString(node SQLNode) string { buf.SetEscapeNoIdentifier() node.Format(buf) return buf.String() + } // CanonicalString returns a canonical string representation of an SQLNode where all identifiers diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index a26fd70c03f..c76eb3e8671 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -818,11 +818,11 @@ func (cached *Plan) CachedSize(alloc bool) int64 { size += elem.CachedSize(true) } } - // field TablesUsed vitess.io/vitess/go/vt/sqlparser.TableNames + // field TablesUsed []string { - size += hack.RuntimeAllocSize(int64(cap(cached.TablesUsed)) * int64(32)) + size += hack.RuntimeAllocSize(int64(cap(cached.TablesUsed)) * int64(16)) for _, elem := range cached.TablesUsed { - size += elem.CachedSize(false) + size += hack.RuntimeAllocSize(int64(len(elem))) } } return size diff --git a/go/vt/vtgate/engine/plan.go b/go/vt/vtgate/engine/plan.go index 8de1ed808d5..769c69aaa06 100644 --- a/go/vt/vtgate/engine/plan.go +++ b/go/vt/vtgate/engine/plan.go @@ -19,7 +19,6 @@ package engine import ( "bytes" "encoding/json" - "fmt" "sync/atomic" "time" @@ -38,7 +37,7 @@ type Plan struct { Instructions Primitive // Instructions contains the instructions needed to fulfil the query. BindVarNeeds *sqlparser.BindVarNeeds // Stores BindVars needed to be provided as part of expression rewriting Warnings []*query.QueryWarning // Warnings that need to be yielded every time this query runs - TablesUsed sqlparser.TableNames // TablesUsed is the list of tables that this plan will query + TablesUsed []string // TablesUsed is the list of tables that this plan will query ExecCount uint64 // Count of times this plan was executed ExecTime uint64 // Total execution time @@ -77,15 +76,6 @@ func (p *Plan) MarshalJSON() ([]byte, error) { instructions = &description } - tablesUsed := make([]string, len(p.TablesUsed)) - for i, table := range p.TablesUsed { - if table.Qualifier.NotEmpty() { - tablesUsed[i] = fmt.Sprintf("%s.%s", table.Qualifier.String(), table.Name.String()) - } else { - tablesUsed[i] = table.Name.String() - } - } - marshalPlan := struct { QueryType string Original string `json:",omitempty"` @@ -107,7 +97,7 @@ func (p *Plan) MarshalJSON() ([]byte, error) { RowsAffected: atomic.LoadUint64(&p.RowsAffected), RowsReturned: atomic.LoadUint64(&p.RowsReturned), Errors: atomic.LoadUint64(&p.Errors), - TablesUsed: tablesUsed, + TablesUsed: p.TablesUsed, } b := new(bytes.Buffer) diff --git a/go/vt/vtgate/logstats/logstats.go b/go/vt/vtgate/logstats/logstats.go index dd32d1aa5a6..8f8ba41e3cd 100644 --- a/go/vt/vtgate/logstats/logstats.go +++ b/go/vt/vtgate/logstats/logstats.go @@ -28,8 +28,6 @@ import ( "vitess.io/vitess/go/streamlog" "vitess.io/vitess/go/vt/callerid" "vitess.io/vitess/go/vt/callinfo" - "vitess.io/vitess/go/vt/sqlparser" - querypb "vitess.io/vitess/go/vt/proto/query" ) @@ -50,7 +48,7 @@ type LogStats struct { ExecuteTime time.Duration CommitTime time.Duration Error error - TablesUsed []sqlparser.TableName + TablesUsed []string SessionUUID string CachedPlan bool ActiveKeyspace string // ActiveKeyspace is the selected keyspace `use ks` @@ -176,12 +174,9 @@ func (stats *LogStats) Logf(w io.Writer, params url.Values) error { log.Key("Cached Plan") log.Bool(stats.CachedPlan) log.Key("TablesUsed") - tablesUsed := make([]string, len(stats.TablesUsed)) - for i, table := range stats.TablesUsed { - tablesUsed[i] = sqlparser.String(table) - } - log.Strings(tablesUsed) + log.Strings(stats.TablesUsed) log.Key("ActiveKeyspace") log.String(stats.ActiveKeyspace) + return log.Flush(w) } diff --git a/go/vt/vtgate/logstats/logstats_test.go b/go/vt/vtgate/logstats/logstats_test.go index c66aecdf01b..ae3c01e0f0b 100644 --- a/go/vt/vtgate/logstats/logstats_test.go +++ b/go/vt/vtgate/logstats/logstats_test.go @@ -40,7 +40,6 @@ import ( "vitess.io/vitess/go/vt/callinfo" "vitess.io/vitess/go/vt/callinfo/fakecallinfo" querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/vt/sqlparser" ) func TestMain(m *testing.M) { @@ -63,10 +62,7 @@ func TestLogStatsFormat(t *testing.T) { logStats := NewLogStats(context.Background(), "test", "sql1", "suuid", nil) logStats.StartTime = time.Date(2017, time.January, 1, 1, 2, 3, 0, time.UTC) logStats.EndTime = time.Date(2017, time.January, 1, 1, 2, 4, 1234, time.UTC) - logStats.TablesUsed = []sqlparser.TableName{ - sqlparser.NewTableNameWithQualifier("tbl1", "ks1"), - sqlparser.NewTableNameWithQualifier("tbl2", "ks2"), - } + logStats.TablesUsed = []string{"ks1.tbl1", "ks2.tbl2"} logStats.TabletType = "PRIMARY" logStats.ActiveKeyspace = "db" params := map[string][]string{"full": {}} diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 472060ad4f0..3215ec67db0 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -29,7 +29,6 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -48,13 +47,13 @@ var plannerVersions = []plancontext.PlannerVersion{Gen4, Gen4GreedyOnly, Gen4Lef type ( planResult struct { primitive engine.Primitive - tables sqlparser.TableNames + tables []string } stmtPlanner func(sqlparser.Statement, *sqlparser.ReservedVars, plancontext.VSchema) (*planResult, error) ) -func newPlanResult(prim engine.Primitive, tablesUsed ...sqlparser.TableName) *planResult { +func newPlanResult(prim engine.Primitive, tablesUsed ...string) *planResult { return &planResult{primitive: prim, tables: tablesUsed} } @@ -99,7 +98,7 @@ func BuildFromStmt(ctx context.Context, query string, stmt sqlparser.Statement, } var primitive engine.Primitive - var tablesUsed []sqlparser.TableName + var tablesUsed []string if planResult != nil { primitive = planResult.primitive tablesUsed = planResult.tables @@ -150,74 +149,9 @@ func buildRoutePlan(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVa return f(stmt, reservedVars, vschema) } -func buildRoutePlanWithMirroring(stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, f func(statement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, schema plancontext.VSchema) (*planResult, error)) (*planResult, error) { - mirrorStmt := stmt - - plan, err := buildRoutePlan(stmt, reservedVars, vschema, f) - if err != nil { - return nil, err - } - - // Avoid mirroring work unless all tables have a mirror rule. - mirrorRules := make(map[sqlparser.TableName]*vindexes.MirrorRule) - for _, table := range plan.tables { - mirrorRule, _, _, _, err := vschema.FindMirrorRule(table) - if err != nil || mirrorRule == nil { - break - } - // Forbid self-mirroring. - if mirrorRule.Table.Keyspace.Name == table.Qualifier.String() { - break - } - mirrorRules[table] = mirrorRule - } - if len(mirrorRules) == 0 || len(mirrorRules) != len(plan.tables) { - return plan, nil - } - - // Set up a vschema for mirroring. - mirrorVSchema := plancontext.ForMirroring(vschema) - - // Use the smallest mirror percent. - var i int - var percent float32 - for _, mirrorRule := range mirrorRules { - if i == 0 || mirrorRule.Percent < percent { - percent = mirrorRule.Percent - } - i++ - } - - // Create plan with cloned statement and mirrored vschema. - target, err := buildRoutePlan(mirrorStmt, reservedVars, mirrorVSchema, f) - if err != nil { - // We don't want to return the error here. Mirroring is meant to be - // best effort, and should not stand in the way of production work. - // - // TODO(maxeng): log an error or increase a metric. - return plan, nil - } - - // Build a new planResult from the original plan and mirror target plan. - tables := make(sqlparser.TableNames, len(plan.tables)+len(target.tables)) - copy(tables, plan.tables) - copy(tables[len(plan.tables):], target.tables) - operators.SortTableNames(tables) - return &planResult{ - engine.NewPercentBasedMirror(percent, plan.primitive, target.primitive), - tables, - }, nil -} - func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { switch stmt := stmt.(type) { - case *sqlparser.Select: - configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) - if err != nil { - return nil, err - } - return buildRoutePlanWithMirroring(stmt, reservedVars, vschema, configuredPlanner) - case *sqlparser.Insert, *sqlparser.Update, *sqlparser.Delete: + case *sqlparser.Select, *sqlparser.Insert, *sqlparser.Update, *sqlparser.Delete: configuredPlanner, err := getConfiguredPlanner(vschema, stmt, query) if err != nil { return nil, err @@ -228,7 +162,7 @@ func createInstructionFor(ctx context.Context, query string, stmt sqlparser.Stat if err != nil { return nil, err } - return buildRoutePlanWithMirroring(stmt, reservedVars, vschema, configuredPlanner) + return buildRoutePlan(stmt, reservedVars, vschema, configuredPlanner) case sqlparser.DDLStatement: return buildGeneralDDLPlan(ctx, query, stmt, reservedVars, vschema, enableOnlineDDL, enableDirectDDL) case *sqlparser.AlterMigration: @@ -329,7 +263,7 @@ func buildAnalyzePlan(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, vsche TargetDestination: dest, Query: sqlparser.String(analyzeStmt), } - return newPlanResult(prim, analyzeStmt.Table), nil + return newPlanResult(prim, sqlparser.String(analyzeStmt.Table)), nil } func buildDBDDLPlan(stmt sqlparser.Statement, _ *sqlparser.ReservedVars, vschema plancontext.VSchema) (*planResult, error) { @@ -401,7 +335,7 @@ func buildVSchemaDDLPlan(stmt *sqlparser.AlterVschema, vschema plancontext.VSche return newPlanResult(&engine.AlterVSchema{ Keyspace: keyspace, AlterVschemaDDL: stmt, - }, sqlparser.NewTableNameWithQualifier(stmt.Table.Name.String(), keyspace.Name)), nil + }, singleTable(keyspace.Name, stmt.Table.Name.String())), nil } func buildFlushPlan(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*planResult, error) { @@ -461,7 +395,7 @@ func buildFlushTables(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*plan if tbl == nil { return nil, vindexes.NotFoundError{TableName: tab.Name.String()} } - tc.addTable(sqlparser.NewTableNameWithQualifier(tbl.Name.String(), tbl.Keyspace.Name)) + tc.addTable(tbl.Keyspace.Name, tbl.Name.String()) ksTab = tbl.Keyspace stmt.TableNames[i] = sqlparser.TableName{ Name: tbl.Name, @@ -505,23 +439,28 @@ func buildFlushTables(stmt *sqlparser.Flush, vschema plancontext.VSchema) (*plan } type tableCollector struct { - tables map[sqlparser.TableName]any + tables map[string]any } -func (tc *tableCollector) addTable(t sqlparser.TableName) { +func (tc *tableCollector) addTable(ks, tbl string) { if tc.tables == nil { - tc.tables = map[sqlparser.TableName]any{} + tc.tables = map[string]any{} } - tc.tables[t] = nil + tc.tables[fmt.Sprintf("%s.%s", ks, tbl)] = nil } -func (tc *tableCollector) getTables() []sqlparser.TableName { - tables := make([]sqlparser.TableName, 0, len(tc.tables)) - for t := range tc.tables { - tables = append(tables, t) +func (tc *tableCollector) addASTTable(ks string, tbl sqlparser.TableName) { + tc.addTable(ks, tbl.Name.String()) +} + +func (tc *tableCollector) getTables() []string { + tableNames := make([]string, 0, len(tc.tables)) + for tbl := range tc.tables { + tableNames = append(tableNames, tbl) } - operators.SortTableNames(tables) - return tables + + sort.Strings(tableNames) + return tableNames } func newFlushStmt(stmt *sqlparser.Flush, tables sqlparser.TableNames) *sqlparser.Flush { diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index eddab9b3a4b..4c4b3791c20 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -74,7 +74,7 @@ func buildGeneralDDLPlan(ctx context.Context, sql string, ddlStatement sqlparser } tc := &tableCollector{} for _, tbl := range ddlStatement.AffectedTables() { - tc.addTable(sqlparser.NewTableNameWithQualifier(tbl.Name.String(), normalDDLPlan.Keyspace.Name)) + tc.addASTTable(normalDDLPlan.Keyspace.Name, tbl) } return newPlanResult(eddl, tc.getTables()...), nil diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index 546a9854f26..c0aa9dd707d 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -77,11 +77,29 @@ func transformToPrimitive(ctx *plancontext.PlanningContext, op operators.Operato return transformSequential(ctx, op) case *operators.DMLWithInput: return transformDMLWithInput(ctx, op) + case *operators.PercentBasedMirror: + return transformPercentBasedMirror(ctx, op) } return nil, vterrors.VT13001(fmt.Sprintf("unknown type encountered: %T (transformToPrimitive)", op)) } +func transformPercentBasedMirror(ctx *plancontext.PlanningContext, op *operators.PercentBasedMirror) (engine.Primitive, error) { + primitive, err := transformToPrimitive(ctx, op.Operator) + if err != nil { + return nil, err + } + + target, err := transformToPrimitive(ctx.UseMirror(), op.Target) + // Mirroring is best-effort. If we encounter an error while building the + // mirror target primitive, proceed without mirroring. + if err != nil { + return primitive, nil + } + + return engine.NewPercentBasedMirror(op.Percent, primitive, target), nil +} + func transformDMLWithInput(ctx *plancontext.PlanningContext, op *operators.DMLWithInput) (engine.Primitive, error) { input, err := transformToPrimitive(ctx, op.Source) if err != nil { @@ -288,7 +306,6 @@ func transformFkVerify(ctx *plancontext.PlanningContext, fkv *operators.FkVerify Verify: verify, Exec: inputLP, }, nil - } func transformAggregator(ctx *plancontext.PlanningContext, op *operators.Aggregator) (engine.Primitive, error) { @@ -451,7 +468,6 @@ func getEvalEngineExpr(ctx *plancontext.PlanningContext, pe *operators.ProjExpr) default: return nil, vterrors.VT13001("project not planned for: %s", pe.String()) } - } // newSimpleProjection creates a simple projections diff --git a/go/vt/vtgate/planbuilder/operators/SQL_builder.go b/go/vt/vtgate/planbuilder/operators/SQL_builder.go index fef4ae2aee4..b7512fbf19d 100644 --- a/go/vt/vtgate/planbuilder/operators/SQL_builder.go +++ b/go/vt/vtgate/planbuilder/operators/SQL_builder.go @@ -40,6 +40,7 @@ type ( func (qb *queryBuilder) asSelectStatement() sqlparser.SelectStatement { return qb.stmt.(sqlparser.SelectStatement) } + func (qb *queryBuilder) asOrderAndLimit() sqlparser.OrderAndLimit { return qb.stmt.(sqlparser.OrderAndLimit) } @@ -214,9 +215,11 @@ type FromStatement interface { SetWherePredicate(sqlparser.Expr) } -var _ FromStatement = (*sqlparser.Select)(nil) -var _ FromStatement = (*sqlparser.Update)(nil) -var _ FromStatement = (*sqlparser.Delete)(nil) +var ( + _ FromStatement = (*sqlparser.Select)(nil) + _ FromStatement = (*sqlparser.Update)(nil) + _ FromStatement = (*sqlparser.Delete)(nil) +) func (qb *queryBuilder) joinWith(other *queryBuilder, onCondition sqlparser.Expr, joinType sqlparser.JoinType) { stmt := qb.stmt.(FromStatement) @@ -292,7 +295,6 @@ func (qb *queryBuilder) sortTables() { sort.Sort(ts) return true, nil }, qb.stmt) - } type tableSorter struct { diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index 0d838610866..f1136e0c6f7 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -26,8 +26,10 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) -const foreignKeyConstraintValues = "fkc_vals" -const foreignKeyUpdateExpr = "fkc_upd" +const ( + foreignKeyConstraintValues = "fkc_vals" + foreignKeyUpdateExpr = "fkc_upd" +) // translateQueryToOp creates an operator tree that represents the input SELECT or UNION query func translateQueryToOp(ctx *plancontext.PlanningContext, selStmt sqlparser.Statement) Operator { @@ -47,6 +49,20 @@ func translateQueryToOp(ctx *plancontext.PlanningContext, selStmt sqlparser.Stat } } +func translateQueryToOpWithMirroring(ctx *plancontext.PlanningContext, stmt sqlparser.Statement) Operator { + op := translateQueryToOp(ctx, stmt) + + switch stmt.(type) { + case sqlparser.SelectStatement: + if mi := ctx.SemTable.GetMirrorInfo(); mi.Percent > 0 { + mirrorOp := translateQueryToOp(ctx.UseMirror(), stmt) + op = NewPercentBasedMirror(mi.Percent, op, mirrorOp) + } + } + + return op +} + func createOperatorFromSelect(ctx *plancontext.PlanningContext, sel *sqlparser.Select) Operator { op := crossJoin(ctx, sel.From) diff --git a/go/vt/vtgate/planbuilder/operators/delete.go b/go/vt/vtgate/planbuilder/operators/delete.go index 797ca3c7977..5bbf5218bd7 100644 --- a/go/vt/vtgate/planbuilder/operators/delete.go +++ b/go/vt/vtgate/planbuilder/operators/delete.go @@ -33,11 +33,6 @@ type Delete struct { noPredicates } -var ( - _ Operator = (*Delete)(nil) - _ TableUser = (*Delete)(nil) -) - // Clone implements the Operator interface func (d *Delete) Clone(inputs []Operator) Operator { newD := *d @@ -60,8 +55,8 @@ func (d *Delete) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -func (d *Delete) TablesUsed() []sqlparser.TableName { - return SingleTableName(d.Target.VTable.Keyspace, d.Target.VTable.Name) +func (d *Delete) TablesUsed() []string { + return SingleQualifiedIdentifier(d.Target.VTable.Keyspace, d.Target.VTable.Name) } func (d *Delete) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/helpers.go b/go/vt/vtgate/planbuilder/operators/helpers.go index 3f23ca1b43c..17c459a3457 100644 --- a/go/vt/vtgate/planbuilder/operators/helpers.go +++ b/go/vt/vtgate/planbuilder/operators/helpers.go @@ -17,8 +17,8 @@ limitations under the License. package operators import ( - "slices" - "strings" + "fmt" + "sort" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -38,6 +38,7 @@ func compact(ctx *plancontext.PlanningContext, op Operator) Operator { if !ok { return op, NoRewrite } + fmt.Println("COMPACTING", op.ShortDescription()) return newOp.Compact(ctx) }, stopAtRoute) return newOp @@ -82,15 +83,15 @@ func TableID(op Operator) (result semantics.TableSet) { // TableUser is used to signal that this operator directly interacts with one or more tables type TableUser interface { - TablesUsed() []sqlparser.TableName + TablesUsed() []string } -func TablesUsed(op Operator) []sqlparser.TableName { - addTableName, collect := collectSortedUniqueTableNames() +func TablesUsed(op Operator) []string { + addString, collect := collectSortedUniqueStrings() _ = Visit(op, func(this Operator) error { if tbl, ok := this.(TableUser); ok { for _, u := range tbl.TablesUsed() { - addTableName(u) + addString(u) } } return nil @@ -116,59 +117,53 @@ func CostOf(op Operator) (cost int) { return } -func QualifiedTableNames(ks *vindexes.Keyspace, ts []sqlparser.TableName) []sqlparser.TableName { - add, collect := collectSortedUniqueTableNames() +func QualifiedIdentifier(ks *vindexes.Keyspace, i sqlparser.IdentifierCS) string { + return QualifiedString(ks, i.String()) +} + +func QualifiedString(ks *vindexes.Keyspace, s string) string { + return fmt.Sprintf("%s.%s", ks.Name, s) +} + +func QualifiedTableName(ks *vindexes.Keyspace, t sqlparser.TableName) string { + return QualifiedIdentifier(ks, t.Name) +} + +func QualifiedTableNames(ks *vindexes.Keyspace, ts []sqlparser.TableName) []string { + add, collect := collectSortedUniqueStrings() for _, t := range ts { - add(sqlparser.NewTableNameWithQualifier(t.Name.String(), ks.Name)) + add(QualifiedTableName(ks, t)) } return collect() } -func QualifiedTables(ks *vindexes.Keyspace, vts []*vindexes.Table) []sqlparser.TableName { - add, collect := collectSortedUniqueTableNames() +func QualifiedTables(ks *vindexes.Keyspace, vts []*vindexes.Table) []string { + add, collect := collectSortedUniqueStrings() for _, vt := range vts { - add(sqlparser.NewTableNameWithQualifier(vt.Name.String(), ks.Name)) + add(QualifiedIdentifier(ks, vt.Name)) } return collect() } -func SingleTableName(ks *vindexes.Keyspace, i sqlparser.IdentifierCS) []sqlparser.TableName { - return []sqlparser.TableName{sqlparser.NewTableNameWithQualifier(i.String(), ks.Name)} +func SingleQualifiedIdentifier(ks *vindexes.Keyspace, i sqlparser.IdentifierCS) []string { + return SingleQualifiedString(ks, i.String()) } -func SortTableNames(ts []sqlparser.TableName) { - slices.SortFunc[[]sqlparser.TableName, sqlparser.TableName](ts, func(a, b sqlparser.TableName) int { - if a.Qualifier.NotEmpty() && b.Qualifier.NotEmpty() { - if cq := strings.Compare(a.Qualifier.String(), b.Qualifier.String()); cq != 0 { - return cq - } - return strings.Compare(a.Name.String(), b.Name.String()) - } - if a.Qualifier.NotEmpty() { - return strings.Compare(a.Qualifier.String(), b.Name.String()) - } - if b.Qualifier.NotEmpty() { - return strings.Compare(a.Name.String(), b.Qualifier.String()) - } - return strings.Compare(a.Name.String(), b.Name.String()) - }) +func SingleQualifiedString(ks *vindexes.Keyspace, s string) []string { + return []string{QualifiedString(ks, s)} } -func collectSortedUniqueTableNames() (add func(sqlparser.TableName), collect func() []sqlparser.TableName) { - uniq := make(map[sqlparser.TableName]any) - - add = func(v sqlparser.TableName) { +func collectSortedUniqueStrings() (add func(string), collect func() []string) { + uniq := make(map[string]any) + add = func(v string) { uniq[v] = nil } - - collect = func() []sqlparser.TableName { - sorted := make([]sqlparser.TableName, 0, len(uniq)) + collect = func() []string { + sorted := make([]string, 0, len(uniq)) for v := range uniq { sorted = append(sorted, v) } - - SortTableNames(sorted) - + sort.Strings(sorted) return sorted } diff --git a/go/vt/vtgate/planbuilder/operators/horizon.go b/go/vt/vtgate/planbuilder/operators/horizon.go index 7539704c2a9..8dd0db37fbb 100644 --- a/go/vt/vtgate/planbuilder/operators/horizon.go +++ b/go/vt/vtgate/planbuilder/operators/horizon.go @@ -18,6 +18,7 @@ package operators import ( "errors" + "fmt" "slices" "vitess.io/vitess/go/vt/sqlparser" @@ -205,7 +206,7 @@ func (h *Horizon) getQP(ctx *plancontext.PlanningContext) *QueryProjection { } func (h *Horizon) ShortDescription() string { - return h.Alias + return fmt.Sprintf("Horizon (Alias: %s)", h.Alias) } func (h *Horizon) introducesTableID() semantics.TableSet { diff --git a/go/vt/vtgate/planbuilder/operators/insert.go b/go/vt/vtgate/planbuilder/operators/insert.go index 1a129946812..6832dc363d5 100644 --- a/go/vt/vtgate/planbuilder/operators/insert.go +++ b/go/vt/vtgate/planbuilder/operators/insert.go @@ -82,10 +82,7 @@ func (i *Insert) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -var ( - _ Operator = (*Insert)(nil) - _ TableUser = (*Insert)(nil) -) +var _ Operator = (*Insert)(nil) func (i *Insert) Clone([]Operator) Operator { return &Insert{ @@ -99,8 +96,8 @@ func (i *Insert) Clone([]Operator) Operator { } } -func (i *Insert) TablesUsed() []sqlparser.TableName { - return SingleTableName(i.VTable.Keyspace, i.VTable.Name) +func (i *Insert) TablesUsed() []string { + return SingleQualifiedIdentifier(i.VTable.Keyspace, i.VTable.Name) } func (i *Insert) Statement() sqlparser.Statement { diff --git a/go/vt/vtgate/planbuilder/operators/mirror.go b/go/vt/vtgate/planbuilder/operators/mirror.go new file mode 100644 index 00000000000..e0794d1246c --- /dev/null +++ b/go/vt/vtgate/planbuilder/operators/mirror.go @@ -0,0 +1,102 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package operators + +import ( + "fmt" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" +) + +type ( + PercentBasedMirror struct { + Percent float32 + Operator Operator + Target Operator + } +) + +var _ Operator = (*PercentBasedMirror)(nil) + +func NewPercentBasedMirror(percent float32, operator, target Operator) *PercentBasedMirror { + return &PercentBasedMirror{ + percent, + operator, + target, + } +} + +// Clone will return a copy of this operator, protected so changed to the original will not impact the clone +func (m *PercentBasedMirror) Clone(inputs []Operator) Operator { + cloneMirror := *m + cloneMirror.Percent = m.Percent + cloneMirror.Operator = inputs[0] + cloneMirror.Target = inputs[1] + return &cloneMirror +} + +// Inputs returns the inputs for this operator +func (m *PercentBasedMirror) Inputs() []Operator { + return []Operator{ + m.Operator, + m.Target, + } +} + +// SetInputs changes the inputs for this op +func (m *PercentBasedMirror) SetInputs(inputs []Operator) { + m.Operator = inputs[0] + m.Target = inputs[1] +} + +// AddPredicate is used to push predicates. It pushed it as far down as is possible in the tree. +// If we encounter a join and the predicate depends on both sides of the join, the predicate will be split into two parts, +// where data is fetched from the LHS of the join to be used in the evaluation on the RHS +// TODO: we should remove this and replace it with rewriters +func (m *PercentBasedMirror) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { + panic("not supported") +} + +func (m *PercentBasedMirror) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, expr *sqlparser.AliasedExpr) int { + panic("not supported") +} + +func (m *PercentBasedMirror) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int { + return m.Operator.FindCol(ctx, expr, underRoute) +} + +func (m *PercentBasedMirror) GetColumns(ctx *plancontext.PlanningContext) []*sqlparser.AliasedExpr { + return m.Operator.GetColumns(ctx) +} + +func (m *PercentBasedMirror) GetSelectExprs(ctx *plancontext.PlanningContext) sqlparser.SelectExprs { + return m.Operator.GetSelectExprs(ctx) +} + +func (m *PercentBasedMirror) ShortDescription() string { + return fmt.Sprintf("PercentBasedMirror (%.02f%%)", m.Percent) +} + +func (m *PercentBasedMirror) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { + return m.Operator.GetOrdering(ctx) +} + +// AddWSColumn implements Operator. +func (m *PercentBasedMirror) AddWSColumn(ctx *plancontext.PlanningContext, offset int, underRoute bool) int { + panic("not supported") +} diff --git a/go/vt/vtgate/planbuilder/operators/plan_query.go b/go/vt/vtgate/planbuilder/operators/plan_query.go index 4d371942c26..40c27d03126 100644 --- a/go/vt/vtgate/planbuilder/operators/plan_query.go +++ b/go/vt/vtgate/planbuilder/operators/plan_query.go @@ -60,7 +60,7 @@ type ( func PlanQuery(ctx *plancontext.PlanningContext, stmt sqlparser.Statement) (result Operator, err error) { defer PanicHandler(&err) - op := translateQueryToOp(ctx, stmt) + op := translateQueryToOpWithMirroring(ctx, stmt) if DebugOperatorTree { fmt.Println("Initial tree:") diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index e88fb53edb3..4b8ff87a7ae 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -107,6 +107,13 @@ func runRewriters(ctx *plancontext.PlanningContext, root Operator) Operator { } } + if pbm, ok := root.(*PercentBasedMirror); ok { + root = pbm.Clone([]Operator{ + runRewriters(ctx, pbm.Operator), + runRewriters(ctx.UseMirror(), pbm.Target), + }) + } + return FixedPointBottomUp(root, TableID, visitor, stopAtRoute) } @@ -733,7 +740,6 @@ func pushFilterUnderProjection(ctx *plancontext.PlanningContext, filter *Filter, } } return Swap(filter, projection, "push filter under projection") - } func tryPushDistinct(in *Distinct) (Operator, *ApplyResult) { diff --git a/go/vt/vtgate/planbuilder/operators/rewriters.go b/go/vt/vtgate/planbuilder/operators/rewriters.go index ab9fe66e368..08ac06bf417 100644 --- a/go/vt/vtgate/planbuilder/operators/rewriters.go +++ b/go/vt/vtgate/planbuilder/operators/rewriters.go @@ -50,9 +50,7 @@ type ( VisitRule bool ) -var ( - NoRewrite *ApplyResult = nil -) +var NoRewrite *ApplyResult = nil const ( VisitChildren VisitRule = true diff --git a/go/vt/vtgate/planbuilder/operators/route.go b/go/vt/vtgate/planbuilder/operators/route.go index 9e63dfa8917..1c91077c2e4 100644 --- a/go/vt/vtgate/planbuilder/operators/route.go +++ b/go/vt/vtgate/planbuilder/operators/route.go @@ -754,11 +754,11 @@ func (r *Route) GetOrdering(ctx *plancontext.PlanningContext) []OrderBy { // TablesUsed returns tables used by MergedWith routes, which are not included // in Inputs() and thus not a part of the operator tree -func (r *Route) TablesUsed() []sqlparser.TableName { - addTable, collect := collectSortedUniqueTableNames() +func (r *Route) TablesUsed() []string { + addString, collect := collectSortedUniqueStrings() for _, mw := range r.MergedWith { for _, u := range TablesUsed(mw) { - addTable(u) + addString(u) } } return collect() diff --git a/go/vt/vtgate/planbuilder/operators/route_planning.go b/go/vt/vtgate/planbuilder/operators/route_planning.go index 47405e3b935..fa2dd47854a 100644 --- a/go/vt/vtgate/planbuilder/operators/route_planning.go +++ b/go/vt/vtgate/planbuilder/operators/route_planning.go @@ -57,7 +57,6 @@ func optimizeJoin(ctx *plancontext.PlanningContext, op *Join) (Operator, *ApplyR } func optimizeQueryGraph(ctx *plancontext.PlanningContext, op *QueryGraph) (result Operator, changed *ApplyResult) { - switch { case ctx.PlannerVersion == querypb.ExecuteOptions_Gen4Left2Right: result = leftToRightSolve(ctx, op) diff --git a/go/vt/vtgate/planbuilder/operators/sharded_routing.go b/go/vt/vtgate/planbuilder/operators/sharded_routing.go index 1319b76f040..121d1981e8f 100644 --- a/go/vt/vtgate/planbuilder/operators/sharded_routing.go +++ b/go/vt/vtgate/planbuilder/operators/sharded_routing.go @@ -653,6 +653,7 @@ func tryMergeJoinShardedRouting( aExpr := tblA.VindexExpressions() bExpr := tblB.VindexExpressions() if aVdx == bVdx && gen4ValuesEqual(ctx, aExpr, bExpr) { + fmt.Println("MERGING SHARDED ROUTING") return m.mergeShardedRouting(ctx, tblA, tblB, routeA, routeB) } } diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index c2256df06f4..f104f24cf2f 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -17,6 +17,8 @@ limitations under the License. package operators import ( + "fmt" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine/opcode" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -143,6 +145,7 @@ func (sqb *SubQueryBuilder) inspectSelect( // then we use the updated AST structs to build the operator // these AST elements have any subqueries replace by arguments + fmt.Println("REPLACING WHERE WITH NEW WHERE", sqlparser.String(sel.Where), sqlparser.String(newWhere)) sel.Where = newWhere sel.Having = newHaving sel.From = newFrom diff --git a/go/vt/vtgate/planbuilder/operators/table.go b/go/vt/vtgate/planbuilder/operators/table.go index e1e4493df30..3ecd4982ece 100644 --- a/go/vt/vtgate/planbuilder/operators/table.go +++ b/go/vt/vtgate/planbuilder/operators/table.go @@ -41,11 +41,6 @@ type ( } ) -var ( - _ Operator = (*Table)(nil) - _ TableUser = (*Table)(nil) -) - // Clone implements the Operator interface func (to *Table) Clone([]Operator) Operator { var columns []*sqlparser.ColName @@ -112,11 +107,11 @@ func (to *Table) AddCol(col *sqlparser.ColName) { to.Columns = append(to.Columns, col) } -func (to *Table) TablesUsed() []sqlparser.TableName { +func (to *Table) TablesUsed() []string { if sqlparser.SystemSchema(to.QTable.Table.Qualifier.String()) { return nil } - return SingleTableName(to.VTable.Keyspace, to.VTable.Name) + return SingleQualifiedIdentifier(to.VTable.Keyspace, to.VTable.Name) } func addColumn(ctx *plancontext.PlanningContext, op ColNameColumns, e sqlparser.Expr) int { diff --git a/go/vt/vtgate/planbuilder/operators/update.go b/go/vt/vtgate/planbuilder/operators/update.go index 40cc8a68574..e843155246c 100644 --- a/go/vt/vtgate/planbuilder/operators/update.go +++ b/go/vt/vtgate/planbuilder/operators/update.go @@ -58,11 +58,6 @@ type ( } ) -var ( - _ Operator = (*Update)(nil) - _ TableUser = (*Update)(nil) -) - func (u *Update) Inputs() []Operator { if u.Source == nil { return nil @@ -94,8 +89,8 @@ func (u *Update) GetOrdering(*plancontext.PlanningContext) []OrderBy { return nil } -func (u *Update) TablesUsed() []sqlparser.TableName { - return SingleTableName(u.Target.VTable.Keyspace, u.Target.VTable.Name) +func (u *Update) TablesUsed() []string { + return SingleQualifiedIdentifier(u.Target.VTable.Keyspace, u.Target.VTable.Name) } func (u *Update) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/operators/vindex.go b/go/vt/vtgate/planbuilder/operators/vindex.go index ce56554d568..fd907fdad27 100644 --- a/go/vt/vtgate/planbuilder/operators/vindex.go +++ b/go/vt/vtgate/planbuilder/operators/vindex.go @@ -50,11 +50,6 @@ type ( const wrongWhereCond = "WHERE clause for vindex function must be of the form id = or id in(,...)" -var ( - _ Operator = (*Vindex)(nil) - _ TableUser = (*Vindex)(nil) -) - // Introduces implements the Operator interface func (v *Vindex) introducesTableID() semantics.TableSet { return v.Solved @@ -169,8 +164,8 @@ func (v *Vindex) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.E // TablesUsed implements the Operator interface. // It is not keyspace-qualified. -func (v *Vindex) TablesUsed() []sqlparser.TableName { - return []sqlparser.TableName{sqlparser.NewTableName(v.Table.Table.Name.String())} +func (v *Vindex) TablesUsed() []string { + return []string{v.Table.Table.Name.String()} } func (v *Vindex) ShortDescription() string { diff --git a/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go b/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go index e957c282fb8..03545fd36ff 100644 --- a/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go +++ b/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go @@ -251,7 +251,7 @@ func (m *mirrorVSchema) FindMirrorRule(name sqlparser.TableName) (*vindexes.Mirr return nil, "", topodatapb.TabletType_UNKNOWN, nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "[BUG] refusing to perform chained traffic mirroring") } -// ForMirroring returns a wrapper which returns mirrored versions of values +// MirrorVSchema returns a wrapper which returns mirrored versions of values // return by the wrapped vschema. // // For example, if the underlying VSchema defines any mirror rules from ks1 to @@ -259,7 +259,7 @@ func (m *mirrorVSchema) FindMirrorRule(name sqlparser.TableName) (*vindexes.Mirr // ks1 will return tables in ks2. // // The returned VSchema cannot be reflected back again by passing it to -// ForMirroring. This restriction prevents infinite mirroring loops. -func ForMirroring(vschema VSchema) VSchema { +// MirrorVSchema. This restriction prevents infinite mirroring loops. +func MirrorVSchema(vschema VSchema) VSchema { return &mirrorVSchema{vschema} } diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context.go b/go/vt/vtgate/planbuilder/plancontext/planning_context.go index a3f5be6ef19..00d4289f363 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context.go @@ -67,9 +67,11 @@ type PlanningContext struct { // Used to set the nullable flag on the columns OuterTables semantics.TableSet - // NodeTransformers are used to influence the formatting of Statement without - // making changes to Statement. - NodeTransformers []sqlparser.NodeTransformer + // mirror contains a mirrored clone of this planning context. + mirror *PlanningContext + + // IsMirror indicates that mirrored tables should be used. + isMirrored bool } // CreatePlanningContext initializes a new PlanningContext with the given parameters. @@ -381,6 +383,27 @@ func (ctx *PlanningContext) ContainsAggr(e sqlparser.SQLNode) (hasAggr bool) { return } -func (ctx *PlanningContext) AddNodeTransformer(transformer sqlparser.NodeTransformer) { - ctx.NodeTransformers = append(ctx.NodeTransformers, transformer) +func (ctx *PlanningContext) IsMirrored() bool { + return ctx.isMirrored +} + +func (ctx *PlanningContext) UseMirror() *PlanningContext { + if ctx.isMirrored { + panic("bug: cannot mirror already mirrored planning context") + } + if ctx.mirror != nil { + return ctx.mirror + } + ctx.mirror = &PlanningContext{ + ReservedVars: ctx.ReservedVars, + SemTable: ctx.SemTable, + VSchema: MirrorVSchema(ctx.VSchema), + joinPredicates: map[sqlparser.Expr][]sqlparser.Expr{}, + skipPredicates: map[sqlparser.Expr]any{}, + PlannerVersion: ctx.PlannerVersion, + ReservedArguments: map[sqlparser.Expr]string{}, + Statement: ctx.Statement, + isMirrored: true, + } + return ctx.mirror } diff --git a/go/vt/vtgate/planbuilder/route.go b/go/vt/vtgate/planbuilder/route.go index 138073a4521..e320df14416 100644 --- a/go/vt/vtgate/planbuilder/route.go +++ b/go/vt/vtgate/planbuilder/route.go @@ -26,34 +26,12 @@ import ( ) // WireupRoute returns an engine primitive for the given route. -func WireupRoute( - ctx *plancontext.PlanningContext, - eroute *engine.Route, - sel sqlparser.SelectStatement, -) (engine.Primitive, error) { - var transform sqlparser.NodeTransformer - if len(ctx.NodeTransformers) > 0 { - transform = sqlparser.ComposeTransformers(ctx.NodeTransformers...) - } - - // prepare the query we will pass down - if transform != nil { - qfmt := sqlparser.TransformFormatter(transform, sqlparser.DefaultFormatter) - qbuf := sqlparser.NewTrackedBuffer(qfmt) - qnode := qbuf.WriteNode(sel) - eroute.Query = qnode.ParsedQuery().Query - } else { - eroute.Query = sqlparser.String(sel) - } - - // prepare the field query we will pass down - ffmt := sqlparser.FormatImpossibleQuery - if transform != nil { - ffmt = sqlparser.TransformFormatter(transform, ffmt) - } - fbuf := sqlparser.NewTrackedBuffer(ffmt) - fnode := fbuf.WriteNode(sel) - eroute.FieldQuery = fnode.ParsedQuery().Query +func WireupRoute(ctx *plancontext.PlanningContext, eroute *engine.Route, sel sqlparser.SelectStatement) (engine.Primitive, error) { + // prepare the queries we will pass down + eroute.Query = sqlparser.String(sel) + buffer := sqlparser.NewTrackedBuffer(sqlparser.FormatImpossibleQuery) + node := buffer.WriteNode(sel) + eroute.FieldQuery = node.ParsedQuery().Query // if we have a planable vindex lookup, let's extract it into its own primitive planableVindex, ok := eroute.RoutingParameters.Vindex.(vindexes.LookupPlanable) diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index 9880f32e500..0f6e9e1ccb4 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -45,12 +45,12 @@ func gen4SelectStmtPlanner( return nil, err } if p != nil { - used := sqlparser.NewTableName("dual") + used := "dual" keyspace, ksErr := vschema.DefaultKeyspace() if ksErr == nil { // we are just getting the ks to log the correct table use. // no need to fail this if we can't find the default keyspace - used = sqlparser.NewTableNameWithQualifier("dual", keyspace.Name) + used = keyspace.Name + ".dual" } return newPlanResult(p, used), nil } @@ -62,7 +62,7 @@ func gen4SelectStmtPlanner( sel.SQLCalcFoundRows = false } - getPlan := func(selStatement sqlparser.SelectStatement) (engine.Primitive, []sqlparser.TableName, error) { + getPlan := func(selStatement sqlparser.SelectStatement) (engine.Primitive, []string, error) { return newBuildSelectPlan(selStatement, reservedVars, vschema, plannerVersion) } @@ -123,7 +123,7 @@ func buildSQLCalcFoundRowsPlan( sel *sqlparser.Select, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, -) (engine.Primitive, []sqlparser.TableName, error) { +) (engine.Primitive, []string, error) { limitPlan, _, err := newBuildSelectPlan(sel, reservedVars, vschema, Gen4) if err != nil { return nil, nil, err @@ -180,7 +180,7 @@ func buildSQLCalcFoundRowsPlan( }, tablesUsed, nil } -func gen4PredicateRewrite(stmt sqlparser.Statement, getPlan func(selStatement sqlparser.SelectStatement) (engine.Primitive, []sqlparser.TableName, error)) (engine.Primitive, []sqlparser.TableName) { +func gen4PredicateRewrite(stmt sqlparser.Statement, getPlan func(selStatement sqlparser.SelectStatement) (engine.Primitive, []string, error)) (engine.Primitive, []string) { rewritten, isSel := sqlparser.RewritePredicate(stmt).(sqlparser.SelectStatement) if !isSel { // Fail-safe code, should never happen @@ -199,13 +199,13 @@ func newBuildSelectPlan( reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, version querypb.ExecuteOptions_PlannerVersion, -) (plan engine.Primitive, tablesUsed []sqlparser.TableName, err error) { +) (plan engine.Primitive, tablesUsed []string, err error) { ctx, err := plancontext.CreatePlanningContext(selStmt, reservedVars, vschema, version) if err != nil { return nil, nil, err } - if ks, _ := ctx.SemTable.SingleUnshardedKeyspace(); ks != nil { + if ks, ok := ctx.SemTable.CanTakeSelectUnshardedShortcut(); ok { plan, tablesUsed, err = selectUnshardedShortcut(ctx, selStmt, ks) if err != nil { return nil, nil, err @@ -214,7 +214,6 @@ func newBuildSelectPlan( return plan, tablesUsed, err } - // From this point on, we know it is not an unsharded query and return the NotUnshardedErr if there is any if ctx.SemTable.NotUnshardedErr != nil { return nil, nil, ctx.SemTable.NotUnshardedErr } diff --git a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go index e16dc908f93..5d877cd341d 100644 --- a/go/vt/vtgate/planbuilder/single_sharded_shortcut.go +++ b/go/vt/vtgate/planbuilder/single_sharded_shortcut.go @@ -28,10 +28,19 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) -var emptyIdentifier = sqlparser.NewIdentifierCS("") - -func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, ks *vindexes.Keyspace) (engine.Primitive, []sqlparser.TableName, error) { - ctx.AddNodeTransformer(removeKeyspacesTransformer()) +func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.SelectStatement, ks *vindexes.Keyspace) (engine.Primitive, []string, error) { + // this method is used when the query we are handling has all tables in the same unsharded keyspace + sqlparser.SafeRewrite(stmt, nil, func(cursor *sqlparser.Cursor) bool { + switch node := cursor.Node().(type) { + case sqlparser.SelectExpr: + removeKeyspaceFromSelectExpr(node) + case sqlparser.TableName: + cursor.Replace(sqlparser.TableName{ + Name: node.Name, + }) + } + return true + }) tableNames, err := getTableNames(ctx.SemTable) if err != nil { @@ -44,7 +53,6 @@ func selectUnshardedShortcut(ctx *plancontext.PlanningContext, stmt sqlparser.Se }, TableName: strings.Join(escapedTableNames(tableNames), ", "), } - prim, err := WireupRoute(ctx, eroute, stmt) if err != nil { return nil, nil, err @@ -91,38 +99,11 @@ func getTableNames(semTable *semantics.SemTable) ([]sqlparser.TableName, error) return tableNames, nil } -// removeKeyspacesTransformer returns a NodeTransformer that produces -// transformed SQLNode stripped of keyspace information. -func removeKeyspacesTransformer() sqlparser.NodeTransformer { - var inAliasedExpr bool - var inSelectExpr bool - - return func(node sqlparser.SQLNode, done func(node sqlparser.SQLNode)) { - switch node := node.(type) { - case *sqlparser.AliasedExpr: - inAliasedExpr = true - done(node) - inAliasedExpr = false - case *sqlparser.ColName: - if inSelectExpr && inAliasedExpr { - if !node.Qualifier.Qualifier.IsEmpty() { - node := sqlparser.Clone(node) - node.Qualifier.Qualifier = emptyIdentifier - } - } - done(node) - case sqlparser.SelectExpr: - inSelectExpr = true - done(node) - inSelectExpr = false - case sqlparser.TableName: - if !node.Qualifier.IsEmpty() { - node = sqlparser.Clone(node) - node.Qualifier = emptyIdentifier - } - done(node) - default: - done(node) - } +func removeKeyspaceFromSelectExpr(expr sqlparser.SelectExpr) { + switch expr := expr.(type) { + case *sqlparser.AliasedExpr: + sqlparser.RemoveKeyspaceInCol(expr.Expr) + case *sqlparser.StarExpr: + expr.TableName.Qualifier = sqlparser.NewIdentifierCS("") } } diff --git a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json index 061badda9f8..e58d2b13cb3 100644 --- a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json @@ -108,7 +108,7 @@ "Variant": "Join", "JoinColumnIndexes": "L:0,R:0", "JoinVars": { - "t1_id": 0 + "t1_id1": 0 }, "TableName": "t1_t1", "Inputs": [ @@ -131,10 +131,10 @@ "Sharded": true }, "FieldQuery": "select t2.id from t1 as t2 where 1 != 1", - "Query": "select t2.id from t1 as t2 where t2.id = :t1_id", + "Query": "select t2.id from t1 as t2 where t2.id = :t1_id1", "Table": "t1", "Values": [ - ":t1_id" + ":t1_id1" ], "Vindex": "xxhash" } @@ -177,7 +177,6 @@ "Collations": [ "(0:1)" ], - "ResultColumns": 1, "Inputs": [ { "OperatorType": "Concatenate", diff --git a/go/vt/vtgate/planbuilder/vexplain.go b/go/vt/vtgate/planbuilder/vexplain.go index cc5cf6a10db..21a35f02967 100644 --- a/go/vt/vtgate/planbuilder/vexplain.go +++ b/go/vt/vtgate/planbuilder/vexplain.go @@ -27,6 +27,7 @@ import ( "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vtgate/planbuilder/operators" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -78,7 +79,7 @@ func explainTabPlan(explain *sqlparser.ExplainTab, vschema plancontext.VSchema) TargetDestination: destination, Query: sqlparser.String(explain), SingleShardOnly: true, - }, sqlparser.NewTableNameWithQualifier(explain.Table.Name.String(), keyspace.Name)), nil + }, singleTable(keyspace.Name, explain.Table.Name.String())), nil } func buildVExplainVtgatePlan(ctx context.Context, explainStatement sqlparser.Statement, reservedVars *sqlparser.ReservedVars, vschema plancontext.VSchema, enableOnlineDDL, enableDirectDDL bool) (*planResult, error) { @@ -147,7 +148,7 @@ func explainPlan(explain *sqlparser.ExplainStmt, reservedVars *sqlparser.Reserve // Remove keyspace qualifier from columns and tables. sqlparser.RemoveKeyspace(explain.Statement) - var tables []sqlparser.TableName + var tables []string for _, table := range ctx.SemTable.Tables { name, err := table.Name() if err != nil { @@ -155,7 +156,7 @@ func explainPlan(explain *sqlparser.ExplainStmt, reservedVars *sqlparser.Reserve // it's OK to ignore errors here continue } - tables = append(tables, sqlparser.NewTableNameWithQualifier(name.Name.String(), ks.Name)) + tables = append(tables, operators.QualifiedString(ks, name.Name.String())) } return newPlanResult(&engine.Send{ diff --git a/go/vt/vtgate/semantics/FakeSI.go b/go/vt/vtgate/semantics/FakeSI.go index 1ca6718f1a8..83f2270d777 100644 --- a/go/vt/vtgate/semantics/FakeSI.go +++ b/go/vt/vtgate/semantics/FakeSI.go @@ -85,3 +85,8 @@ func (s *FakeSI) KeyspaceError(keyspace string) error { func (s *FakeSI) GetAggregateUDFs() []string { return s.UDFs } + +// FindMirrorRule implements SchemaInformation. +func (s *FakeSI) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { + return nil, "", topodatapb.TabletType_UNKNOWN, nil, nil +} diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index 8bb7cc393fc..8dae2eed5bb 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -387,7 +387,14 @@ func (a *analyzer) reAnalyze(statement sqlparser.SQLNode) error { // canShortCut checks if we are dealing with a single unsharded keyspace and no tables that have managed foreign keys // if so, we can stop the analyzer early func (a *analyzer) canShortCut(statement sqlparser.Statement) (canShortCut bool) { - ks, _ := singleUnshardedKeyspace(a.earlyTables.Tables) + var ks *vindexes.Keyspace + switch statement.(type) { + case sqlparser.SelectStatement: + ks, canShortCut = canTakeSelectUnshardedShortcut(a.earlyTables.Tables) + default: + ks, canShortCut = canTakeUnshardedShortcut(a.earlyTables.Tables) + } + a.singleUnshardedKeyspace = ks != nil if !a.singleUnshardedKeyspace { return false diff --git a/go/vt/vtgate/semantics/derived_table.go b/go/vt/vtgate/semantics/derived_table.go index aabbe9f0b22..902408ccd98 100644 --- a/go/vt/vtgate/semantics/derived_table.go +++ b/go/vt/vtgate/semantics/derived_table.go @@ -195,3 +195,8 @@ func (dt *DerivedTable) checkForDuplicates() error { } return nil } + +// GetMirrorRule implements TableInfo. +func (dt *DerivedTable) GetMirrorRule() *vindexes.MirrorRule { + return nil +} diff --git a/go/vt/vtgate/semantics/info_schema.go b/go/vt/vtgate/semantics/info_schema.go index 11e577f3fa7..917f3b2791f 100644 --- a/go/vt/vtgate/semantics/info_schema.go +++ b/go/vt/vtgate/semantics/info_schema.go @@ -1603,11 +1603,15 @@ type infoSchemaWithColumns struct { infoSchemaData map[string][]vindexes.Column } +var _ SchemaInformation = (*infoSchemaWithColumns)(nil) + // MySQLVersion implements SchemaInformation. // We cache this information, since these are maps that are not changed -var infoSchema57 = getInfoSchema57() -var infoSchema80 = getInfoSchema80() +var ( + infoSchema57 = getInfoSchema57() + infoSchema80 = getInfoSchema80() +) // newSchemaInfo returns a SchemaInformation that has the column information for all info_schema tables func newSchemaInfo(inner SchemaInformation) SchemaInformation { @@ -1665,3 +1669,8 @@ func (i *infoSchemaWithColumns) KeyspaceError(keyspace string) error { func (i *infoSchemaWithColumns) GetAggregateUDFs() []string { return i.inner.GetAggregateUDFs() } + +// FindMirrorRule implements SchemaInformation. +func (i *infoSchemaWithColumns) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { + return i.inner.FindMirrorRule(tablename) +} diff --git a/go/vt/vtgate/semantics/real_table.go b/go/vt/vtgate/semantics/real_table.go index 4f1639d0897..d718fa12c96 100644 --- a/go/vt/vtgate/semantics/real_table.go +++ b/go/vt/vtgate/semantics/real_table.go @@ -32,6 +32,7 @@ type RealTable struct { ASTNode *sqlparser.AliasedTableExpr Table *vindexes.Table VindexHint *sqlparser.IndexHint + MirrorRule *vindexes.MirrorRule isInfSchema bool collationEnv *collations.Environment } @@ -154,3 +155,8 @@ func (r *RealTable) authoritative() bool { func (r *RealTable) matches(name sqlparser.TableName) bool { return (name.Qualifier.IsEmpty() || name.Qualifier.String() == r.dbName) && r.tableName == name.Name.String() } + +// GetMirrorRule implements TableInfo. +func (r *RealTable) GetMirrorRule() *vindexes.MirrorRule { + return r.MirrorRule +} diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index ac2fd9c1604..846222a3112 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -63,6 +63,9 @@ type ( dependencies(colName string, org originable) (dependencies, error) getExprFor(s string) (sqlparser.Expr, error) getTableSet(org originable) TableSet + + // GetMirrorRule returns the vschema mirror rule for this TableInfo + GetMirrorRule() *vindexes.MirrorRule } // ColumnInfo contains information about columns @@ -85,6 +88,12 @@ type ( Union bool } + // MirrorInfo stores information used to produce mirror + // operators. + MirrorInfo struct { + Percent float32 + } + // SemTable contains semantic analysis information about the query. SemTable struct { // Tables stores information about the tables in the query, including derived tables @@ -162,6 +171,7 @@ type ( GetForeignKeyChecksState() *bool KeyspaceError(keyspace string) error GetAggregateUDFs() []string + FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) } shortCut = int @@ -173,10 +183,8 @@ const ( dependsOnKeyspace ) -var ( - // ErrNotSingleTable refers to an error happening when something should be used only for single tables - ErrNotSingleTable = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] should only be used for single tables") -) +// ErrNotSingleTable refers to an error happening when something should be used only for single tables +var ErrNotSingleTable = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] should only be used for single tables") // CopyDependencies copies the dependencies from one expression into the other func (st *SemTable) CopyDependencies(from, to sqlparser.Expr) { @@ -733,7 +741,6 @@ func RewriteDerivedTableExpression(expr sqlparser.Expr, vt TableInfo) sqlparser. col := *node col.Qualifier = sqlparser.TableName{} cursor.Replace(&col) - }, nil).(sqlparser.Expr) } @@ -800,6 +807,7 @@ func singleUnshardedKeyspace(tableInfos []TableInfo) (ks *vindexes.Keyspace, tab tables = append(tables, vtbl) } + return ks, tables } @@ -983,3 +991,39 @@ func (st *SemTable) NewTableId() TableSet { st.Tables = append(st.Tables, nil) return tableID } + +func (st *SemTable) CanTakeSelectUnshardedShortcut() (*vindexes.Keyspace, bool) { + return canTakeSelectUnshardedShortcut(st.Tables) +} + +func (st *SemTable) CanTakeUnshardedShortcut() (*vindexes.Keyspace, bool) { + return canTakeUnshardedShortcut(st.Tables) +} + +func canTakeUnshardedShortcut(tableInfos []TableInfo) (*vindexes.Keyspace, bool) { + uks, _ := singleUnshardedKeyspace(tableInfos) + return uks, uks != nil +} + +func canTakeSelectUnshardedShortcut(tableInfos []TableInfo) (*vindexes.Keyspace, bool) { + if mi := mirrorInfo(tableInfos); mi.Percent > 0 { + return nil, false + } + return canTakeUnshardedShortcut(tableInfos) +} + +func (st *SemTable) GetMirrorInfo() MirrorInfo { + return mirrorInfo(st.Tables) +} + +func mirrorInfo(tableInfos []TableInfo) MirrorInfo { + mi := MirrorInfo{} + for _, t := range tableInfos { + if mr := t.GetMirrorRule(); mr != nil { + if mi.Percent == 0 || mr.Percent < mi.Percent { + mi.Percent = mr.Percent + } + } + } + return mi +} diff --git a/go/vt/vtgate/semantics/table_collector.go b/go/vt/vtgate/semantics/table_collector.go index 948edb37d47..8140bafdeaa 100644 --- a/go/vt/vtgate/semantics/table_collector.go +++ b/go/vt/vtgate/semantics/table_collector.go @@ -66,7 +66,6 @@ func (etc *earlyTableCollector) up(cursor *sqlparser.Cursor) { etc.withTables[cte.ID] = nil } } - } func (etc *earlyTableCollector) visitAliasedTableExpr(aet *sqlparser.AliasedTableExpr) { @@ -452,11 +451,14 @@ func createTable( return nil, err } + mr, _, _, _, _ := si.FindMirrorRule(t) + table := &RealTable{ tableName: alias.As.String(), ASTNode: alias, Table: tbl, VindexHint: hint, + MirrorRule: mr, isInfSchema: isInfSchema, collationEnv: si.Environment().CollationEnv(), } diff --git a/go/vt/vtgate/semantics/vindex_table.go b/go/vt/vtgate/semantics/vindex_table.go index b598c93f36a..c8ef271af5d 100644 --- a/go/vt/vtgate/semantics/vindex_table.go +++ b/go/vt/vtgate/semantics/vindex_table.go @@ -84,3 +84,8 @@ func (v *VindexTable) getColumns(ignoreInvisbleCol bool) []ColumnInfo { func (v *VindexTable) IsInfSchema() bool { return v.Table.IsInfSchema() } + +// GetMirrorRule implements TableInfo. +func (v *VindexTable) GetMirrorRule() *vindexes.MirrorRule { + return nil +} diff --git a/go/vt/vtgate/semantics/vtable.go b/go/vt/vtgate/semantics/vtable.go index 14519a7e938..6cd7e34aecc 100644 --- a/go/vt/vtgate/semantics/vtable.go +++ b/go/vt/vtgate/semantics/vtable.go @@ -175,3 +175,8 @@ func selectExprsToInfos( } return } + +// GetMirrorRule implements TableInfo. +func (v *vTableInfo) GetMirrorRule() *vindexes.MirrorRule { + return nil +} From 8bbae3f4424d2a971928eff857a56cfd2f81bcad Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 16 Jul 2024 23:54:38 -0400 Subject: [PATCH 16/27] cr: require.NoError Signed-off-by: Max Englander --- go/vt/vtgate/endtoend/vstream_test.go | 30 +++++++++++---------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/go/vt/vtgate/endtoend/vstream_test.go b/go/vt/vtgate/endtoend/vstream_test.go index 246d17f88b5..8fed95f5d51 100644 --- a/go/vt/vtgate/endtoend/vstream_test.go +++ b/go/vt/vtgate/endtoend/vstream_test.go @@ -60,6 +60,7 @@ func initialize(ctx context.Context, t *testing.T) (*vtgateconn.VTGateConn, *mys } return gconn, conn, mconn, close } + func TestVStream(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -186,7 +187,7 @@ func TestVStreamCopyBasic(t *testing.T) { Lastpk: qr, }} var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -264,20 +265,14 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { defer cancel() conn, err := mysql.Connect(ctx, &vtParams) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) defer conn.Close() _, err = conn.ExecuteFetch("insert into t1_copy_all(id1,id2) values(1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8)", 1, false) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) _, err = conn.ExecuteFetch("insert into t1_copy_all_ks2(id1,id2) values(10,10), (20,20)", 1, false) - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -343,13 +338,11 @@ func TestVStreamCopyUnspecifiedShardGtid(t *testing.T) { gconn, conn, mconn, closeConnections := initialize(ctx, t) defer closeConnections() - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} vgtid.ShardGtids = []*binlogdatapb.ShardGtid{c.shardGtid} reader, err := gconn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags) _, _ = conn, mconn - if err != nil { - require.NoError(t, err) - } + require.NoError(t, err) require.NotNil(t, reader) var evs []*binlogdatapb.VEvent var completedEvs []*binlogdatapb.VEvent @@ -426,7 +419,7 @@ func TestVStreamCopyResume(t *testing.T) { } var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -526,7 +519,7 @@ func TestVStreamCurrent(t *testing.T) { defer closeConnections() var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -580,7 +573,7 @@ func TestVStreamSharded(t *testing.T) { defer closeConnections() var shardGtids []*binlogdatapb.ShardGtid - var vgtid = &binlogdatapb.VGtid{} + vgtid := &binlogdatapb.VGtid{} shardGtids = append(shardGtids, &binlogdatapb.ShardGtid{ Keyspace: "ks", Shard: "-80", @@ -665,7 +658,6 @@ func TestVStreamSharded(t *testing.T) { t.Fatalf("remote error: %v\n", err) } } - } // TestVStreamCopyTransactions tests that we are properly wrapping @@ -822,9 +814,11 @@ type VEventSorter []*binlogdatapb.VEvent func (v VEventSorter) Len() int { return len(v) } + func (v VEventSorter) Swap(i, j int) { v[i], v[j] = v[j], v[i] } + func (v VEventSorter) Less(i, j int) bool { valsI := v[i].GetRowEvent().RowChanges[0].After if valsI == nil { From 4177ba8df807911cc84f7e2a9b3d6ac39c6de191 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 16 Jul 2024 23:57:35 -0400 Subject: [PATCH 17/27] cr: rm unintentional space Signed-off-by: Max Englander --- go/test/endtoend/vtgate/queries/benchmark/main_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/test/endtoend/vtgate/queries/benchmark/main_test.go b/go/test/endtoend/vtgate/queries/benchmark/main_test.go index 82cad2a2ba0..40a215c8007 100644 --- a/go/test/endtoend/vtgate/queries/benchmark/main_test.go +++ b/go/test/endtoend/vtgate/queries/benchmark/main_test.go @@ -1,7 +1,6 @@ /* Copyright 2023 The Vitess Authors. - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at From a7c3da26acd47bc70268f1b8707bcdc004224e1d Mon Sep 17 00:00:00 2001 From: Max Englander Date: Wed, 17 Jul 2024 00:02:23 -0400 Subject: [PATCH 18/27] revert unintended changes Signed-off-by: Max Englander --- go/vt/vtgate/planbuilder/builder.go | 4 +++- go/vt/vtgate/planbuilder/operators/SQL_builder.go | 10 ++++------ go/vt/vtgate/planbuilder/operators/helpers.go | 1 - go/vt/vtgate/planbuilder/operators/rewriters.go | 4 +++- go/vt/vtgate/planbuilder/operators/route_planning.go | 1 + go/vt/vtgate/planbuilder/operators/sharded_routing.go | 1 - go/vt/vtgate/planbuilder/operators/subquery_builder.go | 3 --- 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 3215ec67db0..5d1d4ecd622 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -42,7 +42,9 @@ const ( Gen4Left2Right = querypb.ExecuteOptions_Gen4Left2Right ) -var plannerVersions = []plancontext.PlannerVersion{Gen4, Gen4GreedyOnly, Gen4Left2Right} +var ( + plannerVersions = []plancontext.PlannerVersion{Gen4, Gen4GreedyOnly, Gen4Left2Right} +) type ( planResult struct { diff --git a/go/vt/vtgate/planbuilder/operators/SQL_builder.go b/go/vt/vtgate/planbuilder/operators/SQL_builder.go index b7512fbf19d..fef4ae2aee4 100644 --- a/go/vt/vtgate/planbuilder/operators/SQL_builder.go +++ b/go/vt/vtgate/planbuilder/operators/SQL_builder.go @@ -40,7 +40,6 @@ type ( func (qb *queryBuilder) asSelectStatement() sqlparser.SelectStatement { return qb.stmt.(sqlparser.SelectStatement) } - func (qb *queryBuilder) asOrderAndLimit() sqlparser.OrderAndLimit { return qb.stmt.(sqlparser.OrderAndLimit) } @@ -215,11 +214,9 @@ type FromStatement interface { SetWherePredicate(sqlparser.Expr) } -var ( - _ FromStatement = (*sqlparser.Select)(nil) - _ FromStatement = (*sqlparser.Update)(nil) - _ FromStatement = (*sqlparser.Delete)(nil) -) +var _ FromStatement = (*sqlparser.Select)(nil) +var _ FromStatement = (*sqlparser.Update)(nil) +var _ FromStatement = (*sqlparser.Delete)(nil) func (qb *queryBuilder) joinWith(other *queryBuilder, onCondition sqlparser.Expr, joinType sqlparser.JoinType) { stmt := qb.stmt.(FromStatement) @@ -295,6 +292,7 @@ func (qb *queryBuilder) sortTables() { sort.Sort(ts) return true, nil }, qb.stmt) + } type tableSorter struct { diff --git a/go/vt/vtgate/planbuilder/operators/helpers.go b/go/vt/vtgate/planbuilder/operators/helpers.go index 17c459a3457..31d9bcfd279 100644 --- a/go/vt/vtgate/planbuilder/operators/helpers.go +++ b/go/vt/vtgate/planbuilder/operators/helpers.go @@ -38,7 +38,6 @@ func compact(ctx *plancontext.PlanningContext, op Operator) Operator { if !ok { return op, NoRewrite } - fmt.Println("COMPACTING", op.ShortDescription()) return newOp.Compact(ctx) }, stopAtRoute) return newOp diff --git a/go/vt/vtgate/planbuilder/operators/rewriters.go b/go/vt/vtgate/planbuilder/operators/rewriters.go index 08ac06bf417..ab9fe66e368 100644 --- a/go/vt/vtgate/planbuilder/operators/rewriters.go +++ b/go/vt/vtgate/planbuilder/operators/rewriters.go @@ -50,7 +50,9 @@ type ( VisitRule bool ) -var NoRewrite *ApplyResult = nil +var ( + NoRewrite *ApplyResult = nil +) const ( VisitChildren VisitRule = true diff --git a/go/vt/vtgate/planbuilder/operators/route_planning.go b/go/vt/vtgate/planbuilder/operators/route_planning.go index fa2dd47854a..47405e3b935 100644 --- a/go/vt/vtgate/planbuilder/operators/route_planning.go +++ b/go/vt/vtgate/planbuilder/operators/route_planning.go @@ -57,6 +57,7 @@ func optimizeJoin(ctx *plancontext.PlanningContext, op *Join) (Operator, *ApplyR } func optimizeQueryGraph(ctx *plancontext.PlanningContext, op *QueryGraph) (result Operator, changed *ApplyResult) { + switch { case ctx.PlannerVersion == querypb.ExecuteOptions_Gen4Left2Right: result = leftToRightSolve(ctx, op) diff --git a/go/vt/vtgate/planbuilder/operators/sharded_routing.go b/go/vt/vtgate/planbuilder/operators/sharded_routing.go index 121d1981e8f..1319b76f040 100644 --- a/go/vt/vtgate/planbuilder/operators/sharded_routing.go +++ b/go/vt/vtgate/planbuilder/operators/sharded_routing.go @@ -653,7 +653,6 @@ func tryMergeJoinShardedRouting( aExpr := tblA.VindexExpressions() bExpr := tblB.VindexExpressions() if aVdx == bVdx && gen4ValuesEqual(ctx, aExpr, bExpr) { - fmt.Println("MERGING SHARDED ROUTING") return m.mergeShardedRouting(ctx, tblA, tblB, routeA, routeB) } } diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index f104f24cf2f..c2256df06f4 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -17,8 +17,6 @@ limitations under the License. package operators import ( - "fmt" - "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine/opcode" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" @@ -145,7 +143,6 @@ func (sqb *SubQueryBuilder) inspectSelect( // then we use the updated AST structs to build the operator // these AST elements have any subqueries replace by arguments - fmt.Println("REPLACING WHERE WITH NEW WHERE", sqlparser.String(sel.Where), sqlparser.String(newWhere)) sel.Where = newWhere sel.Having = newHaving sel.From = newFrom From bfaadf9d653e88c906815edbb7c5715863ffaf97 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Wed, 17 Jul 2024 00:09:36 -0400 Subject: [PATCH 19/27] cleanup Signed-off-by: Max Englander --- go/vt/vtgate/planbuilder/operators/ast_to_op.go | 5 ++--- go/vt/vtgate/planbuilder/plancontext/planning_context.go | 6 +----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index f1136e0c6f7..5cf76ee4989 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -52,10 +52,9 @@ func translateQueryToOp(ctx *plancontext.PlanningContext, selStmt sqlparser.Stat func translateQueryToOpWithMirroring(ctx *plancontext.PlanningContext, stmt sqlparser.Statement) Operator { op := translateQueryToOp(ctx, stmt) - switch stmt.(type) { - case sqlparser.SelectStatement: + if selStmt, ok := stmt.(sqlparser.SelectStatement); ok { if mi := ctx.SemTable.GetMirrorInfo(); mi.Percent > 0 { - mirrorOp := translateQueryToOp(ctx.UseMirror(), stmt) + mirrorOp := translateQueryToOp(ctx.UseMirror(), selStmt) op = NewPercentBasedMirror(mi.Percent, op, mirrorOp) } } diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context.go b/go/vt/vtgate/planbuilder/plancontext/planning_context.go index 00d4289f363..62e7e7433cc 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context.go @@ -70,7 +70,7 @@ type PlanningContext struct { // mirror contains a mirrored clone of this planning context. mirror *PlanningContext - // IsMirror indicates that mirrored tables should be used. + // isMirrored indicates that mirrored tables should be used. isMirrored bool } @@ -383,10 +383,6 @@ func (ctx *PlanningContext) ContainsAggr(e sqlparser.SQLNode) (hasAggr bool) { return } -func (ctx *PlanningContext) IsMirrored() bool { - return ctx.isMirrored -} - func (ctx *PlanningContext) UseMirror() *PlanningContext { if ctx.isMirrored { panic("bug: cannot mirror already mirrored planning context") From 4c0161475d7494154cfcf02e3d7a5b3972567f88 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 17 Jul 2024 10:43:48 +0200 Subject: [PATCH 20/27] test: add TestOneMirror Signed-off-by: Andres Taylor --- go/vt/vtgate/planbuilder/plan_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index 7c2f20a4d3a..88c6da9cc55 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -603,6 +603,20 @@ func (s *planTestSuite) TestMirrorPlanning() { s.testFile("mirror_cases.json", vschema, false) } +func (s *planTestSuite) TestOneMirror() { + reset := operators.EnableDebugPrinting() + defer reset() + vschema := &vschemawrapper.VSchemaWrapper{ + V: loadSchema(s.T(), "vschemas/mirror_schema.json", true), + TabletType_: topodatapb.TabletType_PRIMARY, + SysVarEnabled: true, + TestBuilder: TestBuilder, + Env: vtenv.NewTestEnv(), + } + + s.testFile("onecase.json", vschema, false) +} + func loadSchema(t testing.TB, filename string, setCollation bool) *vindexes.VSchema { formal, err := vindexes.LoadFormal(locateFile(filename)) require.NoError(t, err) From a330972351223106d69084cf33748f78869c613b Mon Sep 17 00:00:00 2001 From: Max Englander Date: Thu, 8 Aug 2024 01:03:02 -0400 Subject: [PATCH 21/27] cr: use vcursor.Execute, rm explicit mirrorCtxCancel, fix mirror cases, return mirror keyspace Signed-off-by: Max Englander --- go/vt/vtgate/engine/mirror.go | 18 ++++---- .../planbuilder/operators/query_planning.go | 2 +- .../plancontext/planning_context.go | 2 +- .../planbuilder/testdata/mirror_cases.json | 44 ++++++++++--------- go/vt/vtgate/semantics/semantic_state.go | 2 +- go/vt/vtgate/semantics/semantic_state_test.go | 6 +-- go/vt/vtgate/vcursor_impl.go | 3 ++ 7 files changed, 42 insertions(+), 35 deletions(-) diff --git a/go/vt/vtgate/engine/mirror.go b/go/vt/vtgate/engine/mirror.go index 40b19ae7181..b85a3883f4b 100644 --- a/go/vt/vtgate/engine/mirror.go +++ b/go/vt/vtgate/engine/mirror.go @@ -45,7 +45,7 @@ const ( var _ Primitive = (*percentBasedMirror)(nil) // NewPercentBasedMirror creates a Mirror. -func NewPercentBasedMirror(percentage float32, primitive Primitive, target Primitive) *percentBasedMirror { +func NewPercentBasedMirror(percentage float32, primitive Primitive, target Primitive) Primitive { return &percentBasedMirror{percentage, primitive, target} } @@ -84,19 +84,18 @@ func (m *percentBasedMirror) TryExecute(ctx context.Context, vcursor VCursor, bi go func(target Primitive, vcursor VCursor) { defer close(mirrorCh) - _, _ = target.TryExecute(mirrorCtx, vcursor, bindVars, wantfields) + _, _ = vcursor.ExecutePrimitive(mirrorCtx, target, bindVars, wantfields) }(m.target, vcursor.CloneForMirroring(mirrorCtx)) } - r, err := m.primitive.TryExecute(ctx, vcursor, bindVars, wantfields) + r, err := vcursor.ExecutePrimitive(ctx, m.primitive, bindVars, wantfields) if doMirror { select { case <-mirrorCh: // Mirroring completed within the allowed time. case <-mirrorCtx.Done(): - // Mirroring took too long, cancel the mirror context. - mirrorCtxCancel() + // Mirroring took too long and was canceled. } } @@ -118,19 +117,20 @@ func (m *percentBasedMirror) TryStreamExecute(ctx context.Context, vcursor VCurs go func(target Primitive, vcursor VCursor) { defer close(mirrorCh) - _ = target.TryStreamExecute(mirrorCtx, vcursor, bindVars, wantfields, func(_ *sqltypes.Result) error { + _ = vcursor.StreamExecutePrimitive(mirrorCtx, target, bindVars, wantfields, func(_ *sqltypes.Result) error { return nil }) }(m.target, vcursor.CloneForMirroring(mirrorCtx)) } - err := m.primitive.TryStreamExecute(ctx, vcursor, bindVars, wantfields, callback) + err := vcursor.StreamExecutePrimitive(ctx, m.primitive, bindVars, wantfields, callback) if doMirror { select { case <-mirrorCh: - case <-ctx.Done(): - mirrorCtxCancel() + // Mirroring completed within the allowed time. + case <-mirrorCtx.Done(): + // Mirroring took too long and was canceled. } } diff --git a/go/vt/vtgate/planbuilder/operators/query_planning.go b/go/vt/vtgate/planbuilder/operators/query_planning.go index 4b8ff87a7ae..5a8f8037028 100644 --- a/go/vt/vtgate/planbuilder/operators/query_planning.go +++ b/go/vt/vtgate/planbuilder/operators/query_planning.go @@ -108,7 +108,7 @@ func runRewriters(ctx *plancontext.PlanningContext, root Operator) Operator { } if pbm, ok := root.(*PercentBasedMirror); ok { - root = pbm.Clone([]Operator{ + pbm.SetInputs([]Operator{ runRewriters(ctx, pbm.Operator), runRewriters(ctx.UseMirror(), pbm.Target), }) diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context.go b/go/vt/vtgate/planbuilder/plancontext/planning_context.go index 62e7e7433cc..4a0b8b61703 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context.go @@ -385,7 +385,7 @@ func (ctx *PlanningContext) ContainsAggr(e sqlparser.SQLNode) (hasAggr bool) { func (ctx *PlanningContext) UseMirror() *PlanningContext { if ctx.isMirrored { - panic("bug: cannot mirror already mirrored planning context") + panic(vterrors.VT13001("bug: cannot mirror already mirrored planning context")) } if ctx.mirror != nil { return ctx.mirror diff --git a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json index e58d2b13cb3..5265905364d 100644 --- a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json @@ -42,10 +42,10 @@ }, { "comment": "select unsharded, qualified, table mirrored to sharded table", - "query": "select t1.id from unsharded_src1.t1 where t1.id = 1", + "query": "select t2.id from unsharded_src1.t2 where t2.id = 1", "plan": { "QueryType": "SELECT", - "Original": "select t1.id from unsharded_src1.t1 where t1.id = 1", + "Original": "select t2.id from unsharded_src1.t2 where t2.id = 1", "Instructions": { "OperatorType": "Mirror", "Variant": "PercentBased", @@ -58,26 +58,30 @@ "Name": "unsharded_src1", "Sharded": false }, - "FieldQuery": "select t1.id from t1 where 1 != 1", - "Query": "select t1.id from t1 where t1.id = 1", - "Table": "t1" + "FieldQuery": "select t2.id from t2 where 1 != 1", + "Query": "select t2.id from t2 where t2.id = 1", + "Table": "t2" }, { "OperatorType": "Route", - "Variant": "Unsharded", + "Variant": "EqualUnique", "Keyspace": { - "Name": "unsharded_dst1", - "Sharded": false + "Name": "sharded_dst1", + "Sharded": true }, - "FieldQuery": "select t1.id from t1 where 1 != 1", - "Query": "select t1.id from t1 where t1.id = 1", - "Table": "t1" + "FieldQuery": "select t2.id from t1 as t2 where 1 != 1", + "Query": "select t2.id from t1 as t2 where t2.id = 1", + "Table": "t1", + "Values": [ + "1" + ], + "Vindex": "xxhash" } ] }, "TablesUsed": [ - "unsharded_dst1.t1", - "unsharded_src1.t1" + "sharded_dst1.t1", + "unsharded_src1.t2" ] } }, @@ -285,23 +289,23 @@ }, { "comment": "self-mirror is not allowed", - "query": "select t1.id from unsharded_src1.t3", + "query": "select t1.id from unsharded_src2.t1", "plan": { "QueryType": "SELECT", - "Original": "select t1.id from unsharded_src1.t3", + "Original": "select t1.id from unsharded_src2.t1", "Instructions": { "OperatorType": "Route", "Variant": "Unsharded", "Keyspace": { - "Name": "unsharded_src1", + "Name": "unsharded_src2", "Sharded": false }, - "FieldQuery": "select t1.id from t3 where 1 != 1", - "Query": "select t1.id from t3", - "Table": "t3" + "FieldQuery": "select t1.id from t1 where 1 != 1", + "Query": "select t1.id from t1", + "Table": "t1" }, "TablesUsed": [ - "unsharded_src1.t3" + "unsharded_src2.t1" ] } }, diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index 846222a3112..edaadd912d8 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -184,7 +184,7 @@ const ( ) // ErrNotSingleTable refers to an error happening when something should be used only for single tables -var ErrNotSingleTable = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] should only be used for single tables") +var ErrNotSingleTable = vterrors.VT13001("should only be used for single tables") // CopyDependencies copies the dependencies from one expression into the other func (st *SemTable) CopyDependencies(from, to sqlparser.Expr) { diff --git a/go/vt/vtgate/semantics/semantic_state_test.go b/go/vt/vtgate/semantics/semantic_state_test.go index 84f8cec6cf9..1f324215326 100644 --- a/go/vt/vtgate/semantics/semantic_state_test.go +++ b/go/vt/vtgate/semantics/semantic_state_test.go @@ -464,7 +464,7 @@ func TestRemoveParentForeignKey(t *testing.T) { }, }, }, - expectedErr: "[BUG] should only be used for single tables", + expectedErr: "VT13001: [BUG] should only be used for single tables", }, } for _, tt := range tests { @@ -716,7 +716,7 @@ func TestRemoveNonRequiredForeignKeys(t *testing.T) { SingleTableSet(0).Merge(SingleTableSet(1)): {}, }, }, - expectedErr: "[BUG] should only be used for single tables", + expectedErr: "VT13001: [BUG] should only be used for single tables", }, { name: "Error - Reading table info for child foreign keys", @@ -734,7 +734,7 @@ func TestRemoveNonRequiredForeignKeys(t *testing.T) { }, parentForeignKeysInvolved: map[TableSet][]vindexes.ParentFKInfo{}, }, - expectedErr: "[BUG] should only be used for single tables", + expectedErr: "VT13001: [BUG] should only be used for single tables", }, } for _, tt := range tests { diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 54cd74a9782..c5e7939f0ff 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -1099,6 +1099,9 @@ func (vc *vcursorImpl) FindMirrorRule(name sqlparser.TableName) (*vindexes.Mirro if err != nil { return nil, "", destTabletType, nil, err } + if mirrorRule != nil { + destKeyspace = mirrorRule.Table.Keyspace.Name + } return mirrorRule, destKeyspace, destTabletType, dest, err } From bb0cbc118ed7db0c6b305183a6c3889e1678b810 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Thu, 8 Aug 2024 09:34:17 -0400 Subject: [PATCH 22/27] cr: panic(vterrors), mirror cases percentages, zero-percentage mirror case Signed-off-by: Max Englander --- go/vt/vtgate/planbuilder/operators/mirror.go | 7 ++-- .../planbuilder/testdata/mirror_cases.json | 32 ++++++++++++++++--- .../testdata/vschemas/mirror_schema.json | 22 +++++++------ 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/mirror.go b/go/vt/vtgate/planbuilder/operators/mirror.go index e0794d1246c..5249b4ac8a9 100644 --- a/go/vt/vtgate/planbuilder/operators/mirror.go +++ b/go/vt/vtgate/planbuilder/operators/mirror.go @@ -20,6 +20,7 @@ import ( "fmt" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext" ) @@ -69,11 +70,11 @@ func (m *PercentBasedMirror) SetInputs(inputs []Operator) { // where data is fetched from the LHS of the join to be used in the evaluation on the RHS // TODO: we should remove this and replace it with rewriters func (m *PercentBasedMirror) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator { - panic("not supported") + panic(vterrors.VT13001("not supported")) } func (m *PercentBasedMirror) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, expr *sqlparser.AliasedExpr) int { - panic("not supported") + panic(vterrors.VT13001("not supported")) } func (m *PercentBasedMirror) FindCol(ctx *plancontext.PlanningContext, expr sqlparser.Expr, underRoute bool) int { @@ -98,5 +99,5 @@ func (m *PercentBasedMirror) GetOrdering(ctx *plancontext.PlanningContext) []Ord // AddWSColumn implements Operator. func (m *PercentBasedMirror) AddWSColumn(ctx *plancontext.PlanningContext, offset int, underRoute bool) int { - panic("not supported") + panic(vterrors.VT13001("not supported")) } diff --git a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json index 5265905364d..2466b3dca12 100644 --- a/go/vt/vtgate/planbuilder/testdata/mirror_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/mirror_cases.json @@ -8,7 +8,7 @@ "Instructions": { "OperatorType": "Mirror", "Variant": "PercentBased", - "Percent": 50, + "Percent": 1, "Inputs": [ { "OperatorType": "Route", @@ -40,6 +40,28 @@ ] } }, + { + "comment": "select unsharded, qualified, table mirrored to unsharded table with zero percentage", + "query": "select t3.id from unsharded_src1.t3 where t3.id = 1", + "plan": { + "QueryType": "SELECT", + "Original": "select t3.id from unsharded_src1.t3 where t3.id = 1", + "Instructions": { + "OperatorType": "Route", + "Variant": "Unsharded", + "Keyspace": { + "Name": "unsharded_src1", + "Sharded": false + }, + "FieldQuery": "select t3.id from t3 where 1 != 1", + "Query": "select t3.id from t3 where t3.id = 1", + "Table": "t3" + }, + "TablesUsed": [ + "unsharded_src1.t3" + ] + } + }, { "comment": "select unsharded, qualified, table mirrored to sharded table", "query": "select t2.id from unsharded_src1.t2 where t2.id = 1", @@ -49,7 +71,7 @@ "Instructions": { "OperatorType": "Mirror", "Variant": "PercentBased", - "Percent": 50, + "Percent": 2, "Inputs": [ { "OperatorType": "Route", @@ -94,7 +116,7 @@ "Instructions": { "OperatorType": "Mirror", "Variant": "PercentBased", - "Percent": 50, + "Percent": 1, "Inputs": [ { "OperatorType": "Route", @@ -163,7 +185,7 @@ "Instructions": { "OperatorType": "Mirror", "Variant": "PercentBased", - "Percent": 50, + "Percent": 1, "Inputs": [ { "OperatorType": "Route", @@ -318,7 +340,7 @@ "Instructions": { "OperatorType": "Mirror", "Variant": "PercentBased", - "Percent": 50, + "Percent": 4, "Inputs": [ { "OperatorType": "Route", diff --git a/go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json b/go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json index faa54a15f08..4feaa09c126 100644 --- a/go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json +++ b/go/vt/vtgate/planbuilder/testdata/vschemas/mirror_schema.json @@ -4,44 +4,48 @@ { "from_table": "unsharded_src1.t1", "to_table": "unsharded_dst1.t1", - "percent": 50 + "percent": 1 }, { "from_table": "unsharded_src1.t2", "to_table": "sharded_dst1.t1", - "percent": 50 + "percent": 2 }, { "from_table": "unsharded_src2.t1", "to_table": "unsharded_src2.t1", - "percent": 50 + "percent": 3 }, { "from_table": "unsharded_src2.t2", "to_table": "unsharded_dst2.t2", - "percent": 50 + "percent": 4 }, { "from_table": "unsharded_dst2.t2", "to_table": "unsharded_dst3.t2", - "percent": 50 + "percent": 5 }, { "from_table": "unsharded_src3.t1", "to_table": "unsharded_dst4.t1", - "percent": 50 + "percent": 6 }, { "from_table": "unsharded_dst4.t2", "to_table": "unsharded_src3.t2", - "percent": 50 + "percent": 7 }, { "from_table": "sharded_src1.t1", "to_table": "sharded_dst1.t1", - "percent": 50 + "percent": 8 + }, + { + "from_table": "unsharded_src1.t3", + "to_table": "unsharded_dst1.t2", + "percent": 0 } - ] }, "keyspaces": { From 7d1cdaf7b2a3ff4a5a087503d6f148d517c7ac01 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Fri, 9 Aug 2024 01:55:06 -0400 Subject: [PATCH 23/27] cr: rm mirror_vschema.go Signed-off-by: Max Englander --- go/test/vschemawrapper/vschema_wrapper.go | 12 +- go/vt/schemadiff/semantics.go | 4 +- .../vtgate/planbuilder/operators/ast_to_op.go | 14 + .../planbuilder/plancontext/mirror_vschema.go | 265 ------------------ .../plancontext/planning_context.go | 29 +- .../plancontext/planning_context_test.go | 6 +- .../vtgate/planbuilder/plancontext/vschema.go | 2 +- go/vt/vtgate/semantics/FakeSI.go | 4 +- go/vt/vtgate/semantics/info_schema.go | 2 +- go/vt/vtgate/semantics/semantic_state.go | 2 +- go/vt/vtgate/semantics/table_collector.go | 8 +- go/vt/vtgate/vcursor_impl.go | 13 +- go/vt/vtgate/vindexes/vschema.go | 4 +- 13 files changed, 61 insertions(+), 304 deletions(-) delete mode 100644 go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go diff --git a/go/test/vschemawrapper/vschema_wrapper.go b/go/test/vschemawrapper/vschema_wrapper.go index e7214783595..a1b87f5569c 100644 --- a/go/test/vschemawrapper/vschema_wrapper.go +++ b/go/test/vschemawrapper/vschema_wrapper.go @@ -213,7 +213,6 @@ func (vw *VSchemaWrapper) TargetDestination(qualifier string) (key.Destination, return nil, nil, 0, vterrors.VT05003(keyspaceName) } return vw.Dest, keyspace.Keyspace, vw.TabletType_, nil - } func (vw *VSchemaWrapper) TabletType() topodatapb.TabletType { @@ -317,7 +316,6 @@ func (vw *VSchemaWrapper) TargetString() string { } func (vw *VSchemaWrapper) WarnUnshardedOnly(_ string, _ ...any) { - } func (vw *VSchemaWrapper) ErrorIfShardedF(keyspace *vindexes.Keyspace, _, errFmt string, params ...any) error { @@ -345,14 +343,14 @@ func (vw *VSchemaWrapper) IsViewsEnabled() bool { // FindMirrorRule finds the mirror rule for the requested keyspace, table // name, and the tablet type in the VSchema. -func (vs *VSchemaWrapper) FindMirrorRule(tab sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { - destKeyspace, destTabletType, dest, err := topoproto.ParseDestination(tab.Qualifier.String(), topodatapb.TabletType_PRIMARY) +func (vs *VSchemaWrapper) FindMirrorRule(tab sqlparser.TableName) (*vindexes.MirrorRule, error) { + destKeyspace, destTabletType, _, err := topoproto.ParseDestination(tab.Qualifier.String(), topodatapb.TabletType_PRIMARY) if err != nil { - return nil, "", destTabletType, nil, err + return nil, err } mirrorRule, err := vs.V.FindMirrorRule(destKeyspace, tab.Name.String(), destTabletType) if err != nil { - return nil, "", destTabletType, nil, err + return nil, err } - return mirrorRule, destKeyspace, destTabletType, dest, err + return mirrorRule, err } diff --git a/go/vt/schemadiff/semantics.go b/go/vt/schemadiff/semantics.go index 3e0aca45a88..f12f59ef6ae 100644 --- a/go/vt/schemadiff/semantics.go +++ b/go/vt/schemadiff/semantics.go @@ -80,8 +80,8 @@ func (si *declarativeSchemaInformation) GetForeignKeyChecksState() *bool { } // FindMirrorRule implements semantics.SchemaInformation. -func (si *declarativeSchemaInformation) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { - return nil, "", topodatapb.TabletType_UNKNOWN, nil, nil +func (si *declarativeSchemaInformation) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, error) { + return nil, nil } // addTable adds a fake table with an empty column list diff --git a/go/vt/vtgate/planbuilder/operators/ast_to_op.go b/go/vt/vtgate/planbuilder/operators/ast_to_op.go index 5cf76ee4989..fa515a7b9f2 100644 --- a/go/vt/vtgate/planbuilder/operators/ast_to_op.go +++ b/go/vt/vtgate/planbuilder/operators/ast_to_op.go @@ -276,6 +276,20 @@ func getOperatorFromAliasedTableExpr(ctx *plancontext.PlanningContext, tableExpr } qg := newQueryGraph() isInfSchema := tableInfo.IsInfSchema() + if ctx.IsMirrored() { + if mr := tableInfo.GetMirrorRule(); mr != nil { + newTbl := sqlparser.Clone(tbl) + newTbl.Qualifier = sqlparser.NewIdentifierCS(mr.Table.Keyspace.Name) + newTbl.Name = mr.Table.Name + if newTbl.Name.String() != tbl.Name.String() { + tableExpr = sqlparser.Clone(tableExpr) + tableExpr.As = tbl.Name + } + tbl = newTbl + } else { + panic(vterrors.VT13001(fmt.Sprintf("unable to find mirror rule for table: %T", tbl))) + } + } qt := &QueryTable{Alias: tableExpr, Table: tbl, ID: tableID, IsInfSchema: isInfSchema} qg.Tables = append(qg.Tables, qt) return qg diff --git a/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go b/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go deleted file mode 100644 index 03545fd36ff..00000000000 --- a/go/vt/vtgate/planbuilder/plancontext/mirror_vschema.go +++ /dev/null @@ -1,265 +0,0 @@ -/* -Copyright 2024 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package plancontext - -import ( - "context" - - "vitess.io/vitess/go/mysql/collations" - "vitess.io/vitess/go/vt/key" - querypb "vitess.io/vitess/go/vt/proto/query" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vschemapb "vitess.io/vitess/go/vt/proto/vschema" - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" - "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtenv" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/semantics" - "vitess.io/vitess/go/vt/vtgate/vindexes" -) - -// mirrorVSchema is a wrapper which returns mirrored versions of values -// return by the wrapped vschema. -// -// For example, if the wrapped VSchema defines any mirror rules from ks1 to -// ks2, calls to FindTable for which the wrapped VSchema returns tables in -// ks1 will return tables in ks2. -// -// The returned VSchema cannot be reflected back again by passing it to -// ForMirroring. This restriction allows the returned VSchema to be used in -// recursive planning calls without creating an infinite loop. -type mirrorVSchema struct { - vschema VSchema -} - -// FindTable finds and returns the table with the requested name. -// -// mirrorVSchema returns a mirrored version of the value returned by the underlying VSchema. -// If the underlying VSchema returns a table t1 in ks1, and there is exists a -// routing rule from ks1 to ks2, and ks2 has a table t1, then mirrorVSchema -// returns ks2.t1. -// -// If no table with the requested name can be found, or not mirror rule is -// defined on the keyspace of the found table, or no table is found in the -// target keyspace defined by the mirror rule, then nil is returned. -func (m *mirrorVSchema) FindTable(tablename sqlparser.TableName) (*vindexes.Table, string, topodatapb.TabletType, key.Destination, error) { - mirrorRule, destKeyspace, destTabletType, dest, err := m.vschema.FindMirrorRule(tablename) - if err != nil { - return nil, "", destTabletType, nil, err - } - return mirrorRule.Table, destKeyspace, destTabletType, dest, err -} - -func (m *mirrorVSchema) FindView(name sqlparser.TableName) sqlparser.SelectStatement { - // TODO(maxeng): we don't have all the information we need here to mirror - // views. May need to expose a new method on VSchema interface, such as - // ParseDestinationTarget - return nil -} - -// FindTableOrVindex returns a routed table or vindex. -// -// mirrorVSchema returns a mirrored version of the value returned by the -// underlying VSchema. If the underlying VSchema returns a table t1 in ks1, -// and there is exists a mirror rule from ks1.t1 to ks2.t1, then mirrorVSchema -// returns ks2.t1. Vindexes are not mirrored. -func (m *mirrorVSchema) FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) { - fromTable, vindex, destKeyspace, destTabletType, dest, err := m.vschema.FindTableOrVindex(tablename) - if err != nil { - return nil, vindex, "", destTabletType, nil, err - } - mirrorRule, err := m.GetVSchema().FindMirrorRule(fromTable.Keyspace.Name, fromTable.Name.String(), destTabletType) - if err != nil { - return nil, vindex, "", destTabletType, nil, err - } - // If mirror rule not found, just use the table we initially found. - if mirrorRule == nil { - return fromTable, vindex, destKeyspace, destTabletType, dest, nil - } - return mirrorRule.Table, vindex, destKeyspace, destTabletType, dest, err -} - -func (m *mirrorVSchema) DefaultKeyspace() (*vindexes.Keyspace, error) { - return m.vschema.DefaultKeyspace() -} - -func (m *mirrorVSchema) TargetString() string { - return m.vschema.TargetString() -} - -func (m *mirrorVSchema) Destination() key.Destination { - return m.vschema.Destination() -} - -func (m *mirrorVSchema) TabletType() topodatapb.TabletType { - return m.vschema.TabletType() -} - -func (m *mirrorVSchema) TargetDestination(qualifier string) (key.Destination, *vindexes.Keyspace, topodatapb.TabletType, error) { - return m.vschema.TargetDestination(qualifier) -} - -func (m *mirrorVSchema) AnyKeyspace() (*vindexes.Keyspace, error) { - return m.vschema.AnyKeyspace() -} - -func (m *mirrorVSchema) FirstSortedKeyspace() (*vindexes.Keyspace, error) { - return m.vschema.FirstSortedKeyspace() -} - -func (m *mirrorVSchema) SysVarSetEnabled() bool { - return m.vschema.SysVarSetEnabled() -} - -func (m *mirrorVSchema) KeyspaceExists(keyspace string) bool { - return m.vschema.KeyspaceExists(keyspace) -} - -func (m *mirrorVSchema) AllKeyspace() ([]*vindexes.Keyspace, error) { - return m.vschema.AllKeyspace() -} - -func (m *mirrorVSchema) FindKeyspace(keyspace string) (*vindexes.Keyspace, error) { - return m.vschema.FindKeyspace(keyspace) -} - -func (m *mirrorVSchema) GetSemTable() *semantics.SemTable { - return m.vschema.GetSemTable() -} - -func (m *mirrorVSchema) Planner() PlannerVersion { - return m.vschema.Planner() -} - -func (m *mirrorVSchema) SetPlannerVersion(pv PlannerVersion) { - m.vschema.SetPlannerVersion(pv) -} - -func (m *mirrorVSchema) ConnCollation() collations.ID { - return m.vschema.ConnCollation() -} - -func (m *mirrorVSchema) Environment() *vtenv.Environment { - return m.vschema.Environment() -} - -// ErrorIfShardedF will return an error if the keyspace is sharded, -// and produce a warning if the vtgate if configured to do so -func (m *mirrorVSchema) ErrorIfShardedF(keyspace *vindexes.Keyspace, warn string, errFmt string, params ...any) error { - return m.vschema.ErrorIfShardedF(keyspace, warn, errFmt, params...) -} - -// WarnUnshardedOnly is used when a feature is only supported in unsharded mode. -// This will let the user know that they are using something -// that could become a problem if they move to a sharded keyspace -func (m *mirrorVSchema) WarnUnshardedOnly(format string, params ...any) { - m.vschema.WarnUnshardedOnly(format, params...) -} - -// PlannerWarning records warning created during planning. -func (m *mirrorVSchema) PlannerWarning(message string) { - m.vschema.PlannerWarning(message) -} - -// ForeignKeyMode returns the foreign_key flag value -func (m *mirrorVSchema) ForeignKeyMode(keyspace string) (vschemapb.Keyspace_ForeignKeyMode, error) { - return m.vschema.ForeignKeyMode(keyspace) -} - -// KeyspaceError returns any error in the keyspace vschema. -func (m *mirrorVSchema) KeyspaceError(keyspace string) error { - return m.vschema.KeyspaceError(keyspace) -} - -func (m *mirrorVSchema) GetForeignKeyChecksState() *bool { - return m.vschema.GetForeignKeyChecksState() -} - -// GetVSchema returns the latest cached vindexes.VSchema -func (m *mirrorVSchema) GetVSchema() *vindexes.VSchema { - return m.vschema.GetVSchema() -} - -func (m *mirrorVSchema) GetSrvVschema() *vschemapb.SrvVSchema { - return m.vschema.GetSrvVschema() -} - -// FindRoutedShard looks up shard routing rules for a shard -func (m *mirrorVSchema) FindRoutedShard(keyspace string, shard string) (string, error) { - return m.vschema.FindRoutedShard(keyspace, shard) -} - -// IsShardRoutingEnabled returns true if partial shard routing is enabled -func (m *mirrorVSchema) IsShardRoutingEnabled() bool { - return m.vschema.IsShardRoutingEnabled() -} - -// IsViewsEnabled returns true if Vitess manages the views. -func (m *mirrorVSchema) IsViewsEnabled() bool { - return m.vschema.IsViewsEnabled() -} - -// GetUDV returns user defined value from the variable passed. -func (m *mirrorVSchema) GetUDV(name string) *querypb.BindVariable { - return m.vschema.GetUDV(name) -} - -// PlanPrepareStatement plans the prepared statement. -func (m *mirrorVSchema) PlanPrepareStatement(ctx context.Context, query string) (*engine.Plan, sqlparser.Statement, error) { - return m.vschema.PlanPrepareStatement(ctx, query) -} - -// ClearPrepareData clears the prepared data from the session. -func (m *mirrorVSchema) ClearPrepareData(stmtName string) { - m.vschema.ClearPrepareData(stmtName) -} - -// GetPrepareData returns the prepared data for the statement from the session. -func (m *mirrorVSchema) GetPrepareData(stmtName string) *vtgatepb.PrepareData { - return m.vschema.GetPrepareData(stmtName) -} - -// StorePrepareData stores the prepared data in the session. -func (m *mirrorVSchema) StorePrepareData(name string, v *vtgatepb.PrepareData) { - m.vschema.StorePrepareData(name, v) -} - -// GetAggregateUDFs returns the list of aggregate UDFs. -func (m *mirrorVSchema) GetAggregateUDFs() []string { - return m.vschema.GetAggregateUDFs() -} - -// FindMirrorRule finds the mirror rule for the requested table name and -// VSchema tablet type. -func (m *mirrorVSchema) FindMirrorRule(name sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { - return nil, "", topodatapb.TabletType_UNKNOWN, nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "[BUG] refusing to perform chained traffic mirroring") -} - -// MirrorVSchema returns a wrapper which returns mirrored versions of values -// return by the wrapped vschema. -// -// For example, if the underlying VSchema defines any mirror rules from ks1 to -// ks2, calls to FindTable for which the wrapped VSchema returns tables in -// ks1 will return tables in ks2. -// -// The returned VSchema cannot be reflected back again by passing it to -// MirrorVSchema. This restriction prevents infinite mirroring loops. -func MirrorVSchema(vschema VSchema) VSchema { - return &mirrorVSchema{vschema} -} diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context.go b/go/vt/vtgate/planbuilder/plancontext/planning_context.go index 4a0b8b61703..1b6e22b48ec 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context.go @@ -383,23 +383,32 @@ func (ctx *PlanningContext) ContainsAggr(e sqlparser.SQLNode) (hasAggr bool) { return } +func (ctx *PlanningContext) IsMirrored() bool { + return ctx.isMirrored +} + func (ctx *PlanningContext) UseMirror() *PlanningContext { if ctx.isMirrored { - panic(vterrors.VT13001("bug: cannot mirror already mirrored planning context")) + panic(vterrors.VT13001("cannot mirror already mirrored planning context")) } if ctx.mirror != nil { return ctx.mirror } ctx.mirror = &PlanningContext{ - ReservedVars: ctx.ReservedVars, - SemTable: ctx.SemTable, - VSchema: MirrorVSchema(ctx.VSchema), - joinPredicates: map[sqlparser.Expr][]sqlparser.Expr{}, - skipPredicates: map[sqlparser.Expr]any{}, - PlannerVersion: ctx.PlannerVersion, - ReservedArguments: map[sqlparser.Expr]string{}, - Statement: ctx.Statement, - isMirrored: true, + ctx.ReservedVars, + ctx.SemTable, + ctx.VSchema, + map[sqlparser.Expr][]sqlparser.Expr{}, + map[sqlparser.Expr]any{}, + ctx.PlannerVersion, + map[sqlparser.Expr]string{}, + ctx.VerifyAllFKs, + ctx.MergedSubqueries, + ctx.CurrentPhase, + ctx.Statement, + ctx.OuterTables, + nil, + true, } return ctx.mirror } diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go index ff100273edc..d7315f376b6 100644 --- a/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go +++ b/go/vt/vtgate/planbuilder/plancontext/planning_context_test.go @@ -365,9 +365,9 @@ func (v *vschema) GetAggregateUDFs() []string { panic("implement me") } -func (v *vschema) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { - // TODO implement me - panic("implement me") +// FindMirrorRule implements VSchema. +func (v *vschema) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, error) { + panic("unimplemented") } var _ VSchema = (*vschema)(nil) diff --git a/go/vt/vtgate/planbuilder/plancontext/vschema.go b/go/vt/vtgate/planbuilder/plancontext/vschema.go index 64712fd2b66..6e92ad0d83b 100644 --- a/go/vt/vtgate/planbuilder/plancontext/vschema.go +++ b/go/vt/vtgate/planbuilder/plancontext/vschema.go @@ -99,7 +99,7 @@ type VSchema interface { // FindMirrorRule finds the mirror rule for the requested keyspace, table // name, and the tablet type in the VSchema. - FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) + FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, error) } // PlannerNameToVersion returns the numerical representation of the planner diff --git a/go/vt/vtgate/semantics/FakeSI.go b/go/vt/vtgate/semantics/FakeSI.go index 83f2270d777..cb1b9cec094 100644 --- a/go/vt/vtgate/semantics/FakeSI.go +++ b/go/vt/vtgate/semantics/FakeSI.go @@ -87,6 +87,6 @@ func (s *FakeSI) GetAggregateUDFs() []string { } // FindMirrorRule implements SchemaInformation. -func (s *FakeSI) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { - return nil, "", topodatapb.TabletType_UNKNOWN, nil, nil +func (s *FakeSI) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, error) { + return nil, nil } diff --git a/go/vt/vtgate/semantics/info_schema.go b/go/vt/vtgate/semantics/info_schema.go index 917f3b2791f..127f4a00960 100644 --- a/go/vt/vtgate/semantics/info_schema.go +++ b/go/vt/vtgate/semantics/info_schema.go @@ -1671,6 +1671,6 @@ func (i *infoSchemaWithColumns) GetAggregateUDFs() []string { } // FindMirrorRule implements SchemaInformation. -func (i *infoSchemaWithColumns) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { +func (i *infoSchemaWithColumns) FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, error) { return i.inner.FindMirrorRule(tablename) } diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index edaadd912d8..c12d3d5f4c4 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -171,7 +171,7 @@ type ( GetForeignKeyChecksState() *bool KeyspaceError(keyspace string) error GetAggregateUDFs() []string - FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) + FindMirrorRule(tablename sqlparser.TableName) (*vindexes.MirrorRule, error) } shortCut = int diff --git a/go/vt/vtgate/semantics/table_collector.go b/go/vt/vtgate/semantics/table_collector.go index 8140bafdeaa..5404080436a 100644 --- a/go/vt/vtgate/semantics/table_collector.go +++ b/go/vt/vtgate/semantics/table_collector.go @@ -451,7 +451,13 @@ func createTable( return nil, err } - mr, _, _, _, _ := si.FindMirrorRule(t) + mr, err := si.FindMirrorRule(t) + if err != nil { + // Mirroring is best effort. If we get an error while mirroring, keep going + // as if mirroring was disabled. We don't want to interrupt production work + // because of an issue with mirroring. + mr = nil + } table := &RealTable{ tableName: alias.As.String(), diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index c5e7939f0ff..2adff587471 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -1087,22 +1087,19 @@ func (vc *vcursorImpl) GetAggregateUDFs() []string { // FindMirrorRule finds the mirror rule for the requested table name and // VSchema tablet type. -func (vc *vcursorImpl) FindMirrorRule(name sqlparser.TableName) (*vindexes.MirrorRule, string, topodatapb.TabletType, key.Destination, error) { - destKeyspace, destTabletType, dest, err := vc.executor.ParseDestinationTarget(name.Qualifier.String()) +func (vc *vcursorImpl) FindMirrorRule(name sqlparser.TableName) (*vindexes.MirrorRule, error) { + destKeyspace, destTabletType, _, err := vc.executor.ParseDestinationTarget(name.Qualifier.String()) if err != nil { - return nil, "", destTabletType, nil, err + return nil, err } if destKeyspace == "" { destKeyspace = vc.keyspace } mirrorRule, err := vc.vschema.FindMirrorRule(destKeyspace, name.Name.String(), destTabletType) if err != nil { - return nil, "", destTabletType, nil, err - } - if mirrorRule != nil { - destKeyspace = mirrorRule.Table.Keyspace.Name + return nil, err } - return mirrorRule, destKeyspace, destTabletType, dest, err + return mirrorRule, err } // ParseDestinationTarget parses destination target string and sets default keyspace if possible. diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index e11307e0edf..c251da08167 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -938,7 +938,6 @@ func extractTableParts(tableName string, allowUnqualified bool) (string, string, } // Using fmt.Errorf instead of vterrors here because this error is always wrapped in vterrors. return "", "", fmt.Errorf(errMsgFormat, tableName) - } func parseTable(tableName string) (sqlparser.TableName, error) { @@ -996,7 +995,6 @@ outer: } toKeyspace, toTableName, err := parser.ParseTable(toTable) - if err != nil { vschema.RoutingRules[rule.FromTable] = &RoutingRule{ Error: err, @@ -1559,7 +1557,7 @@ func (vschema *VSchema) GetAggregateUDFs() (udfs []string) { return } -// FindMirroredTable finds a mirror rule from the keyspace, table name and +// FindMirrorRule finds a mirror rule from the keyspace, table name and // tablet type. func (vschema *VSchema) FindMirrorRule(keyspace, tablename string, tabletType topodatapb.TabletType) (*MirrorRule, error) { qualified := tablename From 5b03958e61795ffe5b7d2b1180493979f236807a Mon Sep 17 00:00:00 2001 From: Max Englander Date: Fri, 9 Aug 2024 02:08:49 -0400 Subject: [PATCH 24/27] cr: check inputs len Signed-off-by: Max Englander --- go/vt/vtgate/planbuilder/operators/mirror.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/vtgate/planbuilder/operators/mirror.go b/go/vt/vtgate/planbuilder/operators/mirror.go index 5249b4ac8a9..b5007a31898 100644 --- a/go/vt/vtgate/planbuilder/operators/mirror.go +++ b/go/vt/vtgate/planbuilder/operators/mirror.go @@ -61,6 +61,9 @@ func (m *PercentBasedMirror) Inputs() []Operator { // SetInputs changes the inputs for this op func (m *PercentBasedMirror) SetInputs(inputs []Operator) { + if len(inputs) < 2 { + panic(vterrors.VT13001("unexpected number of inputs for PercentBasedMirror operator")) + } m.Operator = inputs[0] m.Target = inputs[1] } From ec1994a3c6c57593199fc2b7bc1c9ccf462ac81d Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 13 Aug 2024 14:26:58 -0400 Subject: [PATCH 25/27] cr: command semantics pkg mirrorInfo() Signed-off-by: Max Englander --- go/vt/vtgate/semantics/semantic_state.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index c12d3d5f4c4..2426001816d 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -1016,6 +1016,12 @@ func (st *SemTable) GetMirrorInfo() MirrorInfo { return mirrorInfo(st.Tables) } +// mirrorInfo looks through all tables with mirror rules defined, and returns a +// MirrorInfo containing the lowest mirror percentage found across all rules. +// +// The idea here is that if you have two tables with mirror rules both involved +// in a query, and one of those rules is 1% while the other is 100%, to mirror +// the query with 1% chance. func mirrorInfo(tableInfos []TableInfo) MirrorInfo { mi := MirrorInfo{} for _, t := range tableInfos { From 9239ab7f80005c4393f19475de87218be3dbd646 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 13 Aug 2024 14:28:36 -0400 Subject: [PATCH 26/27] Apply suggestions from code review Co-authored-by: Harshit Gangal Signed-off-by: Max Englander --- go/vt/vtgate/engine/mirror.go | 79 ++++++++------------ go/vt/vtgate/planbuilder/operators/mirror.go | 4 +- 2 files changed, 34 insertions(+), 49 deletions(-) diff --git a/go/vt/vtgate/engine/mirror.go b/go/vt/vtgate/engine/mirror.go index b85a3883f4b..fcc9d4ffe4e 100644 --- a/go/vt/vtgate/engine/mirror.go +++ b/go/vt/vtgate/engine/mirror.go @@ -70,68 +70,55 @@ func (m *percentBasedMirror) NeedsTransaction() bool { } func (m *percentBasedMirror) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool) (*sqltypes.Result, error) { - var mirrorCh chan any - var mirrorCtx context.Context - var mirrorCtxCancel func() - - doMirror := m.percentAtLeastDieRoll() + if !m.percentAtLeastDieRoll() { + return vcursor.ExecutePrimitive(ctx, m.primitive, bindVars, wantfields) + } - if doMirror { - mirrorCh = make(chan any) + mirrorCh := make(chan any) + mirrorCtx, mirrorCtxCancel := context.WithTimeout(ctx, maxMirrorTargetLag) + defer mirrorCtxCancel() - mirrorCtx, mirrorCtxCancel = context.WithTimeout(ctx, maxMirrorTargetLag) - defer mirrorCtxCancel() - - go func(target Primitive, vcursor VCursor) { - defer close(mirrorCh) - _, _ = vcursor.ExecutePrimitive(mirrorCtx, target, bindVars, wantfields) - }(m.target, vcursor.CloneForMirroring(mirrorCtx)) - } + go func() { + defer close(mirrorCh) + vcursor.ExecutePrimitive(mirrorCtx, m.target, bindVars, wantfields) + }() r, err := vcursor.ExecutePrimitive(ctx, m.primitive, bindVars, wantfields) - if doMirror { - select { - case <-mirrorCh: - // Mirroring completed within the allowed time. - case <-mirrorCtx.Done(): - // Mirroring took too long and was canceled. - } + select { + case <-mirrorCh: + // Mirroring completed within the allowed time. + case <-mirrorCtx.Done(): + // Mirroring took too long and was canceled. } return r, err } -func (m *percentBasedMirror) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { - var mirrorCh chan any - var mirrorCtx context.Context - var mirrorCtxCancel func() - doMirror := m.percentAtLeastDieRoll() - - if doMirror { - mirrorCh = make(chan any) +func (m *percentBasedMirror) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + if !m.percentAtLeastDieRoll() { + return vcursor.StreamExecutePrimitive(ctx, m.primitive, bindVars, wantfields, callback) + } - mirrorCtx, mirrorCtxCancel = context.WithTimeout(ctx, maxMirrorTargetLag) - defer mirrorCtxCancel() + mirrorCh := make(chan any) + mirrorCtx, mirrorCtxCancel := context.WithTimeout(ctx, maxMirrorTargetLag) + defer mirrorCtxCancel() - go func(target Primitive, vcursor VCursor) { - defer close(mirrorCh) - _ = vcursor.StreamExecutePrimitive(mirrorCtx, target, bindVars, wantfields, func(_ *sqltypes.Result) error { - return nil - }) - }(m.target, vcursor.CloneForMirroring(mirrorCtx)) - } + go func() { + defer close(mirrorCh) + vcursor.StreamExecutePrimitive(mirrorCtx, m.target, bindVars, wantfields, func(_ *sqltypes.Result) error { + return nil + }) + }() err := vcursor.StreamExecutePrimitive(ctx, m.primitive, bindVars, wantfields, callback) - if doMirror { - select { - case <-mirrorCh: - // Mirroring completed within the allowed time. - case <-mirrorCtx.Done(): - // Mirroring took too long and was canceled. - } + select { + case <-mirrorCh: + // Mirroring completed within the allowed time. + case <-mirrorCtx.Done(): + // Mirroring took too long and was canceled. } return err diff --git a/go/vt/vtgate/planbuilder/operators/mirror.go b/go/vt/vtgate/planbuilder/operators/mirror.go index b5007a31898..3ab1d66e70d 100644 --- a/go/vt/vtgate/planbuilder/operators/mirror.go +++ b/go/vt/vtgate/planbuilder/operators/mirror.go @@ -45,9 +45,7 @@ func NewPercentBasedMirror(percent float32, operator, target Operator) *PercentB // Clone will return a copy of this operator, protected so changed to the original will not impact the clone func (m *PercentBasedMirror) Clone(inputs []Operator) Operator { cloneMirror := *m - cloneMirror.Percent = m.Percent - cloneMirror.Operator = inputs[0] - cloneMirror.Target = inputs[1] + cloneMirror.SetInputs(inputs) return &cloneMirror } From 83dce0c5631250b1217a3ebd642d4c8c2ccff2b0 Mon Sep 17 00:00:00 2001 From: Max Englander Date: Tue, 13 Aug 2024 15:20:35 -0400 Subject: [PATCH 27/27] fix Signed-off-by: Max Englander --- go/vt/vtgate/engine/mirror.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/go/vt/vtgate/engine/mirror.go b/go/vt/vtgate/engine/mirror.go index fcc9d4ffe4e..bfab4cee91d 100644 --- a/go/vt/vtgate/engine/mirror.go +++ b/go/vt/vtgate/engine/mirror.go @@ -80,7 +80,9 @@ func (m *percentBasedMirror) TryExecute(ctx context.Context, vcursor VCursor, bi go func() { defer close(mirrorCh) - vcursor.ExecutePrimitive(mirrorCtx, m.target, bindVars, wantfields) + mirrorVCursor := vcursor.CloneForMirroring(mirrorCtx) + // TODO(maxeng) handle error. + _, _ = mirrorVCursor.ExecutePrimitive(mirrorCtx, m.target, bindVars, wantfields) }() r, err := vcursor.ExecutePrimitive(ctx, m.primitive, bindVars, wantfields) @@ -95,7 +97,6 @@ func (m *percentBasedMirror) TryExecute(ctx context.Context, vcursor VCursor, bi return r, err } - func (m *percentBasedMirror) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { if !m.percentAtLeastDieRoll() { return vcursor.StreamExecutePrimitive(ctx, m.primitive, bindVars, wantfields, callback) @@ -107,9 +108,13 @@ func (m *percentBasedMirror) TryStreamExecute(ctx context.Context, vcursor VCurs go func() { defer close(mirrorCh) - vcursor.StreamExecutePrimitive(mirrorCtx, m.target, bindVars, wantfields, func(_ *sqltypes.Result) error { - return nil - }) + mirrorVCursor := vcursor.CloneForMirroring(mirrorCtx) + // TODO(maxeng) handle error. + _ = mirrorVCursor.StreamExecutePrimitive( + mirrorCtx, m.target, bindVars, wantfields, func(_ *sqltypes.Result, + ) error { + return nil + }) }() err := vcursor.StreamExecutePrimitive(ctx, m.primitive, bindVars, wantfields, callback)