-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
mycnf.go
225 lines (188 loc) · 6.19 KB
/
mycnf.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
Copyright 2019 The Vitess Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Generate my.cnf files from templates.
*/
package mysqlctl
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"path"
"strconv"
)
// Mycnf is a memory structure that contains a bunch of interesting
// parameters to start mysqld. It can be used to generate standard
// my.cnf files from a server id and mysql port. It can also be
// populated from an existing my.cnf, or by command line parameters.
type Mycnf struct {
// ServerID is the unique id for this server.
// Used to create a bunch of named directories.
ServerID uint32
// MysqlPort is the port for the MySQL server running on this machine.
// It is mainly used to communicate with topology server.
MysqlPort int32
// DataDir is where the table files are
// (used by vt software for Clone)
DataDir string
// InnodbDataHomeDir is the data directory for innodb.
// (used by vt software for Clone)
InnodbDataHomeDir string
// InnodbLogGroupHomeDir is the logs directory for innodb.
// (used by vt software for Clone)
InnodbLogGroupHomeDir string
// SecureFilePriv is the path for loading secure files
// (used by vt software for bulk loading into tablet instances)
SecureFilePriv string
// SocketFile is the path to the local mysql.sock file.
// (used by vt software to check server is running)
SocketFile string
// GeneralLogPath is the path to store general logs at,
// if general-log is enabled.
// (unused by vt software for now)
GeneralLogPath string
// ErrorLogPath is the path to store error logs at.
// (unused by vt software for now)
ErrorLogPath string
// SlowLogPath is the slow query log path
// (unused by vt software for now)
SlowLogPath string
// RelayLogPath is the path of the relay logs
// (unused by vt software for now)
RelayLogPath string
// RelayLogIndexPath is the file name for the relay log index
// (unused by vt software for now)
RelayLogIndexPath string
// RelayLogInfoPath is the file name for the relay log info file
// (unused by vt software for now)
RelayLogInfoPath string
// BinLogPath is the base path for binlogs
// (used by vt software for binlog streaming)
BinLogPath string
// MasterInfoFile is the master.info file location.
// Unused when vitess manages mysql config because we set
// master_info_repository = TABLE and
// relay_log_info_repository = TABLE
// However it is possible to use custom cnf files with vitess
// and to generate them using command-line flags, so we allow a way to set this property
MasterInfoFile string
// PidFile is the mysql.pid file location
// (used by vt software to check server is running)
PidFile string
// TmpDir is where to create temporary tables
// (unused by vt software for now)
TmpDir string
mycnfMap map[string]string
Path string // the actual path that represents this mycnf
}
// TabletDir returns the tablet directory.
func (cnf *Mycnf) TabletDir() string {
return path.Dir(cnf.DataDir)
}
func (cnf *Mycnf) lookup(key string) string {
key = normKey([]byte(key))
return cnf.mycnfMap[key]
}
func (cnf *Mycnf) lookupWithDefault(key, defaultVal string) (string, error) {
val := cnf.lookup(key)
if val == "" {
if defaultVal == "" {
return "", fmt.Errorf("value for key '%v' not set and no default value set", key)
}
return defaultVal, nil
}
return val, nil
}
func (cnf *Mycnf) lookupInt(key string) (int, error) {
val, err := cnf.lookupWithDefault(key, "")
if err != nil {
return 0, err
}
ival, err := strconv.Atoi(val)
if err != nil {
return 0, fmt.Errorf("failed to convert %s: %v", key, err)
}
return ival, nil
}
func normKey(bkey []byte) string {
// FIXME(msolomon) People are careless about hyphen vs underscore - we should normalize.
// But you have to normalize to hyphen, or mysqld_safe can fail.
return string(bytes.Replace(bytes.TrimSpace(bkey), []byte("_"), []byte("-"), -1))
}
// ReadMycnf will read an existing my.cnf from disk, and update the passed in Mycnf object
// with values from the my.cnf on disk.
func ReadMycnf(mycnf *Mycnf) (*Mycnf, error) {
f, err := os.Open(mycnf.Path)
if err != nil {
return nil, err
}
defer f.Close()
buf := bufio.NewReader(f)
if err != nil {
return nil, err
}
mycnf.mycnfMap = make(map[string]string)
var lval, rval string
var parts [][]byte
for {
line, _, err := buf.ReadLine()
if err == io.EOF {
break
}
line = bytes.TrimSpace(line)
parts = bytes.Split(line, []byte("="))
if len(parts) < 2 {
continue
}
lval = normKey(parts[0])
rval = string(bytes.TrimSpace(parts[1]))
mycnf.mycnfMap[lval] = rval
}
serverID, err := mycnf.lookupInt("server-id")
if err != nil {
return nil, err
}
mycnf.ServerID = uint32(serverID)
port, err := mycnf.lookupInt("port")
if err != nil {
return nil, err
}
mycnf.MysqlPort = int32(port)
mapping := map[string]*string{
"datadir": &mycnf.DataDir,
"innodb_data_home_dir": &mycnf.InnodbDataHomeDir,
"innodb_log_group_home_dir": &mycnf.InnodbLogGroupHomeDir,
"socket": &mycnf.SocketFile,
"general_log_file": &mycnf.GeneralLogPath,
"log-error": &mycnf.ErrorLogPath,
"slow-query-log-file": &mycnf.SlowLogPath,
"relay-log": &mycnf.RelayLogPath,
"relay-log-index": &mycnf.RelayLogIndexPath,
"relay-log-info-file": &mycnf.RelayLogInfoPath,
"log-bin": &mycnf.BinLogPath,
"master-info-file": &mycnf.MasterInfoFile,
"pid-file": &mycnf.PidFile,
"tmpdir": &mycnf.TmpDir,
"secure-file-priv": &mycnf.SecureFilePriv,
}
for key, member := range mapping {
val, err := mycnf.lookupWithDefault(key, *member)
if err != nil {
return nil, err
}
*member = val
}
return mycnf, nil
}