73 votes

Comment gérer les énormes longueurs de lignes créées par mysqldump ?

J'utilise mysqldump dans une tâche cron pour sauvegarder une base de données de plus de 2 millions de lignes.

Il crée un fichier texte qui peut être utilisé pour restaurer l'enregistrement de données à partir de la ligne de commande.

J'ai pensé qu'il serait utile d'éditer le dump avant une restauration en tant que rapide pour modifier les valeurs et les noms de tables ou de colonnes - du moins jusqu'à ce que j'en sache plus et que je sois sûr de pouvoir le faire avec ALTER et UPDATE.

L'édition de gros fichiers texte ne me dérange pas, mais j'ai été surpris de constater que dans une 250 mégaoctets de ma base de données, il n'y avait qu'environ 300 lignes . Chaque ligne comportait quelque chose comme 800 000 caractères.

Existe-t-il un autre moyen de générer des vidages avec un meilleur contrôle de la longueur des lignes ?

Ou devrais-je post-traiter le dump avec des outils comme sed ou Perl ?

0 votes

Considérez le ; entre les requêtes comme votre endienne de ligne.

0 votes

En fait, j'ai utilisé Perl et dit $line =~ s{\\).\(}{\i1}, \n (}g ; donc j'ai eu BEAUCOUP de lignes supplémentaires.

0 votes

C'est-à-dire que le ; était déjà mon eol à la fin de chaque INSERT dans table_name VALUES (..),(..),(..) .. (..) ; 282 lignes dans le fichier entier, 252 se terminant par ; J'ai choisi d'insérer des nouvelles lignes après les virgules

83voto

VoteyDisciple Points 23229

Par défaut, mysqldump ne génère qu'un seul INSERT commande par table Le résultat est une (très longue) ligne de données insérées pour chaque table qui a été vidée. Ceci est essentiellement dû au fait que les insertions "par lots" sont beaucoup plus rapides que si elles généraient un fichier INSERT pour chaque enregistrement de chaque table.

Donc, ce n'est pas que mysqldump a créé des lignes arbitrairement longues, et vous pouvez simplement imposer une autre longueur de coupure. Les lignes sont longues pour une raison.

Si c'est vraiment important d'obtenir le INSERT est réparti sur plusieurs lignes, vous pouvez l'indiquer avec :

mysqldump --extended-insert=FALSE --complete-insert=TRUE ...

Notez cependant que la restauration des tables prendra plus de temps dans ce format.

0 votes

J'avais regardé dans la page de manuel de mysqldump, et essayé --extended-insert=FALSE mais --complete-insert=TRUE est nouveau pour moi. Je vais l'essayer, merci.

0 votes

Cela m'a vraiment aidé, merci. Les lignes extra longues produites par MySQLDump étaient en fait en train de se casser et ne fonctionnaient pas correctement pendant la restauration... désactiver les insertions étendues a réglé le problème. Et comme je zippe l'archive résultante, le fichier de sauvegarde n'est pas si gros.

0 votes

Nous effectuons beaucoup de migrations de systèmes de gestion de contenu existants et les recommandations --extended-insert et --complete-insert sont très utiles. Merci.

36voto

superjer Points 374

Je parcourais le code source de MySQL à la recherche d'une solution à ce problème aujourd'hui. La longueur maximale des lignes est imposée par la variable opt_net_buffer_length qui est censée correspondre à la taille du tampon du serveur MySQL. Elle est comiquement grande.

Mais de toute façon, c'est une option, alors faites ça :

mysqldump --net_buffer_length=5000 ...

La valeur minimale est de 4096.

8 votes

Cela posera-t-il des problèmes avec des lignes individuelles contenant plus de 4K données ?

0 votes

@CyberShadow bonne question. Je parie que oui, mais je n'en ai aucune idée. La prochaine fois que je le ferai, j'essaierai de faire correspondre le mysqldump net_buffer_length au max_allowed_packet et voir si cela fonctionne. Je viens de faire une importation où 16M max_allowed_packet était dépassé par la taille de la requête. Même 64M était trop petit - je suis passé à 256M et j'ai réussi. La prochaine fois, j'essaierai probablement une longueur de tampon nette d'environ 10M et je verrai ce que cela donne.

0 votes

C'est de loin la meilleure réponse, elle ne sera pas trop lente et ne cassera pas d'autres SGBD comme sqlite qui a une limite par défaut de 500 insertions par déclaration d'insertion. merci !

22voto

Stampy Points 227

Je suis tombé sur une réponse sur les forums MySQL, qui montre de manière concluante que l'ajout de ' \n après chaque groupe INSERT n'est pas possible en utilisant mysqldump seul, sans modifier la source :

Le format étendu ne peut pas être analysé correctement à 100 % sur la base de la virgule. ou des parenthèses, il faudrait compter les champs. La meilleure solution est de corriger mysqldump à faire un saut de ligne sur la sortie.

Changement très mineur : À la ligne 3506, vous pouvez voir où la virgule de fin de ligne est sortie :
fputc(',',md_result_file); /* Always row break */

Il suffit d'insérer cette ligne immédiatement après la ligne 3506 :
fputc('\n',md_result_file); /* Lon Binder says wrap that line! */

recompilation et terminé.

@see http://forums.mysql.com/read.php?28,420002,426110#msg-426110

Merci Lon B !

(J'ai inclus le contenu du forum MySQL, au cas où le forum disparaîtrait).

17 votes

Ugh, pourquoi ce n'est pas une option sur mysqldump ? C'est le meilleur des deux mondes.

0 votes

Veuillez donner un lien vers la source de mysqldump.

0 votes

@Speakus - MySQL est la propriété d'Oracle et n'offre aucun lien direct pour télécharger ou visualiser les fichiers sources individuels - vous pouvez télécharger le paquet de sources à partir d'ici : dev.mysql.com/downloads/utilities - il suffit de sélectionner "Source" comme plateforme.

5voto

sebastien Points 152

L'utilisation d'une regex pour diviser les lignes n'est pas suffisante, vous avez besoin d'un analyseur syntaxique qui comprendra correctement les guillemets et les caractères d'échappement.

J'ai juste écrit un parseur puisque je n'en ai pas trouvé : http://blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts.html

0 votes

Très utile pour les dumps existants :)

-4voto

S.Lott Points 207588

Post-traiter le fichier de vidage avec python . Vous serez peut-être plus heureux que perl ou sed.

Si vous êtes sous Linux, vous l'avez déjà installé. Si vous êtes sous Windows, le programme d'installation est facile à utiliser.

Mais avant cela, apprenez à utiliser SQL UPDATE et SQL ALTER. Vous serez plus heureux en faisant les choses de la bonne manière.

0 votes

Je préfère Perl ou sed, simplement parce que c'est ce à quoi je suis habitué. Et bien qu'il y ait une certaine satisfaction à éditer un gros fichier, je vais apprendre les commandes SQL, je vous le promets.

9 votes

Le post-traitement est une mauvaise idée, sauf si vous êtes vraiment certain de comprendre exactement comment les données s'échappent et comment écrire le code pour les traiter. Sinon, vous risquez de corrompre vos données.

3 votes

Si vous êtes sûr de ne pas corrompre les données, voici un exemple de commande pour fractionner les insertions mysqldump -udbuser dbname | sed 's/),(/),\n(/g' > dump.sql

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X