W tym artykule pokażemy, jak skonfigurować mechanizm backupu bazy danych MySQL lub MariaDB w systemie Linux (Debian/Ubuntu). Wykorzystamy do tego narzędzia mysqldump
, zip
oraz rsync
, aby przygotować kopię zapasową, skompresować ją i przesłać na zewnętrzny serwer.
Wymagania wstepne
Artykuł został przygotowany w oparciu o popularny system operacyjny Ubuntu/Debian. Jeżeli korzystasz z innego systemu, część poleceń (jak np. apt-get
) prawdopodobnie będziesz musiał zamienić na te odpowiadające Twojemu systemowi.
Nasze testowe środowisko to:
- System operacyjny Ubuntu Server 20.04 LTS
- Baza danych MySQL w wersji 8
Instalacja wymaganych narzędzi
Zakładam, że posiadasz już zainstalowaną bazę danych. Jeżeli nie, zobacz jak to zrobić w naszym innym artykule: https://ping.pl/blog/posts/jak-postawic-strone-na-ubuntu-i-apache/#instalacja-i-konfiguracja-bazy-danych-mysql.
Upewnij się, że posiadasz pakiety zip
i rsync
w swoim systemie:
sudo apt update
sudo apt install zip rsync
Programy zip
posłuży nam do łatwego skompresowania wygenerowanego pliku sql
, natomiast rsync
do bezpiecznego przesłania kopii bazy danych na zewnętrzny serwer.
Dodanie użytkownika bazodanowego
Aby wykonać zrzut danych z bazy danych, będziemy potrzebować użytkownika bazodanowego z nadanymi odpowiednimi uprawnieniami:
Zaloguj się do konsoli bazy danych:
sudo mysql -u root -p
Jeśli to konieczne, wprowadź hasło użytkownika bazodanowego root
, ale gdy uruchomisz to polecenie przez sudo
lub z poziomu użytkownika systemowego root
to powinieneś zostać zalogowany do konsoli bazy danych automatycznie.
Będąc już zalogowany, możesz utworzyć nowego użytkownika bazodanowego i nadać odpowiednie uprawnienia:
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'haslo12345';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'backup'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Dobrą praktyką jest stosowanie użytkowników dedykowanych do konkretnych zadań, z minimalnym zakresem niezbędnych uprawnień. W przypadku tworzenia kopii zapasowej bazy danych wystarczą uprawnienia wymienione powyżej - nie obejmują one uprawnień umożliwiających na np. usunięcie danych.
Utworzenie skryptu wykonującego zrzut bazy danych
Stworzymy teraz skrypt bashowy, ktory wykona zrzut danych z bazy, skompresuje go do archiwum ZIP, a następnie prześle na zewnętrzny serwer przy użyciu rsync
.
- W wybranym miejscu na serwerze utwórz plik skryptu oraz od razu nadaj mu uprawnienie do jego uruchomienia:
touch backup.sh
chmod +x backup.sh
- Wprowadź treść skryptu do utworzonego pliku (np. przy pomocy polecenia
nano backup.sh
):
#!/bin/bash
# Dane uzytkownika bazodanowego oraz nazwa bazy ktorej ma zostac wykonana kopia
DB_USER="backup"
DB_PASSWORD="haslo12345"
DB_NAME="nazwa_bazy"
# Tymczasowe miejsce przechowywania kopii oraz nazwa pliku zrzutu
BACKUP_DIR="/tmp/mysql_backups"
BACKUP_FILE="${BACKUP_DIR}/backup_$(date +'%Y-%m-%d_%H-%M-%S').sql"
ZIP_FILE="${BACKUP_FILE}.zip"
mkdir -p "${BACKUP_DIR}"
# Serwer zewnetrzny na ktorym beda przechowywane kopie
REMOTE_USER="backup"
REMOTE_HOST="123.123.123.123"
REMOTE_DIR="/home/backup"
# Tworzenie zrzutu danych
mysqldump -u "${DB_USER}" -p"${DB_PASSWORD}" "${DB_NAME}" > "${BACKUP_FILE}"
if [ $? -ne 0 ]; then
echo "Mysqldump ERROR"
exit 1
fi
# Kompresja pliku
zip -j "${ZIP_FILE}" "${BACKUP_FILE}"
if [ $? -ne 0 ]; then
echo "Zip ERROR"
exit 1
fi
# Przeslanie pliku backupu na zewnetrzny serwer
rsync -avz "${ZIP_FILE}" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}"
if [ $? -ne 0 ]; then
echo "Rsync ERROR"
exit 1
fi
# Usunienie lokalnych plikow tymczasowych
rm -f "${BACKUP_FILE}"
rm -f "${ZIP_FILE}"
echo "Backup OK"
Sprawdzenie skryptu
Uruchom skrypt ręcznie, aby upewnić się, że działa poprawnie:
./backup.sh
Po uruchomieniu skryptu sprawdź, czy plik kopii zapasowej bazy danych znajduje się w docelowym katalogu na zewnętrznym serwerze oraz czy skrypt nie wyświetlił żadnego błędu.
Automatyzacja skryptu przy pomocy CRON
Naturalnie chcemy, aby backup bazy danych wykonywał się automatycznie bez naszej ingerencji. Możemy do tego celu wykorzystać CRON
, który służy do automatycznego uruchamiania skryptów o stałych, ustalonych porach, np. każdego dnia o 2 w nocy:
- Otwórz edytor
CRON
poleceniem:
crontab -e
- I dodaj nowy wpis odpowiedzialny za regularne uruchamianie wcześniej przygotowanego skryptu
backup.sh
:
0 2 * * * /bin/bash ~/backup.sh >> ~/backup.log 2>&1
Pamiętaj, że regularne testowanie i monitorowanie działania skryptu jest kluczowe, aby zapewnić niezawodność automatycznego mechanizmu backupu. Możesz regularnie (np. raz na tydzień) sprawdzać czy na zewnętrznym serwerze znajdują się aktualne kopie bazy danych lub też wykorzystać jeden z bardziej automatycznych mechanizmów:
Powiadomienie email o błędzie skryptu
Jeśli Twój serwer ma skonfigurowany serwer poczty (np. sendmail
lub postfix
), możesz dodać wysyłanie wiadomości email w przypadku błędu skryptu.
Zamień linie w skrypcie odpowiadające za wyświetlenie błędu na następujący:
# echo "Mysqldump ERROR"
echo "Error occurred while creating a MySQL backup" | mail -s "MySQL backup failed" jan.nowak@ping.pl
Automatyczny skrypt sprawdzający obecność backupów na serwerze zewnętrznym
Możesz przygotować skrypt bash
która sprawdza, czy plik backupu znajduje się na zewnętrznym serwerze i wyśle maila, jeżeli ten nie zostanie znaleziony:
#!/bin/bash
REMOTE_USER="backup"
REMOTE_HOST="123.123.123.123"
REMOTE_DIR="/home/backup"
ssh "${REMOTE_USER}@${REMOTE_HOST}" "ls -l ${REMOTE_DIR}" | grep "$(date +'%Y-%m-%d')"
if [ $? -eq 0 ]; then
echo "MySQL backup not found" | mail -s "MySQL backup failed" jan.nowak@ping.pl
else
echo "MySQL backup found"
fi
Podepnij skrypt do CRON
, aby uruchamiać go regularnie i automatycznie:
0 3 * * * /bin/bash ~/check-backup.sh
Rotacja logów
Aby uniknąć przepełnienia logów na serwerze zewnętrznym, możesz ustawić rotację plików za pomocą prostego skryptu:
#!/bin/bash
find /home/backup -type f -name "*.zip" -mtime +14 -exec rm -f {} \;
Zadaniem skryptu jest usunięcie plików o rozszerzeniu zip
z podanego katalogu /home/backup
starszych niż 14 dni. Oczywiście powyższy skrypt powinieneś utworzyć na serwerze zewnętrznym, nie na serwerze na którym jest zainstalowana baza danych.
Tak jak poprzednio, dodaj skrypt do CRON
, aby uruchamiał się samoczynnie.