MySQL Backup - kopia zapasowa bazy danych
Jak ważną sprawą jest regularne wykonywanie kopii zapasowych ważnych danych nawet nie wypada pisać. Wystarczy odwiedzić fora internetowe, gdzie pełno jest postów dotyczące utraty ultra ważnych danych. Początkującym użytkownikom, backup kojarzy się ze zgrywaniem plików/katalogów z jednego miejsca w drugie, często zapominając o kopii bazy danych. Jako że najpopularniejszą obecnie bazą danych jest MySQL, postaram się przybliżyć podstawy robienia kopii zapasowych.
Jest kilka sposobów na wykonanie kopii bezpieczeństwa bazy danych MySQL, dobór metody zależny jest od zastosowanego silnika.
Korzystając z silnika MyISAM mamy do wyboru kilka metod. Pierwsza to kopiowane plików, druga to wykorzystanie narzędzia mysqldump. Natomiast jeśli używamy silnika InnoDB, który jest domyślny od wersji MySQL 5.5 lepiej nie ryzykować z kopiowaniem plików. Możemy również wykorzystać mysqldump lub bardzo dobrą aplikację Percona XtraBackup.
Najprostszą i uniwersalną metodą niezależną od używanego przez bazę silnika jest mysqldump. Sprawa komplikuje się nieco, kiedy do zarchiwizowania jest duża porcja danych. Zrzut danych do formatu SQL bazy (MyISAM) o rozmiarze 3.3 GB trwało ~14 min na mało obciążonej maszynie (CPU: ATOM N2800 2 rdzenie/2 wątki, dysk 2 X 500 GB RAID 0/1) ale już jej przywrócenie trwało ~70 min.
Ja skupię się na metodzie binarnej (kopiowanie plików) i na narzędziu mysqldump.
Jak już wcześniej pisałem podstawowym kryterium doboru metody wykonania kopii jest silnik bazy danych. Sprawdzić możemy na kilka sposobów np:
# mysqlshow -u userName --status nazwa_bazy_danych -p
Enter password:
Database: mysql
+---------------------------+--------+---------+------------+------+----------------+-------------+--------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+---------------------------------------------------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+---------------------------+--------+---------+------------+------+----------------+-------------+--------------------+--------------+-----------+----------------+---------------------+---------------------+---------------------+-------------------+----------+----------------+---------------------------------------------------+
| columns_priv | MyISAM | 10 | Fixed | 0 | 0 | 0 | 227994731135631359 | 4096 | 0 | | 2013-04-23 00:34:12 | 2013-04-23 00:34:12 |
Znając już silnik bazy danych możemy przystąpić do działania.
Metoda binarna ( TYLKO MyISAM !!! )
- maszyna_1
- Lokalizujemy miejsce, gdzie znajdują się pliki baz danych poleceniem: grep datadir /etc/mysql/my.cnf (Debian) lub grep datadir /etc/my.cnf (Red Hat/Fedora/Centos), zakładam standardową lokalizację Debiana /var/lib/mysql
- Blokujemy możliwość zapisywania danych do tabel na dwa sposoby:
- Wydając polecenie w konsoli MySQL: FLUSH TABLES WITH READ LOCK;
- Wyłączając serwer MySQL: /etc/init.d/mysql stop
- Kopiujemy interesującą nas bazę: cp -R /var/lib/mysql/baza_danych /home/backup
- Jeśli użyliśmy polecenia FLUSH TABLES..., to teraz należy zdjąć blokadę logując się do konsoli MySQL wydając polecenie UNLOCK TABLES;
- Pozostaje skopiować katalog z bazą na drugą maszynę: scp -r /home/backup/baza_danych user@maszyna_2:/home/user
- maszyna_2
- Kopiujemy katalog bazy do katalogu gdzie są przechowywane katalogi z bazami: cp -R /home/user/dodana_baza /var/lib/mysql
- Teraz można sprawdzić, że MySQL już widzi dodaną bazę:
# mysql -u user -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.xxx
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| dodana_baza |
+--------------------+
3 rows in set (0.00 sec)
mysql> use dodana_baza
Database changed
mysql> show tables;
ERROR 1018 (HY000): Can't read dir of './dodana_baza/' (errno: 13)
Narzędzie mysqldump
Bez wątpienia jest to chyba najpopularniejsza metoda backupu bazy MySQL. Mysqldump wykonuje zrzut danych do formatu SQL lub XML. Na początek kilka opcji:
Opis | Znaczenie |
---|---|
-u username | nazwa użytkownika |
-p hasło | hasło użytkownika |
-h adres IP/nazwa domenowa | adres zdalnego serwera |
--port=numer portu | port nasłuchu zdalnego serwera, jeśli jest inny niż 3306 |
--databases baza1 baza2... | zrzut kilku baz jednocześnie |
--all-databases | zrzut wszystkich baz |
--no-data | zrzut struktury bazy pomijając dane |
--no-create-info | zrzut tylko samych danych bez struktury (tabele, pola, indeksy...) |
--ignore-table=nazwa_tabeli | pomija przy zrzucie tabelę o podanej nazwie |
--add-drop-database | przywracanie bazy danych przy jednoczesnym usunięciu istniejącej |
--add-drop-table | przywracanie tabeli przy jednoczesnym usunięciu istniejącej |
--default-character-set=utf8 | domyślne kodowanie znaków |
--xml | zrzut bazy danych do formatu xml |
Wynik pracy narzędzia mysqldump jest przekazywany na standardowe wyjście, czyli najczęściej ekran monitora, dlatego my przekierujemy cały potok do pliku (np. polecenie > plik.out). NALEŻY PAMIĘTAĆ O ODPOWIEDNICH UPRAWNIENIACH UŻYTKOWNIKA DO BAZY DANYCH ! Zarówno po opcji -u jak i -p nie musimy używać spacji. W przypadku tworzenia kopii zapasowej z konsoli nie musimy podawać hasła, aplikacja sama się o nie zapyta i w związku z tym nie zapisze się w historii. Hasło musimy podać jedynie kiedy używamy mysqldump w skrypcie.
...i na koniec kilka przykładów:
Polecenie | Znaczenie |
---|---|
zrzut lokalnej bazy danych | mysqldump -uuserName -p nazwa_bazy > nazwa_bazy.sql |
zrzut lokalnych baz danych | mysqldump -uuserName -p --databases baza_1 baza_2 baza_3 > bazy.sql |
zrzut wszystkich lokalnych baz danych | mysqldump -uuserName -p --all-databases > wszytskie_bazy.sql |
zrzut wybranych tabel | mysqldump -uuserName -p nazwa_bazy nazwa_tabeli_1 nazwa_tabeli_2 > nazwa_bazy.sql |
zrzut bazy danych z pominięciem wyszczególnionych tabel ( nazwa tabeli poprzedzona nazawą bazy !) | mysqldump -uuserName -p -ignore-table nazwa_bazy.nazwa_tabeli > nazwa_bazy.sql |
kopia samej struktury bazy bez danych | mysqldump -uuserName -p --no-data nazwa_bazy_danych > nazwa_bazy_danych.sql |
zrzut bazy danych do formatu xml, kodowanie utf-8 | mysqldump -uuserName -p --default-character-set=utf8 --xml nazwa_bazy_danych > nazwa_bazy.xml |
zrzut i kompresja bazy danych (bardzo efektywne w przypadku dużych baz) | mysqldump -uuserName -p nazwa_bazy | gzip > nazwa_bazy.gz |
zrzut bazy danych z jednoczesną kopią pliku na zdalny serwer | mysqldump -uuserName -p nazwa_bazy | ssh userName@zdalny_host 'cat > /scieżka/nazwa_bazy.sql' |
zrzut bazy danych ze zdalnego hosta | mysqldump -h ip/domena_zdalnej_maszyny -uuserName -p nazwa_bazy > nazwa_bazy.sql |
Backup bazy danych na zdalną maszynę wraz z aktualizacją
Często dostęp z zewnątrz do serwera MySQL jest zablokowany. Wtedy ostatnia pozaycja z powyższych przykładów nie zadziała. Można to łatwo obejść za pomocą ssh. Na zdalnym serwerze musi istnieć choćby pusta baza.
mysqldump -uroot -p hasło nazwa_bazy | ssh userName@zdalny_host mysql -uuserName -p hasło nazwa_bazy
Przywracanie kopii zapasowej bazy danych MySQL
Przywracanie bazy danych nie jest skomplikowane: mysql -uuserName nazwa_bazy < nazwa_bazy.sql -p, gdzie baza już musi istnieć.
Powrót »