Le serveur MySQL a disparu en empêchant l'importation de gros vidages

14

J'essaie d'importer un grand vidage sql (2 Go) sur mon mysql local sur mon mac. J'ai pu le faire dans le passé (j'utilisais MAMP), mais maintenant j'obtiens une ERREUR 2006 (HY000) à la ligne 7758: le serveur MySQL a disparu à chaque fois que j'essaie d'importer le vidage. La base de données contient des tables innodb.

J'ai essayé de copier le fichier my-innodb-heavy-4G.cnf sur mon my.cnf pour voir si ces paramètres aideraient, mais pas de chance.

Des idées sur quoi modifier?

J'utilise le "Mac OS X ver. 10.6 (x86, 64 bits), DMG Archive" à partir d'ici: http://dev.mysql.com/downloads/mysql/

naxoc
la source

Réponses:

15

L'un des tueurs silencieux de MySQL Connections est le paquet MySQL. Même le thread d'E / S de la réplication MySQL peut en être victime.

Selon la documentation MySQL

  • Vous pouvez également obtenir ces erreurs si vous envoyez au serveur une requête incorrecte ou trop volumineuse. Si mysqld reçoit un paquet trop volumineux ou en panne, il suppose que quelque chose s'est mal passé avec le client et ferme la connexion. Si vous avez besoin de grandes requêtes (par exemple, si vous travaillez avec de grandes colonnes BLOB), vous pouvez augmenter la limite de requête en définissant la variable max_allowed_packet du serveur, qui a une valeur par défaut de 1 Mo. Vous devrez peut-être également augmenter la taille maximale des paquets côté client. Plus d'informations sur la définition de la taille des paquets sont fournies dans la Section C.5.2.10, «Paquet trop volumineux».

  • Une instruction INSERT ou REPLACE qui insère un grand nombre de lignes peut également provoquer ce type d'erreurs. L'une ou l'autre de ces instructions envoie une seule demande au serveur, quel que soit le nombre de lignes à insérer; ainsi, vous pouvez souvent éviter l'erreur en réduisant le nombre de lignes envoyées par INSERT ou REPLACE.

À tout le moins, vous devez vous assurer que les tailles de paquet pour la machine à partir de laquelle vous mysqldumped et la machine que vous chargez sont identiques.

Vous pouvez adopter deux (2) approches:

APPROCHE # 1: Effectuez le mysqldump en utilisant --skip-extended-insert

Cela garantira que le paquet MySQL n'est pas inondé de plusieurs BLOBs, champs TEXT. De cette façon, les INSERT SQL sont effectués un à la fois. Les principaux inconvénients sont

  1. le mysqldump est beaucoup plus grand
  2. recharger un tel vidage prend beaucoup plus de temps.

APPROCHE # 2: Augmenter max_allowed_packet

Cela peut être l'approche préférée car l'implémentation n'est qu'un redémarrage de mysql. Comprendre ce qu'est le paquet MySQL peut clarifier cela.

Selon la page 99 de "Understanding MySQL Internals" (ISBN 0-596-00957-7) , voici les paragraphes 1-3 qui l'expliquent:

Le code de communication réseau MySQL a été écrit en supposant que les requêtes sont toujours raisonnablement courtes, et peuvent donc être envoyées et traitées par le serveur en un seul morceau, qui est appelé un paquet dans la terminologie MySQL. Le serveur alloue la mémoire à un tampon temporaire pour stocker le paquet et il en demande suffisamment pour l'adapter entièrement. Cette architecture nécessite une précaution pour éviter que le serveur manque de mémoire --- un plafond sur la taille du paquet, ce que cette option accomplit.

Le code d'intérêt par rapport à cette option se trouve dans sql / net_serv.cc . Jetez un œil à my_net_read () , puis suivez l'appel à my_real_read () et portez une attention particulière à net_realloc () .

Cette variable limite également la longueur d'un résultat de nombreux fonctons de chaîne. Voir sql / field.cc et sql / intem_strfunc.cc pour plus de détails.

