Attente d'E / S causant autant de ralentissement (EXT4 JDB2 à 99% d'E / S) pendant la validation de Mysql

14

J'écris un indexeur, en utilisant python, qui indexe les documents et les insère dans la base de données, Avant c'était un processus unique mais maintenant je l'ai fait en multitraitement avec 4 processus parallèles en cours d'exécution. Après chaque extraction de texte, il s'insère dans la base de données et fait un commit.

Maintenant qu'il rencontre un problème d'E / S, le principal problème d'E / S n'est pas mon processus mais le système de journalisation jdb2 d'EXT4. Il est à 99,99% et incite le processeur à attendre les E / S à chaque validation de MySQL.

J'ai vu beaucoup de gens avoir ce problème sur Internet et leur solution est de monter en utilisant barrière = 0. Cela désactiverait-il totalement la journalisation? Mes serveurs ont UPS et tentent de le faire, dois-je?

Phyo Arkar Lwin
la source
Toutes vos données sont-elles InnoDB ???
RolandoMySQLDBA

Réponses:

4

Placez la base de données sur un système de fichiers sans journalisation. Au moins les serveurs plus grands (Oracle, SQL Server) ont leur propre fonction de journal (journal des transactions) et optimisent leur IO en conséquence. Vous disposez d'un journal et d'une base de données sur des systèmes de fichiers et des disques distincts et vous comptez sur les fonctionnalités internes de la base de données pour gérer les mauvaises E / S. Il n'y a normalement pas de modification du système de fichiers (configuration plus grande), sauf la date d'écriture de toute façon, car les fichiers ne se développent pas - ils seraient générés avec leur taille "finale" (ok, les administrateurs peuvent changer cela), et les modifications sont, comme je l'ai dit, suivies par la base de données journal des transactions de niveau.

Vous pouvez également nous dire quelle est votre couche matérielle. La plupart des gens sous-estiment que l' IOPS est le facteur limitant pour une base de données et pensent qu'un petit ensemble de disques est un environnement approprié pour une grande base de données. Alors que certains d'entre nous travaillent sur des bases de données utilisant un plus grand nombre de disques, prenant ainsi potentiellement en charge un nombre plus élevé d'IOPS.

TomTom
la source
Je modifierais cela en utilisant un système de fichiers n'utilisant pas le journal pour les données mais uniquement les métadonnées. Ext4 peut également être configuré de cette façon.
le-wabbit le
Oui. À la fin, le jouirnal double l'IO - et le journal de la base de données fera de même, donc vous vous retrouvez avec beaucoup plus d'IOPS que nécessaire. Et une redondance qui n'est fondamentalement pas nécessaire. Le système jouirnalling est NICE pour protéger le fichier .... mais inutile quand l'application le fait déjà, ce que font les bases de données.
TomTom
Laquelle offre les meilleures performances en non-journalisation? Merci!
Phyo Arkar Lwin
4

Il y aura toujours un compromis entre la résilience et la performance.

Avec MySQL sur ext4, les barrières = 1 par défaut provoquent en effet un ralentissement, cependant la première action ne doit pas être de désactiver la journalisation ou d'activer data = writeback.

Premièrement, si la résilience est d'une grande importance, un RAID soutenu par batterie en vaut certainement la peine.

Les options de montage que j'ai choisies, en particulier sur un RAID sans batterie, sont:

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

Ceci n'utilise pas intentionnellement data = writeback parce que je ne veux pas risquer une corruption du système de fichiers entraînant "d'anciennes données à apparaître dans les fichiers après un crash et une récupération du journal" (citation de man mount).

La configuration idéale dans my.cnf pour une résilience complète autour des paramètres liés aux E / S est:

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

J'ai opté pour la séquence de compromis suivante pour augmenter les performances:

  1. sync_binlog = 0: c'est la première config MySQL que je change loin de la pleine résilience. La raison en est qu'il donne une amélioration significative des performances, en particulier là où binlog_format=row(malheureusement requis pour Jira). J'utilise suffisamment de répliques MySQL dans le cluster que si le binlog venait à être corrompu par un scénario de perte de puissance, je ferais une copie binaire d'une autre réplique.
  2. innodb_flush_log_at_trx_commit = 2: Bien qu'une valeur de 1 soit requise pour une conformité ACID complète, avec une valeur de 2 ", le tampon de journal est écrit dans le fichier à chaque validation, mais l'opération de vidage sur disque n'y est pas effectuée. Cependant, le vidage sur le le fichier journal a lieu une fois par seconde également lorsque la valeur est 2. Notez que le vidage une fois par seconde n'est pas garanti à 100% à chaque seconde, en raison de problèmes de planification du processus. " (citation de la documentation MySQL)
  3. Mettez à jour les options de montage à utiliser data=writeback. Notez que s'il s'agit de votre système de fichiers racine, vous devrez également passer une option de ligne de commande du noyau. J'ai mis en place quelques étapes à ce sujet à coderwall .
  4. Testez différentes valeurs de innodb_flush_method. Il est démontré qu'O_DIRECT améliore les performances dans certaines charges de travail, mais cela ne va pas de soi que cela fonctionnera dans votre environnement.
  5. Mise à niveau vers les disques SSD, dans ce cas , vous aurez également besoin d'augmenter innodb_io_capacity, et les paramètres syntoniser tels que innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threadset d' autres paramètres possibles.
