web-dev-qa-db-fra.com

Comment identifiez-vous la corruption de la table InnoDB?

J'ai quelques tables qui sont partitionnées et ont plusieurs index sur un esclave répliqué. Après avoir copié l'instantané (vérifié en toute sécurité) sur un nouvel esclave et mis à niveau mysqld de 5.1.42 à 5.5.15 et redémarré la réplication, je reçois des plantages d'InnoDB avec le message d'erreur "Pointeur invalide ..."

Ces erreurs se sont produites sur 2 serveurs avec du matériel et des O/S différents. Après l'exécution:

ALTER TABLE .... COALESCE PARTION n;

le problème disparaît pour cette table.

Ma question est plus large, cependant, et c'est "Comment identifiez-vous la corruption de la table InnoDB?" ou reformulé "Comment évaluez-vous la santé de la table InnoDB?" "CHECK TABLE" est-il le seul outil disponible pour identifier les problèmes avant le crash?

Je ne sais pas si cela importe, mais les plantages se sont produits en cours d'exécution: Version: socket '5.5.15-55-log': port '/opt/mysql.sock': 3306 Percona Server (GPL), Release rel21.0, Revision 158

24
randomx

Morgan donne un indice dans son commentaire qu'InnoDB vérifie constamment les pages corrompues en faisant des sommes de contrôle sur les pages qu'il lit. Si InnoDB trouve une incompatibilité de somme de contrôle, il crash arrêtez le serveur.

Si vous souhaitez accélérer ce processus (au lieu d'attendre qu'InnoDB lise la page corrompue), vous pouvez utiliser innochecksum :

Étant donné que les incompatibilités de somme de contrôle entraîneront délibérément InnoDB à arrêter un serveur en cours d'exécution, il peut être préférable d'utiliser cet outil plutôt que d'attendre qu'un serveur en utilisation de production rencontre les pages endommagées.

Une mise en garde intéressante:

innochecksum ne peut pas être utilisé sur des fichiers d'espace disque logique que le serveur a déjà ouverts. Pour ces fichiers, vous devez utiliser CHECK TABLE pour vérifier les tables dans l'espace disque logique.

Alors oui, pour une table en ligne CHECK TABLE est probablement l'outil (ou comme indiqué dans une autre réponsemysqlcheck si vous voulez faire plus d'une base de données à la fois.)

Si vous pouvez fermer votre base de données, vous pouvez forcer la somme de contrôle à l'aide de innochecksum

Anecdotique: Sur un tablespace innodb de 29 Go (avec innodb_file_per_table=1), ce script a pris environ 2 minutes

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

En bonus, cependant, puisque vous utilisez Percona, ils ont implémenté une nouvelle méthode pour somme de contrôle innodb rapide . Je ne l'ai jamais utilisé, mais cela pourrait accélérer le processus.

18
Derek Downey

AVERTISSEMENT: avant d'essayer l'une de ces instructions, il est fortement recommandé de vérifier qu'il existe une sauvegarde saine de votre base de données entre les mains, au cas où. (merci à @Nick pour l'avertissement)

Essayez d'utiliser la commande mysqlcheck. Sur un terminal:

mysqlcheck -u username -p --databases database1 database2

Cette commande affichera une liste de toutes les tables et un état vous indiquant s'il y a eu une sorte de corruption:

table1  OK
table2  OK
table3  OK
tableN  OK

Avec cela en main, vous saurez déjà quelles tables vous devez réparer. Juste au cas où vous voudriez tout réparer en même temps:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

En savoir plus sur mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

Remarque: vous avez marqué votre question avec percona . Je n'avais aucune idée de ce que c'était, alors j'ai googlé. Cela semble être un fork de MySQL, mais je n'ai aucune raison de croire que les commandes sont incompatibles (doigts croisés).


