Comment identifiez-vous la corruption de la table InnoDB?

24

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?" Est « CHECK TABLE » le seul outil disponible pour identifier les problèmes pré-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

randomx
la source
2
Salut Randy! Je pense que les réponses ici sont crédibles - InnoDB a identifié sa propre corruption. Vous devriez peut-être reformuler votre question, pourquoi ce que vous faites causerait-il la corruption d'InnoDB?
Morgan Tocker

Réponses:

18

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 différence de somme de contrôle, il se bloquer arrêter 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 les 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 TABLEest probablement l'outil (ou comme indiqué dans une autre réponse mysqlcheck si vous voulez faire plus d'une seule 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 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 exécutez Percona, ils ont implémenté une nouvelle méthode pour la somme de contrôle innodb rapide . Je ne l'ai jamais utilisé, mais cela pourrait accélérer le processus.

Derek Downey
la source
1
Je vais essayer ici, semble être la solution @randymelder recherche +1
marcio
2
Le serveur Percona a d'autres fonctionnalités intéressantes. Voir innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability/… (!!)
Morgan Tocker
@DTest: innochecksum est la voie à suivre. Celui-ci est un gardien. +1 !!!
RolandoMySQLDBA
@DTest: Chapeau à vous aujourd'hui sur celui-ci !!!!
RolandoMySQLDBA
@MorganTocker Intéressant. Il va falloir que je récupère mes connaissances et que je fasse des recherches sur Percona
Derek Downey
6

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 mysqlcheckcommande. 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 tagué votre question avec . 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

marcio
la source
1
mysqlcheck est synonyme de 'check table ...' -1
randomx
Pas vrai. Premièrement, mysqlcheck est un utilitaire de ligne de commande et CHECK TABLE est une instruction SQL (c'est comme comparer orange à lemmons). De plus, vous NE POUVEZ PAS vérifier une base de données entière avec CHECK TABLE sans inclure TOUS les noms de table dans l'instruction SQL ( ce ne serait pas très productif aussi)
marcio
Et mysqlcheck a une option pour --auto-réparer les tables qui sont corrompues tandis que CHECK TABLE vérifie seulement si les tables sont corrompues ou non, mais ne peut effectuer aucune réparation.
marcio
2
@randymelder - Vous avez tort de dire que mysqlcheck est synonyme de CHECK TABLE. La documentation que vous avez lié aux Etats: " mysqlcheckutilise les instructions SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLEet OPTIMIZE TABLEil détermine les déclarations à utiliser pour l'opération que vous souhaitez effectuer d'une manière pratique pour l'utilisateur, et envoie ensuite les instructions au serveur à exécuter.. " Ce n'est pas un synonyme; c'est une interface utilisateur pour une collection d'instructions.
Nick Chammas
6

Selon le 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 MySQL Docs sur InnoDB Forced Recovery  

RolandoMySQLDBA
la source
3
FWIW, le guide de certification a une réponse très politiquement correcte :) Si vous VERIFIEZ TABLE sur une table InnoDB et qu'elle est réellement corrompue, elle ne reviendra jamais comme "corrompue", elle plantera le serveur. L'instruction est presque obsolète dans InnoDB, car chaque fois que vous lisez des pages InnoDB, elle vérifie la corruption (via les sommes de contrôle de page).
Morgan Tocker
2

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 dit la documentation MySQL sur le format de fichier InnoDB à 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 plug-in 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.

RolandoMySQLDBA
la source