Должен ли я сделать резервную копию и восстановить базу данных `mysql`?

15

В процессе создания автоматизированного решения для резервного копирования и восстановления всего сервера MySQL я натолкнулся на mysqlбазу данных, которая, кажется, содержит учетные записи пользователей, разрешения, метаданные и тому подобное. Нужно ли создавать резервную копию этой базы данных? Будет ли резервное копирование и попытка восстановить это сломать вещи?

У меня было чертовски много времени, когда я гуглял "mysql для резервного копирования базы данных mysql", как вы можете себе представить.

Дэниэл Бердсли
источник
3
Чтобы выполнить полное восстановление, вам нужно сделать резервную копию всего, кроме базы данных «information_schema».
Джон Гарденье

Ответы:

16

Вот кое-что интересное: резервное копирование mysqlбазы данных сильно ограничивает вас тем, что вы можете восстановить такую ​​базу данных только до той же версии mysql, с которой вы выполняли резервное копирование. Вот почему:

Вот mysql.user из 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)

Вот mysql.user из 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)

Вот mysql.user из 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)

Если вы попытаетесь восстановить mysql.user до версии MySQL, для которой он не предназначен, это приведет к случайным проблемам с разрешениями. Способ резервного копирования пользовательских разрешений mysql в зависимости от версии - сбросить пользовательские разрешения в SQL. Таким образом, пользовательские гранты полностью переносимы. Есть два способа сделать это:

ВАРИАНТ № 1: Использование MAATKIT

mk-show-grants сгенерирует необходимый SQL-запрос независимо от того, к какому экземпляру mysql вы подключаетесь. (Имейте в виду, что MAATKIT переносится в Percona Toolkit. Этот инструмент, скорее всего, будет называться pt-show-grants).

ВАРИАНТ № 2: Сценарий сброса SQL-грантов

Я написал свою собственную эмуляцию mk-show-grants. Это исключит анонимных пользователей. Это выглядит так:

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

Использование любого из этих параметров создаст более стабильную резервную копию пользовательских грантов.

НА ОТДЕЛЬНОМ ПРИМЕЧАНИЕ

Теперь, если вы используете эту опцию вывода журнала

[mysqld]
log-output=TABLE

база данных mysql заполняет медленный журнал (если он включен) как таблицу mysql в схеме mysql, а не как текстовый файл. Таким образом, создание физических резервных копий будет включать такие журналы на основе таблиц mysql. Поверьте, это не стоит дискового пространства, если общий лог и медленный журнал запросов включены и накапливаются в схеме mysql. Просто придерживайтесь опций дампов MySQL Grants.

ОБНОВЛЕНИЕ 2011-09-19 15:54 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Существует один очень важный фактор в поддержке резервного копирования разрешений MySQL с помощью грантов SQL:

Каждый пользователь выходит со своим паролем в каком-то измененном формате MD5. Для mysql 4.0 и обратно это шестнадцатеричная строка из 16 символов. Для mysql 4.1+ это 41 символ (звездочка, за которой следует шестнадцатеричная строка из 40 символов).

Прежде чем восстанавливать дамп SQL-грантов, проверьте файл дампа SQL-грантов на наличие 16-значных шестнадцатеричных паролей. Если вы видите даже один, вы должны добавить следующее в /etc/my.cnf (или my.ini для Windows) на сервере MySQL, на который вы будете восстанавливать:

[mysqld]
old_password=1

Old_password директива разрешает 16-полукокса и 41 преобразовывались пароли сосуществовать и правильно аутентификации в том же экземпляре Запуск MySQL. Все пароли, созданные в будущем, будут состоять из 16 символов.

Перезапуск MySQL не требуется. Просто запустите это:

SET GLOBAL old_password = 1;
RolandoMySQLDBA
источник
+1 за полный ответ.
Мирча Вутцовичи
1
Я бы лучше SHOW GRANTSQUOTE()SELECT CONCAT('SHOW GRANTS FOR ',QUOTE(user),'@',QUOTE(host),';') FROM mysql.user WHERE user<>'';
записал
11

Да, вы определенно хотите сделать резервную копию mysqlбазы данных - это неотъемлемая часть вашего сервиса. Несмотря на то, что вы можете восстановить его содержимое из другой информации, сложность сделать это непомерно высока, если вы пытаетесь быстро вернуться к обслуживанию.

ombble
источник
1
+1 Если вы не сделаете резервную копию базы данных mysql, вероятность того, что система будет повреждена после восстановления, очень высока. Был там, сделал это, получил психические шрамы, чтобы доказать это.
Джон Гарденье
6

Вы можете восстановить базу данных mysql между версиями, по крайней мере, относительно недавних версий. В mysql_upgradeновые версии MySQL включен инструмент , который обновит системные таблицы для вас.

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

HampusLi
источник
Это очень верно. Я видел случаи, когда некоторые используют это и обновляют просто отлично. Я видел, как другие убивали его. С моей точки зрения, как MySQL DBA. Я потерял веру в этот метод. Поскольку ваш ответ отражает твердую веру в его использование, вы должны быть из первой группы. +1 за такую ​​уверенность в mysql_upgrade.
RolandoMySQLDBA
Когда я импортировал свой 5.6 в версию 8.0, он потерял работу сервера.
PHPst
5

Пока вы восстанавливаете аналогичную версию mysql, вы можете восстановить базу данных mysql из резервной копии. Если вы сомневаетесь, просто проведите различие между схемами базы данных mysql (из резервной копии и из нового сервера mysql).

Мирча Вуцовичи
источник
+1 за упоминание о восстановлении mysql до той же версии, с которой вы сделали резервную копию.
RolandoMySQLDBA