Mysql s'est écrasé et ne démarre pas

19

Notre serveur mysql de production vient de planter et ne reviendra pas. Cela donne une erreur de segfault. J'ai essayé un redémarrage et je ne sais pas quoi d'autre à essayer. Voici le stacktrace:

140502 14:13:05 [Note] Le plugin 'FEDERATED' est désactivé.
InnoDB: l'analyse des journaux a progressé au-delà du point de contrôle lsn 108 1057948207
140502 14:13:06 InnoDB: La base de données n'a pas été fermée normalement!
InnoDB: démarrage de la récupération après incident.
InnoDB: lecture des informations sur l'espace disque logique à partir des fichiers .ibd ...
InnoDB: Restauration des éventuelles pages de données semi-écrites à partir de la double écriture
InnoDB: tampon ...
InnoDB: Faire la récupération: numérisé jusqu'au numéro de séquence du journal 108 1058059648
InnoDB: 1 transaction (s) qui doit être annulée ou nettoyée
InnoDB: au total 15 opérations de ligne à annuler
InnoDB: le compteur d'ID Trx est 0 562485504
140502 14:13:06 InnoDB: Démarrage d'un lot d'application d'enregistrements de journal à la base de données ...
InnoDB: Progression en pourcentages: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 
InnoDB: Appliquer le lot terminé
InnoDB: Démarrage en arrière-plan du retour en arrière des transactions non validées
140502 14:13:06 InnoDB: restauration de trx avec l'ID 0 562485192, 15 lignes à annuler
140502 14:13:06 InnoDB: démarré; journal séquence numéro 108 1058059648
140502 14:13:06 InnoDB: échec d'assertion dans le thread 1873206128 dans le fichier ../../../storage/innobase/fsp/fsp0fsp.c ligne 1593
InnoDB: Échec de l'assertion: frag_n_used> 0
InnoDB: Nous générons intentionnellement un piège mémoire.
InnoDB: soumettez un rapport de bogue détaillé à http://bugs.mysql.com.
InnoDB: si vous obtenez des échecs ou des plantages d’assertion répétés, même
InnoDB: immédiatement après le démarrage de mysqld, il peut y avoir
InnoDB: corruption dans l'espace de table InnoDB. Prière de se référer à
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: pour forcer la récupération.
140502 14:13:06 - mysqld a reçu le signal 6;
Cela pourrait être parce que vous frappez un bug. Il est également possible que ce binaire
ou l'une des bibliothèques avec lesquelles il a été lié est corrompue, mal construite,
ou mal configuré. Cette erreur peut également être causée par un mauvais fonctionnement du matériel.
Nous ferons de notre mieux pour récupérer des informations qui, nous l'espérons, aideront à diagnostiquer
le problème, mais comme nous avons déjà planté, quelque chose ne va vraiment pas
et cela peut échouer.

key_buffer_size = 16777216
read_buffer_size = 131072
max_used_connections = 0
max_threads = 151
threads_connected = 0
Il est possible que mysqld utilise jusqu'à 
key_buffer_size + (read_buffer_size + sort_buffer_size) * max_threads = 345919 K
octets de mémoire
J'espère que ça va; sinon, diminuez certaines variables de l'équation.

