diff --git a/go/cmd/vtctldclient/command/schema.go b/go/cmd/vtctldclient/command/schema.go index ed640a4509f..3a3e0c6961d 100644 --- a/go/cmd/vtctldclient/command/schema.go +++ b/go/cmd/vtctldclient/command/schema.go @@ -58,13 +58,6 @@ For --sql, semi-colons and repeated values may be mixed, for example: Args: cobra.ExactArgs(1), RunE: commandApplySchema, } - CopySchemaShard = &cobra.Command{ - Use: "CopySchemaShard [--tables=,,...] [--exclude-tables=,,...] [--include-views] [--skip-verify] [--wait-replicas-timeout=10s] { || } ", - Short: "Copies the schema from a source shard's primary (or a specific tablet) to a destination shard. The schema is applied directly on the primary of the destination shard, and it is propagated to the replicas through binlogs.", - DisableFlagsInUseLine: true, - Args: cobra.ExactArgs(2), - RunE: commandCopySchemaShard, - } // GetSchema makes a GetSchema gRPC call to a vtctld. GetSchema = &cobra.Command{ Use: "GetSchema [--tables TABLES ...] [--exclude-tables EXCLUDE_TABLES ...] [{--table-names-only | --table-sizes-only}] [--include-views] alias", @@ -180,47 +173,6 @@ func commandApplySchema(cmd *cobra.Command, args []string) error { return nil } -func commandCopySchemaShard(cmd *cobra.Command, args []string) error { - /* - tables := subFlags.String("tables", "", "Specifies a comma-separated list of tables to copy. Each is either an exact match, or a regular expression of the form /regexp/") - excludeTables := subFlags.String("exclude_tables", "", "Specifies a comma-separated list of tables to exclude. Each is either an exact match, or a regular expression of the form /regexp/") - includeViews := subFlags.Bool("include-views", true, "Includes views in the output") - skipVerify := subFlags.Bool("skip-verify", false, "Skip verification of source and target schema after copy") - // for backwards compatibility - waitReplicasTimeout := subFlags.Duration("wait_replicas_timeout", grpcvtctldserver.DefaultWaitReplicasTimeout, "The amount of time to wait for replicas to receive the schema change via replication.") - if err := subFlags.Parse(args); err != nil { - return err - } - - if subFlags.NArg() != 2 { - return fmt.Errorf("the and arguments are both required for the CopySchemaShard command. Instead of the argument, you can also specify which refers to a specific tablet of the shard in the source keyspace") - } - var tableArray []string - if *tables != "" { - tableArray = strings.Split(*tables, ",") - } - var excludeTableArray []string - if *excludeTables != "" { - excludeTableArray = strings.Split(*excludeTables, ",") - } - destKeyspace, destShard, err := topoproto.ParseKeyspaceShard(subFlags.Arg(1)) - if err != nil { - return err - } - - sourceKeyspace, sourceShard, err := topoproto.ParseKeyspaceShard(subFlags.Arg(0)) - if err == nil { - return wr.CopySchemaShardFromShard(ctx, tableArray, excludeTableArray, *includeViews, sourceKeyspace, sourceShard, destKeyspace, destShard, *waitReplicasTimeout, *skipVerify) - } - sourceTabletAlias, err := topoproto.ParseTabletAlias(subFlags.Arg(0)) - if err == nil { - return wr.CopySchemaShard(ctx, sourceTabletAlias, tableArray, excludeTableArray, *includeViews, destKeyspace, destShard, *waitReplicasTimeout, *skipVerify) - } - return err - */ - return nil -} - var getSchemaOptions = struct { Tables []string ExcludeTables []string @@ -423,7 +375,6 @@ func init() { ApplySchema.Flags().StringArrayVar(&applySchemaOptions.SQL, "sql", nil, "Semicolon-delimited, repeatable SQL commands to apply. Exactly one of --sql|--sql-file is required.") ApplySchema.Flags().StringVar(&applySchemaOptions.SQLFile, "sql-file", "", "Path to a file containing semicolon-delimited SQL commands to apply. Exactly one of --sql|--sql-file is required.") ApplySchema.Flags().Int64Var(&applySchemaOptions.BatchSize, "batch-size", 0, "How many queries to batch together. Only applicable when all queries are CREATE TABLE|VIEW") - Root.AddCommand(ApplySchema) GetSchema.Flags().StringSliceVar(&getSchemaOptions.Tables, "tables", nil, "List of tables to display the schema for. Each is either an exact match, or a regular expression of the form `/regexp/`.") diff --git a/go/test/endtoend/vtgate/schema/schema_test.go b/go/test/endtoend/vtgate/schema/schema_test.go index 4c28e29ca0d..1fc9dc2c285 100644 --- a/go/test/endtoend/vtgate/schema/schema_test.go +++ b/go/test/endtoend/vtgate/schema/schema_test.go @@ -17,12 +17,10 @@ limitations under the License. package schema import ( - "encoding/json" "flag" "fmt" "os" "path" - "reflect" "strings" "testing" "time" @@ -108,9 +106,6 @@ func TestSchemaChange(t *testing.T) { testApplySchemaBatch(t) testUnsafeAllowForeignKeys(t) testCreateInvalidView(t) - testCopySchemaShards(t, clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].VttabletProcess.TabletPath, 2) - testCopySchemaShards(t, fmt.Sprintf("%s/0", keyspaceName), 3) - testCopySchemaShardWithDifferentDB(t, 4) testWithAutoSchemaFromChangeDir(t) } @@ -286,58 +281,6 @@ func checkTablesCount(t *testing.T, tablet *cluster.Vttablet, count int) { assert.Equal(t, len(queryResult.Rows), count) } -// testCopySchemaShards tests that schema from source is correctly applied to destination -func testCopySchemaShards(t *testing.T, source string, shard int) { - addNewShard(t, shard) - // InitShardPrimary creates the db, but there shouldn't be any tables yet. - checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[0], 0) - checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[1], 0) - // Run the command twice to make sure it's idempotent. - for i := 0; i < 2; i++ { - err := clusterInstance.VtctlclientProcess.ExecuteCommand("CopySchemaShard", source, fmt.Sprintf("%s/%d", keyspaceName, shard)) - require.Nil(t, err) - } - // shard2 primary should look the same as the replica we copied from - checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[0], totalTableCount) - checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[1], totalTableCount) - - matchSchema(t, clusterInstance.Keyspaces[0].Shards[0].Vttablets[0].VttabletProcess.TabletPath, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[0].VttabletProcess.TabletPath) -} - -// testCopySchemaShardWithDifferentDB if we apply different schema to new shard, it should throw error -func testCopySchemaShardWithDifferentDB(t *testing.T, shard int) { - addNewShard(t, shard) - checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[0], 0) - checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[1], 0) - source := fmt.Sprintf("%s/0", keyspaceName) - - tabletAlias := clusterInstance.Keyspaces[0].Shards[shard].Vttablets[0].VttabletProcess.TabletPath - schema, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("GetSchema", tabletAlias) - require.Nil(t, err) - - resultMap := make(map[string]any) - err = json.Unmarshal([]byte(schema), &resultMap) - require.Nil(t, err) - dbSchema := reflect.ValueOf(resultMap["database_schema"]) - assert.True(t, strings.Contains(dbSchema.String(), "utf8")) - - // Change the db charset on the destination shard from utf8 to latin1. - // This will make CopySchemaShard fail during its final diff. - // (The different charset won't be corrected on the destination shard - // because we use "CREATE DATABASE IF NOT EXISTS" and this doesn't fail if - // there are differences in the options e.g. the character set.) - err = clusterInstance.VtctldClientProcess.ExecuteCommand("ExecuteFetchAsDBA", "--json", tabletAlias, "ALTER DATABASE vt_ks CHARACTER SET latin1") - require.Nil(t, err) - - output, err := clusterInstance.VtctlclientProcess.ExecuteCommandWithOutput("CopySchemaShard", source, fmt.Sprintf("%s/%d", keyspaceName, shard)) - require.Error(t, err) - assert.True(t, strings.Contains(output, "schemas are different")) - - // shard2 primary should have the same number of tables. Only the db - // character set is different. - checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[shard].Vttablets[0], totalTableCount) -} - // addNewShard adds a new shard dynamically func addNewShard(t *testing.T, shard int) { keyspace := &cluster.Keyspace{