Założenie jest takie, ażeby utworzyć skrypt w bashu, który automatycznie i cyklicznie będzie tworzył kopię zapasową bazy danych MySQL, a następnie będzie ją wysyłał na odrębny serwer FTP bez potrzeby ingerencji użytkownika. Serwer na który będzie backup wysyłany to oddzielna maszyna, wymagająca logowania. Aby uniknąć potrzeby podawania hasła w skrypcie, wykorzystać można „autoprzedstawiania” się przy użyciu pliku .netrc. Plik ten znajduje się w katalogu głównym użytkownika i uniksowy program ftp wykorzystuje go do przedstawiania się innym komputerom. Więcej informacji o .netrc tutaj.
Tak więc na początek należy w katalogu /root utworzyć plik .netrc (backup będzie wykonywany przez użytkownika root).
cd /root vi .netrc machine XX.XX.XX.XX login backuper password P@$$w0rd
Jak widać struktura jest dość prosta, po słowie machine należy najpierw podać nazwę komputera/hosta, następnie login i hasło (jawnie). Teraz przy próbie połączenia przez ftp z podanym hostem, zostanie mu podany automatycznie login i hasło, jeśli wymaga uwierzytelniania.
Utworzyłem również oddzielny katalog jako tymczasowe miejsce do którego tworzony jest backup.
mkdir /tmp/mybackup
Katalog utworzony jest wewnątrz /tmp. Katalog ten jak sama nazwa wskazuje jest tymczasowy, przy każdym uruchomieniu jest czyszczony albo jak też w przypadku mojej konfiguracji sam co kilka dni usuwa starsze pliki, tak więc nie ma obaw o zapchanie dysku w przyszłości.
Sam skrypt wygląda następująco:
#! /bin/bash # ---- Skrypt robiący backup bazy danych ----- # nazwa bazy danych DB=mydatabase_tobackup # nazwa pliku z data w nazwie DATE=`date +%Y%m%d_%H%M` FILE="db-$DB-$DATE" # ---- MySQL ------ HOST=localhost # uzytkownik bazy danych USER=user-backup # hasło do bazy danych PASS=P@$$w0rd # ---- FTP ------ # nazwa hosta i port do serwera FTP FTPHOST="XX.XX.XX.XX 6022" # --- end of settings ---- cd /tmp/backup echo -e "\n\n" echo "# Backp bazy danych" echo "# --------------------------------------" echo -ne " > Zrzut bazy danych ($DB)..." mysqldump -h $HOST --user=$USER --password=$PASS $DB > $FILE.sql if [ $? -eq 0 ]; then echo "OK" else echo "ERROR $?" fi echo -ne " > Kompresowanie..." tar -czf $FILE.tgz $FILE.sql if [ $? -eq 0 ]; then echo "OK" else echo "ERROR $?" fi echo -ne " > Wysyłanie na serwer docelowy..." ftp <<EOF open $FTPHOST cd /DB_BACKUP put $FILE.tgz $FILE.tgz bye EOF if [ $? -ne 0 ]; then ret="ERROR $?" else ret="OK" fi echo $ret echo -e "\n\n" # END
Dane do logowania podawane są tutaj w postaci jawnej, dlatego najlepiej jest wykorzystywać do tego celu oddzielnego użytkownika, który będzie wykonywał tylko zrzut bazy danych, bez praw do modyfikacji czy usuwania danych. Zgodnie z informacjami znalezionymi tutaj, powinno to wyglądać mniej więcej tak:
GRANT SHOW DATABASES, SELECT, LOCK TABLES, RELOAD ON *.* to user-backup@localhost IDENTIFIED BY 'P@$$w0rd'; FLUSH PRIVILEGES;
Generalny plan działania skryptu:
- Zrzut wybranej bazy danych do pliku przy użyciu mysqldump.
- Skompresowanie pliku
- Wysłanie na docelowy serwer FTP
Pozostaje jeszcze umieszczenie skryptu w zadaniach crona. Można wrzucić plik skryptu do katalogu /etc/cron.daily/, bądź dodać wpis do crontab.
crontab -e ... 30 3 * * * sh /root/scripts/mybackup.sh
W tym wypadku skrypt uruchamiany jest codziennie o godzinie 3:30. Należy obrać taki czas, kiedy serwer jest najmniej wykorzystywany. Na czas tworzenia zrzutu bazy jest ona blokowana, a przy dużej ilości danych może to chwilę potrwać.
Dodatkowo skrypt ma wyrzucać na ekran (echo) informacje o przebiegu procesu. W przypadku, gdy jest on uruchamiany z crona, wszystko co „wyrzuci” skrypt przesyłane jest na e-mail administratora, tak więc rano w pracy 😉 widać czy wysyłanie kopii się powiodło czy też nie.
Jak można wysłać na inny serwer FTP nie podając loginu i hasła do konta? Sam port i adres nie wystarczy.