thd: 0x0
Tentative de retour en arrière. Vous pouvez utiliser les informations suivantes pour découvrir
où mysqld est mort. Si vous ne voyez aucun message après cela, quelque chose s'est passé
terriblement mal ...
stack_bottom = (nil) thread_stack 0x30000
140502 14:13:06 [Note] Planificateur d'événements: 0 événement chargé
140502 14:13:06 [Remarque] / usr / sbin / mysqld: prêt pour les connexions.
Version: socket '5.1.41-3ubuntu12.10': port '/var/run/mysqld/mysqld.sock': 3306 (Ubuntu)
/ usr / sbin / mysqld (my_print_stacktrace + 0x2d) [0xb7579cbd]
/ usr / sbin / mysqld (handle_segfault + 0x494) [0xb7245854]
[0xb6fc0400]
/lib/tls/i686/cmov/libc.so.6(abort+0x182) [0xb6cc5a82]
/ usr / sbin / mysqld (+ 0x4867e9) [0xb74647e9]
/ usr / sbin / mysqld (btr_page_free_low + 0x122) [0xb74f1622]
/ usr / sbin / mysqld (btr_compress + 0x684) [0xb74f4ca4]
/ usr / sbin / mysqld (btr_cur_compress_if_useful + 0xe7) [0xb74284e7]
/ usr / sbin / mysqld (btr_cur_pessimistic_delete + 0x332) [0xb7429e72]
/ usr / sbin / mysqld (btr_node_ptr_delete + 0x82) [0xb74f4012]
/ usr / sbin / mysqld (btr_discard_page + 0x175) [0xb74f41e5]
/ usr / sbin / mysqld (btr_cur_pessimistic_delete + 0x3e8) [0xb7429f28]
/ usr / sbin / mysqld (+ 0x526197) [0xb7504197]
/ usr / sbin / mysqld (row_undo_ins + 0x1b1) [0xb7504771]
/ usr / sbin / mysqld (row_undo_step + 0x25f) [0xb74c210f]
/ usr / sbin / mysqld (que_run_threads + 0x58a) [0xb74a31da]
/ usr / sbin / mysqld (trx_rollback_or_clean_all_without_sess + 0x3e3) [0xb74ded43]
/lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0xb6f9f96e]
/lib/tls/i686/cmov/libc.so.6(clone+0x5e) [0xb6d65a4e]
La page de manuel sur http://dev.mysql.com/doc/mysql/en/crashing.html contient
des informations qui devraient vous aider à déterminer la cause de l'accident.

Des recommandations?

tilleryj
la source
Tout d'abord; quelqu'un a-t-il changé la configuration de MySQL d'une manière ou d'une autre? Voir la dernière date de modification pour /etc/mysql/my.cnfenviron.
Janne Pikkarainen
Non. J'ai fini par devoir définir innodb_force_recovery = 3 afin de faire un mysqldump, puis j'ai supprimé et relu la base de données. Cela l'a corrigé.
tilleryj

Réponses:

26

Aie.

InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: about forcing recovery.

Consultez la page Web suggérée: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html .

Fondamentalement, essayez de démarrer le serveur MySQL en mode de récupération et de faire une sauvegarde de vos tables en panne .

Modifiez votre /etc/my.cnfet ajoutez:

 innodb_force_recovery = 1

... pour voir si vous pouvez accéder à votre base de données et obtenir vos données / trouver la table corrompue.

