Backup database MariaDB in Go

Mattepuffo's logo
Backup database MariaDB in Go

Backup database MariaDB in Go

In questo articolo vi propongo un piccolo script, di tre funzioni, per eseguire un backup di un database MariaDB in Go.

Il file poi viene compresso ed inviato ad un server FTP.

L'unica libreria esterna che dovete installare è questa:

go get -u github.com/jlaffaye/ftp

Ovviamente sulla macchina dove volete eseguire lo script dovete avere mysqldump installato.

Qui sotto lo script completo, dovete solo sostituire i parametri di connessione al db e FTP:

package main

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/jlaffaye/ftp"
)

func main() {
	sqlFile := createBackup()
	gzFile := compressGzip(sqlFile)
	uploadFtp(gzFile)
}

func createBackup() string {
	user := ""
	password := ""
	host := ""
	port := "3306"
	database := ""

	backupDir := "./backups"
	os.MkdirAll(backupDir, os.ModePerm)

	timestamp := time.Now().Format("20060102_150405")
	filename := fmt.Sprintf("%s_backup_%s.sql", database, timestamp)
	filePath := filepath.Join(backupDir, filename)

	cmd := exec.Command(
		"mysqldump",
		"-h", host,
		"-P", port,
		"-u", user,
		fmt.Sprintf("--password=%s", password),
		"--single-transaction",
		"--routines",
		"--events",
		"--triggers",
		"--add-drop-table",
		database,
	)

	var out, stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr

	fmt.Println("Eseguo il backup...")

	if err := cmd.Run(); err != nil {
		log.Fatalf("Errore durante mysqldump: %v\nDettagli: %s", err, stderr.String())
	}

	if err := os.WriteFile(filePath, out.Bytes(), 0644); err != nil {
		log.Fatalf("Errore nel salvataggio del file: %v", err)
	}

	fmt.Printf("Backup completato con successo: %s\n", filePath)

	return filePath
}

func compressGzip(sqlFile string) string {
	gzFile := sqlFile + ".gz"

	inFile, err := os.Open(sqlFile)

	if err != nil {
		log.Fatalf("Errore aprendo file SQL: %v", err)
	}

	defer inFile.Close()

	outFile, err := os.Create(gzFile)

	if err != nil {
		log.Fatalf("Errore creando file gzip: %v", err)
	}

	defer outFile.Close()

	gw := gzip.NewWriter(outFile)

	defer gw.Close()

	_, err = io.Copy(gw, inFile)

	if err != nil {
		log.Fatalf("Errore durante la compressione: %v", err)
	}

	fmt.Printf("File compresso: %s\n", gzFile)

	return gzFile
}

func uploadFtp(localFilePath string) {
	c, err := ftp.Dial(":21", ftp.DialWithTimeout(5*time.Second))

	if err != nil {
		log.Fatalf("Errore connessione FTP: %v", err)
	}

	defer c.Quit()

	if err = c.Login("", ""); err != nil {
		log.Fatalf("Errore login FTP: %v", err)
	}

	if err = c.ChangeDir("/BCK_DB"); err != nil {
		log.Fatalf("Errore cambio directory FTP: %v", err)
	}

	file, err := os.Open(localFilePath)

	if err != nil {
		log.Fatalf("Impossibile aprire file: %v", err)
	}

	defer file.Close()

	remoteName := filepath.Base(localFilePath)

	if err = c.Stor(remoteName, file); err != nil {
		log.Fatalf("Errore upload FTP: %v", err)
	}

	fmt.Printf("File caricato con successo: %s\n", remoteName)
}

Enjoy!


Condividi

Commentami!