mirror of
https://github.com/jkaninda/mysql-bkup.git
synced 2025-12-07 14:09:41 +01:00
This commit is contained in:
148
pkg/backup.go
148
pkg/backup.go
@@ -26,7 +26,6 @@ SOFTWARE.
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jkaninda/encryptor"
|
"github.com/jkaninda/encryptor"
|
||||||
"github.com/jkaninda/go-storage/pkg/local"
|
"github.com/jkaninda/go-storage/pkg/local"
|
||||||
@@ -34,7 +33,6 @@ import (
|
|||||||
"github.com/jkaninda/mysql-bkup/utils"
|
"github.com/jkaninda/mysql-bkup/utils"
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -114,10 +112,14 @@ func multiBackupTask(databases []Database, bkConfig *BackupConfig) {
|
|||||||
func BackupTask(db *dbConfig, config *BackupConfig) {
|
func BackupTask(db *dbConfig, config *BackupConfig) {
|
||||||
utils.Info("Starting backup task...")
|
utils.Info("Starting backup task...")
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
|
prefix := db.dbName
|
||||||
|
if config.all {
|
||||||
|
prefix = "all_databases"
|
||||||
|
}
|
||||||
// Generate file name
|
// Generate file name
|
||||||
backupFileName := fmt.Sprintf("%s_%s.sql.gz", db.dbName, time.Now().Format("20060102_150405"))
|
backupFileName := fmt.Sprintf("%s_%s.sql.gz", prefix, time.Now().Format("20060102_150405"))
|
||||||
if config.disableCompression {
|
if config.disableCompression {
|
||||||
backupFileName = fmt.Sprintf("%s_%s.sql", db.dbName, time.Now().Format("20060102_150405"))
|
backupFileName = fmt.Sprintf("%s_%s.sql", prefix, time.Now().Format("20060102_150405"))
|
||||||
}
|
}
|
||||||
config.backupFileName = backupFileName
|
config.backupFileName = backupFileName
|
||||||
switch config.storage {
|
switch config.storage {
|
||||||
@@ -199,123 +201,67 @@ func startMultiBackup(bkConfig *BackupConfig, configFile string) {
|
|||||||
// BackupDatabase backup database
|
// BackupDatabase backup database
|
||||||
func BackupDatabase(db *dbConfig, backupFileName string, disableCompression, all bool) error {
|
func BackupDatabase(db *dbConfig, backupFileName string, disableCompression, all bool) error {
|
||||||
storagePath = os.Getenv("STORAGE_PATH")
|
storagePath = os.Getenv("STORAGE_PATH")
|
||||||
|
|
||||||
utils.Info("Starting database backup...")
|
utils.Info("Starting database backup...")
|
||||||
|
|
||||||
//err := os.Setenv("MYSQL_PWD", db.dbPassword)
|
if err := testDatabaseConnection(db); err != nil {
|
||||||
//if err != nil {
|
return fmt.Errorf("database connection failed: %w", err)
|
||||||
// return fmt.Errorf("failed to set MYSQL_PWD environment variable: %v", err)
|
|
||||||
//}
|
|
||||||
err := testDatabaseConnection(db)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New(err.Error())
|
|
||||||
}
|
}
|
||||||
// Backup Database database
|
|
||||||
utils.Info("Backing up database...")
|
dumpArgs := []string{fmt.Sprintf("--defaults-file=%s", mysqlClientConfig)}
|
||||||
// Verify is compression is disabled
|
if all {
|
||||||
|
dumpArgs = append(dumpArgs, "--all-databases", "--single-transaction", "--routines", "--triggers")
|
||||||
|
} else {
|
||||||
|
dumpArgs = append(dumpArgs, db.dbName)
|
||||||
|
}
|
||||||
|
|
||||||
|
backupPath := filepath.Join(tmpPath, backupFileName)
|
||||||
if disableCompression {
|
if disableCompression {
|
||||||
if all {
|
return runCommandAndSaveOutput("mysqldump", dumpArgs, backupPath)
|
||||||
// Backup all databases
|
}
|
||||||
// Execute mysqldump
|
return runCommandWithCompression("mysqldump", dumpArgs, backupPath)
|
||||||
cmd := exec.Command("mysqldump",
|
}
|
||||||
fmt.Sprintf("--defaults-file=%s", mysqlClientConfig), "--all-databases", "--single-transaction", "--routines", "--triggers",
|
|
||||||
)
|
func runCommandAndSaveOutput(command string, args []string, outputPath string) error {
|
||||||
|
cmd := exec.Command(command, args...)
|
||||||
output, err := cmd.Output()
|
output, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to backup database: %v output: %v", err, string(output))
|
return fmt.Errorf("failed to execute %s: %v, output: %s", command, err, string(output))
|
||||||
}
|
}
|
||||||
|
|
||||||
// save output
|
return os.WriteFile(outputPath, output, 0644)
|
||||||
file, err := os.Create(filepath.Join(tmpPath, backupFileName))
|
}
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create backup file: %v", err)
|
|
||||||
}
|
|
||||||
defer func(file *os.File) {
|
|
||||||
err := file.Close()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}(file)
|
|
||||||
|
|
||||||
_, err = file.Write(output)
|
func runCommandWithCompression(command string, args []string, outputPath string) error {
|
||||||
if err != nil {
|
cmd := exec.Command(command, args...)
|
||||||
return err
|
|
||||||
}
|
|
||||||
utils.Info("Database has been backed up")
|
|
||||||
} else {
|
|
||||||
// Execute mysqldump
|
|
||||||
cmd := exec.Command("mysqldump",
|
|
||||||
fmt.Sprintf("--defaults-file=%s", mysqlClientConfig), db.dbName,
|
|
||||||
)
|
|
||||||
output, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to backup database: %v output: %v", err, string(output))
|
|
||||||
}
|
|
||||||
|
|
||||||
// save output
|
|
||||||
file, err := os.Create(filepath.Join(tmpPath, backupFileName))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create backup file: %v", err)
|
|
||||||
}
|
|
||||||
defer func(file *os.File) {
|
|
||||||
err := file.Close()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}(file)
|
|
||||||
|
|
||||||
_, err = file.Write(output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
utils.Info("Database has been backed up")
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if all {
|
|
||||||
// Execute mysqldump
|
|
||||||
cmd := exec.Command("mysqldump", fmt.Sprintf("--defaults-file=%s", mysqlClientConfig), "--all-databases", "--single-transaction", "--routines", "--triggers")
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to backup database: %v output: %v", err, stdout)
|
return fmt.Errorf("failed to create stdout pipe: %w", err)
|
||||||
}
|
|
||||||
gzipCmd := exec.Command("gzip")
|
|
||||||
gzipCmd.Stdin = stdout
|
|
||||||
gzipCmd.Stdout, err = os.Create(filepath.Join(tmpPath, backupFileName))
|
|
||||||
err = gzipCmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to backup database: %v", err)
|
|
||||||
}
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := gzipCmd.Wait(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
// Execute mysqldump
|
|
||||||
cmd := exec.Command("mysqldump", fmt.Sprintf("--defaults-file=%s", mysqlClientConfig), db.dbName)
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to backup database: %v output: %v", err, stdout)
|
|
||||||
}
|
|
||||||
gzipCmd := exec.Command("gzip")
|
gzipCmd := exec.Command("gzip")
|
||||||
gzipCmd.Stdin = stdout
|
gzipCmd.Stdin = stdout
|
||||||
gzipCmd.Stdout, err = os.Create(filepath.Join(tmpPath, backupFileName))
|
gzipFile, err := os.Create(outputPath)
|
||||||
err = gzipCmd.Start()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to backup database: %v", err)
|
return fmt.Errorf("failed to create gzip file: %w", err)
|
||||||
|
}
|
||||||
|
defer func(gzipFile *os.File) {
|
||||||
|
err := gzipFile.Close()
|
||||||
|
if err != nil {
|
||||||
|
utils.Error("Error closing gzip file: %v", err)
|
||||||
|
}
|
||||||
|
}(gzipFile)
|
||||||
|
gzipCmd.Stdout = gzipFile
|
||||||
|
|
||||||
|
if err := gzipCmd.Start(); err != nil {
|
||||||
|
return fmt.Errorf("failed to start gzip: %w", err)
|
||||||
}
|
}
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
log.Fatal(err)
|
return fmt.Errorf("failed to execute %s: %w", command, err)
|
||||||
}
|
}
|
||||||
if err := gzipCmd.Wait(); err != nil {
|
if err := gzipCmd.Wait(); err != nil {
|
||||||
log.Fatal(err)
|
return fmt.Errorf("failed to wait for gzip completion: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
utils.Info("Database has been backed up")
|
utils.Info("Database has been backed up")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -408,8 +354,8 @@ func recoverMode(err error, msg string) {
|
|||||||
utils.Error("Backup rescue mode is enabled")
|
utils.Error("Backup rescue mode is enabled")
|
||||||
utils.Error("Backup will continue")
|
utils.Error("Backup will continue")
|
||||||
} else {
|
} else {
|
||||||
utils.Error("Error 10: %s", msg)
|
utils.Error("Error: %s", msg)
|
||||||
utils.Fatal("Error 10: %v", err)
|
utils.Fatal("Error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user