Quelqu'un m'a indiqué ce guide qui contient des instructions plus spécifiques pour la récupération de la base de données InnoDB pour les situations plus critiques où la base de données entière ne démarre pas: http://www.softwareprojects.com/resources/programming/t-how-to -fix-mysql-database-myisam-innodb-1634.html

6
marcio

Selon Guide d'étude de certification MySQL 5.0, page 443 444, section 30.4 :

Vous pouvez vérifier les tables InnoDB en utilisant la commande CHECK TABLE ou en utilisant un programme client pour émettre l'instruction pour vous. Cependant, si une table InnoDB a des problèmes, vous ne pouvez pas la résoudre en utilisant REPAIR TABLE car cette instruction s'applique uniquement à MyISAM.

Si une vérification de table indique qu'une table InnoDB a des problèmes, vous devriez pouvoir restaurer la table dans un état cohérent en la vidant avec mysqldump, en la supprimant et en la recréant à partir de ce vidage.

En cas de panne d'un serveur MySQL ou de l'hôte sur lequel il s'exécute, certaines tables InnoDB pourraient avoir besoin de réparations. Normalement, il suffit de redémarrer le serveur car le moteur de stockage InnoDB effectue une récupération automatique dans le cadre de sa séquence de démarrage. Dans de rares cas, le serveur peut ne pas démarrer en raison de l'échec de la récupération automatique d'InnoDB. Si cela se produit, utilisez la procédure suivante:

  • Redémarrez le serveur avec l'option --innodb_force_recovery définie sur une valeur comprise entre 1 et 6. Ces valeurs indiquent des niveaux de prudence croissants pour éviter un plantage et des niveaux de tolérance croissants pour une éventuelle incohérence dans les tables récupérées. Une bonne valeur pour commencer est 4.

  • Lorsque vous démarrez le serveur avec --innodb_force_recovery défini sur une valeur non nulle, InnoDB traite l'espace disque logique en lecture seule. Par conséquent, vous devez vider les tables InnoDB avec mysqldump puis les supprimer pendant que l'option est en vigueur. Redémarrez ensuite le serveur sans l'option --innodb_force_recovery. Lorsque le serveur démarre, récupérez les tables InnoDB à partir des fichiers de vidage.

  • Si les étapes précédentes échouent, il est nécessaire de restaurer les tables InnoDB à partir d'une sauvegarde précédente.

Veuillez lire la documentation MySQL sur InnoDB Forced Recovery

6
RolandoMySQLDBA

Je me demande ce qui se passe si quelqu'un utilise les données InnoDB créées via le plug-in InnoDB et passe ensuite à une autre version d'InnoDB. Cela pourrait créer une possible corruption de page aux yeux de mysqld.

Notez ce que la documentation MySQL sur le format de fichier InnoDB dit à propos de cette possibilité:

En général, une nouvelle version d'InnoDB peut créer une table ou un index qui ne peut pas être lu ou écrit en toute sécurité avec une version antérieure d'InnoDB sans risque de plantage, de blocage, de mauvais résultats ou de corruption. Le plugin InnoDB introduit un nouveau mécanisme pour se prémunir contre ces conditions et pour aider à préserver la compatibilité entre les fichiers de base de données et les versions d'InnoDB.

Je ferais disparaître les données de l'esclave. En fait, je voudrais simplement utiliser la force brute en obtenant un vidage logique (mysqldump) des données:

  • Supprimez toutes les bases de données à l'aide d'InnoDB sur l'esclave
  • Arrêter mysql sur l'esclave
  • Supprimer ibdata1, ib_logfile0 et ib_logfile1 sur l'esclave
  • Démarrez mysql sur l'esclave, en laissant recréer ibdata1, ib_logfile0 et ib_logfile1
  • mysqldump les données du maître dans l'esclave

Ma réponse originale publiée est considérée comme de la "vieille école". Pourtant, dans ce cas, j'examinerais certainement les formats de fichiers utilisés par .ibd et/ou ibdata1.

2
RolandoMySQLDBA