Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions go/base/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,33 @@ func StringContainsAll(s string, substrings ...string) bool {
return nonEmptyStringsFound
}

func ValidateConnection(db *gosql.DB, connectionConfig *mysql.ConnectionConfig, migrationContext *MigrationContext, name string) (string, error) {
versionQuery := `select @@global.version`
var port, extraPort int
var version string
if err := db.QueryRow(versionQuery).Scan(&version); err != nil {
return "", err
// ValidateConnection confirms the database connection matches the provided connection config. On success the
// function returns the server version as a string, otherwise an empty string and an error is returned.
func ValidateConnection(db *gosql.DB, connectionConfig *mysql.ConnectionConfig, migrationContext *MigrationContext, name string) (version string, err error) {
var port, extraPort gosql.NullInt64
// port may be NULL on AliyunRDS and GCP
query := `select @@global.version, @@global.port`
if err = db.QueryRow(query).Scan(&version, &port); err != nil {
return version, err
}

extraPortQuery := `select @@global.extra_port`
if err := db.QueryRow(extraPortQuery).Scan(&extraPort); err != nil { // nolint:staticcheck
// swallow this error. not all servers support extra_port
}
// swallow possible error. not all servers support extra_port
_ = db.QueryRow(extraPortQuery).Scan(&extraPort)

// AliyunRDS set users port to "NULL", replace it by gh-ost param
// GCP set users port to "NULL", replace it by gh-ost param
// Azure MySQL set users port to a different value by design, replace it by gh-ost para
// Azure MySQL set users port to a different value by design, replace it by gh-ost param
if migrationContext.AliyunRDS || migrationContext.GoogleCloudPlatform || migrationContext.AzureMySQL {
port = connectionConfig.Key.Port
} else {
portQuery := `select @@global.port`
if err := db.QueryRow(portQuery).Scan(&port); err != nil {
return "", err
}
port.Int64 = connectionConfig.Key.Port
port.Valid = connectionConfig.Key.Port > 0
}

if connectionConfig.Key.Port == port || (extraPort > 0 && connectionConfig.Key.Port == extraPort) {
migrationContext.Log.Infof("%s connection validated on %+v", name, connectionConfig.Key)
return version, nil
} else if extraPort == 0 {
return "", fmt.Errorf("Unexpected database port reported: %+v", port)
} else {
return "", fmt.Errorf("Unexpected database port reported: %+v / extra_port: %+v", port, extraPort)
if !port.Valid && !extraPort.Valid {
return version, fmt.Errorf("Unexpected database port reported: %+v", port.Int64)
} else if connectionConfig.Key.Port != port.Int64 && connectionConfig.Key.Port != extraPort.Int64 {
return version, fmt.Errorf("Unexpected database port reported: %+v / extra_port: %+v", port.Int64, extraPort.Int64)
}
migrationContext.Log.Infof("%s connection validated on %+v", name, connectionConfig.Key)
return version, err
}
2 changes: 1 addition & 1 deletion go/cmd/gh-ost/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func main() {
migrationContext := base.NewMigrationContext()
flag.StringVar(&migrationContext.InspectorConnectionConfig.Key.Hostname, "host", "127.0.0.1", "MySQL hostname (preferably a replica, not the master)")
flag.StringVar(&migrationContext.AssumeMasterHostname, "assume-master-host", "", "(optional) explicitly tell gh-ost the identity of the master. Format: some.host.com[:port] This is useful in master-master setups where you wish to pick an explicit master, or in a tungsten-replicator where gh-ost is unable to determine the master")
flag.IntVar(&migrationContext.InspectorConnectionConfig.Key.Port, "port", 3306, "MySQL port (preferably a replica, not the master)")
flag.Int64Var(&migrationContext.InspectorConnectionConfig.Key.Port, "port", 3306, "MySQL port (preferably a replica, not the master)")
flag.Float64Var(&migrationContext.InspectorConnectionConfig.Timeout, "mysql-timeout", 0.0, "Connect, read and write timeout for MySQL")
flag.StringVar(&migrationContext.CliUser, "user", "", "MySQL user")
flag.StringVar(&migrationContext.CliPassword, "password", "", "MySQL password")
Expand Down
6 changes: 3 additions & 3 deletions go/mysql/instance_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"strings"
)

const DefaultInstancePort = 3306
const DefaultInstancePort int64 = 3306

var (
ipv4HostPortRegexp = regexp.MustCompile("^([^:]+):([0-9]+)$")
Expand All @@ -28,7 +28,7 @@ var (
// InstanceKey is an instance indicator, identified by hostname and port
type InstanceKey struct {
Hostname string
Port int
Port int64
}

const detachHint = "//"
Expand All @@ -52,7 +52,7 @@ func NewRawInstanceKey(hostPort string) (*InstanceKey, error) {
instanceKey := &InstanceKey{Hostname: hostname, Port: DefaultInstancePort}
if port != "" {
var err error
if instanceKey.Port, err = strconv.Atoi(port); err != nil {
if instanceKey.Port, err = strconv.ParseInt(port, 10, 64); err != nil {
return instanceKey, fmt.Errorf("Invalid port: %s", port)
}
}
Expand Down
2 changes: 1 addition & 1 deletion go/mysql/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func GetMasterKeyFromSlaveStatus(connectionConfig *ConnectionConfig) (masterKey

masterKey = &InstanceKey{
Hostname: rowMap.GetString("Master_Host"),
Port: rowMap.GetInt("Master_Port"),
Port: rowMap.GetInt64("Master_Port"),
}
return nil
})
Expand Down