¿Debo hacer una copia de seguridad y restaurar la base de datos `mysql`?

15

En el proceso de crear una solución automatizada para realizar copias de seguridad y restaurar un servidor MySQL completo , me encontré con la mysqlbase de datos que parece contener cuentas de usuario, permisos, metadatos, ese tipo de cosas. ¿Se debe hacer una copia de seguridad de esta base de datos? ¿Hacer copias de seguridad e intentar restaurarlo romperá las cosas?

He tenido un gran momento buscando en Google "copia de seguridad de mysql de la base de datos mysql" como te puedes imaginar.

Daniel Beardsley
fuente
3
Para realizar una restauración completa, debe hacer una copia de seguridad de todo excepto la base de datos "information_schema".
John Gardeniers

Respuestas:

16

Aquí hay algo interesante a considerar: Hacer una copia de seguridad de la mysqlbase de datos lo limita enormemente, ya que solo puede restaurar dicha base de datos a la misma versión de mysql desde la que ejecutó la copia de seguridad. Aquí es por qué:

Aquí está mysql.user de 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)

Aquí está mysql.user de 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)

Aquí está mysql.user de 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)

Si intenta restaurar mysql.user a una versión de MySQL para la que no estaba destinado, producirá problemas de permisos aleatorios. La forma de hacer una copia de seguridad de los permisos de usuario de mysql de una manera independiente de la versión es volcar las concesiones de usuario en SQL. De esa manera, las subvenciones de los usuarios son completamente portátiles. Hay dos maneras de lograr esto:

OPCIÓN # 1: Usar MAATKIT

mk-show-Grant generará el SQL necesario para cualquier instancia de mysql a la que se conecte. (Tenga en cuenta que MAATKIT se está migrando a Percona Toolkit. Esta herramienta probablemente se denominará pt-show-grant).

OPCIÓN # 2: Script el volcado de las SUBVENCIONES SQL

He escrito mi propia emulación de mk-show-grant. Dejará fuera a los usuarios anónimos. Se parece a esto:

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

El uso de cualquiera de estas opciones creará una copia de seguridad más estable de las subvenciones de los usuarios.

EN UNA NOTA SEPARADA

Ahora, si está utilizando esta opción de salida de registro

[mysqld]
log-output=TABLE

la base de datos mysql completará el registro lento (si está habilitado) como una tabla mysql en el esquema mysql en lugar de un archivo de texto. Por lo tanto, hacer copias de seguridad físicas incluirá dichos registros basados ​​en tablas mysql. Créame, no vale la pena el espacio en disco si el registro general y el registro de consulta lenta están habilitados y se acumulan en el esquema mysql. Simplemente quédese con las opciones de volcado de subvenciones de MySQL.

ACTUALIZACIÓN 2011-09-19 15:54 EDT

Hay un factor muy importante en el mantenimiento de copias de seguridad de los permisos de MySQL a través de SQL Grants:

Cada usuario obtiene su contraseña en algún formato MD5 modificado. Para mysql 4.0 y versiones anteriores, es una cadena hexadecimal de 16 caracteres. Para mysql 4.1+, tiene 41 caracteres (un asterisco seguido de una cadena hexadecimal de 40 caracteres).

Antes de restaurar un volcado de Grants de SQL, revise el archivo de volcado de Grants de SQL para ver las contraseñas hexadecimales de 16 caracteres. Si ve incluso uno, debe agregar lo siguiente a /etc/my.cnf (o my.ini para Windows) en el servidor mysql al que restaurará:

[mysqld]
old_password=1

La directiva old_password permite que las contraseñas 16-char y 41-char coexistan y se autentiquen correctamente en la misma instancia de mysql en ejecución. Cualquier contraseña creada en adelante será de 16 caracteres.

No se requiere reiniciar MySQL. Solo ejecuta esto:

SET GLOBAL old_password = 1;
RolandoMySQLDBA
fuente
+1 para una respuesta completa.
Mircea Vutcovici
1
Mejor deletrearía la SHOW GRANTSgeneración de SQL usando QUOTE(), así:SELECT CONCAT('SHOW GRANTS FOR ',QUOTE(user),'@',QUOTE(host),';') FROM mysql.user WHERE user<>'';
kostix
11

Sí, definitivamente desea hacer una copia de seguridad de la mysqlbase de datos, es una parte integral de su servicio. Si bien puede reconstruir su contenido a partir de otra información, la dificultad de hacerlo es prohibitiva si está tratando de volver al servicio rápidamente.

womble
fuente
1
+1 Si no realiza una copia de seguridad de la base de datos mysql, las probabilidades de tener un sistema dañado después de realizar una restauración son muy altas. He estado allí, hecho eso, tengo las cicatrices mentales para probarlo.
John Gardeniers
6

Puede restaurar la base de datos mysql entre versiones, al menos versiones bastante recientes. Hay una herramienta llamada mysql_upgradeincluida en las nuevas versiones de MySQL que actualizará las tablas del sistema por usted.

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

HampusLi
fuente
Esto es muy cierto. He visto casos en los que algunos usan esto y se actualizan perfectamente. He visto a otros matarlo. Desde mi punto de vista como MySQL DBA. He perdido la fe en ese método. Como su respuesta refleja una fe sólida en su uso, debe ser del primer grupo. +1 por tanta confianza en mysql_upgrade.
RolandoMySQLDBA
Cuando importé mi versión 5.6 a 8.0, echó a perder el servidor.
PHPst
5

Siempre que restaure a una versión similar de mysql, puede restaurar la base de datos mysql desde una copia de seguridad. Si tiene dudas, simplemente haga una diferencia entre los esquemas de la base de datos mysql (el del respaldo y el del nuevo servidor mysql).

Mircea Vutcovici
fuente
+1 por ser el primero en mencionar la restauración de mysql a la misma versión de la que realizó la copia de seguridad.
RolandoMySQLDBA