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"),