diff --git a/changelog/19.0/19.0.0/summary.md b/changelog/19.0/19.0.0/summary.md index 2b5fdfe3d65..a303dff02cc 100644 --- a/changelog/19.0/19.0.0/summary.md +++ b/changelog/19.0/19.0.0/summary.md @@ -12,6 +12,8 @@ - [Stream Consolidations](#stream-consolidations) - **[VTGate](#vtgate)** - [`FOREIGN_KEY_CHECKS` is now a Vitess Aware Variable](#fk-checks-vitess-aware) + - **[Vttestserver](#vttestserver)** + - [`--vtcombo-bind-host` flag](#vtcombo-bind-host) - **[Query Compatibility](#query-compatibility)** - [`SHOW VSCHEMA KEYSPACES` Query](#show-vschema-keyspaces) - **[Planned Reparent Shard](#planned-reparent-shard)** @@ -57,6 +59,12 @@ Prior to 19.0 VTTablet reported how much time non-streaming executions spend wai When VTGate receives a query to change the `FOREIGN_KEY_CHECKS` value for a session, instead of sending the value down to MySQL, VTGate now keeps track of the value and changes the queries by adding `SET_VAR(FOREIGN_KEY_CHECKS=On/Off)` style query optimizer hints wherever required. +### Vttestserver + +#### `--vtcombo-bind-host` flag + +A new flag `--vtcombo-bind-host` has been added to vttestserver that allows the users to configure the bind host that vtcombo uses. This is especially useful when running vttestserver as a docker image and you want to run vtctld commands and look at the vtcombo `/debug/status` dashboard. + ### Query Compatibility #### `SHOW VSCHEMA KEYSPACES` Query diff --git a/docker/vttestserver/run.sh b/docker/vttestserver/run.sh index 1ff79153af5..e3a99ab38f4 100755 --- a/docker/vttestserver/run.sh +++ b/docker/vttestserver/run.sh @@ -35,6 +35,7 @@ rm -vf "$VTDATAROOT"/"$tablet_dir"/{mysql.sock,mysql.sock.lock} --keyspaces "$KEYSPACES" \ --num_shards "$NUM_SHARDS" \ --mysql_bind_host "${MYSQL_BIND_HOST:-127.0.0.1}" \ + --vtcombo-bind-host "${VTCOMBO_BIND_HOST:-127.0.0.1}" \ --mysql_server_version "${MYSQL_SERVER_VERSION:-$1}" \ --charset "${CHARSET:-utf8mb4}" \ --foreign_key_mode "${FOREIGN_KEY_MODE:-allow}" \ diff --git a/go/cmd/vttestserver/cli/main.go b/go/cmd/vttestserver/cli/main.go index ea92ae7dda0..644796c5bca 100644 --- a/go/cmd/vttestserver/cli/main.go +++ b/go/cmd/vttestserver/cli/main.go @@ -177,6 +177,9 @@ func New() (cmd *cobra.Command) { cmd.Flags().StringVar(&config.MySQLBindHost, "mysql_bind_host", "localhost", "which host to bind vtgate mysql listener to") + cmd.Flags().StringVar(&config.VtComboBindAddress, "vtcombo-bind-host", "localhost", + "which host to bind vtcombo servenv listener to") + cmd.Flags().StringVar(&mycnf, "extra_my_cnf", "", "extra files to add to the config, separated by ':'") diff --git a/go/flags/endtoend/vttestserver.txt b/go/flags/endtoend/vttestserver.txt index f6b9332a95e..aac0d1e5286 100644 --- a/go/flags/endtoend/vttestserver.txt +++ b/go/flags/endtoend/vttestserver.txt @@ -140,6 +140,7 @@ Flags: -v, --version print binary version --vmodule vModuleFlag comma-separated list of pattern=N settings for file-filtered logging --vschema_ddl_authorized_users string Comma separated list of users authorized to execute vschema ddl operations via vtgate + --vtcombo-bind-host string which host to bind vtcombo servenv listener to (default "localhost") --vtctl_client_protocol string Protocol to use to talk to the vtctl server. (default "grpc") --vtctld_grpc_ca string the server ca to use to validate servers when connecting --vtctld_grpc_cert string the cert to use to connect diff --git a/go/test/endtoend/docker/vttestserver.go b/go/test/endtoend/docker/vttestserver.go index 7f24134a28f..4f86c7616a1 100644 --- a/go/test/endtoend/docker/vttestserver.go +++ b/go/test/endtoend/docker/vttestserver.go @@ -39,7 +39,7 @@ type vttestserver struct { keyspaces []string numShards []int mysqlMaxConnecetions int - port int + basePort int } func newVttestserver(dockerImage string, keyspaces []string, numShards []int, mysqlMaxConnections, port int) *vttestserver { @@ -48,7 +48,7 @@ func newVttestserver(dockerImage string, keyspaces []string, numShards []int, my keyspaces: keyspaces, numShards: numShards, mysqlMaxConnecetions: mysqlMaxConnections, - port: port, + basePort: port, } } @@ -64,13 +64,16 @@ func (v *vttestserver) teardown() { func (v *vttestserver) startDockerImage() error { cmd := exec.Command("docker", "run") cmd.Args = append(cmd.Args, "--name=vttestserver-end2end-test") - cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:33577", v.port)) - cmd.Args = append(cmd.Args, "-e", "PORT=33574") + cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort, v.basePort)) + cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort+1, v.basePort+1)) + cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:%d", v.basePort+3, v.basePort+3)) + cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("PORT=%d", v.basePort)) cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("KEYSPACES=%s", strings.Join(v.keyspaces, ","))) cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("NUM_SHARDS=%s", strings.Join(convertToStringSlice(v.numShards), ","))) cmd.Args = append(cmd.Args, "-e", "MYSQL_BIND_HOST=0.0.0.0") + cmd.Args = append(cmd.Args, "-e", "VTCOMBO_BIND_HOST=0.0.0.0") cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("MYSQL_MAX_CONNECTIONS=%d", v.mysqlMaxConnecetions)) - cmd.Args = append(cmd.Args, "--health-cmd", "mysqladmin ping -h127.0.0.1 -P33577") + cmd.Args = append(cmd.Args, "--health-cmd", fmt.Sprintf("mysqladmin ping -h127.0.0.1 -P%d", v.basePort+3)) cmd.Args = append(cmd.Args, "--health-interval=5s") cmd.Args = append(cmd.Args, "--health-timeout=2s") cmd.Args = append(cmd.Args, "--health-retries=5") diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index c89f6299f30..e34be52accf 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -22,6 +22,7 @@ import ( "os" "testing" + "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" "vitess.io/vitess/go/mysql" @@ -44,7 +45,7 @@ func TestUnsharded(t *testing.T) { dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} for _, image := range dockerImages { t.Run(image, func(t *testing.T) { - vtest := newVttestserver(image, []string{"unsharded_ks"}, []int{1}, 1000, 33577) + vtest := newVttestserver(image, []string{"unsharded_ks"}, []int{1}, 1000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -56,7 +57,7 @@ func TestUnsharded(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) @@ -73,7 +74,7 @@ func TestSharded(t *testing.T) { dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} for _, image := range dockerImages { t.Run(image, func(t *testing.T) { - vtest := newVttestserver(image, []string{"ks"}, []int{2}, 1000, 33577) + vtest := newVttestserver(image, []string{"ks"}, []int{2}, 1000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -85,7 +86,7 @@ func TestSharded(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) @@ -103,7 +104,7 @@ func TestMysqlMaxCons(t *testing.T) { dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} for _, image := range dockerImages { t.Run(image, func(t *testing.T) { - vtest := newVttestserver(image, []string{"ks"}, []int{2}, 100000, 33577) + vtest := newVttestserver(image, []string{"ks"}, []int{2}, 100000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -115,7 +116,7 @@ func TestMysqlMaxCons(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) @@ -125,6 +126,29 @@ func TestMysqlMaxCons(t *testing.T) { } } +// TestVtctldCommands tests that vtctld commands can be run with the docker image. +func TestVtctldCommands(t *testing.T) { + dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} + for _, image := range dockerImages { + t.Run(image, func(t *testing.T) { + vtest := newVttestserver(image, []string{"long_ks_name"}, []int{2}, 100, 33574) + err := vtest.startDockerImage() + require.NoError(t, err) + defer vtest.teardown() + + // wait for the docker to be setup + err = vtest.waitUntilDockerHealthy(10) + require.NoError(t, err) + + vtctldClient := cluster.VtctldClientProcessInstance("localhost", vtest.basePort+1, os.TempDir()) + res, err := vtctldClient.ExecuteCommandWithOutput("GetKeyspaces") + require.NoError(t, err) + // We verify that the command succeeds, and the keyspace name is present in the output. + require.Contains(t, res, "long_ks_name") + }) + } +} + func TestLargeNumberOfKeyspaces(t *testing.T) { dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} for _, image := range dockerImages { @@ -136,7 +160,7 @@ func TestLargeNumberOfKeyspaces(t *testing.T) { numShards = append(numShards, 1) } - vtest := newVttestserver(image, keyspaces, numShards, 100000, 33577) + vtest := newVttestserver(image, keyspaces, numShards, 100000, 33574) err := vtest.startDockerImage() require.NoError(t, err) defer vtest.teardown() @@ -148,7 +172,7 @@ func TestLargeNumberOfKeyspaces(t *testing.T) { ctx := context.Background() vttestParams := mysql.ConnParams{ Host: "localhost", - Port: vtest.port, + Port: vtest.basePort + 3, } conn, err := mysql.Connect(ctx, &vttestParams) require.NoError(t, err) diff --git a/go/vt/vttest/local_cluster.go b/go/vt/vttest/local_cluster.go index 6138508aea6..fcf164df187 100644 --- a/go/vt/vttest/local_cluster.go +++ b/go/vt/vttest/local_cluster.go @@ -109,6 +109,10 @@ type Config struct { // cluster startup if the data directory does not already exist. PersistentMode bool + // VtCombo bind address. + // vtcombo will bind to this address when running the servenv. + VtComboBindAddress string + // MySQL protocol bind address. // vtcombo will bind to this address when exposing the mysql protocol socket MySQLBindHost string @@ -641,6 +645,7 @@ func (db *LocalCluster) JSONConfig() any { } config := map[string]any{ + "bind_address": db.vt.BindAddress, "port": db.vt.Port, "socket": db.mysql.UnixSocket(), "vtcombo_mysql_port": db.Env.PortForProtocol("vtcombo_mysql_port", ""), @@ -783,7 +788,7 @@ func (db *LocalCluster) VTProcess() *VtProcess { // a pointer to the interface. To read this vschema, the caller must convert it to a map func (vt *VtProcess) ReadVSchema() (*interface{}, error) { httpClient := &http.Client{Timeout: 5 * time.Second} - resp, err := httpClient.Get(fmt.Sprintf("http://%s:%d/debug/vschema", "127.0.0.1", vt.Port)) + resp, err := httpClient.Get(fmt.Sprintf("http://%s:%d/debug/vschema", vt.BindAddress, vt.Port)) if err != nil { return nil, err } diff --git a/go/vt/vttest/vtprocess.go b/go/vt/vttest/vtprocess.go index 2053973b766..c17d66dedec 100644 --- a/go/vt/vttest/vtprocess.go +++ b/go/vt/vttest/vtprocess.go @@ -50,6 +50,7 @@ type VtProcess struct { Binary string ExtraArgs []string Env []string + BindAddress string Port int PortGrpc int HealthCheck HealthChecker @@ -91,7 +92,7 @@ func (vtp *VtProcess) IsHealthy() bool { // Address returns the main address for this Vitess process. // This is usually the main HTTP endpoint for the service. func (vtp *VtProcess) Address() string { - return fmt.Sprintf("localhost:%d", vtp.Port) + return fmt.Sprintf("%s:%d", vtp.BindAddress, vtp.Port) } // WaitTerminate attempts to gracefully shutdown the Vitess process by sending @@ -128,7 +129,7 @@ func (vtp *VtProcess) WaitStart() (err error) { vtp.proc = exec.Command( vtp.Binary, "--port", fmt.Sprintf("%d", vtp.Port), - "--bind-address", "127.0.0.1", + "--bind-address", vtp.BindAddress, "--log_dir", vtp.LogDirectory, "--alsologtostderr", ) @@ -196,11 +197,16 @@ var QueryServerArgs = []string{ // configured with the given Config. // The process must be manually started by calling WaitStart() func VtcomboProcess(environment Environment, args *Config, mysql MySQLManager) (*VtProcess, error) { + vtcomboBindAddress := "127.0.0.1" + if args.VtComboBindAddress != "" { + vtcomboBindAddress = args.VtComboBindAddress + } vt := &VtProcess{ Name: "vtcombo", Directory: environment.Directory(), LogDirectory: environment.LogDirectory(), Binary: environment.BinaryPath("vtcombo"), + BindAddress: vtcomboBindAddress, Port: environment.PortForProtocol("vtcombo", ""), PortGrpc: environment.PortForProtocol("vtcombo", "grpc"), HealthCheck: environment.ProcessHealthCheck("vtcombo"),