Czy powinienem wykonać kopię zapasową i przywrócić bazę danych `mysql`?

15

W trakcie tworzenia zautomatyzowanego rozwiązania do tworzenia kopii zapasowych i przywracania całego serwera MySQL natrafiłem na mysqlbazę danych, która wydaje się zawierać konta użytkowników, uprawnienia, metadane itp. Czy należy wykonać kopię zapasową tej bazy danych? Czy tworzenie kopii zapasowej i próba jej przywrócenia spowoduje uszkodzenie?

Miałem trochę czasu, że Googling na „mysql tworzy kopię zapasową bazy danych mysql”, jak można sobie wyobrazić.

Daniel Beardsley
źródło
3
Aby wykonać pełne przywracanie, musisz wykonać kopię zapasową wszystkiego oprócz bazy danych „information_schema”.
John Gardeniers,

Odpowiedzi:

16

Oto coś interesującego do rozważenia: Tworzenie kopii zapasowej mysqlbazy danych znacznie Cię ogranicza, ponieważ możesz przywrócić taką bazę tylko do tej samej wersji mysql, z której uruchomiono kopię zapasową. Oto dlaczego:

Oto mysql.user z MySQL 5.0.45

mysql> desc mysql.user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     |         |       |
| x509_issuer           | blob                              | NO   |     |         |       |
| x509_subject          | blob                              | NO   |     |         |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+
37 rows in set (0.01 sec)

Oto mysql.user z MySQL 5.1.32

mysql> desc mysql.user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Event_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Trigger_priv          | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     | NULL    |       |
| x509_issuer           | blob                              | NO   |     | NULL    |       |
| x509_subject          | blob                              | NO   |     | NULL    |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+
39 rows in set (0.00 sec)

Oto mysql.user z MySQL 5.5.12

mysql> desc mysql.user;
+------------------------+-----------------------------------+------+-----+---------+-------+
| Field                  | Type                              | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+---------+-------+
| Host                   | char(60)                          | NO   | PRI |         |       |
| User                   | char(16)                          | NO   | PRI |         |       |
| Password               | char(41)                          | NO   |     |         |       |
| Select_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv              | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv           | enum('N','Y')                     | NO   |     | N       |       |
| File_priv              | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv             | enum('N','Y')                     | NO   |     | N       |       |
| References_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv  | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv     | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Event_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Trigger_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_tablespace_priv | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type               | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher             | blob                              | NO   |     | NULL    |       |
| x509_issuer            | blob                              | NO   |     | NULL    |       |
| x509_subject           | blob                              | NO   |     | NULL    |       |
| max_questions          | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates            | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections        | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections   | int(11) unsigned                  | NO   |     | 0       |       |
| plugin                 | char(64)                          | YES  |     |         |       |
| authentication_string  | text                              | YES  |     | NULL    |       |
+------------------------+-----------------------------------+------+-----+---------+-------+
42 rows in set (0.01 sec)

Próba przywrócenia pliku mysql.user do wersji MySQL, do której nie był przeznaczony, spowoduje losowe problemy z uprawnieniami. Sposobem na wykonanie kopii zapasowej uprawnień użytkownika mysql w sposób niezależny od wersji jest zrzucenie przyznanych uprawnień użytkownika w SQL. W ten sposób granty użytkownika są całkowicie przenośne. Istnieją dwa sposoby na osiągnięcie tego:

OPCJA 1: Korzystanie z MAATKIT

mk-show-grants wygeneruje SQL potrzebny do dowolnej instancji mysql, z którą się łączysz. (Należy pamiętać, że MAATKIT jest migrowany do Percona Toolkit. To narzędzie najprawdopodobniej nazywa się pt-show-grants).

OPCJA 2: Skrypt zrzuć DOTACJE SQL

Napisałem własną emulację grantów mk-show-grants. Pominie anonimowych użytkowników. To wygląda tak:

mysql -hhostaddr -umyuserid -pmypassword --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql -hhostaddr -umyuserid -pmypassword --skip-column-names -A | sed 's/$/;/g' > MySQLUserGrants.sql

Użycie jednej z tych opcji spowoduje utworzenie bardziej stabilnej kopii zapasowej dotacji użytkowników.

NA ODDZIELNEJ INFORMACJI

