зеркало из https://github.com/github/vitess-gh.git
Start mysqld for mysql_upgrade with --skip-grant-tables and --skip-networking.
When mysqld is started on a database from an older version (the only use case when mysql_upgrade will do anything and is really necessary) it may fail to start due to mysql.* tables having old structure. --skip-grant-tables will ensure that mysqld doesn't try to read mysql.* tables before mysql_upgrade fixed their structure. Since anyone can connect to mysqld without password when it's started with --skip-grant-tables, we should also pass --skip-networking to it. To make passing those flags to mysqld possible I'm extending notion of mysqld_start hook to accept list of any arguments that should be passed to mysqld.
This commit is contained in:
Родитель
973f5e19a7
Коммит
88e607da13
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
log "github.com/golang/glog"
|
||||
"github.com/youtube/vitess/go/exit"
|
||||
"github.com/youtube/vitess/go/flagutil"
|
||||
"github.com/youtube/vitess/go/netutil"
|
||||
"github.com/youtube/vitess/go/vt/dbconfigs"
|
||||
"github.com/youtube/vitess/go/vt/logutil"
|
||||
|
@ -93,6 +94,8 @@ func shutdownCmd(subFlags *flag.FlagSet, args []string) error {
|
|||
|
||||
func startCmd(subFlags *flag.FlagSet, args []string) error {
|
||||
waitTime := subFlags.Duration("wait_time", 5*time.Minute, "how long to wait for startup")
|
||||
var mysqldArgs flagutil.StringListValue
|
||||
subFlags.Var(&mysqldArgs, "mysqld_args", "List of comma-separated flags to pass additionally to mysqld")
|
||||
subFlags.Parse(args)
|
||||
|
||||
// There ought to be an existing my.cnf, so use it to find mysqld.
|
||||
|
@ -104,7 +107,7 @@ func startCmd(subFlags *flag.FlagSet, args []string) error {
|
|||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), *waitTime)
|
||||
defer cancel()
|
||||
if err := mysqld.Start(ctx); err != nil {
|
||||
if err := mysqld.Start(ctx, mysqldArgs...); err != nil {
|
||||
return fmt.Errorf("failed start mysql: %v", err)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -654,8 +654,14 @@ func Restore(ctx context.Context, mysqld MysqlDaemon, dir string, restoreConcurr
|
|||
}
|
||||
|
||||
// mysqld needs to be running in order for mysql_upgrade to work.
|
||||
// If we've just restored from a backup from previous MySQL version then mysqld
|
||||
// may fail to start due to a different structure of mysql.* tables. The flag
|
||||
// --skip-grant-tables ensures that these tables are not read until mysql_upgrade
|
||||
// is executed. And since with --skip-grant-tables anyone can connect to MySQL
|
||||
// without password, we are passing --skip-networking to greatly reduce the set
|
||||
// of those who can connect.
|
||||
logger.Infof("Restore: starting mysqld for mysql_upgrade")
|
||||
err = mysqld.Start(ctx)
|
||||
err = mysqld.Start(ctx, "--skip-grant-tables", "--skip-networking")
|
||||
if err != nil {
|
||||
return replication.Position{}, err
|
||||
}
|
||||
|
|
|
@ -41,8 +41,10 @@ func factory(network, addr string, dialTimeout time.Duration) (mysqlctlclient.My
|
|||
}
|
||||
|
||||
// Start is part of the MysqlctlClient interface.
|
||||
func (c *client) Start(ctx context.Context) error {
|
||||
_, err := c.c.Start(ctx, &mysqlctlpb.StartRequest{})
|
||||
func (c *client) Start(ctx context.Context, mysqldArgs ...string) error {
|
||||
_, err := c.c.Start(ctx, &mysqlctlpb.StartRequest{
|
||||
MysqldArgs: mysqldArgs,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ type server struct {
|
|||
|
||||
// Start implements the server side of the MysqlctlClient interface.
|
||||
func (s *server) Start(ctx context.Context, request *mysqlctlpb.StartRequest) (*mysqlctlpb.StartResponse, error) {
|
||||
return &mysqlctlpb.StartResponse{}, s.mysqld.Start(ctx)
|
||||
return &mysqlctlpb.StartResponse{}, s.mysqld.Start(ctx, request.MysqldArgs...)
|
||||
}
|
||||
|
||||
// Shutdown implements the server side of the MysqlctlClient interface.
|
||||
|
|
|
@ -29,7 +29,7 @@ type MysqlDaemon interface {
|
|||
TabletDir() string
|
||||
|
||||
// methods related to mysql running or not
|
||||
Start(ctx context.Context) error
|
||||
Start(ctx context.Context, mysqldArgs ...string) error
|
||||
Shutdown(ctx context.Context, waitForMysqld bool) error
|
||||
RunMysqlUpgrade() error
|
||||
ReinitConfig(ctx context.Context) error
|
||||
|
@ -229,7 +229,7 @@ func (fmd *FakeMysqlDaemon) TabletDir() string {
|
|||
}
|
||||
|
||||
// Start is part of the MysqlDaemon interface
|
||||
func (fmd *FakeMysqlDaemon) Start(ctx context.Context) error {
|
||||
func (fmd *FakeMysqlDaemon) Start(ctx context.Context, mysqldArgs ...string) error {
|
||||
if fmd.Running {
|
||||
return fmt.Errorf("fake mysql daemon already running")
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ var connectionTimeout = flag.Duration("mysqlctl_client_connection_timeout", 30*t
|
|||
// MysqlctlClient defines the interface used to send remote mysqlctl commands
|
||||
type MysqlctlClient interface {
|
||||
// Start calls Mysqld.Start remotely.
|
||||
Start(ctx context.Context) error
|
||||
Start(ctx context.Context, mysqldArgs ...string) error
|
||||
|
||||
// Shutdown calls Mysqld.Shutdown remotely.
|
||||
Shutdown(ctx context.Context, waitForMysqld bool) error
|
||||
|
|
|
@ -169,7 +169,7 @@ func (mysqld *Mysqld) RunMysqlUpgrade() error {
|
|||
// Start will start the mysql daemon, either by running the 'mysqld_start'
|
||||
// hook, or by running mysqld_safe in the background.
|
||||
// If a mysqlctld address is provided in a flag, Start will run remotely.
|
||||
func (mysqld *Mysqld) Start(ctx context.Context) error {
|
||||
func (mysqld *Mysqld) Start(ctx context.Context, mysqldArgs ...string) error {
|
||||
// Execute as remote action on mysqlctld if requested.
|
||||
if *socketFile != "" {
|
||||
log.Infof("executing Mysqld.Start() remotely via mysqlctld server: %v", *socketFile)
|
||||
|
@ -178,14 +178,14 @@ func (mysqld *Mysqld) Start(ctx context.Context) error {
|
|||
return fmt.Errorf("can't dial mysqlctld: %v", err)
|
||||
}
|
||||
defer client.Close()
|
||||
return client.Start(ctx)
|
||||
return client.Start(ctx, mysqldArgs...)
|
||||
}
|
||||
|
||||
var name string
|
||||
ts := fmt.Sprintf("Mysqld.Start(%v)", time.Now().Unix())
|
||||
|
||||
// try the mysqld start hook, if any
|
||||
switch hr := hook.NewSimpleHook("mysqld_start").Execute(); hr.ExitStatus {
|
||||
switch hr := hook.NewHook("mysqld_start", mysqldArgs).Execute(); hr.ExitStatus {
|
||||
case hook.HOOK_SUCCESS:
|
||||
// hook exists and worked, we can keep going
|
||||
name = "mysqld_start hook"
|
||||
|
@ -202,6 +202,7 @@ func (mysqld *Mysqld) Start(ctx context.Context) error {
|
|||
}
|
||||
arg := []string{
|
||||
"--defaults-file=" + mysqld.config.path}
|
||||
arg = append(arg, mysqldArgs...)
|
||||
env := []string{os.ExpandEnv("LD_LIBRARY_PATH=$VT_MYSQL_ROOT/lib/mysql")}
|
||||
|
||||
cmd := exec.Command(name, arg...)
|
||||
|
|
|
@ -5,7 +5,9 @@ syntax = "proto3";
|
|||
|
||||
package mysqlctl;
|
||||
|
||||
message StartRequest{}
|
||||
message StartRequest{
|
||||
repeated string mysqld_args = 1;
|
||||
}
|
||||
|
||||
message StartResponse{}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче