Skip to content

Commit

Permalink
fix(mysql): dbbackup处理mydumper中断不退出的问题 #9085
Browse files Browse the repository at this point in the history
  • Loading branch information
seanlook committed Jan 15, 2025
1 parent 9c7e992 commit 5a60b32
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 21 deletions.
4 changes: 2 additions & 2 deletions dbm-services/mysql/db-tools/mysql-dbbackup/cmd/subcmd_dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
)

func init() {
dumpCmd.Flags().String("backup-type", cst.BackupTypeAuto, "overwrite Public.BackupType")
dumpCmd.Flags().StringP("backup-type", "t", cst.BackupTypeAuto, "overwrite Public.BackupType")
_ = viper.BindPFlag("Public.BackupType", dumpCmd.Flags().Lookup("backup-type"))

dumpCmd.PersistentFlags().String("backup-id", "", "overwrite Public.BackupId")
Expand All @@ -50,7 +50,7 @@ func init() {
"backup root path to save, overwrite Public.BackupDir")
dumpCmd.PersistentFlags().String("cluster-domain", "",
"cluster domain to report, overwrite Public.ClusterAddress")
dumpCmd.PersistentFlags().String("data-schema-grant", "",
dumpCmd.PersistentFlags().StringP("data-schema-grant", "g", "",
"all|schema|data|grant, overwrite Public.DataSchemaGrant")
dumpCmd.PersistentFlags().Int("is-full-backup", 0,
"report backup-id as full backup. default 0 means auto judge by backup-type,data-schema-grant")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ func init() {
dumpLogicalCmd.Flags().BoolP("no-data", "d", false, "tables to dump, comma separated")
dumpLogicalCmd.Flags().BoolP("no-schemas", "m", false, "Do not dump table data")
//dumpLogicalCmd.Flags().BoolP("no-views", "W", false, "Do not dump VIEWs")
dumpLogicalCmd.Flags().BoolP("triggers", "G", false, "Dump triggers. By default, it do not dump triggers")
dumpLogicalCmd.Flags().BoolP("events", "E", false, "Dump stored procedures and functions. "+
"By default, it do not dump stored procedures nor functions")
dumpLogicalCmd.Flags().BoolP("routines", "R", false, "Dump events. By default, it do not dump events")
dumpLogicalCmd.Flags().BoolP("triggers", "G", false,
"Dump triggers. By default, it do not dump triggers. work only when data-schema-grant is empty")
dumpLogicalCmd.Flags().BoolP("events", "E", false,
"Dump events. By default, it do not dump events. work only when data-schema-grant is empty")
dumpLogicalCmd.Flags().BoolP("routines", "R", false,
"Dump stored procedures and functions. By default, it do not dump. work only when data-schema-grant is empty")
viper.BindPFlag("LogicalBackup.NoData", dumpLogicalCmd.Flags().Lookup("no-data"))
viper.BindPFlag("LogicalBackup.NoSchemas", dumpLogicalCmd.Flags().Lookup("no-schemas"))
//viper.BindPFlag("LogicalBackup.NoViews", dumpLogicalCmd.Flags().Lookup("no-views"))
Expand Down Expand Up @@ -106,7 +108,7 @@ var dumpLogicalCmd = &cobra.Command{
}
err = backupData(&cnf)
if err != nil {
logger.Log.Error("dumpbackup logical failed", err.Error())
logger.Log.Error("dumpbackup logical failed ", err.Error())
}
return err
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import (
"fmt"
"os"
"os/exec"
"os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -178,7 +180,28 @@ func (l *LogicalDumper) Execute(enableTimeOut bool) error {

cmd.Stdout = outFile
cmd.Stderr = outFile
err = cmd.Run()

cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}

err = cmd.Start()

sig := make(chan os.Signal)
signal.Notify(sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) // syscall.SIGKILL
go func() {
select {
case s := <-sig:
logger.Log.Warn("dbbackup got signal %v,", s)
time.Sleep(500 * time.Millisecond)
if cmd.Process != nil {
err := cmd.Process.Kill() // syscall.Kill(-cmd.Process.Pid,syscall.SIGKILL)
logger.Log.Warnf("kill mydumper %d exit with %v", cmd.Process.Pid, err)
}
}
}()

err = cmd.Wait()
if err != nil {
errStrPrefix := fmt.Sprintf("tail 5 error from %s", mydumperLogFile)
errStrDetail, _ := util.GrepLinesFromFile(mydumperLogFile, []string{"ERROR", "fatal", "critical"},
Expand All @@ -189,7 +212,7 @@ func (l *LogicalDumper) Execute(enableTimeOut bool) error {
} else {
logger.Log.Warn("tail can not find more detail error message from ", mydumperLogFile)
}
logger.Log.Error("run logical backup failed", err, l.cnf.Public.MysqlPort)
logger.Log.Error("run logical backup failed ", err, l.cnf.Public.MysqlPort)
return errors.WithMessagef(err, fmt.Sprintf("%s\n%s", errStrPrefix, errStrDetail))
}
// check the integrity of backup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"bytes"
"context"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
Expand All @@ -33,6 +34,7 @@ import (
"dbm-services/mysql/db-tools/mysql-dbbackup/pkg/src/dbareport"
"dbm-services/mysql/db-tools/mysql-dbbackup/pkg/src/logger"
"dbm-services/mysql/db-tools/mysql-dbbackup/pkg/src/mysqlconn"
"dbm-services/mysql/db-tools/mysql-dbbackup/pkg/util"
)

// LogicalDumperMysqldump logical dumper using mysqldump tool
Expand Down Expand Up @@ -242,6 +244,8 @@ func (l *LogicalDumperMysqldump) Execute(enableTimeOut bool) (err error) {
if l.cnf.LogicalBackup.DisableCompress {
args = append(args, "-r", outSqlFile)
} else {
// 注意这里用了管道
// bash -c "aaa | bbb" 只要 bbb 命令没报错,返回值一直是 0,所有不能根据 return code 判断命令成功失败,而要从 stderr 判断
args = append(args, "|", CmdZstd, "-q", "-f", "-o", outSqlFile+cst.ZstdSuffix)
}
var cmd *exec.Cmd
Expand All @@ -253,18 +257,16 @@ func (l *LogicalDumperMysqldump) Execute(enableTimeOut bool) (err error) {
ctx, cancel := context.WithTimeout(context.Background(), (time.Duration(timeDiffUnix))*time.Second)
defer cancel()

cmd = exec.CommandContext(ctx,
"bash", "-c",
fmt.Sprintf(`%s %s`, binPath, strings.Join(args, " ")))
cmd = exec.CommandContext(ctx, "bash", "-c", fmt.Sprintf(`%s %s`, binPath, strings.Join(args, " ")))
} else {
cmd = exec.Command("bash", "-c",
fmt.Sprintf(`%s %s`, binPath, strings.Join(args, " ")))
cmd = exec.Command("bash", "-c", fmt.Sprintf(`%s %s`, binPath, strings.Join(args, " ")))
}

logger.Log.Info("logical dump command with mysqldump: ", cmd.String())

outFile, err := os.Create(filepath.Join(logger.GetLogDir(),
fmt.Sprintf("mysqldump_%d.log", int(time.Now().Weekday()))))
mysqldumpLogFile := filepath.Join(logger.GetLogDir(),
fmt.Sprintf("mysqldump_%d_%d.log", l.cnf.Public.MysqlPort, int(time.Now().Weekday())))
outFile, err := os.OpenFile(mysqldumpLogFile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
logger.Log.Error("create log file failed: ", err)
return err
Expand All @@ -273,9 +275,10 @@ func (l *LogicalDumperMysqldump) Execute(enableTimeOut bool) (err error) {
_ = outFile.Close()
}()
cmd.Stdout = outFile
//cmd.Stderr = outFile
var stderr bytes.Buffer
cmd.Stderr = &stderr

errWriter := io.MultiWriter(outFile, &stderr)
cmd.Stderr = errWriter

mysqldumpBeginTime := time.Now().Format("2006-01-02 15:04:05")
l.backupInfo.BackupBeginTime, err = time.ParseInLocation(cst.MydumperTimeLayout, mysqldumpBeginTime, time.Local)
Expand Down Expand Up @@ -314,9 +317,20 @@ func (l *LogicalDumperMysqldump) Execute(enableTimeOut bool) (err error) {
}

err = cmd.Run()
if err != nil {
logger.Log.Error("run logical backup(with mysqldump) failed: ", err, stderr.String())
return errors.WithMessage(err, stderr.String())
if err != nil || stderr.String() != "" {
errStrPrefix := fmt.Sprintf("tail 5 error from %s", mysqldumpLogFile)
errStrDetail, _ := util.GrepLinesFromFile(mysqldumpLogFile, nil, 2, false, true)
if len(errStrDetail) > 0 {
logger.Log.Info(errStrPrefix)
logger.Log.Error(errStrDetail)
} else {
logger.Log.Warn("tail can not find more detail error message from ", mysqldumpLogFile)
}
logger.Log.Error("run logical(mysqldump) backup failed", err, l.cnf.Public.MysqlPort)
if err == nil {
return errors.Errorf("%s\n%s", errStrPrefix, errStrDetail)
}
return errors.WithMessagef(err, fmt.Sprintf("%s\n%s", errStrPrefix, errStrDetail))
}
mysqldumpEndTime := time.Now().Format("2006-01-02 15:04:05")
l.backupInfo.BackupEndTime, err = time.ParseInLocation(cst.MydumperTimeLayout, mysqldumpEndTime, time.Local)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func (p *PhysicalLoader) decompress() error {
fmt.Sprintf("--parallel=%d", p.cnf.PhysicalLoad.Threads),
}
if strings.Compare(p.mysqlVersion, "005007000") < 0 {
// xtrabackup <=5.6 没有 removal original 选项
args = append(args, p.cnf.PhysicalLoad.MysqlLoadDir)
} else {
args = append(args, "--remove-original")
Expand Down

0 comments on commit 5a60b32

Please sign in to comment.