web-dev-qa-db-fra.com

Est-il possible que MySQL utilise plus d'un cœur?

On m'a présenté des serveurs MySQL dédiés qui n'utilisent jamais plus d'un seul cœur. Je suis plus développeur que DBA pour MySQL, j'ai donc besoin d'aide

Installer

Les serveurs sont assez lourds avec une charge de type OLAP/DataWarehouse (DW):

  • Primaire: 96 Go de RAM, 8 cœurs + une seule matrice RAID 10
  • Test: 32 Go RAM avec 4 cœurs
  • La plus grande base de données est de 540 Go, le total est d'environ 1,1 To et principalement des tables InnoDB
  • Solaris 10 Intel-64
  • MySQL 5.5.x

Remarque: La plus grande base de données est la base de données répliquée du serveur OLTP DR et le DW est chargé à partir de cela. Ce n'est pas un DW complet: dure seulement 6 mois à 6 semaines, il est donc plus petit que le OLTP DB.

Observations sur un serveur de test

  • 3 connexions séparées
  • chacun a un concurrent (et différent) ALTER TABLE...DROP KEY...ADD INDEX
  • les 3 tables ont 2,5, 3,8 et 4,5 millions de lignes
  • L'utilisation du processeur va jusqu'à 25% (un cœur est au maximum) et pas plus
  • les 3 ALTERs prennent 12-25 minutes (un seul sur le plus petit prend 4,5)

Des questions

  1. Quel paramètre ou correctif est requis pour autoriser l'utilisation de plusieurs cœurs?
    Autrement dit, pourquoi MySQL n'utilise-t-il pas tous les cœurs disponibles? (comme les autres SGBDR)
  2. Est-ce une conséquence de la réplication?