JinnKo
la source
3

Il est fort probable que votre backend d'E / S ne supporte pas bien la charge. Vous devez vous assurer que votre système de fichiers ne consigne pas de données. Je suggérerais d'utiliser les data=writeback,relatime,nobarrierparamètres à monter pour la partition de données de votre base de données comme première optimisation rapide et sale.

En outre, en déduisant de vos symptômes, vous n'utilisez apparemment pas la mise en cache d'écriture avec votre contrôleur. Vous devez vous assurer que vous utilisez un cache d'écriture sauvegardé par batterie ou flash sur votre contrôleur et l'activer - cela devrait vous donner une amélioration significative des performances sans augmenter considérablement le risque de perte ou de corruption de données. Notez que l'utilisation du cache d'écriture sans batterie ou sauvegarde flash augmente considérablement le risque de perte ou de corruption de données - ne le faites qu'à des fins de test et / ou si vous pouvez prendre la perte.

le-wabbit
la source
alors que diriez-vous: data = writeback, relatime, nobarrier et ensuite désactiver totalement la journalisation mysql? Je pense que cela accélérerait beaucoup les choses?
Phyo Arkar Lwin
hdpram -i montre que j'utilise la mise en cache d'écriture. alors hmm ??
Phyo Arkar Lwin
@ V3ss0n vous ne pouvez pas désactiver la journalisation pour un moteur transactionnel - c'est le cœur même de celui-ci. Vous pouvez choisir de déplacer le journal des transactions vers un autre ensemble de disques car il a un modèle d'accès totalement différent (principalement des écritures linéaires) que vos données de base de données principales (lecture / écritures aléatoires) - il s'agit d'une configuration couramment recommandée. Quant à votre configuration de stockage: vous n'utilisez pas de contrôleur RAID mais simplement des disques individuels avec cache d'écriture activé? Cela n'aiderait aucune de vos écritures synchrones car elles sont accompagnées de demandes de vidage de cache explicites.
the-wabbit
Est-ce nobarrierla même chose que barrier=0?
Nic Cottrell
@NicCottrell oui, ce sont les mêmes.
kouton
3

C'est une vieille question, mais nous avons fait face aux mêmes problèmes (attentes élevées d'E / S et vitesses d'insertion / mise à jour terribles) la semaine dernière sur un nouveau serveur dédié et cette solution résout ce problème directement.

La désactivation de la journalisation avec a tune2fs -O "^has_journal" /dev/<drive>été la solution la plus rapide car elle élimine l'attente d'E / S en raison du processus JDB2. Mais ce n'est pas recommandé, sauf si vous avez un lecteur alimenté par batterie, car vous perdrez des données en cas de crash. Les tables InnoDB sont sûres si vous les avez doublewriteactivées dans MySQL. Mais les fichiers comme .frm, les journaux, etc. ne sont pas sûrs. Nous avons essayé de déplacer ces fichiers vers un autre lecteur (en particulier les journaux de bin) mais l'attente d'E / S jdb2 persistait toujours. Cela ne nous a donc pas laissé très à l'aise.

data=writeback,relatime,nobarriern'a pas aidé à accélérer les écritures / lectures autant qu'à désactiver la journalisation sur toute la partition. Plus d'options pour ext4 sont dans le doc EXT4 .

Le vrai coupable dans notre cas était sync_binlog. Nous avions fixé est aussi 1dans /etc/mysql/my.cnfet il a été tué la performance.

Percona valide ici . Nous l'avons réglé sur sa valeur par défaut 0et les performances ont augmenté de plus de 500%.

kouton
la source
0

Dans quel moteur de base de données utilisez-vous pour insérer ces données?

Si c'est MyISAM: cela doit verrouiller la table entière pendant une écriture, donc l'exécution de threads d'insertion simultanés tuera N'IMPORTE QUEL système, quelle que soit sa puissance.

Assurez-vous que vous utilisez InnoDB pour ces tables.

adaptr
la source
Puisqu'il valide des transactions, le moteur ne serait pas MyISAM puisque MyISAM ne prend pas en charge les transactions.
le-wabbit le
Arr, brainfart.
adaptr
J'utilise innodb, mysql5.5 est par défaut innodb.
Phyo Arkar Lwin
0

De plus, pas directement lié à mysql, mais certains HD ont des problèmes avec ext4 en raison d'une gestion agressive de l'alimentation ... lorsque cela se produit, la charge de la machine augmente sans aucune activité apparente.

Essayez de le désactiver. vérifiez d'abord la valeur que vous avez (si vous devez la remettre sans redémarrer), puis désactivez-la.

Vérifiez la valeur actuelle:

    hdparm -B /dev/sda

Le désactiver

   hdparm -B 255 /dev/sda

(ou quel que soit votre HD) et testez. Cela n'aidera probablement pas la plupart des problèmes, mais cela pourrait aider certains utilisateurs. Le redémarrage réinitialisera la valeur ou remplacera manuellement le 255 pour la valeur précédente.

Si cela vous aide, vérifiez le /etc/default/hdparmou /etc/hdparm.confpour une configuration plus permanente, en le définissant au démarrage.

higuita
la source