Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental: Multi-tenant import support in Vitess #15503

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
1b8029f
Add multi_tenant attribute to keyspace
rohit-nayak-ps Mar 13, 2024
4ee9820
Update internal KeyspaceSchema object and add unit test for it
rohit-nayak-ps Mar 13, 2024
07a795e
Fix json serialization/deserialization adding a test for it
rohit-nayak-ps Mar 13, 2024
aa959db
Change multi tenant attribute to use an object with column name/type.…
rohit-nayak-ps Mar 13, 2024
f5b5a9b
Add tenant id to Create. Pass it to the server
rohit-nayak-ps Mar 13, 2024
8d0f27c
Create json/struct for vrep options and update related sql/func. Upda…
rohit-nayak-ps Mar 13, 2024
a619db6
Initial e2e test
rohit-nayak-ps Mar 13, 2024
d58dcb4
Add logic to append tenant clause filter to forward workflow
rohit-nayak-ps Mar 13, 2024
20f22ea
Update options and filter on reverse streams
rohit-nayak-ps Mar 13, 2024
b30edf0
Add e2e test to CI
rohit-nayak-ps Mar 14, 2024
8000c5b
Add KeyspaceRoutingRules to the vschema and related topo/vschema file…
rohit-nayak-ps Mar 14, 2024
10b811c
Add keyspace routing rules for a multi-tenant migration
rohit-nayak-ps Mar 16, 2024
4f7e07d
Don't point target keyspace in routing rules since we can't have targ…
rohit-nayak-ps Mar 16, 2024
890a6a9
Remove reverse switching tests since we cannot really do it in multi-…
rohit-nayak-ps Mar 16, 2024
7960093
Add default to options column in VReplicationExec insert generator
rohit-nayak-ps Mar 17, 2024
097e900
Fix unit tests in go/vt/binlog
rohit-nayak-ps Mar 17, 2024
931f9b6
Fix failing unit tests in go/vt/vtctl/workflow
rohit-nayak-ps Mar 17, 2024
2a357bb
Fix TestInsertGenerator
rohit-nayak-ps Mar 17, 2024
9036db2
Fix Materializer tests
rohit-nayak-ps Mar 17, 2024
ce4e897
Fix Reshard unit tests
rohit-nayak-ps Mar 17, 2024
1fd7766
Fix unit tests in /go/vt/vttablet/tabletmanager
rohit-nayak-ps Mar 17, 2024
a2fb454
Fix failing tests in tabletmanager/vreplication
rohit-nayak-ps Mar 17, 2024
78cdbc6
Revert temporary hacks
rohit-nayak-ps Mar 17, 2024
670ef6d
Revert to warn on no config
rohit-nayak-ps Mar 17, 2024
d42d6f9
Start a simple multi tenant test. To be expanded
rohit-nayak-ps Mar 17, 2024
4f599c4
Fix TestUpdateVSchema
rohit-nayak-ps Mar 17, 2024
f4d78e0
Use latest versions of vtctld/vtctl in Query Serving (Queries) - Upgr…
rohit-nayak-ps Mar 18, 2024
b2c6e1c
Fix static code check failures. Attempt to fix upgrade/downgrade test
rohit-nayak-ps Mar 18, 2024
6b18d92
Add Get/ApplyKeyspaceRoutingRules to vtctldclient
rohit-nayak-ps Mar 18, 2024
1aec51c
Add multi tenant ci workflow
rohit-nayak-ps Mar 18, 2024
c4066e9
Fix keyspace routing rules duplicate and modify help text
rohit-nayak-ps Mar 18, 2024
1248a1d
Change attribute from VReplicationWorkflowOptions to WorkflowOptions
rohit-nayak-ps Mar 18, 2024
b680c4b
Minor refactors
rohit-nayak-ps Mar 18, 2024
e698083
Validate tenant id provided matches specified type in vschema
rohit-nayak-ps Mar 18, 2024
863ab46
Fix failing tests
rohit-nayak-ps Mar 18, 2024
4a4c48d
Enhance simple multi tenant test to validate routing better. Remove r…
rohit-nayak-ps Mar 19, 2024
59521fd
Fix incorrect insert into target keyspace before switching traffic
rohit-nayak-ps Mar 19, 2024
562b61e
Minor refactor. Cleanup comments/commented code
rohit-nayak-ps Mar 24, 2024
f54b2a9
Address review comments
rohit-nayak-ps Mar 24, 2024
4123421
Address more review comments
rohit-nayak-ps Mar 24, 2024
d154b66
Remove timeout for workflow to see if it will fix static check error …
rohit-nayak-ps Mar 24, 2024
a18387e
Rebase and make ci workflows again
rohit-nayak-ps Mar 24, 2024
f70f7eb
Add mise config file to .gitignore
rohit-nayak-ps Mar 24, 2024
2eb44e6
Fix regression in reverse workflow validation.
rohit-nayak-ps Mar 24, 2024
7850fea
Make Proto
rohit-nayak-ps Mar 24, 2024
6758d01
Update e2e tests: don't specify multi_tenant_spec in source vschema
rohit-nayak-ps Mar 27, 2024
077a5fa
Address review comments
rohit-nayak-ps Mar 31, 2024
a437a7f
Address more review comments
rohit-nayak-ps Mar 31, 2024
082d6d4
Re-enable wait for throttler config to be applied on all shards durin…
rohit-nayak-ps Mar 31, 2024
94b0291
Use query.Type instead of string equivalent in vschema to define data…
rohit-nayak-ps Apr 1, 2024
38d34e9
Use INT64 string instead of enum in test vschema
rohit-nayak-ps Apr 1, 2024
36027f3
Address review comments
rohit-nayak-ps Apr 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
172 changes: 172 additions & 0 deletions .github/workflows/cluster_endtoend_vreplication_multi_tenant.yml
@@ -0,0 +1,172 @@
# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"

