Quand innoDB nous fait des misères....
18/03/15 06:55 Classé dans: Techniques
C'était lundi noir cette semaine Mon MacBook est parti en vrille avec occupation excessive de la mémoire ce qui a provoqué un crash du système. Et lors du redémarrage de ma VM Centreon, j'ai eu la désagréable surprise du message suivant :
Grosse galère ! après quelques recherches sur le net, voici ma procédure pour résoudre ce problème. Je ne vous souhaite pas cette mésaventure, mais oui, vous avez une infrastructure redondée, ultra-sécurisée avec une sauvegarde d'enfer mais on ne sait jamais, vous en aurez peut-être besoin. D'autant qu'il n'est pas facile de réfléchir sereinement lorsque la catastrophe arrive !
Avant touche chose, sauvegardez vos bases MySQL. Vérifiez bien que vous avez assez d'espace disponible. Nous allons sauvegarder le datadir (par défaut sur Debian /var/lib/mysql) sur un autre espace.
En modifiant le fichier de configuration /etc/mysql/my.cnf, nous ajoutons l'instruction suivante :
Nous tentons de démarrer MySQL
Si le démarrage échoue, augmentez la valeur innodb_force_recovery de 1 et recommencez. Attention, quand vous arrivez à la valeur de 3, rajoutez l'instruction suivante :
Normalement MySQL devrait démarrer, si ce n'est pas le cas, désolé pour vous
Une fois MySQL démarré, vérifiez les tables.
Tout est OK, il faut passer à la sauvegarde des données.
Sauvegardez vos données afin de les réinjecter quand MySQL sera réparé. Attention à l'espace disque si vous avez beaucoup de données.
Avant de réinstaller MySQL, arrêtez la base de données. A ce stade, je n'ai pas trouvé mieux que la commande kill, car en utilisant la commande d'arrêt normal, MySQL met deux "plombes" à s'arrêter.
On vérifie les processus de MySQL.
Et on joue à l'admin system fou en killant les processus
On supprime MySQL.
On enlève les instructions innodb dans le fichier de configuration /etc/mysql/my.cnf. On supprime les données dans le datadir pour faire place nette.
On installe de nouveau MySQL.
On restaure les données de MySQL.
Votre basse de données doit fonctionner de nouveau.
Catastrophe, en y regardant de plus près, le service MySQL est arrêté. Une petite vérification des logs et le constat suivant, la base du moteur InnoDB est crashée :
Mar 16 16:11:24 central mysqld: 150316 16:11:24 InnoDB: Waiting for the background threads to start
Mar 16 16:11:24 central mysqld: InnoDB: Starting in background the rollback of uncommitted transactions
Mar 16 16:11:24 central mysqld: 150316 16:11:24 InnoDB: Rolling back trx with id 1278E, 1 rows to undo
Mar 16 16:11:24 central mysqld: 150316 16:11:24 InnoDB: Assertion failure in thread 140567022315264 in file fut0lst.ic line 83
Mar 16 16:11:24 central mysqld: InnoDB: Failing assertion: addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA
Grosse galère ! après quelques recherches sur le net, voici ma procédure pour résoudre ce problème. Je ne vous souhaite pas cette mésaventure, mais oui, vous avez une infrastructure redondée, ultra-sécurisée avec une sauvegarde d'enfer mais on ne sait jamais, vous en aurez peut-être besoin. D'autant qu'il n'est pas facile de réfléchir sereinement lorsque la catastrophe arrive !
1 sauvegarde du datadir
Avant touche chose, sauvegardez vos bases MySQL. Vérifiez bien que vous avez assez d'espace disponible. Nous allons sauvegarder le datadir (par défaut sur Debian /var/lib/mysql) sur un autre espace.
cd /var/lib
cp -vpr mysql mysql-backup
2 tentative de redémarrage MySQL
En modifiant le fichier de configuration /etc/mysql/my.cnf, nous ajoutons l'instruction suivante :
innodb_force_recovery = 1
Nous tentons de démarrer MySQL
service mysql start
Si le démarrage échoue, augmentez la valeur innodb_force_recovery de 1 et recommencez. Attention, quand vous arrivez à la valeur de 3, rajoutez l'instruction suivante :
innodb_purge_threads = 0
Normalement MySQL devrait démarrer, si ce n'est pas le cas, désolé pour vous
3 Test des tables
Une fois MySQL démarré, vérifiez les tables.
mysqlcheck -u root -ppass --all-databases
Tout est OK, il faut passer à la sauvegarde des données.
4 Sauvegarde des données
Sauvegardez vos données afin de les réinjecter quand MySQL sera réparé. Attention à l'espace disque si vous avez beaucoup de données.
mysqldump -u root -ppass --all-databases > /home/vmdebian/alldbs.sql
5 Arrêt de MySQL
Avant de réinstaller MySQL, arrêtez la base de données. A ce stade, je n'ai pas trouvé mieux que la commande kill, car en utilisant la commande d'arrêt normal, MySQL met deux "plombes" à s'arrêter.
On vérifie les processus de MySQL.
ps aux | grep mysql
root 7914 0.0 0.0 4180 720 pts/0 S 08:45 0:00 /bin/sh /usr/bin/mysqld_safe
mysql 8277 1.8 8.1 369888 82712 pts/0 Sl 08:45 0:01 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306
root 8278 0.0 0.0 5588 712 pts/0 S 08:45 0:00 logger -t mysqld -p daemon.error
root 8555 0.0 0.0 7848 884 pts/0 S+ 08:47 0:00 grep mysql
Et on joue à l'admin system fou en killant les processus
kill -9 7914
kill -9 8277
6 Suppression de MySQL
On supprime MySQL.
apt-get remove --purge mysql-server-5.5
On enlève les instructions innodb dans le fichier de configuration /etc/mysql/my.cnf. On supprime les données dans le datadir pour faire place nette.
7 Installation de MySQL
On installe de nouveau MySQL.
apt-get install mysql-server
8 Restauration des données
On restaure les données de MySQL.
mysql -u root -ppass < /home/vmdebian/alldbs.sql
Votre basse de données doit fonctionner de nouveau.
blog comments powered by Disqus