Habituellement, lorsque cela se produit, il s'agit d'une reconstruction (au moins d'une ou deux tables corrompues).

Sur http://chepri.com/mysql-innodb-corruption-and-recovery/ :

  1. Arrêtez mysqld( service mysql stop).
  2. Sauvegarde /var/lib/mysql/ib*
  3. Ajoutez la ligne suivante dans /etc/my.cnf:

    innodb_force_recovery = 1
    

    (ils suggèrent 4, mais il vaut mieux commencer par 1 et incrémenter s'il ne démarre pas)

  4. Redémarrez mysqld( service mysql start).

  5. Vider toutes les tables: mysqldump -A > dump.sql
  6. Supprimez toutes les bases de données qui nécessitent une récupération.
  7. Arrêtez mysqld( service mysql stop).
  8. Retirer /var/lib/mysql/ib*
  9. Commenter innodb_force_recoverydans/etc/my.cnf
  10. Redémarrez mysqld. Regardez le journal des erreurs mysql. Par défaut, cela devrait être /var/lib/mysql/server/hostname.com.errde voir comment il crée de nouveaux ib*fichiers.
  11. Restaurez les bases de données depuis le vidage: mysql < dump.sql
Jonathan
la source
Je considérerais d'abord que vous pouvez avoir une corruption du système de fichiers ou un mauvais disque.
bombcar
1
essayez toutes les valeurs innodb_force_recovery jusqu'à 6. Et ajoutez innodb_purge_threads = 0 - parfois le thread principal ne peut pas en démarrer, vous le verrez dans le journal des erreurs
akuzminsky
2
Je sais que c'est un vieux fil, mais toute élaboration sur la détermination des bases de données qui nécessitent une récupération?
nkanderson
@nicolekanderson J'aimerais également des éclaircissements sur ce point. Après avoir exécuté mysqldump, cela ne m'indique en aucune façon que l'une des bases de données était corrompue.
Andrew Thaddeus Martin
point 10 dans la réponse - essayez de redémarrer le serveur de base de données et lisez le journal des erreurs, il devrait donner le nom des tables en panne. mysqldump ne vous donne qu'une copie des tableaux, rien de plus.
Jonathan
2

J'étais confronté à cette même erreur lors de l'utilisation de l'image docker mysql: 5.7. L'erreur principale a été de créer un utilisateur root qui existe par défaut. Plus d'informations: https://github.com/docker-library/mysql/issues/129

Comme indiqué dans le lien ci-dessus, la solution consistait à NE PAS définir MYSQL_USER et MYSQL_PASSWORD dans les variables d'environnement lors du démarrage de l'image docker.

rahuljain1311
la source
1

Cela m'est arrivé dans Laravel Homestead (Vagrant après une panique du noyau sous Mac OS Sierra 10.12.4 (16E195):

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:    14.04
Codename:   trusty

$ mysql -V
mysql  Ver 14.14 Distrib 5.7.9, for Linux (x86_64) using  EditLine 
wrapper

Voici quelques ressources que vous pouvez essayer, bien qu'aucune des options de réparation ne fonctionne pour moi :

https://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html

https://forums.mysql.com/read.php?22,603093,604631#msg-604631

https://support.plesk.com/hc/en-us/articles/213939865-How-to-fix-InnoDB-corruption-cases-for-the-MySQL-database

J'ai essayé d'ajouter la récupération de force à la configuration mysql (commencez à 1 et allez progressivement plus haut car des nombres supposément plus élevés peuvent provoquer une corruption permanente):

sudo nano /etc/mysql/my.cnf

[mysqld]
innodb_force_recovery = 1
#innodb-read-only=1
#innodb_purge_threads=0
#key_buffer_size=16M
#event-scheduler=disabled

Dans une autre fenêtre, exécutez:

tail -f /var/log/mysql/error.log

Essayez ensuite de redémarrer mysqld avec les différentes options activées:

sudo /etc/init.d/mysql restart

S'il expire, vous pouvez forcer le redémarrage des processus mysql avec:

# process id is first column with number, just ignore lines with grep because they list the process running 'grep mysql'
ps aux | grep mysql
sudo kill -9 <process-id>
sudo /etc/init.d/mysql restart

Si cela fonctionne, le journal affichera quelque chose comme:

Version: '5.7.9' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)

S'il échoue, le journal affichera quelque chose comme:

InnoDB: Assertion failure in thread 140049488692992 in file log0recv.cc line 1420


Au pire, j'ai essayé de supprimer les bases de données susceptibles d'être corrompues:

sudo ls -alt /var/lib/mysql

Il s'est avéré que la base de données sur laquelle je travaillais était la plus récemment modifiée en haut de la liste. Heureusement, j'ai eu un vidage SQL pour ce jour-là, j'ai donc pu le supprimer:

sudo rm -rf /var/lib/mysql/<database_name>

J'ai laissé tous les autres fichiers et mysql a quand même pu démarrer.

MISE À JOUR: assurez-vous de désactiver innodb_force_recovery = 1une fois que mysql fonctionne à nouveau, sinon vous obtiendrez des erreurs lorsque vous tenterez de modifier des bases de données et des tables.

Ensuite, j'ai recréé la base de données avec Sequel Pro, réimporté mes données et j'ai pu continuer sans avoir à jeter toutes les bases de données de mes autres projets.

À l'avenir, je dois supposer que toute base de données mysql peut être corrompue et essayer de conserver des sauvegardes quotidiennes et de documenter ou coder le script de recréation de la base de données dans mes outils d'intégration continue.

Zack Morris
la source