name: Cluster (vreplication_multi_tenant)
on: [push, pull_request]
concurrency:
group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vreplication_multi_tenant)')
cancel-in-progress: true

permissions: read-all

env:
LAUNCHABLE_ORGANIZATION: "vitess"
LAUNCHABLE_WORKSPACE: "vitess-app"
GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}"

jobs:
build:
name: Run endtoend tests on Cluster (vreplication_multi_tenant)
runs-on: gh-hosted-runners-4cores-1
rohit-nayak-ps marked this conversation as resolved.
Show resolved Hide resolved

steps:
- name: Skip CI
run: |
if [[ "${{contains( github.event.pull_request.labels.*.name, 'Skip CI')}}" == "true" ]]; then
echo "skipping CI due to the 'Skip CI' label"
exit 1
fi

- name: Check if workflow needs to be skipped
id: skip-workflow
run: |
skip='false'
if [[ "${{github.event.pull_request}}" == "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then
skip='true'
fi
echo Skip ${skip}
echo "skip-workflow=${skip}" >> $GITHUB_OUTPUT

PR_DATA=$(curl -s\
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}")
draft=$(echo "$PR_DATA" | jq .draft -r)
echo "is_draft=${draft}" >> $GITHUB_OUTPUT

- name: Check out code
if: steps.skip-workflow.outputs.skip-workflow == 'false'
uses: actions/checkout@v4

- name: Check for changes in relevant files
if: steps.skip-workflow.outputs.skip-workflow == 'false'
uses: dorny/paths-filter@v3.0.1
id: changes
with:
token: ''
filters: |
end_to_end:
- 'go/**/*.go'
- 'go/vt/sidecardb/**/*.sql'
- 'go/test/endtoend/onlineddl/vrepl_suite/**'
- 'test.go'
- 'Makefile'
- 'build.env'
- 'go.sum'
- 'go.mod'
- 'proto/*.proto'
- 'tools/**'
- 'config/**'
- 'bootstrap.sh'
- '.github/workflows/cluster_endtoend_vreplication_multi_tenant.yml'

- name: Set up Go
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
uses: actions/setup-go@v5
with:
go-version: 1.22.1

- name: Set up python
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
uses: actions/setup-python@v5

- name: Tune the OS
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
run: |
# Limit local port range to not use ports that overlap with server side
# ports that we listen on.
sudo sysctl -w net.ipv4.ip_local_port_range="22768 65535"
# Increase the asynchronous non-blocking I/O. More information at https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_use_native_aio
echo "fs.aio-max-nr = 1048576" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf

- name: Get dependencies
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
run: |

# Get key to latest MySQL repo
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A8D3785C
# Setup MySQL 8.0
wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb
echo mysql-apt-config mysql-apt-config/select-server select mysql-8.0 | sudo debconf-set-selections
sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config*
sudo apt-get -qq update
# Install everything else we need, and configure
sudo apt-get -qq install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata xz-utils libncurses5

sudo service mysql stop
sudo service etcd stop
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
go mod download

# install JUnit report formatter
go install github.com/vitessio/go-junit-report@HEAD

- name: Setup launchable dependencies
if: steps.skip-workflow.outputs.is_draft == 'false' && steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && github.base_ref == 'main'
run: |
# Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up
pip3 install --user launchable~=1.0 > /dev/null

# verify that launchable setup is all correct.
launchable verify || true

# Tell Launchable about the build you are producing and testing
launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source .

- name: Run cluster endtoend test
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
timeout-minutes: 45
run: |
# We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file
# which musn't be more than 107 characters long.
export VTDATAROOT="/tmp/"
source build.env

set -exo pipefail

# Increase our open file descriptor limit as we could hit this
ulimit -n 65536
cat <<-EOF>>./config/mycnf/mysql80.cnf
innodb_buffer_pool_dump_at_shutdown=OFF
innodb_buffer_pool_in_core_file=OFF
innodb_buffer_pool_load_at_startup=OFF
innodb_buffer_pool_size=64M
innodb_doublewrite=OFF
innodb_flush_log_at_trx_commit=0
innodb_flush_method=O_DIRECT
innodb_numa_interleave=ON
innodb_adaptive_hash_index=OFF
sync_binlog=0
sync_relay_log=0
performance_schema=OFF
slow-query-log=OFF
EOF

cat <<-EOF>>./config/mycnf/mysql80.cnf
binlog-transaction-compression=ON
EOF

# run the tests however you normally do, then produce a JUnit XML file
eatmydata -- go run test.go -docker=false -follow -shard vreplication_multi_tenant | tee -a output.txt | go-junit-report -set-exit-code > report.xml

- name: Print test output and Record test result in launchable if PR is not a draft
if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always()
run: |
if [[ "${{steps.skip-workflow.outputs.is_draft}}" == "false" ]]; then
# send recorded tests to launchable
launchable record tests --build "$GITHUB_RUN_ID" go-test . || true
fi

# print test output
cat output.txt
Expand Up @@ -201,6 +201,12 @@ jobs:

rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate

cp /tmp/vitess-build-other/bin/vtctld $PWD/bin
cp /tmp/vitess-build-other/bin/vtctldclient $PWD/bin
cp /tmp/vitess-build-other/bin/vtctl $PWD/bin
cp /tmp/vitess-build-other/bin/vtctlclient $PWD/bin

cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -86,3 +86,6 @@ report

# plan test output
/go/vt/vtgate/planbuilder/testdata/plan_test*

# mise files
.mise.toml
156 changes: 156 additions & 0 deletions go/cmd/vtctldclient/command/keyspace_routing_rules.go
@@ -0,0 +1,156 @@
/*
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 (
// ApplyKeyspaceRoutingRules makes an ApplyKeyspaceRoutingRules gRPC call to a vtctld.
ApplyKeyspaceRoutingRules = &cobra.Command{
Use: "ApplyKeyspaceRoutingRules {--rules RULES | --rules-file RULES_FILE} [--cells=c1,c2,...] [--skip-rebuild] [--dry-run]",
Short: "Applies the provided keyspace routing rules.",
DisableFlagsInUseLine: true,
Args: cobra.NoArgs,
PreRunE: validateApplyKeyspaceRoutingRulesOptions,
RunE: commandApplyKeyspaceRoutingRules,
}
// GetKeyspaceRoutingRules makes a GetKeyspaceRoutingRules gRPC call to a vtctld.
GetKeyspaceRoutingRules = &cobra.Command{
Use: "GetKeyspaceRoutingRules",
Short: "Displays the currently active keyspace routing rules.",
DisableFlagsInUseLine: true,
Args: cobra.NoArgs,
RunE: commandGetKeyspaceRoutingRules,
}
)

func validateApplyKeyspaceRoutingRulesOptions(cmd *cobra.Command, args []string) error {
opts := applyKeyspaceRoutingRulesOptions
if (opts.Rules != "" && opts.RulesFilePath != "") || (opts.Rules == "" && opts.RulesFilePath == "") {
return errors.New("must pass exactly one of --rules or --rules-file")
}
return nil
}

var applyKeyspaceRoutingRulesOptions = struct {
Rules string
RulesFilePath string
Cells []string
SkipRebuild bool
DryRun bool
}{}

func commandApplyKeyspaceRoutingRules(cmd *cobra.Command, args []string) error {
opts := applyKeyspaceRoutingRulesOptions
cli.FinishedParsing(cmd)

var rulesBytes []byte
if opts.RulesFilePath != "" {
data, err := os.ReadFile(opts.RulesFilePath)
if err != nil {
return err
}
rulesBytes = data
} else {
rulesBytes = []byte(opts.Rules)
}

krr := &vschemapb.KeyspaceRoutingRules{}
if err := json2.Unmarshal(rulesBytes, &krr); err != nil {
return err
}
// Round-trip so that when we display the result it's readable.
data, err := cli.MarshalJSON(krr)
if err != nil {
return err
}

if opts.DryRun {
fmt.Printf("[DRY RUN] Would have saved new KeyspaceRoutingRules object:\n%s\n", data)

if opts.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(opts.Cells) == 0 {
fmt.Print(" in all cells\n")
} else {
fmt.Printf(" in the following cells: %s.\n", strings.Join(applyKeyspaceRoutingRulesOptions.Cells, ", "))
}
}

return nil
}

_, err = client.ApplyKeyspaceRoutingRules(commandCtx, &vtctldatapb.ApplyKeyspaceRoutingRulesRequest{
KeyspaceRoutingRules: krr,
SkipRebuild: opts.SkipRebuild,
RebuildCells: opts.Cells,
})
if err != nil {
return err
}

fmt.Printf("New KeyspaceRoutingRules object:\n%s\nIf this is not what you expected, check the input data (as JSON parsing will skip unexpected fields).\n", data)

if opts.SkipRebuild {
fmt.Println("Skipping rebuild of VSchema graph as requested, you will need to run RebuildVSchemaGraph for the changes to take effect.")
}

return nil
}

func commandGetKeyspaceRoutingRules(cmd *cobra.Command, args []string) error {
cli.FinishedParsing(cmd)

resp, err := client.GetKeyspaceRoutingRules(commandCtx, &vtctldatapb.GetKeyspaceRoutingRulesRequest{})
if err != nil {
return err
}

data, err := cli.MarshalJSON(resp.KeyspaceRoutingRules)
if err != nil {
return err
}

fmt.Printf("%s\n", data)

return nil
}

func init() {
ApplyKeyspaceRoutingRules.Flags().StringVarP(&applyKeyspaceRoutingRulesOptions.Rules, "rules", "r", "", "Keyspace routing rules, specified as a string")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we mean a valid JSON document as a string or something else? This is where examples in the command definition can be helpful for the user. For example, see:

Example: `vtctldclient --server localhost:15999 materialize --workflow product_sales --target-keyspace commerce create --source-keyspace commerce --table-settings '[{"target_table": "sales_by_sku", "create_ddl": "create table sales_by_sku (sku varbinary(128) not null primary key, orders bigint, revenue bigint)", "source_expression": "select sku, count(*) as orders, sum(price) as revenue from corder group by sku"}]' --cells zone1 --cells zone2 --tablet-types replica`,
Long: `Materialize is a lower level VReplication command that allows for generalized materialization
of tables. The target tables can be copies, aggregations, or views. The target tables are kept
in sync in near-realtime. The primary flag used to define the materializations (you can have
multiple per workflow) is table-settings which is a JSON array where each value must contain
two key/value pairs. The first required key is 'target_table' and it is the name of the table
in the target-keyspace to store the results in. The second required key is 'source_expression'
and its value is the select query to run against the source table. An optional key/value pair
can also be specified for 'create_ddl' which provides the DDL to create the target table if it
does not exist -- you can alternatively specify a value of 'copy' if the target table schema
should be copied as-is from the source keyspace. Here's an example value for table-settings:
[
{
"target_table": "customer_one_email",
"source_expression": "select email from customer where customer_id = 1"
},
{
"target_table": "states",
"source_expression": "select * from states",
"create_ddl": "copy"
},
{
"target_table": "sales_by_sku",
"source_expression": "select sku, count(*) as orders, sum(price) as revenue from corder group by sku",
"create_ddl": "create table sales_by_sku (sku varbinary(128) not null primary key, orders bigint, revenue bigint)"
}
]
`,

ApplyKeyspaceRoutingRules.Flags().StringVarP(&applyKeyspaceRoutingRulesOptions.RulesFilePath, "rules-file", "f", "", "Path to a file containing keyspace routing rules specified as JSON")
rohit-nayak-ps marked this conversation as resolved.
Show resolved Hide resolved
ApplyKeyspaceRoutingRules.Flags().StringSliceVarP(&applyKeyspaceRoutingRulesOptions.Cells, "cells", "c", nil, "Limit the VSchema graph rebuilding to the specified cells. Ignored if --skip-rebuild is specified.")
ApplyKeyspaceRoutingRules.Flags().BoolVar(&applyKeyspaceRoutingRulesOptions.SkipRebuild, "skip-rebuild", false, "Skip rebuilding the SrvVSchema objects.")
ApplyKeyspaceRoutingRules.Flags().BoolVarP(&applyKeyspaceRoutingRulesOptions.DryRun, "dry-run", "d", false, "Validate the specified keyspace routing rules and note actions that would be taken, but do not actually apply the rules to the topo.")
Root.AddCommand(ApplyKeyspaceRoutingRules)
Root.AddCommand(GetKeyspaceRoutingRules)
}
Expand Up @@ -39,6 +39,7 @@ var (
SourceTimeZone string
NoRoutingRules bool
AtomicCopy bool
WorkflowOptions vtctldatapb.WorkflowOptions
}{}

// create makes a MoveTablesCreate gRPC call to a vtctld.
Expand Down Expand Up @@ -109,6 +110,7 @@ func commandCreate(cmd *cobra.Command, args []string) error {
StopAfterCopy: common.CreateOptions.StopAfterCopy,
NoRoutingRules: createOptions.NoRoutingRules,
AtomicCopy: createOptions.AtomicCopy,
WorkflowOptions: &createOptions.WorkflowOptions,
}

resp, err := common.GetClient().MoveTablesCreate(common.GetCommandCtx(), req)
Expand Down
Expand Up @@ -47,6 +47,8 @@ func registerCommands(root *cobra.Command) {
create.Flags().StringSliceVar(&createOptions.ExcludeTables, "exclude-tables", nil, "Source tables to exclude from copying.")
create.Flags().BoolVar(&createOptions.NoRoutingRules, "no-routing-rules", false, "(Advanced) Do not create routing rules while creating the workflow. See the reference documentation for limitations if you use this flag.")
create.Flags().BoolVar(&createOptions.AtomicCopy, "atomic-copy", false, "(EXPERIMENTAL) A single copy phase is run for all tables from the source. Use this, for example, if your source keyspace has tables which use foreign key constraints.")
create.Flags().StringVar(&createOptions.WorkflowOptions.TenantId, "tenant-id", "", "(EXPERIMENTAL) The tenant ID to use for the MoveTables workflow into a multi-tenant keyspace.")
create.Flags().StringVar(&createOptions.WorkflowOptions.SourceKeyspaceAlias, "source-keyspace-alias", "", "(EXPERIMENTAL) Used currently only for multi-tenant migrations. This value will be used instead of the source keyspace name in the keyspace routing rules.")
base.AddCommand(create)

opts := &common.SubCommandsOpts{
Expand Down
2 changes: 2 additions & 0 deletions go/flags/endtoend/vtctldclient.txt
Expand Up @@ -11,6 +11,7 @@ Usage:
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.
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.
Expand Down Expand Up @@ -39,6 +40,7 @@ Available Commands:
GetCellsAliases Gets all CellsAlias objects in the cluster.
GetFullStatus Outputs a JSON structure that contains full status of MySQL including the replication information, semi-sync information, GTID information among others.
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.
GetPermissions Displays the permissions for a tablet.
GetRoutingRules Displays the VSchema routing rules.
Expand Down