From 4596f9c2c2d9a72b9538829c6092b547f8df7e47 Mon Sep 17 00:00:00 2001 From: ssongliu <73214554+ssongliu@users.noreply.github.com> Date: Tue, 23 Apr 2024 17:59:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=95=B0=E6=8D=AE=E5=BA=93=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20Mariadb=2011.x=20(#4665)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ssonglius11 --- backend/app/service/database_mysql.go | 17 +++++++++-------- backend/utils/mysql/client.go | 5 +++-- backend/utils/mysql/client/info.go | 1 + backend/utils/mysql/client/local.go | 15 ++++++++++----- backend/utils/mysql/client/remote.go | 19 ++++++++++++------- .../database/mysql/remote/operate/index.vue | 5 ++++- 6 files changed, 39 insertions(+), 23 deletions(-) diff --git a/backend/app/service/database_mysql.go b/backend/app/service/database_mysql.go index 33aa6a049..0df08b88d 100644 --- a/backend/app/service/database_mysql.go +++ b/backend/app/service/database_mysql.go @@ -456,7 +456,7 @@ func (u *MysqlService) LoadRemoteAccess(req dto.OperationWithNameAndType) (bool, if err != nil { return false, err } - hosts, err := executeSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';") + hosts, err := executeSqlForRows(app.ContainerName, app.Key, app.Password, "select host from mysql.user where user='root';") if err != nil { return false, err } @@ -474,7 +474,7 @@ func (u *MysqlService) LoadVariables(req dto.OperationWithNameAndType) (*dto.Mys if err != nil { return nil, err } - variableMap, err := executeSqlForMaps(app.ContainerName, app.Password, "show global variables;") + variableMap, err := executeSqlForMaps(app.ContainerName, app.Key, app.Password, "show global variables;") if err != nil { return nil, err } @@ -493,7 +493,7 @@ func (u *MysqlService) LoadStatus(req dto.OperationWithNameAndType) (*dto.MysqlS return nil, err } - statusMap, err := executeSqlForMaps(app.ContainerName, app.Password, "show global status;") + statusMap, err := executeSqlForMaps(app.ContainerName, app.Key, app.Password, "show global status;") if err != nil { return nil, err } @@ -517,7 +517,7 @@ func (u *MysqlService) LoadStatus(req dto.OperationWithNameAndType) (*dto.MysqlS info.File = "OFF" info.Position = "OFF" - rows, err := executeSqlForRows(app.ContainerName, app.Password, "show master status;") + rows, err := executeSqlForRows(app.ContainerName, app.Key, app.Password, "show master status;") if err != nil { return nil, err } @@ -532,8 +532,8 @@ func (u *MysqlService) LoadStatus(req dto.OperationWithNameAndType) (*dto.MysqlS return &info, nil } -func executeSqlForMaps(containerName, password, command string) (map[string]string, error) { - cmd := exec.Command("docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command) +func executeSqlForMaps(containerName, dbType, password, command string) (map[string]string, error) { + cmd := exec.Command("docker", "exec", containerName, dbType, "-uroot", "-p"+password, "-e", command) stdout, err := cmd.CombinedOutput() stdStr := strings.ReplaceAll(string(stdout), "mysql: [Warning] Using a password on the command line interface can be insecure.\n", "") if err != nil || strings.HasPrefix(string(stdStr), "ERROR ") { @@ -551,8 +551,8 @@ func executeSqlForMaps(containerName, password, command string) (map[string]stri return rowMap, nil } -func executeSqlForRows(containerName, password, command string) ([]string, error) { - cmd := exec.Command("docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command) +func executeSqlForRows(containerName, dbType, password, command string) ([]string, error) { + cmd := exec.Command("docker", "exec", containerName, dbType, "-uroot", "-p"+password, "-e", command) stdout, err := cmd.CombinedOutput() stdStr := strings.ReplaceAll(string(stdout), "mysql: [Warning] Using a password on the command line interface can be insecure.\n", "") if err != nil || strings.HasPrefix(string(stdStr), "ERROR ") { @@ -614,6 +614,7 @@ func LoadMysqlClientByFrom(database string) (mysql.MysqlClient, string, error) { if err != nil { return nil, "", err } + dbInfo.Type = databaseItem.Type dbInfo.From = databaseItem.From dbInfo.Database = database if dbInfo.From != "local" { diff --git a/backend/utils/mysql/client.go b/backend/utils/mysql/client.go index b6f39d945..d61cb7783 100644 --- a/backend/utils/mysql/client.go +++ b/backend/utils/mysql/client.go @@ -30,8 +30,8 @@ type MysqlClient interface { func NewMysqlClient(conn client.DBInfo) (MysqlClient, error) { if conn.From == "local" { - connArgs := []string{"exec", conn.Address, "mysql", "-u" + conn.Username, "-p" + conn.Password, "-e"} - return client.NewLocal(connArgs, conn.Address, conn.Password, conn.Database), nil + connArgs := []string{"exec", conn.Address, conn.Type, "-u" + conn.Username, "-p" + conn.Password, "-e"} + return client.NewLocal(connArgs, conn.Type, conn.Address, conn.Password, conn.Database), nil } if strings.Contains(conn.Address, ":") { @@ -59,6 +59,7 @@ func NewMysqlClient(conn client.DBInfo) (MysqlClient, error) { } return client.NewRemote(client.Remote{ + Type: conn.Type, Client: db, Database: conn.Database, User: conn.Username, diff --git a/backend/utils/mysql/client/info.go b/backend/utils/mysql/client/info.go index 0dbc20315..3c6c4c25b 100644 --- a/backend/utils/mysql/client/info.go +++ b/backend/utils/mysql/client/info.go @@ -10,6 +10,7 @@ import ( ) type DBInfo struct { + Type string `json:"type"` From string `json:"from"` Database string `json:"database"` Address string `json:"address"` diff --git a/backend/utils/mysql/client/local.go b/backend/utils/mysql/client/local.go index a5cb3f837..6d6c8fcdb 100644 --- a/backend/utils/mysql/client/local.go +++ b/backend/utils/mysql/client/local.go @@ -18,14 +18,15 @@ import ( ) type Local struct { + Type string PrefixCommand []string Database string Password string ContainerName string } -func NewLocal(command []string, containerName, password, database string) *Local { - return &Local{PrefixCommand: command, ContainerName: containerName, Password: password, Database: database} +func NewLocal(command []string, dbType, containerName, password, database string) *Local { + return &Local{Type: dbType, PrefixCommand: command, ContainerName: containerName, Password: password, Database: database} } func (r *Local) Create(info CreateInfo) error { @@ -223,8 +224,12 @@ func (r *Local) Backup(info BackupInfo) error { } } outfile, _ := os.OpenFile(path.Join(info.TargetDir, info.FileName), os.O_RDWR|os.O_CREATE, 0755) - global.LOG.Infof("start to mysqldump | gzip > %s.gzip", info.TargetDir+"/"+info.FileName) - cmd := exec.Command("docker", "exec", r.ContainerName, "mysqldump", "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name) + dumpCmd := "mysqldump" + if r.Type == constant.AppMariaDB { + dumpCmd = "mariadb-dump" + } + global.LOG.Infof("start to %s | gzip > %s.gzip", dumpCmd, info.TargetDir+"/"+info.FileName) + cmd := exec.Command("docker", "exec", r.ContainerName, dumpCmd, "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name) gzipCmd := exec.Command("gzip", "-cf") gzipCmd.Stdin, _ = cmd.StdoutPipe() gzipCmd.Stdout = outfile @@ -237,7 +242,7 @@ func (r *Local) Backup(info BackupInfo) error { func (r *Local) Recover(info RecoverInfo) error { fi, _ := os.Open(info.SourceFile) defer fi.Close() - cmd := exec.Command("docker", "exec", "-i", r.ContainerName, "mysql", "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name) + cmd := exec.Command("docker", "exec", "-i", r.ContainerName, r.Type, "-uroot", "-p"+r.Password, "--default-character-set="+info.Format, info.Name) if strings.HasSuffix(info.SourceFile, ".gz") { gzipFile, err := os.Open(info.SourceFile) if err != nil { diff --git a/backend/utils/mysql/client/remote.go b/backend/utils/mysql/client/remote.go index 336d778e8..5d934cb6d 100644 --- a/backend/utils/mysql/client/remote.go +++ b/backend/utils/mysql/client/remote.go @@ -21,6 +21,7 @@ import ( ) type Remote struct { + Type string Client *sql.DB Database string User string @@ -234,13 +235,17 @@ func (r *Remote) Backup(info BackupInfo) error { } } outfile, _ := os.OpenFile(path.Join(info.TargetDir, info.FileName), os.O_RDWR|os.O_CREATE, 0755) - global.LOG.Infof("start to mysqldump | gzip > %s.gzip", info.TargetDir+"/"+info.FileName) + dumpCmd := "mysqldump" + if r.Type == constant.AppMariaDB { + dumpCmd = "mariadb-dump" + } + global.LOG.Infof("start to %s | gzip > %s.gzip", dumpCmd, info.TargetDir+"/"+info.FileName) image, err := loadImage(info.Type, info.Version) if err != nil { return err } - backupCmd := fmt.Sprintf("docker run --rm --net=host -i %s /bin/bash -c 'mysqldump -h %s -P %d -u%s -p%s %s --default-character-set=%s %s'", - image, r.Address, r.Port, r.User, r.Password, sslSkip(info.Version), info.Format, info.Name) + backupCmd := fmt.Sprintf("docker run --rm --net=host -i %s /bin/bash -c '%s -h %s -P %d -u%s -p%s %s --default-character-set=%s %s'", + image, dumpCmd, r.Address, r.Port, r.User, r.Password, sslSkip(info.Version, r.Type), info.Format, info.Name) global.LOG.Debug(backupCmd) cmd := exec.Command("bash", "-c", backupCmd) @@ -263,8 +268,8 @@ func (r *Remote) Recover(info RecoverInfo) error { return err } - recoverCmd := fmt.Sprintf("docker run --rm --net=host -i %s /bin/bash -c 'mysql -h %s -P %d -u%s -p%s %s --default-character-set=%s %s'", - image, r.Address, r.Port, r.User, r.Password, sslSkip(info.Version), info.Format, info.Name) + recoverCmd := fmt.Sprintf("docker run --rm --net=host -i %s /bin/bash -c '%s -h %s -P %d -u%s -p%s %s --default-character-set=%s %s'", + image, r.Type, r.Address, r.Port, r.User, r.Password, sslSkip(info.Version, r.Type), info.Format, info.Name) global.LOG.Debug(recoverCmd) cmd := exec.Command("bash", "-c", recoverCmd) @@ -436,8 +441,8 @@ func loadImage(dbType, version string) (string, error) { return "mysql:" + version, nil } -func sslSkip(version string) string { - if strings.HasPrefix(version, "5.6") || strings.HasPrefix(version, "5.7") { +func sslSkip(version, dbType string) string { + if dbType == constant.AppMariaDB || strings.HasPrefix(version, "5.6") || strings.HasPrefix(version, "5.7") { return "--skip-ssl" } return "--ssl-mode=DISABLED" diff --git a/frontend/src/views/database/mysql/remote/operate/index.vue b/frontend/src/views/database/mysql/remote/operate/index.vue index 763165500..812cc6a53 100644 --- a/frontend/src/views/database/mysql/remote/operate/index.vue +++ b/frontend/src/views/database/mysql/remote/operate/index.vue @@ -32,7 +32,10 @@ - +
+ + +