Files
mysql-bkup/main.go

217 lines
5.6 KiB
Go
Raw Normal View History

2024-01-18 14:19:27 +01:00
package main
/*****
2024-01-19 14:12:05 +01:00
* MySQL Backup & Restore
2024-01-18 14:19:27 +01:00
* @author Jonas Kaninda
* @license MIT License <https://opensource.org/licenses/MIT>
* @link https://github.com/jkaninda/mysql-bkup
**/
import (
"fmt"
2024-01-19 14:12:05 +01:00
"github.com/jkaninda/mysql-bkup/cmd"
"github.com/jkaninda/mysql-bkup/pkg"
2024-01-18 14:19:27 +01:00
"github.com/jkaninda/mysql-bkup/utils"
flag "github.com/spf13/pflag"
"os"
"os/exec"
2024-01-18 14:19:27 +01:00
)
const s3MountPath string = "/s3mnt"
var (
2024-01-18 19:13:04 +01:00
operation string = "backup"
2024-01-18 14:19:27 +01:00
storage string = "local"
file string = ""
s3Path string = "/mysql-bkup"
dbName string = ""
dbHost string = ""
dbPort string = ""
dbPassword string = ""
dbUserName string = ""
executionMode string = "default"
storagePath string = "/backup"
accessKey string = ""
secretKey string = ""
bucketName string = ""
s3Endpoint string = ""
s3fsPasswdFile string = "/etc/passwd-s3fs"
disableCompression bool = false
startBackup bool = true
timeout int = 30
period string = "0 1 * * *"
2024-01-18 14:19:27 +01:00
)
func init() {
var (
operationFlag = flag.StringP("operation", "o", "backup", "Operation")
storageFlag = flag.StringP("storage", "s", "local", "Storage, local or s3")
fileFlag = flag.StringP("file", "f", "", "File name")
pathFlag = flag.StringP("path", "P", "/mysql-bkup", "S3 path, without file name")
dbnameFlag = flag.StringP("dbname", "d", "", "Database name")
modeFlag = flag.StringP("mode", "m", "default", "Execution mode. default or scheduled")
periodFlag = flag.StringP("period", "", "0 1 * * *", "Schedule period time")
timeoutFlag = flag.IntP("timeout", "t", 30, "Timeout (in seconds) to stop database connexion")
2024-01-18 14:19:27 +01:00
disableCompressionFlag = flag.BoolP("disable-compression", "", false, "Disable backup compression")
portFlag = flag.IntP("port", "p", 3306, "Database port")
2024-01-18 14:19:27 +01:00
helpFlag = flag.BoolP("help", "h", false, "Print this help message")
versionFlag = flag.BoolP("version", "v", false, "Version information")
2024-01-18 14:19:27 +01:00
)
flag.Parse()
operation = *operationFlag
storage = *storageFlag
file = *fileFlag
s3Path = *pathFlag
dbName = *dbnameFlag
executionMode = *modeFlag
dbPort = fmt.Sprint(*portFlag)
2024-01-18 19:13:04 +01:00
timeout = *timeoutFlag
2024-01-18 14:19:27 +01:00
period = *periodFlag
disableCompression = *disableCompressionFlag
flag.Usage = func() {
2024-01-19 14:12:05 +01:00
fmt.Print("MySQL Database backup and restoration tool. Backup database to AWS S3 storage or any S3 Alternatives for Object Storage.\n\n")
fmt.Print("Usage: bkup --operation backup -storage s3 --dbname databasename --path /my_path ...\n")
2024-01-18 14:19:27 +01:00
fmt.Print(" bkup -o backup -d databasename --disable-compression ...\n")
2024-01-19 14:12:05 +01:00
fmt.Print(" Restore: bkup -o restore -d databasename -f db_20231217_051339.sql.gz ...\n\n")
2024-01-18 14:19:27 +01:00
flag.PrintDefaults()
}
if *helpFlag {
startBackup = false
flag.Usage()
os.Exit(0)
}
if *versionFlag {
startBackup = false
2024-01-19 14:12:05 +01:00
cmd.Version()
2024-01-18 14:19:27 +01:00
os.Exit(0)
}
if *dbnameFlag != "" {
2024-01-18 19:13:04 +01:00
err := os.Setenv("DB_NAME", dbName)
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
}
if *pathFlag != "" {
s3Path = *pathFlag
2024-01-18 19:13:04 +01:00
err := os.Setenv("S3_PATH", fmt.Sprint(*pathFlag))
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
}
if *fileFlag != "" {
file = *fileFlag
2024-01-18 19:13:04 +01:00
err := os.Setenv("FILE_NAME", fmt.Sprint(*fileFlag))
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
}
if *portFlag != 3306 {
2024-01-18 19:13:04 +01:00
err := os.Setenv("DB_PORT", fmt.Sprint(*portFlag))
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
}
if *periodFlag != "" {
2024-01-18 19:13:04 +01:00
err := os.Setenv("SCHEDULE_PERIOD", fmt.Sprint(*periodFlag))
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
}
if *storageFlag != "" {
2024-01-18 19:13:04 +01:00
err := os.Setenv("STORAGE", fmt.Sprint(*storageFlag))
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
}
storage = os.Getenv("STORAGE")
err := os.Setenv("STORAGE_PATH", storagePath)
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
}
func main() {
2024-01-18 19:13:04 +01:00
err := os.Setenv("STORAGE_PATH", storagePath)
if err != nil {
return
}
2024-01-18 14:19:27 +01:00
if startBackup {
start()
}
}
func start() {
if executionMode == "default" {
if operation != "backup" {
if storage != "s3" {
2024-01-19 14:12:05 +01:00
utils.Info("Restore database from local")
2024-01-19 06:56:19 +01:00
pkg.RestoreDatabase(file)
2024-01-18 14:19:27 +01:00
} else {
2024-01-19 14:12:05 +01:00
utils.Info("Restore database from s3")
2024-01-18 14:19:27 +01:00
s3Restore()
}
} else {
if storage != "s3" {
2024-01-19 14:12:05 +01:00
utils.Info("Backup database to local storage")
2024-01-19 06:56:19 +01:00
pkg.BackupDatabase(disableCompression)
2024-01-18 14:19:27 +01:00
} else {
2024-01-19 14:12:05 +01:00
utils.Info("Backup database to s3 storage")
2024-01-18 14:19:27 +01:00
s3Backup()
}
}
} else if executionMode == "scheduled" {
scheduledMode()
} else {
utils.Fatal("Error, unknown execution mode!")
}
}
func s3Backup() {
2024-01-19 06:56:19 +01:00
// Backup Database to S3 storage
pkg.MountS3Storage(s3Path)
2024-01-19 06:56:19 +01:00
pkg.BackupDatabase(disableCompression)
2024-01-18 14:19:27 +01:00
}
// Run in scheduled mode
func scheduledMode() {
// Verify operation
if operation == "backup" {
fmt.Println()
fmt.Println("**********************************")
fmt.Println(" Starting MySQL Bkup... ")
fmt.Println("***********************************")
utils.Info("Running in Scheduled mode")
utils.Info("Log file in /var/log/mysql-bkup.log")
utils.Info("Execution period ", os.Getenv("SCHEDULE_PERIOD"))
//Test database connexion
utils.TestDatabaseConnection()
2024-01-18 14:19:27 +01:00
utils.Info("Creating backup job...")
pkg.CreateCrontabScript(disableCompression, storage)
2024-01-19 14:12:05 +01:00
//Start Supervisor
2024-01-18 14:19:27 +01:00
supervisordCmd := exec.Command("supervisord", "-c", "/etc/supervisor/supervisord.conf")
if err := supervisordCmd.Run(); err != nil {
utils.Fatalf("Error starting supervisord: %v\n", err)
}
} else {
utils.Fatal("Scheduled mode supports only backup operation")
}
}
func s3Restore() {
// Restore database from S3
pkg.MountS3Storage(s3Path)
2024-01-19 06:56:19 +01:00
pkg.RestoreDatabase(file)
2024-01-18 14:19:27 +01:00
}