vitess-gh/go/vt/mysqlctl/mycnf_gen.go

135 строки
4.4 KiB
Go

// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Generate my.cnf files from templates.
package mysqlctl
import (
"bytes"
"fmt"
"io/ioutil"
"path"
"text/template"
"github.com/youtube/vitess/go/vt/env"
)
// This files handles the creation of Mycnf objects for the default 'vt'
// file structure. These path are used by the mysqlctl commands.
//
// The default 'vt' file structure is as follows:
// - the root is specified by the environment variable VTDATAROOT,
// and defaults to /vt
// - each tablet with uid NNNNNNNNNN is located in <root>/vt_NNNNNNNNNN
// - in that tablet directory, there is a my.cnf file for the mysql instance,
// and 'data', 'innodb', 'relay-logs', 'bin-logs' directories.
// - these sub-directories might be symlinks to other places,
// see comment for createTopDir, to allow some data types to be on
// different disk partitions.
const (
dataDir = "data"
innodbDir = "innodb"
relayLogDir = "relay-logs"
binLogDir = "bin-logs"
innodbDataSubdir = "innodb/data"
innodbLogSubdir = "innodb/logs"
snapshotDir = "snapshot"
)
// NewMycnf fills the Mycnf structure with vt root paths and derived values.
// This is used to fill out the cnfTemplate values and generate my.cnf.
// uid is a unique id for a particular tablet - it must be unique within the
// tabletservers deployed within a keyspace, lest there be collisions on disk.
// mysqldPort needs to be unique per instance per machine.
func NewMycnf(uid uint32, mysqlPort int32) *Mycnf {
cnf := new(Mycnf)
cnf.path = mycnfFile(uid)
tabletDir := TabletDir(uid)
cnf.ServerID = uid
cnf.MysqlPort = mysqlPort
cnf.DataDir = path.Join(tabletDir, dataDir)
cnf.InnodbDataHomeDir = path.Join(tabletDir, innodbDataSubdir)
cnf.InnodbLogGroupHomeDir = path.Join(tabletDir, innodbLogSubdir)
cnf.SocketFile = path.Join(tabletDir, "mysql.sock")
cnf.ErrorLogPath = path.Join(tabletDir, "error.log")
cnf.SlowLogPath = path.Join(tabletDir, "slow-query.log")
cnf.RelayLogPath = path.Join(tabletDir, relayLogDir,
fmt.Sprintf("vt-%010d-relay-bin", cnf.ServerID))
cnf.RelayLogIndexPath = cnf.RelayLogPath + ".index"
cnf.RelayLogInfoPath = path.Join(tabletDir, relayLogDir, "relay-log.info")
cnf.BinLogPath = path.Join(tabletDir, binLogDir,
fmt.Sprintf("vt-%010d-bin", cnf.ServerID))
cnf.MasterInfoFile = path.Join(tabletDir, "master.info")
cnf.PidFile = path.Join(tabletDir, "mysql.pid")
cnf.TmpDir = path.Join(tabletDir, "tmp")
cnf.SlaveLoadTmpDir = cnf.TmpDir
return cnf
}
// TabletDir returns the default directory for a tablet
func TabletDir(uid uint32) string {
return fmt.Sprintf("%s/vt_%010d", env.VtDataRoot(), uid)
}
// SnapshotDir returns the default directory for a tablet's snapshots
func SnapshotDir(uid uint32) string {
return fmt.Sprintf("%s/%s/vt_%010d", env.VtDataRoot(), snapshotDir, uid)
}
// mycnfFile returns the default location of the my.cnf file.
func mycnfFile(uid uint32) string {
return path.Join(TabletDir(uid), "my.cnf")
}
// TopLevelDirs returns the list of directories in the toplevel tablet directory
// that might be located in a different place.
func TopLevelDirs() []string {
return []string{dataDir, innodbDir, relayLogDir, binLogDir}
}
// directoryList returns the list of directories to create in an empty
// mysql instance.
func (cnf *Mycnf) directoryList() []string {
return []string{
cnf.DataDir,
cnf.InnodbDataHomeDir,
cnf.InnodbLogGroupHomeDir,
cnf.TmpDir,
path.Join(TabletDir(cnf.ServerID), relayLogDir),
path.Join(TabletDir(cnf.ServerID), binLogDir),
}
}
// makeMycnf will join cnf files cnfPaths and substitute in the right values.
func (cnf *Mycnf) makeMycnf(cnfFiles []string) (string, error) {
myTemplateSource := new(bytes.Buffer)
myTemplateSource.WriteString("[mysqld]\n")
for _, path := range cnfFiles {
data, dataErr := ioutil.ReadFile(path)
if dataErr != nil {
return "", dataErr
}
myTemplateSource.WriteString("## " + path + "\n")
myTemplateSource.Write(data)
}
return cnf.fillMycnfTemplate(myTemplateSource.String())
}
// fillMycnfTemplate will fill in the passed in template with the values
// from Mycnf
func (cnf *Mycnf) fillMycnfTemplate(tmplSrc string) (string, error) {
myTemplate, err := template.New("").Parse(tmplSrc)
if err != nil {
return "", err
}
mycnfData := new(bytes.Buffer)
err = myTemplate.Execute(mycnfData, cnf)
if err != nil {
return "", err
}
return mycnfData.String(), nil
}