vitess.io/vitess@v0.16.2/go/vt/vttest/mysqlctl.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package vttest
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"os"
    23  	"os/exec"
    24  	"path"
    25  	"strings"
    26  	"time"
    27  
    28  	"vitess.io/vitess/go/vt/log"
    29  
    30  	"vitess.io/vitess/go/mysql"
    31  	"vitess.io/vitess/go/vt/mysqlctl"
    32  )
    33  
    34  // MySQLManager is an interface to a mysqld process manager, capable
    35  // of starting/shutting down mysqld services and initializing them.
    36  type MySQLManager interface {
    37  	Setup() error
    38  	Start() error
    39  	TearDown() error
    40  	Auth() (string, string)
    41  	Address() (string, int)
    42  	UnixSocket() string
    43  	TabletDir() string
    44  	Params(dbname string) mysql.ConnParams
    45  }
    46  
    47  // Mysqlctl implements MySQLManager through Vitess' mysqlctld tool
    48  type Mysqlctl struct {
    49  	Binary    string
    50  	InitFile  string
    51  	Directory string
    52  	Port      int
    53  	MyCnf     []string
    54  	Env       []string
    55  	UID       uint32
    56  }
    57  
    58  // Setup spawns a new mysqld service and initializes it with the defaults.
    59  // The service is kept running in the background until TearDown() is called.
    60  func (ctl *Mysqlctl) Setup() error {
    61  	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    62  	defer cancel()
    63  
    64  	cmd := exec.CommandContext(ctx,
    65  		ctl.Binary,
    66  		"--alsologtostderr",
    67  		"--tablet_uid", fmt.Sprintf("%d", ctl.UID),
    68  		"--mysql_port", fmt.Sprintf("%d", ctl.Port),
    69  		"init", "--",
    70  		"--init_db_sql_file", ctl.InitFile,
    71  	)
    72  
    73  	myCnf := strings.Join(ctl.MyCnf, ":")
    74  
    75  	cmd.Env = append(cmd.Env, os.Environ()...)
    76  	cmd.Env = append(cmd.Env, ctl.Env...)
    77  	cmd.Env = append(cmd.Env, fmt.Sprintf("EXTRA_MY_CNF=%s", myCnf))
    78  
    79  	_, err := cmd.Output()
    80  	return err
    81  }
    82  
    83  // Start spawns a mysqld service for an existing data directory
    84  // The service is kept running in the background until TearDown() is called.
    85  func (ctl *Mysqlctl) Start() error {
    86  	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    87  	defer cancel()
    88  
    89  	cmd := exec.CommandContext(ctx,
    90  		ctl.Binary,
    91  		"--alsologtostderr",
    92  		"--tablet_uid", fmt.Sprintf("%d", ctl.UID),
    93  		"--mysql_port", fmt.Sprintf("%d", ctl.Port),
    94  		"start",
    95  	)
    96  
    97  	myCnf := strings.Join(ctl.MyCnf, ":")
    98  
    99  	cmd.Env = append(cmd.Env, os.Environ()...)
   100  	cmd.Env = append(cmd.Env, ctl.Env...)
   101  	cmd.Env = append(cmd.Env, fmt.Sprintf("EXTRA_MY_CNF=%s", myCnf))
   102  	log.Infof("Starting MySQL using: %+v", cmd.Env)
   103  	_, err := cmd.Output()
   104  	return err
   105  }
   106  
   107  // TearDown shutdowns the running mysqld service
   108  func (ctl *Mysqlctl) TearDown() error {
   109  	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
   110  	defer cancel()
   111  
   112  	cmd := exec.CommandContext(ctx,
   113  		ctl.Binary,
   114  		"--alsologtostderr",
   115  		"--tablet_uid", fmt.Sprintf("%d", ctl.UID),
   116  		"--mysql_port", fmt.Sprintf("%d", ctl.Port),
   117  		"shutdown",
   118  	)
   119  
   120  	cmd.Env = append(cmd.Env, os.Environ()...)
   121  	cmd.Env = append(cmd.Env, ctl.Env...)
   122  
   123  	_, err := cmd.Output()
   124  	return err
   125  }
   126  
   127  // Auth returns the username/password tuple required to log in to mysqld
   128  func (ctl *Mysqlctl) Auth() (string, string) {
   129  	return "vt_dba", ""
   130  }
   131  
   132  // Address returns the hostname/tcp port pair required to connect to mysqld
   133  func (ctl *Mysqlctl) Address() (string, int) {
   134  	return "", ctl.Port
   135  }
   136  
   137  // UnixSocket returns the path to the local Unix socket required to connect to mysqld
   138  func (ctl *Mysqlctl) UnixSocket() string {
   139  	return path.Join(ctl.TabletDir(), "mysql.sock")
   140  }
   141  
   142  // TabletDir returns the path where data for this Tablet would be stored
   143  func (ctl *Mysqlctl) TabletDir() string {
   144  	return mysqlctl.DefaultTabletDirAtRoot(ctl.Directory, ctl.UID)
   145  }
   146  
   147  // Params returns the mysql.ConnParams required to connect directly to mysqld
   148  // using Vitess' mysql client.
   149  func (ctl *Mysqlctl) Params(dbname string) mysql.ConnParams {
   150  	return mysql.ConnParams{
   151  		DbName:     dbname,
   152  		Uname:      "vt_dba",
   153  		UnixSocket: ctl.UnixSocket(),
   154  	}
   155  }