J'ai une base de données MySQL de taille moyenne avec environ 30 tables, dont 10 millions d'enregistrements, 100 millions. Le mysqldump
de toutes les tables (dans des fichiers séparés) est assez rapide, prend peut-être 20 minutes. Il génère environ 15 Go de données. Les fichiers les plus volumineux sont de l'ordre de 2 Go.
Lorsque je charge les données dans MySQL sur une autre boîte, une machine à six cœurs et 8 Go, cela prend une éternité. Facilement 12 heures d'horloge ou plus.
Je lance juste le client mysql pour charger le fichier, c'est à dire
mysql database < footable.sql
directement avec le fichier directement depuis mysqldump
mysqldump database foo > footable.sql
De toute évidence, je fais quelque chose de mal. Par où dois-je commencer pour qu'il puisse se terminer dans un délai raisonnable?
Je n'utilise aucun interrupteur sur le vidage ou la charge.
Réponses:
Prenez ces quelques points en considération, ils peuvent vous aider en cas de génération du vidage et de restauration.
Extended inserts
dans les décharges.--tab
format afin que vous puissiez l'utilisermysqlimport
, ce qui est plus rapide quemysql < dumpfile
.innodb_flush_log_at_trx_commit = 2
votre my.cnf, temporairement pendant que l'importation est en cours. vous pouvez le remettre à 1 si vous avez besoin d'ACIDEEssaie..
la source
innodb_flush_log_at_trx_commit = 2
sauvé ma journée. L'importation d'un vidage de 600 Mo (comme une seule grosse transaction) aurait nécessité 6 heures, mais avec ce paramètre temporaire, cela s'est fait en 30 minutes!En plus de la réponse d' Abdul , je voudrais souligner l'importance de l'
--disable-keys
option, qui désactive les clés jusqu'à ce que toutes les données soient chargées pour une table. Cette option est activée dans le cadre de la--opt
bascule, qui est activée par défaut, mais il est important de le souligner.Si vous ne sautez pas de clés pendant les insertions, chaque ligne insérée reconstruira l'index. Un processus extrêmement lent.
la source
--opt
estThis option is effective only for nonunique indexes of MyISAM tables. It has no effect for other tables
J'en ai beaucoup traité récemment. Vous pouvez certainement améliorer les performances d'importation en effectuant les importations en parallèle. La plupart du ralentissement est basé sur les E / S, mais vous pouvez toujours obtenir une amélioration de 40% en effectuant un dumping dans les tables, puis en les important, disons 4 à la fois.
Vous pouvez le faire avec des xargs comme celui-ci:
le fait de compresser les fichiers avant de les pousser vers mysql ne ralentit rien, principalement à cause des E / S réduites. Mes tables ont été compressées jusqu'à environ 10: 1, ce qui permet d'économiser beaucoup d'espace disque.
J'ai trouvé que sur 4 machines de base, l'utilisation de 4 processus est optimale, bien que seulement légèrement meilleure que l'utilisation de 3. Si vous avez des SSD ou un RAID rapide, vous évoluerez probablement mieux.
Quelques autres choses à noter. Si vous avez 4k lecteurs du secteur, assurez - vous que vous avez
key_cache_block_size=4096
etmyisam_block_size=4K
.Si vous utilisez des tables MyISAM, définissez le
myisam_repair_threads = 2
ou supérieure. Cela permettra à vos cœurs supplémentaires d'aider à reconstruire les index.Assurez-vous que vous n'échangez pas du tout. Si vous l'êtes, réduisez la taille du
innodb_buffer_pool_size
.Je pense que j'ai également accéléré avec innnodb par ces options:
(les trois derniers, je n'ai pas testé intensivement - je pense que je les ai trouvés comme suggestions sur les internets.) Notez que cela
innodb_flush_log_at_commit=0
peut entraîner une corruption avec le crash de mysql ou une panne de courant.la source
*_block_size
etmyisam_repair_threads
? De plus, je ne suis pas sûr que nous devrions offrir des conseils pour régler les variables en fonction des «suggestions des internets» :)Si vous avez principalement des tables MyISAM, vous devez augmenter le tampon d'insertion en bloc . Voici ce que dit la documentation MySQL sur la définition de bulk_insert_buffer_size :
Il y a deux choses que vous devez faire
1) Ajoutez-le à /etc/my.cnf
2) Définissez sa valeur globale
Si vous n'avez pas le privilège de définir globalement bulk_insert_buffer_size, procédez comme suit
Bien sûr, ce n'est pas pour InnoDB.
Sous un autre angle, que les tables soient InnoDB ou MyISAM, si les index sont plus grands que la table, vous pouvez avoir trop d'index. Je pense généralement qu'un rechargement d'un MyISAM mysqldump devrait prendre 3 fois plus de temps que le mysqldump a pris. Je pense également qu'un rechargement d'un mysqldump InnoDB devrait prendre 4 fois plus de temps que le mysqldump a pris.
Si vous dépassez le ratio 4: 1 pour recharger un mysqldump, vous avez certainement l'un des deux problèmes suivants:
Vous pouvez mesurer la taille de vos données par moteur de stockage avec ceci:
Voyez si les index sont presque aussi gros que les données ou même plus gros
Vous pouvez également envisager de désactiver la journalisation binaire comme ceci:
avant de recharger le script
la source
Si vous contournez complètement le système de fichiers et que vous dirigez simplement la sortie de mysqldump directement dans un processus MySQL, vous devriez voir des améliorations de performances notables. La quantité dépend finalement du type de lecteur de disque que vous utilisez, mais j'utilise rarement les fichiers de vidage, quelle que soit la taille de la base de données, pour cette seule raison.
la source
D'après mes expériences, le disque dur est le goulot d'étranglement. Oubliez les disques en rotation. Le SSD est meilleur, mais de loin le mieux est de le faire en RAM - si vous en avez assez pour contenir la base de données entière pendant un court instant. Grossièrement:
Pour moi, un vidage de ~ 10G (/ var / lib / mysql consommant ~ 20G) peut être importé en environ 35 minutes (mydumper / myloader), 45 minutes (mysqldump --tab / mysqlimport), 50 minutes (mysqldump / mysql) , sur un Xeon 2x6 à 3,2 GHz.
Si vous n'avez pas assez de RAM sur une seule machine, mais que vous avez plusieurs ordinateurs côte à côte avec un réseau rapide, il serait intéressant de voir si leurs RAM peuvent être jointes avec nbd (périphérique de bloc réseau). Ou, avec innodb_file_per_table, vous pouvez probablement répéter le processus ci-dessus pour chaque table.
la source