Záloha MySQL databáze 1. díl

(publikováno 20.04.2016) 2 Databáze, Linux

Jednoduchý návod na pravidelnou zálohu MySQL databáze. V prvím díle se podíváme na operační systém Linux a jeho možnost skriptování s využitím CRONu.

Záloha MySQL databáze 1. díl

Ve druhém díle je ukázka tvorby záloh pomocí knihovny do PHP, vhodné pro hostingy, kde nelze spouštět příkazy v příkazové řádce.

Aktualizace 9.9. Přidána ukázka komprese výsledné zálohy


Zálohování je důležité, to je jasné. Projekty mám na Gitu i na Dropboxu, ale když jsem chtěl pracovat na druhém PC, vždy mi chyběla aktuální DB. Rozhodl jsem se, vytvořit jednoduchý skript pro pravidelnou automatickou zálohu.

V dnešním článku vyřešíme zálohu na Linuxu, v příštím na Windows a na hostingu, kde máte omezené možnosti skriptů.

Skriptujeme

Abychom mohli jednoduše v budoucnu škálovat zálohy a přidávat další, rozhodl jsem se k řešení pomocí více skriptů. Tímto jednoduše můžeme k novým projektům jen přidat kopii zálohovacího skriptu. Při příštím spuštění se záloha vytvoří pro nový projekt automaticky, bez nutnosti nové konfigurace.

Hlavní skript

Prvně vytvoříme hlavní skript pomocí příkazů níže, který umístíme do /var/www/html, která je pro Debian/Ubuntu hlavní složka pro umisťování webů. Nesmíme zapomenout změnit práva na 755, abychom skript mohli spouštět.

cd /var/www/html
echo "find /var/www/html -name backupDB.sh | source /dev/stdin" > mainBackupDB.sh
chmod 755 mainBackupDB.sh

POZOR: Skript bude spuštěn cronem v domovské složce. Proto je lepší všude uvádět absolutní cestu k souborům!

Skript obsahuje pouze 1 řádek, ale více ani nepotřebujeme. Najde všechny soubory s názvem backupDB.sh v aktuální složce a všech podsložkách a následně je spustí.

Zálohovací skript

Skript pojmenujeme backupDB.sh a vložíme jej k projektu. Umístění je libovolné, nezapomeňte ale vytvořit složku sqldumps ve stejném adresáři.

Ve skriptu provedeme samotnou zálohu databáze a trochu po sobě uklidíme. Vymažeme všechny soubory starší 30 dnů.

#!/bin/bash

HOST="localhost"
USER="root"
PASS="root"
DB="blog"
BACKUP_DIR="`dirname "$0"`/sqldumps"
FILENAME="$BACKUP_DIR/`date +'%Y-%m-%d %H:%M:%S'`.sql"

# Všechny možnosti na http://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
mysqldump --host="$HOST" --user="$USER" --password="$PASS" --result-file="$FILENAME" "$DB"

# Smažeme zálohy starší 30 dnů pouze pokud existuje
# alespoň 20 novějších
# Děkuji za připomínku v komentářích Vaškovi

NEWER_CNT=`find "$BACKUP_DIR" -maxdepth 1 -name "*.sql" -mtime -30 | wc -l`
if [ $NEWER_CNT -gt 20 ]; then
    find "$BACKUP_DIR" -maxdepth 1 -name "*.sql" -mtime +30 -exec rm {} \;
fi

POZOR: Pokud používáte Linux i Windows zároveň, změňte formát názvu zálohy. Dvojtečky nejsou povolené v názvu na Windows, a případná synchronizace se nepovede

CRON

Abychom se nemuseli o zálohy starat, vložíme zápis do crontab pro automatické spouštění. Čas spouštění záleží na vás, já ale zvolil 20:30, protože v tento čas je počítač puštěn téměř vždy. Pokud se jedná o server, doporučuji čas okolo 3 ráno, kdy je provoz nejslabší.

# Otevřeme crontab soubor k zápisu
# Příkazy v tomto souboru se spouští s právy aktuálního uživatele
crontab -e

# Vložíme na konec souboru nový řádek a uložíme
0 20 * * * /bin/bash /var/www/html/mainBackupDB.sh
# Soubor bude spuštěn v adresáři ~ proto doporučuji uvádět všude
# absolutní cesty

Zapnutí komprese

Přepínač --compress, který mysqldump podporuje bohužel nefunguje úplně dobře s result-filename. Pokud je tedy nutné ukládat zálohu, lze přesměrovat výstup na gzip, viz následující skript:

mysqldump --host="$HOST" --user="$USER" --password="$PASS" "$DB" | gzip > "$FILENAME"

Testování

Pokud si chcete otestovat, že skript funguje, asi není nic jednoduššího než jej spustit. Jak ale otestovat mazání souborů, když se toto projeví až za 30 dnů? Stačí změnit přepínač z mtime na mmin. Zatímco mtime počítá celé dny, mmin počítá minuty. Konec skriptu tedy upravíme následovně a stačí spustit a po půlhodině zmizí nejstarší soubory.

# Zakomentujeme kontrolu 20 novějších souborů a změníme parametr na minuty
#NEWER_CNT=`find "$BACKUP_DIR" -maxdepth 1 -name "*.sql" -mtime -30 | wc -l`
#if [ $NEWER_CNT -gt 20 ]; then
    find "$BACKUP_DIR" -maxdepth 1 -name "*.sql" -mmin +30 -exec rm {} \;
#fi

Máte tipy na vylepšení? Podělte se v komentářích. Obrázky v cover jsou převzaty z Freepik

K tomuto článku již není možné přidávat další komentáře

Komentáře

Jenom opatrně na to že: "Ve skriptu provedeme samotnou zálohu databáze a trochu po sobě uklidíme. Vymažeme všechny soubory starší 30 dnů."

Protože pokud ti 30 dnů bude failovat backup tak ... víš co :D

Máš pravdu.. Přidal jsem kontrolu, že souborů mladších než 30 dnů musí být alespoň 20.

Díky