Dois-je sauvegarder et restaurer la base de données `mysql`?

15

En train de créer une solution automatisée pour sauvegarder et restaurer un serveur MySQL entier , je suis tombé sur la mysqlbase de données qui semble contenir des comptes d'utilisateurs, des autorisations, des métadonnées, ce genre de chose. Cette base de données doit-elle être sauvegardée? Est-ce que la sauvegarde et la tentative de restauration vont casser les choses?

J'ai eu un sacré temps sur Google pour "mysql sauvegarder la base de données mysql" comme vous pouvez l'imaginer.

Daniel Beardsley
la source
3
Pour effectuer une restauration complète, vous devez tout sauvegarder sauf la base de données "information_schema".
John Gardeniers

Réponses:

16

Voici quelque chose d'intéressant à considérer: La sauvegarde de la mysqlbase de données vous limite considérablement dans la mesure où vous ne pouvez restaurer une telle base de données que dans la même version de mysql à partir de laquelle vous avez exécuté la sauvegarde. Voici pourquoi:

Voici 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)

Voici 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)

Voici 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 vous tentez une restauration de mysql.user vers une version de MySQL à laquelle il n'était pas destiné, cela produira des problèmes d'autorisation aléatoire. La façon de sauvegarder les autorisations utilisateur mysql d'une manière indépendante de la version consiste à vider les autorisations utilisateur dans SQL. De cette façon, les subventions utilisateur sont entièrement portables. Il y a deux façons d'y parvenir:

OPTION 1: Utiliser MAATKIT

mk-show-grant générera le SQL nécessaire quelle que soit l'instance mysql à laquelle vous vous connectez. (Gardez à l'esprit que MAATKIT est en cours de migration vers Percona Toolkit. Cet outil sera très probablement appelé pt-show-grant).

OPTION # 2: Script le dumping des subventions SQL

J'ai écrit ma propre émulation de mk-show-grant. Il exclura les utilisateurs anonymes. Cela ressemble à ceci:

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

L'utilisation de l'une de ces options créera une sauvegarde plus stable des autorisations utilisateur.

SUR UNE NOTE SÉPARÉE

Maintenant, si vous utilisez cette option de sortie de journal

[mysqld]
log-output=TABLE

la base de données mysql remplira le journal lent (si activé) comme une table mysql dans le schéma mysql plutôt que comme un fichier texte. Donc, faire des sauvegardes physiques inclura de tels journaux basés sur une table mysql. Croyez-moi, cela ne vaut pas l'espace disque si le journal général et le journal des requêtes lentes sont activés et s'accumulent dans le schéma mysql. Restez avec les options de vidage de MySQL Grants.

MISE À JOUR 2011-09-19 15:54 EDT

Il existe un facteur très important dans la maintenance des sauvegardes des autorisations MySQL via les subventions SQL:

Chaque utilisateur sort son mot de passe dans un format MD5 modifié. Pour mysql 4.0 et les versions antérieures, il s'agit d'une chaîne hexadécimale de 16 caractères. Pour mysql 4.1+, il est de 41 caractères (un astérisque suivi d'une chaîne hexadécimale de 40 caractères).

Avant de restaurer un vidage SQL Grants, recherchez dans le fichier de vidage SQL Grants des mots de passe hexadécimaux à 16 caractères. Si vous en voyez un, vous devez ajouter ce qui suit à /etc/my.cnf (ou my.ini pour Windows) sur le serveur mysql sur lequel vous allez restaurer:

[mysqld]
old_password=1

La directive old_password permet aux mots de passe de 16 et 41 caractères de coexister et de s'authentifier correctement dans la même instance mysql en cours d'exécution. Tout mot de passe créé à l'avenir comportera 16 caractères.

Le redémarrage de MySQL n'est pas requis. Exécutez simplement ceci:

SET GLOBAL old_password = 1;
RolandoMySQLDBA
la source
+1 pour une réponse complète.
Mircea Vutcovici
1
Je préfère épeler la SHOW GRANTSgénération SQL en utilisant QUOTE(), comme ceci:SELECT CONCAT('SHOW GRANTS FOR ',QUOTE(user),'@',QUOTE(host),';') FROM mysql.user WHERE user<>'';
kostix
11

Oui, vous voulez vraiment sauvegarder la mysqlbase de données - elle fait partie intégrante de votre service. Bien que vous puissiez reconstruire son contenu à partir d'autres informations, la difficulté de le faire est prohibitive si vous essayez de revenir rapidement en service.

womble
la source
1
+1 Si vous ne sauvegardez pas la base de données mysql, les chances d'avoir un système cassé après avoir fait une restauration sont très élevées. J'y suis allé, j'ai fait les cicatrices mentales pour le prouver.
John Gardeniers
6

Vous pouvez restaurer la base de données mysql entre les versions, au moins des versions assez récentes. Il existe un outil appelé mysql_upgradeinclus dans les nouvelles versions de MySQL qui mettra à niveau les tables système pour vous.

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

HampusLi
la source
C'est très vrai. J'ai vu des cas où certains l'utilisent et se mettent à niveau parfaitement. J'en ai vu d'autres l'abattre. De mon point de vue en tant que DBA MySQL. J'ai perdu confiance en cette méthode. Puisque votre réponse reflète une foi solide dans son utilisation, vous devez appartenir au premier groupe. +1 pour une telle confiance en mysql_upgrade.
RolandoMySQLDBA
Lorsque j'ai importé ma version 5.6 dans la version 8.0, cela a bouché le serveur.
PHPst
5

Tant que vous restaurez dans une version similaire de mysql, vous pouvez restaurer la base de données mysql à partir d'une sauvegarde. En cas de doute, faites simplement une différence entre les schémas de base de données mysql (celui de la sauvegarde et celui du nouveau serveur mysql).

Mircea Vutcovici
la source
+1 pour avoir été le premier à mentionner la restauration de mysql dans la même version que celle que vous avez sauvegardée.
RolandoMySQLDBA