Compte tenu de cette explication, faire des INSERT en vrac chargera / déchargera un paquet MySQL assez rapidement. Cela est particulièrement vrai lorsque max_allowed_packet est trop petit pour la charge donnée de données qui y arrive.

CONCLUSION

Dans la plupart des installations de MySQL, je la règle généralement sur 256M ou 512M. Vous devriez expérimenter avec des valeurs plus grandes lorsque le chargement des données produit des erreurs «MySQL a disparu».

RolandoMySQLDBA
la source
J'ai essayé de régler max_allowed_packetà 900M et j'utilisais --skip-extended-insert(et vous avez raison - cela fait des db-dumps huuuge), mais cela échoue toujours. Je soupçonne une ligne particulière dans le dépotoir maintenant que je peux probablement contourner. Mais c'est toujours bizarre - le vidage peut être importé très bien sur mon serveur CentOS.
naxoc
J'ai fini par retirer un insert du vidage sql qui était une très, très longue ligne. Cela l'a corrigé (et la ligne n'était pas nécessaire).
naxoc
BTW veuillez vous assurer que le caractère par défaut pour le vidage des données peut être pris en charge dans le système d'exploitation MacOSX et dans MySQL.
RolandoMySQLDBA
@naxov - Je suis simplement curieux de savoir la seule ligne que vous soupçonnez dans le dépotoir. Y a-t-il des champs TEXT ou BLOB impliqués ???
RolandoMySQLDBA du
Oui, un champ de texte très long.
naxoc
2

Combien de temps cela dure-t-il avant la fin du délai? La première étape serait de vérifier les paramètres wait_timeoutet interactive_timeoutpour vous assurer qu'ils sont suffisamment grands pour votre importation:

SHOW VARIABLES LIKE '%_timeout';
SET SESSION wait_timeout=28800;

La valeur par défaut est 8 heures (28800), donc ce n'est potentiellement pas le problème. D'autres indications de ce problème peuvent être trouvées ici . Celui qui se démarque est le suivant:

Une application cliente exécutée sur un hôte différent n'a pas les privilèges nécessaires pour se connecter au serveur MySQL à partir de cet hôte.

Vérifiez d'abord les autorisations, puis parcourez cette liste de problèmes potentiels.

Derek Downey
la source
Tout est sur localhost, donc soit je ne comprends pas ce que vous voulez dire, soit ce n'est pas le problème. Voulez-vous dire les autorisations comme dans les privilèges dans mysql?
naxoc
2

Ouais, jouer avec wait_timeout et max_allowed_packets me permet également de contourner le message d'erreur.

p4guru
la source
Ça n'a pas marché pour moi. J'ai dû modifier le sql dans le fichier de vidage et supprimer une très longue ligne à l'origine du problème.
naxoc
il ne faut pas jouer avec certains paramètres qu'il ne comprend pas
Jeredepp
2

Ce n'est peut-être pas la «bonne» chose à faire, mais cela pourrait fonctionner (faites-le, non?):

Essayez de diviser votre grand vidage en plusieurs fichiers et de les exécuter un à la fois dans l'ordre. Mon approche serait de le casser en deux et de le tester. Ensuite, divisez chaque moitié en deux, refaites le test, etc.

Je suis un peu curieux de savoir si la quantité de RAM que vous avez sur votre boîte pourrait avoir quelque chose à voir avec cela. MySQL charge-t-il le vidage entier en mémoire quand il va l'exécuter? Je ne sais pas ... mais si vous n'avez que 2 Go de RAM et que certains d'entre eux sont en cours d'utilisation sous votre système d'exploitation et d'autres applications, cela pourrait être le problème.

Jour Davis Waterbury
la source
2

Ceux qui n'ont pas réussi avec les autres suggestions pourraient envisager de jeter un œil au script d'importateur de vidage MySQL de BigDump PHP .

Il s'agit d'une solution de contournement pour l'importation de grands vidages de base de données dans MySQL. Je l'ai utilisé avec succès pour importer un grand vidage MySQL dans mon environnement de développement local (j'utilise MAMP dans ce cas).

Marcus Barnes
la source