初始化2
This commit is contained in:
@@ -197,23 +197,25 @@ func (s *BackupService) doBackup(policy *model.BackupPolicy, log *model.BackupLo
|
||||
s.cleanOldBackups(policy)
|
||||
}
|
||||
|
||||
// backupDatabase 备份数据库
|
||||
// backupDatabase 备份数据库(根据数据库类型选择工具)
|
||||
func (s *BackupService) backupDatabase(tarWriter *tar.Writer, timestamp string) (int64, error) {
|
||||
dbCfg := config.AppConfig.Database
|
||||
dumpFile := filepath.Join(os.TempDir(), fmt.Sprintf("db_dump_%s.sql", timestamp))
|
||||
|
||||
mysqldumpPath := s.findTool("mysqldump", config.AppConfig.Backup.MysqlDumpPath)
|
||||
var dumpFile string
|
||||
var cmd *exec.Cmd
|
||||
var err error
|
||||
|
||||
cmd := exec.Command(mysqldumpPath,
|
||||
"-h", dbCfg.Host,
|
||||
"-P", fmt.Sprintf("%d", dbCfg.Port),
|
||||
"-u", dbCfg.Username,
|
||||
"-p"+dbCfg.Password,
|
||||
"--single-transaction",
|
||||
"--routines",
|
||||
"--triggers",
|
||||
dbCfg.DBName,
|
||||
)
|
||||
switch dbCfg.Type {
|
||||
case "sqlserver":
|
||||
dumpFile, cmd, err = s.buildSQLServerDump(dbCfg, timestamp)
|
||||
case "postgres":
|
||||
dumpFile, cmd, err = s.buildPostgresDump(dbCfg, timestamp)
|
||||
default:
|
||||
dumpFile, cmd, err = s.buildMySQLDump(dbCfg, timestamp)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
outFile, err := os.Create(dumpFile)
|
||||
if err != nil {
|
||||
@@ -225,18 +227,16 @@ func (s *BackupService) backupDatabase(tarWriter *tar.Writer, timestamp string)
|
||||
if err := cmd.Run(); err != nil {
|
||||
outFile.Close()
|
||||
os.Remove(dumpFile)
|
||||
return 0, fmt.Errorf("mysqldump执行失败: %w", err)
|
||||
return 0, fmt.Errorf("数据库备份命令执行失败: %w", err)
|
||||
}
|
||||
outFile.Close()
|
||||
|
||||
// 获取文件大小
|
||||
info, _ := os.Stat(dumpFile)
|
||||
dbSize := int64(0)
|
||||
if info != nil {
|
||||
dbSize = info.Size()
|
||||
}
|
||||
|
||||
// 写入tar
|
||||
file, err := os.Open(dumpFile)
|
||||
if err != nil {
|
||||
os.Remove(dumpFile)
|
||||
@@ -264,6 +264,51 @@ func (s *BackupService) backupDatabase(tarWriter *tar.Writer, timestamp string)
|
||||
return dbSize, nil
|
||||
}
|
||||
|
||||
// buildMySQLDump 构建 mysqldump 命令
|
||||
func (s *BackupService) buildMySQLDump(dbCfg config.DatabaseConfig, timestamp string) (string, *exec.Cmd, error) {
|
||||
dumpFile := filepath.Join(os.TempDir(), fmt.Sprintf("db_dump_%s.sql", timestamp))
|
||||
mysqldumpPath := s.findTool("mysqldump", config.AppConfig.Backup.MysqlDumpPath)
|
||||
cmd := exec.Command(mysqldumpPath,
|
||||
"-h", dbCfg.Host,
|
||||
"-P", fmt.Sprintf("%d", dbCfg.Port),
|
||||
"-u", dbCfg.Username,
|
||||
"-p"+dbCfg.Password,
|
||||
"--single-transaction", "--routines", "--triggers",
|
||||
dbCfg.DBName,
|
||||
)
|
||||
return dumpFile, cmd, nil
|
||||
}
|
||||
|
||||
// buildPostgresDump 构建 pg_dump 命令
|
||||
func (s *BackupService) buildPostgresDump(dbCfg config.DatabaseConfig, timestamp string) (string, *exec.Cmd, error) {
|
||||
dumpFile := filepath.Join(os.TempDir(), fmt.Sprintf("db_dump_%s.sql", timestamp))
|
||||
pgDumpPath := s.findTool("pg_dump", config.AppConfig.Backup.PgDumpPath)
|
||||
cmd := exec.Command(pgDumpPath,
|
||||
"-h", dbCfg.Host,
|
||||
"-p", fmt.Sprintf("%d", dbCfg.Port),
|
||||
"-U", dbCfg.Username,
|
||||
"-F", "p", // plain text SQL
|
||||
"--no-owner",
|
||||
dbCfg.DBName,
|
||||
)
|
||||
cmd.Env = append(os.Environ(), "PGPASSWORD="+dbCfg.Password)
|
||||
return dumpFile, cmd, nil
|
||||
}
|
||||
|
||||
// buildSQLServerDump 构建 sqlcmd 导出命令
|
||||
func (s *BackupService) buildSQLServerDump(dbCfg config.DatabaseConfig, timestamp string) (string, *exec.Cmd, error) {
|
||||
dumpFile := filepath.Join(os.TempDir(), fmt.Sprintf("db_dump_%s.sql", timestamp))
|
||||
sqlCmdPath := s.findTool("sqlcmd", config.AppConfig.Backup.SqlCmdPath)
|
||||
cmd := exec.Command(sqlCmdPath,
|
||||
"-S", fmt.Sprintf("%s,%d", dbCfg.Host, dbCfg.Port),
|
||||
"-U", dbCfg.Username,
|
||||
"-P", dbCfg.Password,
|
||||
"-d", dbCfg.DBName,
|
||||
"-Q", fmt.Sprintf("BACKUP DATABASE [%s] TO DISK='%s' WITH FORMAT", dbCfg.DBName, dumpFile),
|
||||
)
|
||||
return dumpFile, cmd, nil
|
||||
}
|
||||
|
||||
// backupFiles 备份文件
|
||||
func (s *BackupService) backupFiles(tarWriter *tar.Writer) (int64, int, error) {
|
||||
basePath := config.AppConfig.Storage.LocalBasePath
|
||||
@@ -525,12 +570,23 @@ func (s *BackupService) extractTarGz(tarGzPath, destDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// restoreDatabase 从SQL文件恢复数据库
|
||||
// restoreDatabase 从SQL文件恢复数据库(根据数据库类型选择工具)
|
||||
func (s *BackupService) restoreDatabase(sqlFilePath string) error {
|
||||
dbCfg := config.AppConfig.Database
|
||||
|
||||
mysqlPath := s.findTool("mysql", config.AppConfig.Backup.MysqlPath)
|
||||
switch dbCfg.Type {
|
||||
case "postgres":
|
||||
return s.restorePostgres(dbCfg, sqlFilePath)
|
||||
case "sqlserver":
|
||||
return s.restoreSQLServer(dbCfg, sqlFilePath)
|
||||
default:
|
||||
return s.restoreMySQL(dbCfg, sqlFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
// restoreMySQL mysql恢复
|
||||
func (s *BackupService) restoreMySQL(dbCfg config.DatabaseConfig, sqlFilePath string) error {
|
||||
mysqlPath := s.findTool("mysql", config.AppConfig.Backup.MysqlPath)
|
||||
cmd := exec.Command(mysqlPath,
|
||||
"-h", dbCfg.Host,
|
||||
"-P", fmt.Sprintf("%d", dbCfg.Port),
|
||||
@@ -538,16 +594,42 @@ func (s *BackupService) restoreDatabase(sqlFilePath string) error {
|
||||
"-p"+dbCfg.Password,
|
||||
dbCfg.DBName,
|
||||
)
|
||||
|
||||
sqlFile, err := os.Open(sqlFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sqlFile.Close()
|
||||
|
||||
cmd.Stdin = sqlFile
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// restorePostgres psql恢复
|
||||
func (s *BackupService) restorePostgres(dbCfg config.DatabaseConfig, sqlFilePath string) error {
|
||||
psqlPath := s.findTool("psql", config.AppConfig.Backup.PsqlPath)
|
||||
cmd := exec.Command(psqlPath,
|
||||
"-h", dbCfg.Host,
|
||||
"-p", fmt.Sprintf("%d", dbCfg.Port),
|
||||
"-U", dbCfg.Username,
|
||||
"-d", dbCfg.DBName,
|
||||
"-f", sqlFilePath,
|
||||
)
|
||||
cmd.Env = append(os.Environ(), "PGPASSWORD="+dbCfg.Password)
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// restoreSQLServer sqlcmd恢复
|
||||
func (s *BackupService) restoreSQLServer(dbCfg config.DatabaseConfig, sqlFilePath string) error {
|
||||
sqlCmdPath := s.findTool("sqlcmd", config.AppConfig.Backup.SqlCmdPath)
|
||||
cmd := exec.Command(sqlCmdPath,
|
||||
"-S", fmt.Sprintf("%s,%d", dbCfg.Host, dbCfg.Port),
|
||||
"-U", dbCfg.Username,
|
||||
"-P", dbCfg.Password,
|
||||
"-d", dbCfg.DBName,
|
||||
"-i", sqlFilePath,
|
||||
)
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user