diff --git a/go/mysql/endtoend/main_test.go b/go/mysql/endtoend/main_test.go index cc1c858bf71..bdf6b787379 100644 --- a/go/mysql/endtoend/main_test.go +++ b/go/mysql/endtoend/main_test.go @@ -28,6 +28,7 @@ import ( "vitess.io/vitess/go/mysql" vtenv "vitess.io/vitess/go/vt/env" + "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/tlstest" "vitess.io/vitess/go/vt/vttest" @@ -76,6 +77,32 @@ func runMysql(t *testing.T, params *mysql.ConnParams, command string) (string, b // The args contain '-v' 3 times, to switch to very verbose output. // In particular, it has the message: // Query OK, 1 row affected (0.00 sec) + + version, getErr := mysqlctl.GetVersionString() + f, v, err := mysqlctl.ParseVersionString(version) + + if getErr != nil || err != nil { + f, v, err = mysqlctl.GetVersionFromEnv() + if err != nil { + vtenvMysqlRoot, _ := vtenv.VtMysqlRoot() + message := fmt.Sprintf(`could not auto-detect MySQL version. You may need to set your PATH so a mysqld binary can be found, or set the environment variable MYSQL_FLAVOR if mysqld is not available locally: + PATH: %s + VT_MYSQL_ROOT: %s + VTROOT: %s + vtenv.VtMysqlRoot(): %s + MYSQL_FLAVOR: %s + `, + os.Getenv("PATH"), + os.Getenv("VT_MYSQL_ROOT"), + os.Getenv("VTROOT"), + vtenvMysqlRoot, + os.Getenv("MYSQL_FLAVOR")) + panic(message) + } + } + + t.Logf("Using flavor: %v, version: %v", f, v) + args := []string{ "-v", "-v", "-v", } @@ -97,12 +124,15 @@ func runMysql(t *testing.T, params *mysql.ConnParams, command string) (string, b args = append(args, "-D", params.DbName) } if params.Flags&mysql.CapabilityClientSSL > 0 { + if f != mysqlctl.FlavorMySQL || v.Major != 8 { + args = append(args, + "--ssl", + "--ssl-verify-server-cert") + } args = append(args, - "--ssl", "--ssl-ca", params.SslCa, "--ssl-cert", params.SslCert, - "--ssl-key", params.SslKey, - "--ssl-verify-server-cert") + "--ssl-key", params.SslKey) } env := []string{ "LD_LIBRARY_PATH=" + path.Join(dir, "lib/mysql"), diff --git a/go/vt/mysqlctl/capabilityset.go b/go/vt/mysqlctl/capabilityset.go index 1b0855e3c1c..cba89adc837 100644 --- a/go/vt/mysqlctl/capabilityset.go +++ b/go/vt/mysqlctl/capabilityset.go @@ -22,10 +22,11 @@ package mysqlctl type mysqlFlavor string +// Flavor constants define the type of mysql flavor being used const ( - flavorMySQL mysqlFlavor = "mysql" - flavorPercona mysqlFlavor = "percona" - flavorMariaDB mysqlFlavor = "mariadb" + FlavorMySQL mysqlFlavor = "mysql" + FlavorPercona mysqlFlavor = "percona" + FlavorMariaDB mysqlFlavor = "mariadb" ) // Mysqld is the object that represents a mysqld daemon running on this server. @@ -54,8 +55,8 @@ func (c *capabilitySet) hasMaria104InstallDb() bool { // or Percona Server. At least currently, Vitess doesn't // make use of any specific Percona Server features. func (c *capabilitySet) isMySQLLike() bool { - return c.flavor == flavorMySQL || c.flavor == flavorPercona + return c.flavor == FlavorMySQL || c.flavor == FlavorPercona } func (c *capabilitySet) isMariaDB() bool { - return c.flavor == flavorMariaDB + return c.flavor == FlavorMariaDB } diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index 22a512e0d1e..7abd1da7a78 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -125,8 +125,8 @@ func NewMysqld(dbcfgs *dbconfigs.DBConfigs) *Mysqld { log.Info("mysqld is unmanaged or remote. Skipping flavor detection") return result } - version, getErr := getVersionString() - f, v, err := parseVersionString(version) + version, getErr := GetVersionString() + f, v, err := ParseVersionString(version) /* By default Vitess searches in vtenv.VtMysqlRoot() for a mysqld binary. @@ -147,7 +147,7 @@ func NewMysqld(dbcfgs *dbconfigs.DBConfigs) *Mysqld { */ if getErr != nil || err != nil { - f, v, err = getVersionFromEnv() + f, v, err = GetVersionFromEnv() if err != nil { vtenvMysqlRoot, _ := vtenv.VtMysqlRoot() message := fmt.Sprintf(`could not auto-detect MySQL version. You may need to set your PATH so a mysqld binary can be found, or set the environment variable MYSQL_FLAVOR if mysqld is not available locally: @@ -172,31 +172,32 @@ func NewMysqld(dbcfgs *dbconfigs.DBConfigs) *Mysqld { } /* -getVersionFromEnv returns the flavor and an assumed version based on the legacy +GetVersionFromEnv returns the flavor and an assumed version based on the legacy MYSQL_FLAVOR environment variable. The assumed version may not be accurate since the legacy variable only specifies broad families of compatible versions. However, the differences between those versions should only matter if Vitess is managing the lifecycle of mysqld, in which case we should have a local copy of the mysqld binary from which we can fetch -the accurate version instead of falling back to this function (see getVersionString). +the accurate version instead of falling back to this function (see GetVersionString). */ -func getVersionFromEnv() (flavor mysqlFlavor, ver serverVersion, err error) { +func GetVersionFromEnv() (flavor mysqlFlavor, ver serverVersion, err error) { env := os.Getenv("MYSQL_FLAVOR") switch env { case "MariaDB": - return flavorMariaDB, serverVersion{10, 0, 10}, nil + return FlavorMariaDB, serverVersion{10, 0, 10}, nil case "MariaDB103": - return flavorMariaDB, serverVersion{10, 3, 7}, nil + return FlavorMariaDB, serverVersion{10, 3, 7}, nil case "MySQL80": - return flavorMySQL, serverVersion{8, 0, 11}, nil + return FlavorMySQL, serverVersion{8, 0, 11}, nil case "MySQL56": - return flavorMySQL, serverVersion{5, 7, 10}, nil + return FlavorMySQL, serverVersion{5, 7, 10}, nil } return flavor, ver, fmt.Errorf("could not determine version from MYSQL_FLAVOR: %s", env) } -func getVersionString() (string, error) { +// GetVersionString runs mysqld --version and returns its output as a string +func GetVersionString() (string, error) { mysqlRoot, err := vtenv.VtMysqlRoot() if err != nil { return "", err @@ -212,16 +213,16 @@ func getVersionString() (string, error) { return version, nil } -// parse the output of mysqld --version into a flavor and version -func parseVersionString(version string) (flavor mysqlFlavor, ver serverVersion, err error) { +// ParseVersionString parses the output of mysqld --version into a flavor and version +func ParseVersionString(version string) (flavor mysqlFlavor, ver serverVersion, err error) { if strings.Contains(version, "Percona") { - flavor = flavorPercona + flavor = FlavorPercona } else if strings.Contains(version, "MariaDB") { - flavor = flavorMariaDB + flavor = FlavorMariaDB } else { // OS distributed MySQL releases have a version string like: // mysqld Ver 5.7.27-0ubuntu0.19.04.1 for Linux on x86_64 ((Ubuntu)) - flavor = flavorMySQL + flavor = FlavorMySQL } v := versionRegex.FindStringSubmatch(version) if len(v) != 4 { @@ -813,9 +814,9 @@ func (mysqld *Mysqld) getMycnfTemplate() string { // mysql version specific file. // master_{flavor}{major}{minor}.cnf - f := flavorMariaDB + f := FlavorMariaDB if mysqld.capabilities.isMySQLLike() { - f = flavorMySQL + f = FlavorMySQL } fn := fmt.Sprintf("mycnf/master_%s%d%d.cnf", f, mysqld.capabilities.version.Major, mysqld.capabilities.version.Minor) b, err = riceBox.Bytes(fn) diff --git a/go/vt/mysqlctl/mysqld_test.go b/go/vt/mysqlctl/mysqld_test.go index 3e27b89c7ae..35f919b8f1d 100644 --- a/go/vt/mysqlctl/mysqld_test.go +++ b/go/vt/mysqlctl/mysqld_test.go @@ -34,74 +34,74 @@ func TestParseVersionString(t *testing.T) { { versionString: "mysqld Ver 5.7.27-0ubuntu0.19.04.1 for Linux on x86_64 ((Ubuntu))", version: serverVersion{5, 7, 27}, - flavor: flavorMySQL, + flavor: FlavorMySQL, }, { versionString: "mysqld Ver 5.6.43 for linux-glibc2.12 on x86_64 (MySQL Community Server (GPL))", version: serverVersion{5, 6, 43}, - flavor: flavorMySQL, + flavor: FlavorMySQL, }, { versionString: "mysqld Ver 5.7.26 for linux-glibc2.12 on x86_64 (MySQL Community Server (GPL))", version: serverVersion{5, 7, 26}, - flavor: flavorMySQL, + flavor: FlavorMySQL, }, { versionString: "mysqld Ver 8.0.16 for linux-glibc2.12 on x86_64 (MySQL Community Server - GPL)", version: serverVersion{8, 0, 16}, - flavor: flavorMySQL, + flavor: FlavorMySQL, }, { versionString: "mysqld Ver 5.7.26-29 for Linux on x86_64 (Percona Server (GPL), Release 29, Revision 11ad961)", version: serverVersion{5, 7, 26}, - flavor: flavorPercona, + flavor: FlavorPercona, }, { versionString: "mysqld Ver 10.0.38-MariaDB for Linux on x86_64 (MariaDB Server)", version: serverVersion{10, 0, 38}, - flavor: flavorMariaDB, + flavor: FlavorMariaDB, }, { versionString: "mysqld Ver 10.1.40-MariaDB for Linux on x86_64 (MariaDB Server)", version: serverVersion{10, 1, 40}, - flavor: flavorMariaDB, + flavor: FlavorMariaDB, }, { versionString: "mysqld Ver 10.2.25-MariaDB for Linux on x86_64 (MariaDB Server)", version: serverVersion{10, 2, 25}, - flavor: flavorMariaDB, + flavor: FlavorMariaDB, }, { versionString: "mysqld Ver 10.3.16-MariaDB for Linux on x86_64 (MariaDB Server)", version: serverVersion{10, 3, 16}, - flavor: flavorMariaDB, + flavor: FlavorMariaDB, }, { versionString: "mysqld Ver 10.4.6-MariaDB for Linux on x86_64 (MariaDB Server)", version: serverVersion{10, 4, 6}, - flavor: flavorMariaDB, + flavor: FlavorMariaDB, }, { versionString: "mysqld Ver 5.6.42 for linux-glibc2.12 on x86_64 (MySQL Community Server (GPL))", version: serverVersion{5, 6, 42}, - flavor: flavorMySQL, + flavor: FlavorMySQL, }, { versionString: "mysqld Ver 5.6.44-86.0 for Linux on x86_64 (Percona Server (GPL), Release 86.0, Revision eba1b3f)", version: serverVersion{5, 6, 44}, - flavor: flavorPercona, + flavor: FlavorPercona, }, { versionString: "mysqld Ver 8.0.15-6 for Linux on x86_64 (Percona Server (GPL), Release 6, Revision 63abd08)", version: serverVersion{8, 0, 15}, - flavor: flavorPercona, + flavor: FlavorPercona, }, } for _, testcase := range testcases { - f, v, err := parseVersionString(testcase.versionString) + f, v, err := ParseVersionString(testcase.versionString) if v != testcase.version || f != testcase.flavor || err != nil { - t.Errorf("parseVersionString failed for: %#v, Got: %#v, %#v Expected: %#v, %#v", testcase.versionString, v, f, testcase.version, testcase.flavor) + t.Errorf("ParseVersionString failed for: %#v, Got: %#v, %#v Expected: %#v, %#v", testcase.versionString, v, f, testcase.version, testcase.flavor) } } @@ -116,30 +116,30 @@ func TestAssumeVersionString(t *testing.T) { { versionString: "MySQL80", version: serverVersion{8, 0, 11}, - flavor: flavorMySQL, + flavor: FlavorMySQL, }, { versionString: "MySQL56", version: serverVersion{5, 7, 10}, // Yes, this has to lie! - flavor: flavorMySQL, // There was no MySQL57 option + flavor: FlavorMySQL, // There was no MySQL57 option }, { versionString: "MariaDB", version: serverVersion{10, 0, 10}, - flavor: flavorMariaDB, + flavor: FlavorMariaDB, }, { versionString: "MariaDB103", version: serverVersion{10, 3, 7}, - flavor: flavorMariaDB, + flavor: FlavorMariaDB, }, } for _, testcase := range testcases { os.Setenv("MYSQL_FLAVOR", testcase.versionString) - f, v, err := getVersionFromEnv() + f, v, err := GetVersionFromEnv() if v != testcase.version || f != testcase.flavor || err != nil { - t.Errorf("getVersionFromEnv() failed for: %#v, Got: %#v, %#v Expected: %#v, %#v", testcase.versionString, v, f, testcase.version, testcase.flavor) + t.Errorf("GetVersionFromEnv() failed for: %#v, Got: %#v, %#v Expected: %#v, %#v", testcase.versionString, v, f, testcase.version, testcase.flavor) } }