Skip to content

Commit

Permalink
Improve efficiency and accuracy of mysqld.GetVersionString
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Lord <[email protected]>
  • Loading branch information
mattlord committed Jan 31, 2024
1 parent ebf0106 commit 5e45865
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
18 changes: 13 additions & 5 deletions go/vt/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"path"
"path/filepath"
"strings"
"sync"
)

const (
Expand All @@ -33,6 +34,9 @@ const (
DefaultVtRoot = "/usr/local/vitess"
)

// Used to ensure that we only add /usr/sbin to the PATH once.
var once sync.Once

// VtRoot returns $VTROOT or tries to guess its value if it's not set.
// This is the root for the 'vt' distribution, which contains bin/vttablet
// for instance.
Expand Down Expand Up @@ -72,11 +76,15 @@ func VtMysqlRoot() (string, error) {
return root, nil
}

// otherwise let's look for mysqld in the PATH.
// ensure that /usr/sbin is included, as it might not be by default
// This is the default location for mysqld from packages.
newPath := fmt.Sprintf("/usr/sbin:%s", os.Getenv("PATH"))
os.Setenv("PATH", newPath)
// Otherwise let's look for mysqld in the PATH env var.
// Ensure that /usr/sbin is included, as it might not be by default
// and this is often the default location used by mysqld system
// packages (apt, dnf, etc).
once.Do(func() {
newPath := fmt.Sprintf("/usr/sbin:%s", os.Getenv("PATH"))
os.Setenv("PATH", newPath)
})

Check warning on line 86 in go/vt/env/env.go

View check run for this annotation

Codecov / codecov/patch

go/vt/env/env.go#L83-L86

Added lines #L83 - L86 were not covered by tests

path, err := exec.LookPath("mysqld")
if err != nil {
return "", errors.New("VT_MYSQL_ROOT is not set and no mysqld could be found in your PATH")
Expand Down
28 changes: 22 additions & 6 deletions go/vt/mysqlctl/mysqld.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,14 @@ import (
"vitess.io/vitess/go/vt/proto/vtrpc"
)

var (
// The string we expect before the MySQL version number
// in strings containing MySQL version information.
const versionStringPrefix = "Ver "

// How many bytes from MySQL error log to sample for error messages
const maxLogFileSampleSize = 4096

var (
// DisableActiveReparents is a flag to disable active
// reparents for safety reasons. It is used in three places:
// 1. in this file to skip registering the commands.
Expand All @@ -87,15 +93,15 @@ var (

replicationConnectRetry = 10 * time.Second

versionRegex = regexp.MustCompile(`Ver ([0-9]+)\.([0-9]+)\.([0-9]+)`)
versionRegex = regexp.MustCompile(fmt.Sprintf(`%s([0-9]+)\.([0-9]+)\.([0-9]+)`, versionStringPrefix))
// The SQL query that will return a version string directly from
// a MySQL server that will comply with the versionRegex.
versionSQLQuery = fmt.Sprintf("select concat('%s', @@global.version, ' ', @@global.version_comment) as version", versionStringPrefix)

binlogEntryCommittedTimestampRegex = regexp.MustCompile("original_committed_timestamp=([0-9]+)")
binlogEntryTimestampGTIDRegexp = regexp.MustCompile(`^#(.+) server id.*\bGTID\b`)
)

// How many bytes from MySQL error log to sample for error messages
const maxLogFileSampleSize = 4096

// Mysqld is the object that represents a mysqld daemon running on this server.
type Mysqld struct {
dbcfgs *dbconfigs.DBConfigs
Expand Down Expand Up @@ -1186,7 +1192,16 @@ func buildLdPaths() ([]string, error) {

// GetVersionString is part of the MysqlExecutor interface.
func (mysqld *Mysqld) GetVersionString(ctx context.Context) (string, error) {
// Execute as remote action on mysqlctld to ensure we get the actual running MySQL version.
// Try to query the mysqld instance directly.
// This query produces output that is compatible with what we expect from
// mysqld --version. For example: Ver 8.0.35 MySQL Community Server - GPL
qr, err := mysqld.FetchSuperQuery(ctx, versionSQLQuery)
if err == nil && len(qr.Rows) == 1 {
return qr.Rows[0][0].ToString(), nil

}

Check warning on line 1202 in go/vt/mysqlctl/mysqld.go

View check run for this annotation

Codecov / codecov/patch

go/vt/mysqlctl/mysqld.go#L1195-L1202

Added lines #L1195 - L1202 were not covered by tests
// Execute as remote action on mysqlctld to use the actual running MySQL
// version.
if socketFile != "" {
client, err := mysqlctlclient.New("unix", socketFile)
if err != nil {
Expand All @@ -1195,6 +1210,7 @@ func (mysqld *Mysqld) GetVersionString(ctx context.Context) (string, error) {
defer client.Close()
return client.VersionString(ctx)
}
// Fall back to the sys exec method using mysqld --version.
return GetVersionString()
}

Expand Down

0 comments on commit 5e45865

Please sign in to comment.