web-dev-qa-db-fra.com

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

J'utilise mysqldump dans un travail cron pour sauvegarder une base de données avec plus de 2 millions de lignes.

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

J'ai pensé qu'il serait utile de modifier le vidage avant une restauration comme moyen rapide de changer les valeurs et les noms de table ou de colonne - au moins jusqu'à ce que j'en apprenne plus et devenez sûr de 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 un 250 mégaoctets vidage de ma base de données, il n'y avait qu'environ 300 lignes. Chaque ligne comptait quelque 800k caractères.

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

Ou dois-je post-traiter le vidage avec des outils comme sed ou Perl?

57
pavium

Par défaut, mysqldump génère une seule commande INSERTpar table, résultant en une (très longue) ligne de données insérées pour chaque table qui a été vidée. Cela est essentiellement dû au fait que les insertions "batch" sont beaucoup plus rapides que si elles généraient une requête INSERT distincte 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.

S'il est vraiment important de décomposer les INSERTs 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.

72
VoteyDisciple

Je parcourais le code source MySQL à la recherche d'une solution à ce problème aujourd'hui. La longueur de ligne maximale est appliquée par la variable opt_net_buffer_length qui est censée correspondre à la taille de la mémoire tampon du serveur MySQL. Il est comiquement grand.

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

mysqldump --net_buffer_length=5000 ...

La valeur minimale est 4096.

30
superjer

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

Le format étendu ne peut pas être correctement analysé à 100% en fonction de la virgule ou des parenthèses, vous devez compter les champs. La meilleure solution, fixez mysqldump au saut de ligne en 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 */

Insérez simplement cette ligne immédiatement après la ligne 3506:
fputc('\n',md_result_file); /* Lon Binder says wrap that line! */

recompiler et terminé.

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

Merci Lon B!

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

17
StampyCode

Ce drapeau est également travaillé:

mysqldump --skip-extended-insert 

Tout comme --extended-insert=FALSE.

4
Nick Tsai

L'utilisation d'une expression régulière pour séparer les lignes ne suffit pas, vous avez besoin d'un analyseur qui comprendra correctement les guillemets et les caractères d'échappement.

Je viens d'écrire un analyseur car je n'en ai pas trouvé un: http://blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts.html

4
sebastien