Teraz, jeśli używasz tej opcji log-output

[mysqld]
log-output=TABLE

baza danych mysql zapełni wolny dziennik (jeśli jest włączony) jako tabelę mysql w schemacie mysql zamiast w pliku tekstowym. Tak więc wykonywanie fizycznych kopii zapasowych będzie obejmować takie dzienniki oparte na tabeli mysql. Uwierz mi, nie jest warte miejsca na dysku, jeśli dziennik ogólny i dziennik wolnych zapytań są włączone i gromadzą się w schemacie mysql. Po prostu trzymaj się opcji zrzutu zrzutu MySQL.

AKTUALIZACJA 2011-09-19 15:54 EDT

Jest jeden bardzo ważny czynnik w utrzymywaniu kopii zapasowych uprawnień MySQL przez SQL Grants:

Każdy użytkownik wychodzi ze swoim hasłem w jakimś zmodyfikowanym formacie MD5. W przypadku mysql 4.0 i starszych jest to 16-znakowy ciąg szesnastkowy. W mysql 4.1+ jest to 41 znaków (gwiazdka, po której następuje 40-znakowy ciąg szesnastkowy).

Przed przywróceniem zrzutu SQL Grants sprawdź plik zrzutu SQL Grants pod kątem 16-znakowych haseł szesnastkowych. Jeśli widzisz choć jeden, musisz dodać następujące pliki do /etc/my.cnf (lub my.ini dla Windows) na serwerze mysql, na którym przywrócisz:

[mysqld]
old_password=1

Old_password dyrektywa dopuszcza 16-char i 41-char haseł współistnieć i prawidłowo uwierzytelniać w tej samej instancji bieg mysql. Wszelkie hasła utworzone w przyszłości będą miały 16 znaków.

Ponowne uruchomienie MySQL nie jest wymagane. Po prostu uruchom to:

SET GLOBAL old_password = 1;
RolandoMySQLDBA
źródło
+1 za pełną odpowiedź.
Mircea Vutcovici,
1
Lepiej przeliteruję SHOW GRANTSgenerację SQL, używając QUOTE():SELECT CONCAT('SHOW GRANTS FOR ',QUOTE(user),'@',QUOTE(host),';') FROM mysql.user WHERE user<>'';
kostix
11

Tak, zdecydowanie chcesz wykonać kopię zapasową mysqlbazy danych - jest to integralna część twojej usługi. Podczas można odtworzyć jego zawartość od innych informacji, trudności w ten sposób są wygórowane, jeśli starasz się wrócić do służby szybko.

womble
źródło
1
+1 Jeśli nie wykonasz kopii zapasowej bazy danych mysql, prawdopodobieństwo uszkodzenia systemu po przywróceniu jest bardzo wysokie. Byłem tam, zrobiłem to, mam blizny mentalne, aby to udowodnić.
John Gardeniers,
6

Możesz przywrócić bazę danych mysql między wersjami, przynajmniej nowszymi wersjami. Istnieje narzędzie o nazwie mysql_upgradezawarte w nowych wersjach MySQL, które uaktualni dla ciebie tabele systemowe.

http://dev.mysql.com/doc/refman/5.0/en/mysql-upgrade.html

HampusLi
źródło
To najprawdziwsza prawda. Widziałem przypadki, w których niektórzy używają tego i aktualizują się idealnie. Widziałem innych rzeźników. Z mojego punktu widzenia jako MySQL DBA. Straciłem wiarę w tę metodę. Ponieważ twoja odpowiedź odzwierciedla solidną wiarę w jej użycie, musisz pochodzić z pierwszej grupy. +1 za takie zaufanie do mysql_upgrade.
RolandoMySQLDBA
Kiedy zaimportowałem mój 5.6 do wersji 8.0, zepsuł serwer.
PHPst
5

Tak długo, jak przywracasz do podobnej wersji mysql, możesz przywracać bazę danych mysql z kopii zapasowej. Jeśli masz wątpliwości, po prostu różnicuj schematy bazy danych mysql (ten z kopii zapasowej i ten z nowego serwera mysql).

Mircea Vutcovici
źródło
+1 za to, że jako pierwszy wspomniał o przywracaniu mysql do tej samej wersji, z której wykonałeś kopię zapasową.
RolandoMySQLDBA