Skip to content

Commit 1e742c9

Browse files
committed
Use go-sql-driver for connecting to mysql
1 parent b0c6bb0 commit 1e742c9

34 files changed

+8481
-49
lines changed

Gopkg.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/mysql-helper/apphelper/apphelper.go

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,41 +44,48 @@ func RunRunCommand(stopCh <-chan struct{}) error {
4444
return fmt.Errorf("mysql is not ready, err: %s", err)
4545
}
4646

47-
// deactivate read only
48-
if _, err := tb.RunQuery("SET GLOBAL READ_ONLY = 0"); err != nil {
47+
// deactivate super read only
48+
if err := tb.RunQuery("SET GLOBAL READ_ONLY = 1; SET GLOBAL SUPER_READ_ONLY = 0;"); err != nil {
4949
return fmt.Errorf("failed to configure master node, err: %s", err)
5050
}
51+
glog.V(2).Info("Temporary disabled SUPER_READ_ONLY...")
5152

5253
// update orchestrator user and password if orchestrator is configured
5354
if len(tb.GetOrcUser()) > 0 {
54-
if err := tb.UpdateOrcUserPass(); err != nil {
55+
if err := configureOrchestratorUser(); err != nil {
5556
return err
5657
}
5758
}
59+
glog.V(2).Info("Configured orchestrator user...")
5860

5961
// update replication user and password
6062
if err := configureReplicationUser(); err != nil {
6163
return err
6264
}
65+
glog.V(2).Info("Configured replication user...")
6366

6467
// update metrics exporter user and password
6568
if err := configureExporterUser(); err != nil {
6669
return err
6770
}
71+
glog.V(2).Info("Configured metrics exporter user...")
6872

6973
// if it's slave set replication source (master host)
7074
if err := configTopology(); err != nil {
7175
return err
7276
}
77+
glog.V(2).Info("Configured topology...")
7378

7479
if err := markConfigurationDone(); err != nil {
7580
return err
7681
}
82+
glog.V(2).Info("Flag setup as complete...")
7783

7884
// if it's master node then make it writtable else make it read only
7985
if err := configReadOnly(); err != nil {
8086
return err
8187
}
88+
glog.V(2).Info("Configured read only flag...")
8289

8390
// start http server for readiness probe
8491
// here the server is ready to accept traffic
@@ -88,12 +95,27 @@ func RunRunCommand(stopCh <-chan struct{}) error {
8895
return startServeBackups()
8996
}
9097

98+
func configureOrchestratorUser() error {
99+
query := fmt.Sprintf(`
100+
SET @@SESSION.SQL_LOG_BIN = 0;
101+
GRANT SUPER, PROCESS, REPLICATION SLAVE, REPLICATION CLIENT, RELOAD ON *.* TO '%[1]s'@'%%' IDENTIFIED BY '%[2]s';
102+
GRANT SELECT ON meta.* TO '%[1]s'@'%%';
103+
GRANT SELECT ON mysql.slave_master_info TO '%[1]s'@'%%';
104+
`, tb.GetOrcUser(), tb.GetOrcPass())
105+
106+
if err := tb.RunQuery(query); err != nil {
107+
return fmt.Errorf("failed to configure orchestrator (user/pass/access), err: %s", err)
108+
}
109+
110+
return nil
111+
}
112+
91113
func configureReplicationUser() error {
92114
query := fmt.Sprintf(`
93115
SET @@SESSION.SQL_LOG_BIN = 0;
94116
GRANT SELECT, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO '%s'@'%%' IDENTIFIED BY '%s';
95117
`, tb.GetReplUser(), tb.GetReplPass())
96-
if _, err := tb.RunQuery(query); err != nil {
118+
if err := tb.RunQuery(query); err != nil {
97119
return fmt.Errorf("failed to configure replication user: %s", err)
98120
}
99121

@@ -105,7 +127,7 @@ func configureExporterUser() error {
105127
SET @@SESSION.SQL_LOG_BIN = 0;
106128
GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO '%s'@'%%' IDENTIFIED BY '%s' WITH MAX_USER_CONNECTIONS 3;
107129
`, tb.GetExporterUser(), tb.GetExporterPass())
108-
if _, err := tb.RunQuery(query); err != nil {
130+
if err := tb.RunQuery(query); err != nil {
109131
return fmt.Errorf("failed to metrics exporter user: %s", err)
110132
}
111133

@@ -158,11 +180,11 @@ func waitForMysqlReady() error {
158180

159181
for i := 0; i < timeOut; i++ {
160182
time.Sleep(1 * time.Second)
161-
if _, err := tb.RunQuery("SELECT 1"); err == nil {
183+
if err := tb.RunQuery("SELECT 1"); err == nil {
162184
break
163185
}
164186
}
165-
if _, err := tb.RunQuery("SELECT 1"); err != nil {
187+
if err := tb.RunQuery("SELECT 1"); err != nil {
166188
glog.V(2).Info("Mysql is not ready.")
167189
return err
168190
}
@@ -179,7 +201,7 @@ func configReadOnly() error {
179201
} else {
180202
query = "SET GLOBAL SUPER_READ_ONLY = 1"
181203
}
182-
if _, err := tb.RunQuery(query); err != nil {
204+
if err := tb.RunQuery(query); err != nil {
183205
return fmt.Errorf("failed to set read_only config, err: %s", err)
184206
}
185207
return nil
@@ -189,21 +211,22 @@ func configTopology() error {
189211
if tb.NodeRole() == "slave" {
190212
// slave node
191213
query := fmt.Sprintf(`
214+
STOP SLAVE;
192215
CHANGE MASTER TO MASTER_AUTO_POSITION=1,
193216
MASTER_HOST='%s',
194217
MASTER_USER='%s',
195218
MASTER_PASSWORD='%s',
196219
MASTER_CONNECT_RETRY=%d;
197220
`, tb.GetMasterHost(), tb.GetReplUser(), tb.GetReplPass(), connRetry)
198221

199-
if _, err := tb.RunQuery(query); err != nil {
222+
if err := tb.RunQuery(query); err != nil {
200223
return fmt.Errorf("failed to configure slave node, err: %s", err)
201224
}
202225

203226
query = `
204227
START SLAVE;
205228
`
206-
if _, err := tb.RunQuery(query); err != nil {
229+
if err := tb.RunQuery(query); err != nil {
207230
glog.Warning("Failed to start slave simple, err: %s, try second method.")
208231
// TODO: https://bugs.mysql.com/bug.php?id=83713
209232
query2 := `
@@ -213,7 +236,7 @@ func configTopology() error {
213236
reset slave;
214237
start slave;
215238
`
216-
if _, err := tb.RunQuery(query2); err != nil {
239+
if err := tb.RunQuery(query2); err != nil {
217240
return fmt.Errorf("failed to start slave node, err: %s", err)
218241
}
219242
}
@@ -237,8 +260,8 @@ func markConfigurationDone() error {
237260
COMMIT;
238261
`, tb.ToolsDbName, tb.ToolsInitTableName, tb.GetHostname())
239262

240-
if _, err := tb.RunQuery(query); err != nil {
241-
return fmt.Errorf("to mark configuration done, err: %s", err)
263+
if err := tb.RunQuery(query); err != nil {
264+
return fmt.Errorf("failed to mark configuration done, err: %s", err)
242265
}
243266

244267
return nil

cmd/mysql-helper/util/util.go

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ package util
1818

1919
import (
2020
"bufio"
21-
"bytes"
21+
"database/sql"
2222
"fmt"
2323
"io"
2424
"os"
25-
"os/exec"
25+
"path"
2626
"strconv"
2727
"strings"
2828

29+
"github.com/go-ini/ini"
30+
_ "github.com/go-sql-driver/mysql"
2931
"github.com/golang/glog"
3032

3133
api "github.com/presslabs/mysql-operator/pkg/apis/mysql/v1alpha1"
@@ -215,47 +217,68 @@ func readFileContent(fileName string) string {
215217
return scanner.Text()
216218
}
217219

218-
func UpdateOrcUserPass() error {
219-
glog.V(2).Info("Creating orchestrator user, password and privileges...")
220-
query := fmt.Sprintf(`
221-
SET @@SESSION.SQL_LOG_BIN = 0;
222-
GRANT SUPER, PROCESS, REPLICATION SLAVE, REPLICATION CLIENT, RELOAD ON *.* TO '%[1]s'@'%%' IDENTIFIED BY '%[2]s';
223-
GRANT SELECT ON meta.* TO '%[1]s'@'%%';
224-
GRANT SELECT ON mysql.slave_master_info TO '%[1]s'@'%%';
225-
`, GetOrcUser(), GetOrcPass())
226-
227-
if _, err := RunQuery(query); err != nil {
228-
return fmt.Errorf("failed to configure orchestrator (user/pass/access), err: %s", err)
220+
func GetMySQLConnectionString() (dsn string, err error) {
221+
cnfPath := path.Join(ConfigDir, "client.cnf")
222+
cfg, err := ini.Load(cnfPath)
223+
if err != nil {
224+
return "", fmt.Errorf("Could not open %s: %s", cnfPath, err)
229225
}
230-
glog.V(2).Info("Orchestrator user configured!")
231-
232-
return nil
226+
client := cfg.Section("client")
227+
host := client.Key("host").String()
228+
user := client.Key("user").String()
229+
passowrd := client.Key("password").String()
230+
port, err := client.Key("port").Int()
231+
if err != nil {
232+
return "", fmt.Errorf("Invalid port in %s: %s", cnfPath, err)
233+
}
234+
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/?timeout=5s&multiStatements=true", user, passowrd, host, port)
235+
return
233236
}
234237

235-
func RunQuery(q string) (string, error) {
236-
glog.V(3).Infof("QUERY: %s", q)
237-
238-
mysql := exec.Command("mysql",
239-
fmt.Sprintf("--defaults-file=%s/%s", ConfigDir, "client.cnf"),
240-
)
238+
func RunQuery(q string) (err error) {
239+
dsn, err := GetMySQLConnectionString()
240+
if err != nil {
241+
glog.Warningf("Could not get mysql connection dsn: %s", err)
242+
return
243+
}
241244

242-
// write query through pipe to mysql
243-
rq := strings.NewReader(q)
244-
mysql.Stdin = rq
245-
var bufOUT, bufERR bytes.Buffer
246-
mysql.Stdout = &bufOUT
247-
mysql.Stderr = &bufERR
245+
db, err := sql.Open("mysql", dsn)
246+
if err != nil {
247+
glog.Warningf("Could not open mysql connection: %s", err)
248+
return
249+
}
248250

249-
if err := mysql.Run(); err != nil {
250-
glog.Errorf("Failed to run query, err: %s", err)
251-
glog.V(2).Infof("Mysql STDOUT: %s, STDERR: %s", bufOUT.String(), bufERR.String())
252-
return "", err
251+
if _, err := db.Query(q); err != nil {
252+
glog.V(2).Infof("QUERY: %s", q)
253+
glog.Warningf("Could not query mysql: %s", err)
254+
return err
253255
}
254256

255-
glog.V(2).Infof("Mysql STDOUT: %s, STDERR: %s", bufOUT.String(), bufERR.String())
256-
glog.V(3).Infof("Mysql output for query %s is: %s", q, bufOUT.String())
257+
return
258+
259+
// glog.V(3).Infof("QUERY: %s", q)
260+
261+
// mysql := exec.Command("mysql",
262+
// fmt.Sprintf("--defaults-file=%s/%s", ConfigDir, "client.cnf"),
263+
// )
264+
265+
// // write query through pipe to mysql
266+
// rq := strings.NewReader(q)
267+
// mysql.Stdin = rq
268+
// var bufOUT, bufERR bytes.Buffer
269+
// mysql.Stdout = &bufOUT
270+
// mysql.Stderr = &bufERR
271+
272+
// if err := mysql.Run(); err != nil {
273+
// glog.Errorf("Failed to run query, err: %s", err)
274+
// glog.V(2).Infof("Mysql STDOUT: %s, STDERR: %s", bufOUT.String(), bufERR.String())
275+
// return "", err
276+
// }
277+
278+
// glog.V(2).Infof("Mysql STDOUT: %s, STDERR: %s", bufOUT.String(), bufERR.String())
279+
// glog.V(3).Infof("Mysql output for query %s is: %s", q, bufOUT.String())
257280

258-
return bufOUT.String(), nil
281+
// return bufOUT.String(), nil
259282
}
260283

261284
func getOrcUri() string {

vendor/github.com/go-sql-driver/mysql/.github/ISSUE_TEMPLATE.md

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/go-sql-driver/mysql/.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/go-sql-driver/mysql/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/go-sql-driver/mysql/.travis.yml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)