InnoDB est l'un des moteurs de stockage les plus utilisés dans MySQL. Ce moteur de stockage est connu comme un moteur de stockage haute fiabilité et hautes performances et ses principaux avantages incluent la prise en charge du verrouillage au niveau des lignes, des clés étrangères et le respect du modèle ACID. InnoDB remplace MyISAM comme moteur de stockage par défaut depuis MySQL 5.5, sorti en 2010.
Ce moteur de stockage peut être incroyablement performant et puissant s'il est optimisé correctement. Aujourd'hui, nous examinons ce que nous pouvons faire pour qu'il fonctionne au mieux de ses capacités, mais avant de plonger dans InnoDB cependant, nous devons comprendre ce qu'est le modèle ACID susmentionné.
Qu'est-ce que l'ACID et pourquoi est-ce important ?
ACID est un ensemble de propriétés des transactions de base de données. L'acronyme se traduit par quatre mots :Atomicité, Cohérence, Isolation et Durabilité. En bref, ces propriétés garantissent que les transactions de la base de données sont traitées de manière fiable et garantissent la validité des données malgré les erreurs, les pannes de courant ou tout autre problème de ce type. Un système de gestion de base de données qui adhère à ces principes est dit être un SGBD conforme à ACID. Voici comment tout fonctionne dans InnoDB :
- L'atomicité garantit que les instructions d'une transaction fonctionnent comme une unité indivisible et que leurs effets sont vus collectivement ou pas du tout ;
- La cohérence est gérée par les mécanismes de journalisation de MySQL qui enregistrent toutes les modifications apportées à la base de données ;
- L'isolation fait référence au verrouillage au niveau des lignes d'InnoDB ;
- La durabilité est également maintenue car InnoDB maintient un fichier journal qui suit toutes les modifications apportées au système.
Comprendre InnoDB
Maintenant que nous avons couvert ACID, nous devrions probablement regarder à quoi ressemble InnoDB sous le capot. Voici à quoi ressemble InnoDB de l'intérieur (image avec l'aimable autorisation de Percona) :
InnoDB InternalsD'après l'image ci-dessus, nous pouvons clairement voir qu'InnoDB a quelques paramètres cruciaux pour sa performance et ceux-ci sont les suivants :
- Le paramètre innodb_data_file_path décrit l'espace de table système (l'espace de table système est la zone de stockage du dictionnaire de données InnoDB, des doubles tampons d'écriture et de modification et des journaux d'annulation). Le paramètre décrit le fichier dans lequel les données dérivées des tables InnoDB seront stockées ;
- Le paramètre innodb_buffer_pool_size est une mémoire tampon qu'InnoDB utilise pour mettre en cache les données et les index de ses tables ;
- Le paramètre innodb_log_file_size décrit la taille des fichiers journaux InnoDB ;
- Le paramètre innodb_log_buffer_size est utilisé pour écrire dans les fichiers journaux sur le disque ;
- Le paramètre innodb_flush_log_at_trx_commit contrôle l'équilibre entre la stricte conformité ACID et des performances supérieures ;
- Le paramètre innodb_lock_wait_timeout est la durée en secondes pendant laquelle une transaction InnoDB attend un verrou de ligne avant d'abandonner ;
- Le paramètre innodb_flush_method définit la méthode utilisée pour vider les données dans les fichiers de données InnoDB et les fichiers journaux qui peuvent affecter le débit d'E/S.
InnoDB stocke également les données de ses tables dans un fichier appelé ibdata1 - les journaux sont cependant stockés dans deux fichiers distincts nommés ib_logfile0 et ib_logfile1 :ces trois fichiers résident tous dans /var/lib/mysql annuaire.
Afin de rendre InnoDB aussi performant que possible, nous devons affiner ces paramètres et les optimiser autant que possible en examinant nos ressources matérielles disponibles.
Régler InnoDB pour des performances élevées
Afin d'ajuster les performances d'InnoDB sur votre matériel, suivez ces étapes :
-
Afin d'étendre automatiquement innodb_data_file_path, spécifiez l'attribut autoextend dans le paramètre et redémarrez le serveur. Par exemple :
innodb_data_file_path=ibdata1:10M:autoextend
Lorsque le paramètre d'extension automatique est utilisé, la taille du fichier de données augmente automatiquement par incréments de 8 Mo chaque fois que de l'espace est requis. Un nouveau fichier de données à extension automatique peut également être spécifié comme suit (dans ce cas, le nouveau fichier de données s'appelle ibdata2) :
innodb_data_file_path=ibdata1:10M;ibdata2:10M:autoextend
-
Lors de l'utilisation d'InnoDB, le principal mécanisme utilisé est le pool de mémoire tampon. InnoDB s'appuie fortement sur le pool de mémoire tampon et, en règle générale, le paramètre innodb_buffer_pool_size doit représenter environ 60 % à 80 % de la RAM totale disponible sur le serveur. Gardez à l'esprit que vous devez également laisser de la RAM pour les processus en cours d'exécution dans le système d'exploitation ;
-
Innodb_log_file_size d'InnoDB doit être défini aussi grand que possible, mais pas plus grand que nécessaire. Dans ce cas, gardez à l'esprit qu'une taille de fichier journal plus grande est meilleure pour les performances, mais plus elle est grande, plus le temps de récupération après un crash est long. En tant que tel, il n'existe pas de solution "taille unique", mais il est dit que la taille combinée des fichiers journaux doit être suffisamment grande. Cela aide le serveur MySQL à travailler régulièrement sur les points de contrôle et les activités de vidage de disque. Cela économise trop d'E/S de CPU et de disque et peut fonctionner sans problème pendant les heures de pointe ou les charges de travail élevées. Bien que l'approche recommandée soit de tester et d'expérimenter vous-même et de trouver vous-même la valeur optimale ;
-
La valeur innodb_log_buffer_size doit être définie sur au moins 16 M. Un grand tampon de journal permet aux transactions volumineuses de s'exécuter sans qu'il soit nécessaire d'écrire le journal sur le disque avant que les transactions ne soient validées, ce qui permet d'économiser des E/S de disque ;
-
Lors du réglage d'innodb_flush_log_at_trx_commit, gardez à l'esprit que ce paramètre accepte trois valeurs - 0, 1 et 2. Avec une valeur de 1, vous obtenez la conformité ACID et avec les valeurs 0 ou 2, vous obtenez plus de performances, mais moins de fiabilité car dans ce cas, les transactions pour lesquelles les journaux n'ont pas encore été vidés sur le disque peuvent être perdues en cas de plantage ;
-
Afin de définir innodb_lock_wait_timeout sur une valeur appropriée, gardez à l'esprit que ce paramètre définit le temps en secondes (la valeur par défaut est 50) avant émettant l'erreur suivante et annulant l'instruction actuelle :
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
-
Dans InnoDB, plusieurs méthodes de vidage sont disponibles. Par défaut, ce paramètre est défini sur "async_unbuffered" sur les machines Windows si la valeur est définie sur NULL et sur "fsync" sur les machines Linux. Voici quelles sont les méthodes et ce qu'elles font :
Méthode de vidage InnoDB | Objectif |
normal | InnoDB utilisera des E/S asynchrones simulées et des E/S tamponnées. |
sans tampon | InnoDB utilisera des E/S asynchrones simulées et des E/S non tamponnées. |
async_unbuffered | InnoDB utilisera les E/S asynchrones de Windows et les E/S non tamponnées. Paramètres par défaut sur les machines Windows. |
fsync | InnoDB utilisera la fonction fsync() pour vider les données et les fichiers journaux. Paramètre par défaut sur les machines Linux. |
O_DSYNC | InnoDB utilisera O_SYNC pour ouvrir et vider les fichiers journaux et la fonction fsync() pour vider les fichiers de données. O_DSYNC est plus rapide que O_DIRECT, mais les données peuvent ou non être cohérentes en raison de la latence ou d'un plantage pur et simple. |
nosync | Utilisé pour les tests de performances internes - non pris en charge. |
littlesync | Utilisé pour les tests de performances internes - non pris en charge. |
O_DIRECT | InnoDB utilisera O_DIRECT pour ouvrir les fichiers de données et la fonction fsync() pour vider à la fois les données et les fichiers journaux. En comparaison avec O_DSYNC, O_DIRECT est plus stable et plus cohérent avec les données, mais plus lent. Le cache du système d'exploitation sera évité en utilisant ce paramètre - ce paramètre est le paramètre recommandé sur les machines Linux. |
O_DIRECT_NO_FSYNC | InnoDB utilisera O_DIRECT lors du vidage des E/S - la partie "NO_FSYNC" définit que la fonction fsync() sera ignorée. |
- Vous devriez également envisager d'activer le paramètre innodb_file_per_table. Ce paramètre est activé par défaut dans MySQL 5.6 et supérieur. Ce paramètre vous soulage des problèmes de gestion liés aux tables InnoDB en les stockant dans des fichiers séparés et en évitant les dictionnaires principaux et les tables système gonflés. L'activation de cette variable évite également de faire face à la complexité de la récupération de données lorsqu'une certaine table est corrompue
- Maintenant que vous avez modifié ces paramètres selon les instructions décrites ci-dessus, vous devriez être presque prêt ! Avant de commencer, vous devriez probablement garder un œil sur le fichier le plus occupé de toute l'infrastructure InnoDB :ibdata1.
Traitement avec ibdata1
Plusieurs classes d'informations sont stockées dans ibdata1 :
- Les données des tables InnoDB ;
- Les index des tables InnoDB ;
- Métadonnées de la table InnoDB ;
- Données MVCC (Multiversion Concurrency Control) ;
- Le tampon de double écriture - un tel tampon permet à InnoDB de récupérer des pages à moitié écrites. Le but d'un tel tampon est d'empêcher la corruption des données ;
- Le tampon d'insertion - un tel tampon est utilisé par InnoDB pour mettre en mémoire tampon les mises à jour de la même page afin qu'elles puissent être effectuées en une seule fois et non l'une après l'autre.
Lorsqu'il s'agit de grands ensembles de données, le fichier ibdata1 peut devenir extrêmement volumineux et cela peut être au cœur d'un problème très frustrant - le fichier ne peut que croître et par défaut, il ne peut pas rétrécir. Vous pouvez arrêter MySQL et supprimer ce fichier, mais cela n'est pas recommandé, sauf si vous savez ce que vous faites. Une fois supprimé, MySQL ne fonctionnera pas correctement car le dictionnaire et les tables système ont disparu, donc la table système principale est corrompue.
Afin de réduire ibdata1 une fois pour toutes, suivez ces étapes :
- Vide toutes les données des bases de données InnoDB. Vous pouvez utiliser mysqldump ou mysqlpump pour cette action ;
- Supprimer toutes les bases de données à l'exception des bases de données mysql, performance_schema et information_schema ;
- Arrêtez MySQL ;
- Ajoutez ce qui suit à votre fichier my.cnf :
[mysqld] innodb_file_per_table = 1 innodb_flush_method = O_DIRECT innodb_log_file_size = 25% of innodb_buffer_pool_size innodb_buffer_pool_size = up to 60-80% of available RAM.
- Supprimez les fichiers ibdata1 et ib_logfile* (ceux-ci seront recréés au prochain redémarrage de MySQL) ;
- Démarrez MySQL et restaurez les données du vidage que vous avez effectué auparavant. Après avoir effectué les étapes décrites ci-dessus, le fichier ibdata1 continuera de croître, mais il ne contiendra plus les données des tables InnoDB - le fichier ne contiendra que des métadonnées et chaque table InnoDB existera en dehors de ibdata1. Maintenant, si vous allez dans le répertoire /var/lib/mysql, vous verrez deux fichiers représentant chaque table que vous avez avec le moteur InnoDB. Les fichiers ressembleront à ceci :
- demotable.frm
- demotable.ibd
Le fichier .frm contient l'en-tête du moteur de stockage et le fichier .ibd contient les données de table et les index de votre table.
Avant de déployer les modifications, assurez-vous d'ajuster les paramètres en fonction de votre infrastructure. Ces paramètres peuvent faire ou défaire les performances d'InnoDB, alors assurez-vous de les surveiller à tout moment. Maintenant, vous devriez être prêt !
Résumé
Pour résumer, l'optimisation des performances d'InnoDB peut être un grand avantage si vous développez des applications qui nécessitent à la fois l'intégrité des données et des performances élevées - InnoDB vous permet de modifier la quantité de mémoire que le moteur est autorisé à consomment, pour modifier la taille du fichier journal, la méthode de vidage utilisée par le moteur, etc. - ces modifications peuvent rendre InnoDB extrêmement performant s'ils sont correctement réglés. Avant d'effectuer des améliorations, méfiez-vous des conséquences de vos actions sur votre serveur et MySQL.
Comme toujours, avant d'optimiser quoi que ce soit pour les performances, effectuez toujours (et testez !) Des sauvegardes afin de pouvoir restaurer vos données si nécessaire et testez toujours les modifications sur un serveur local avant de déployer les modifications en production.