Autres notes

  • Je comprends la différence entre un "thread" RDBMS et un "thread" OS
  • Je ne demande aucune forme de parallélisme
  • Certaines variables système pour InnoDB et les threads sont sous-optimales
    (à la recherche d'une victoire rapide)
  • À court terme, je ne peux pas changer la disposition du disque
  • Le système d'exploitation peut être modifié si nécessaire
  • Une seule ALTER TABLE sur la plus petite table prend 4,5 minutes (choquant IMO)

Modifier 1

  • innodb_thread_concurrency est défini sur 8 sur les deux. Oui, c'est faux mais ne fera pas MySQL utiliser plusieurs cœurs
  • innodb_buffer_pool_size fait 80 Go sur le primaire, 10 Go sur un test (une autre instance est arrêtée). C'est OK pour l'instant.
  • innodb_file_per_table = ON

Modifier 2

Tester

  • innodb_flush_method n'est pas affiché comme O_DIRECT alors qu'il devrait l'être
  • suivra les paramètres de RolandoMySQLDBA

Faites-moi savoir si j'ai raté quelque chose d'important

À votre santé

Mise à jour

Innodb_flush_method + 3 paramètres de threads modifiés dans la réponse de RolandoMySQLDBA
Résultat:> 1 noyau utilisé pour les tests = résultat positif

136
gbn

J'ai en fait discuté innodb_thread_concurrency avec un expert MySQL lors de la conférence Percona Live NYC en mai 2011 .

J'ai appris quelque chose de surprenant: malgré la documentation, il vaut mieux laisser innodb_thread_concurrency à 0 (concurrence infinie). De cette façon, InnoDB décide du meilleur nombre de innodb_concurrency_tickets à ouvrir pour une configuration d'instance MySQL donnée.

Une fois que vous avez défini innodb_thread_concurrency à 0, vous pouvez définir innodb_read_io_threads et innodb_write_io_threads (tous deux depuis MySQL 5.1.38) à la valeur maximale de 64. Cela devrait engager plus de cœurs.

130
RolandoMySQLDBA

MySQL utilisera automatiquement plusieurs cœurs, donc votre charge de 25% est une coïncidence1 ou une mauvaise configuration potentielle sur Solaris. Je ne prétendrai pas savoir comment régler Solaris, mais voici un article qui passe en revue informations de réglage spécifiques à Solaris .

Les pages de réglage d'InnoDB ont été remaniées dans MySQL 5.5, il y a donc également de bonnes informations. Depuis le disque InnoDB IO astuces :

Si l'outil supérieur Unix ou le Gestionnaire des tâches de Windows montre que le pourcentage d'utilisation du processeur avec votre charge de travail est inférieur à 70%, votre charge de travail est probablement liée au disque. Vous effectuez peut-être trop de validations de transactions ou le pool de tampons est trop petit. Rendre le pool de tampons plus grand peut aider, mais ne le définissez pas comme supérieur à 80% de la mémoire physique.

Quelques autres choses à vérifier:

  • Passer de innodb_flush_method à O_DIRECT vaut la peine d'être testé. Si cela vous aide, vous devrez peut-être monter le système de fichiers avec l'option forcedirectio

  • Changez le innodb_flush_log_at_trx_commit de 1 à 0 (si cela ne vous dérange pas de perdre la dernière seconde sur crash mysql) ou 2 (si cela ne vous dérange pas de perdre la dernière seconde sur crash OS).

  • Vérifiez la valeur de innodb_use_sys_malloc . Cet article a plus d'informations sur la variable.

    À cette époque, aucune bibliothèque d'allocateurs de mémoire n'était réglée pour les processeurs multicœurs. Par conséquent, InnoDB a implémenté son propre allocateur de mémoire dans le sous-système mem. Cet allocateur est gardé par un seul mutex, qui peut devenir un goulot d'étranglement.

    Mais il y a quelques mises en garde à la fin de la section sur ce que signifie activer la variable (elle est activée par défaut dans 5.5).

    Notez que lorsque l'allocateur de mémoire InnoDB est désactivé, InnoDB ignorera la valeur du paramètre innodb_additional_mem_pool_size.

  • Il est possible que la réplication soit à l'origine d'une partie du problème. Je me rends compte que vous n'êtes pas intéressé par le parallélisme, mais d'après la description de ce journal de travail :

    Actuellement, la réplication ne s'adapte pas bien aux machines multicœurs. Le thread esclave unique exécute les événements de réplication un par un et peut ne pas faire face à une charge produite par des connexions client multiples simultanées servies par le processeur du serveur maître séparé.

En fin de compte, InnoDB n'est peut-être pas le meilleur moteur de stockage de données, en raison des opérations sur disque qui se produisent. Vous pourriez envisager de modifier la ou les tables de datawarehouse pour qu'elles soient MyISAM compressé .

1Par coïncidence, je veux dire qu'il y a un goulot d'étranglement qui empêche votre charge d'augmenter au-dessus de 25%, mais ce n'est pas nécessairement un problème de cœur unique forcé.

31
Derek Downey

Remarque: cette réponse concerne une seule connexion utilisant plusieurs cœurs. La question du PO était ambiguë; il supposait à tort que MySQL dans son ensemble ne pouvait pas utiliser plus d'un cœur. Les autres réponses soulignent correctement que le 3-Alter le cas de test est vraiment lié aux E/S, donc ne prouve pas la question du titre.

Une seule connexion n'utilisera qu'un seul cœur. (OK, InnoDB utilise d'autres threads, donc des cœurs, pour certains traitements d'E/S, mais ce n'est pas significatif.)

Vous aviez 3 ALTER, donc vous n'utilisiez pas beaucoup plus que la valeur de 3 cœurs.

Hélas, même PARTITION n'utilise pas plusieurs cœurs.

Jusqu'à récemment, plusieurs connexions atteignaient leur maximum après 4 à 8 cœurs. Le Xtradb de Percona (inclus dans MariaDB) fait un meilleur usage de plusieurs cœurs, mais toujours un seul par thread. Ils atteignent un maximum d'environ 32 cœurs.

(Mise à jour en 2015 :) Plusieurs connexions avec 5,6 max à environ 48 cœurs. 5.7 promet d'être encore meilleur. (C'est ce que disent les benchmarks Oracle.) Mais toujours pas d'utilisation de plusieurs cœurs pour une seule connexion.

Mise à jour (après être passé à Oracle's OpenWorld): la nouvelle version 8.x n'aura aucun parallélisme.

Mise à jour supplémentaire - 8.0.17 a des cas où il utilisera plusieurs cœurs sur très peu de requêtes sélectionnées. (Autrement dit, ne vous excitez pas.)

17
Rick James

À mon humble avis et dans le cas d'utilisation décrit, vous n'utiliserez jamais plus d'un cœur. La raison en est que votre charge de travail est IO lié, pas lié au CPU. Comme vos 3 connexions créent un nouvel index, chacune d'elles doit lire la table entière du disque: c'est ce qui prend temps, sans calculer les indices.

10
jfg956

Considérez que votre goulot d'étranglement pourrait être la performance IO de votre système de fichiers.

En plus de les paramètres suggérés par @RolandoMySQLDBA , j'ai également défini les paramètres de montage noatime dans /etc/fstab pour la partition contenant mon répertoire de données mysql (/data01/mysql dans mon cas, avec /dev/sdb1 monté sur /data01).

Par défaut, linux enregistre le temps d'accès pour CHAQUE lecture ou écriture sur le disque, ce qui affecte négativement les performances IO, en particulier pour les applications IO élevées comme les bases de données. Cela signifie que même la lecture les données d'un fichier déclenchent une écriture sur le disque ... WAT!

Pour désactiver cela, ajoutez l'option de montage noatime dans /etc/fstab pour le point de montage souhaité comme suit (exemple dans mon cas):

/dev/sdb1  /data01  ext4  defaults,noatime  0  2

Remontez ensuite la partition:

mount -o,remount /data01

Cela devrait améliorer les performances de lecture/écriture des applications utilisant cette partition. MAIS ... rien ne vaut la conservation de toutes vos données en mémoire.

9
OkezieE