Aller au contenu
medium

Configurer MySQL : InnoDB, mémoire, connexions et logging

23 min de lecture

La configuration par défaut de MySQL est fonctionnelle pour le développement mais inadaptée à la production : 128 Mo de buffer pool InnoDB, 151 connexions maximum, pas de slow query log activé. Un serveur avec ces réglages sous-utilise la RAM disponible, ne capture aucune requête lente, et peut surprendre quand la charge augmente.

Ce guide vous montre comment adapter la configuration à votre serveur, en partant des paramètres les plus impactants. Chaque modification est testée sur un lab réel (MySQL 8.4 LTS, Debian 12, 2 Go de RAM) et accompagnée de la méthode d’application adaptée — SET GLOBAL pour un changement immédiat, SET PERSIST pour un changement persistant, ou redémarrage quand c’est obligatoire.

  • Localiser les fichiers de configuration et comprendre la hiérarchie my.cnfmysqld.cnfmysqld-auto.cnf
  • Dimensionner la mémoire InnoDB : innodb_buffer_pool_size, innodb_log_buffer_size
  • Configurer les connexions, le binary log, le slow query log et le réseau
  • Appliquer les changements à chaud avec SET GLOBAL et SET PERSIST
  • Comprendre les nouveaux défauts InnoDB de MySQL 8.4 et quand les ajuster

Vous devez configurer MySQL dans ces situations :

  • Vous venez d’installer MySQL et le buffer pool de 128 Mo ne correspond pas à votre serveur avec 8 Go de RAM
  • Vous mettez un serveur en production et devez garantir des performances correctes et un logging utile
  • Vous devez ouvrir les connexions réseau pour qu’une application distante puisse se connecter
  • Vous constatez des requêtes lentes et avez besoin de les identifier
  • Vous préparez MySQL pour la réplication et devez configurer le binary log et le GTID
  • MySQL installé et le service actif (voir le guide Installation)
  • Accès au compte root ou un compte avec les privilèges SYSTEM_VARIABLES_ADMIN (pour SET GLOBAL / SET PERSIST) et PERSIST_RO_VARIABLES_ADMIN (pour SET PERSIST_ONLY sur les variables statiques)
  • Connaître les bases du client mysql (voir le guide Prise en main du client mysql)

MySQL lit ses fichiers de configuration dans un ordre précis. Vérifiez cet ordre sur votre système :

Fenêtre de terminal
mysqld --verbose --help 2>/dev/null | grep -A1 "Default options"
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf

Sur Debian/Ubuntu, l’organisation typique après installation depuis le dépôt Oracle :

/etc/mysql/
├── my.cnf → Fichier principal (inclut conf.d/ et mysql.conf.d/)
├── conf.d/
│ └── mysql.cnf → Options du client mysql
└── mysql.conf.d/
└── mysqld.cnf → Configuration du serveur mysqld
FichierRôle
/etc/mysql/my.cnfPoint d’entrée — inclut conf.d/ et mysql.conf.d/ via !includedir
/etc/mysql/mysql.conf.d/mysqld.cnfConfiguration serveur principale — c’est là que vous ajoutez vos paramètres
/var/lib/mysql/mysqld-auto.cnfÉcrit par SET PERSISTprioritaire sur les fichiers manuels

Sur RHEL/Rocky, tout est dans un fichier unique /etc/my.cnf.

Les fichiers de configuration MySQL utilisent des sections entre crochets :

SectionS’applique àExemples de paramètres
[mysqld]Le serveurinnodb_buffer_pool_size, max_connections, bind_address
[client]Tous les clients (mysql, mysqldump, mysqlimport)port, socket, default-character-set
[mysql]Le client mysql uniquementprompt, pager, auto-rehash

La section la plus importante est [mysqld] — c’est elle qui configure le serveur.

Quand vous exécutez SET PERSIST innodb_buffer_pool_size = 1073741824;, MySQL écrit la valeur dans /var/lib/mysql/mysqld-auto.cnf — un fichier JSON (pas le format INI classique).

Fenêtre de terminal
cat /var/lib/mysql/mysqld-auto.cnf | python3 -m json.tool | head -20
{
"Version": 2,
"mysql_dynamic_parse_early_variables": {
"innodb_buffer_pool_size": {
"Value": "1073741824",
"Metadata": {
"Host": "",
"User": "root",
"Timestamp": 1744530000
}
}
}
}

Règle de priorité : mysqld-auto.cnf est lu en dernier et ses valeurs sont prioritaires sur mysqld.cnf et my.cnf.

MySQL offre trois méthodes pour modifier la configuration :

SET GLOBAL : modification à chaud, non persistante

Section intitulée « SET GLOBAL : modification à chaud, non persistante »

Le changement prend effet immédiatement pour les nouvelles sessions mais sera perdu au prochain redémarrage :

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;

SET PERSIST : modification à chaud ET persistante

Section intitulée « SET PERSIST : modification à chaud ET persistante »

Le changement prend effet immédiatement et est écrit dans mysqld-auto.cnf — il survivra au redémarrage :

SET PERSIST slow_query_log = ON;
SET PERSIST long_query_time = 1;

Certaines variables ne peuvent pas être changées à chaud (contexte statique). SET PERSIST_ONLY écrit la valeur dans mysqld-auto.cnf sans tenter de l’appliquer immédiatement — elle prendra effet au prochain redémarrage :

SET PERSIST_ONLY innodb_buffer_pool_instances = 4;
-- Prend effet au prochain restart
RESET PERSIST slow_query_log; -- supprime cette variable
RESET PERSIST; -- supprime TOUTES les variables persistées
TypeModifiable à chaud ?Méthode
DynamiqueOuiSET GLOBAL ou SET PERSIST
StatiqueNonModifier dans mysqld.cnf ou SET PERSIST_ONLY, puis restart

Pour savoir si une variable est dynamique, consultez la référence des variables serveur — chaque variable y porte l’indicateur Dynamic: Yes ou Dynamic: No. En pratique, si un SET GLOBAL échoue avec ERROR 1238 (HY000): Variable 'xxx' is a read only variable, la variable est statique.

Le paramètre le plus important. Le buffer pool est le cache mémoire central d’InnoDB — il stocke les pages de données et d’index lues depuis le disque. Plus il est grand, moins MySQL fait d’I/O disque.

Valeur par défaut : 128 Mo — beaucoup trop faible pour la production.

Règle de dimensionnement : entre 50 et 70 % de la RAM totale sur un serveur dédié MySQL. Sur notre lab avec 2 Go de RAM :

SET PERSIST innodb_buffer_pool_size = 1073741824; -- 1 Go

La valeur doit être exprimée en octets (pas de suffixe M ou G avec SET). En fichier my.cnf, les suffixes sont acceptés :

[mysqld]
innodb_buffer_pool_size = 1G

Pourquoi 50-70 % et pas 90 % ? Parce que MySQL a besoin de mémoire pour d’autres structures : le cache de threads, les buffers de tri, les tables temporaires, le binary log cache, et le système d’exploitation a besoin de son propre page cache.

Vérifier l’utilisation du buffer pool :

SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%';

Les métriques clés :

CompteurSignification
Innodb_buffer_pool_read_requestsLectures servies depuis le buffer pool (cache hit)
Innodb_buffer_pool_readsLectures nécessitant un accès disque (cache miss)
Innodb_buffer_pool_pages_totalPages totales dans le buffer pool
Innodb_buffer_pool_pages_freePages libres (si 0, le buffer pool est plein)

Le hit ratio optimal :

SELECT
ROUND((1 - (Reads / Read_requests)) * 100, 2) AS buffer_pool_hit_ratio
FROM (
SELECT
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') AS Reads,
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests') AS Read_requests
) AS stats;

Un hit ratio supérieur à 99 % est l’objectif. En dessous de 95 %, augmentez le buffer pool.

MySQL 8.4 ajuste automatiquement le nombre d’instances du buffer pool selon la taille totale — vous n’avez généralement plus besoin de le configurer manuellement. La règle interne : 1 instance par Go, plafonné à 64.

Buffer mémoire utilisé par InnoDB avant l’écriture des entrées de redo log sur disque.

Valeur par défaut MySQL 8.4 : 64 MiB (contre 16 MiB en MySQL 8.0)

Cette valeur convient à la plupart des charges. Augmentez-la si vous exécutez de grosses transactions (LOAD DATA, insertions massives, batchs volumineux), afin de limiter les flushs intermédiaires du log buffer :

SET PERSIST innodb_log_buffer_size = 134217728; -- 128 Mo

Contrôle comment MySQL écrit les données et les logs sur disque.

Valeur par défaut MySQL 8.4 : O_DIRECT — les données sont écrites directement sur disque sans passer par le cache du système d’exploitation. C’est le bon choix pour la plupart des systèmes Linux avec un stockage performant.

ValeurComportementRecommandation
O_DIRECTBypass du cache OS (défaut 8.4)Recommandé — évite la double bufferisation
fsyncPasse par le cache OS puis fsyncAncien défaut, moins efficace
O_DIRECT_NO_FSYNCComme O_DIRECT mais sans fsync pour les redo logsRisque de perte si le stockage n’a pas de cache protégé par batterie

MySQL 8.4 a modifié plusieurs valeurs par défaut d’InnoDB pour mieux correspondre aux workloads modernes. Si vous migrez depuis MySQL 8.0, ces changements peuvent impacter les performances :

ParamètreAncien défaut (8.0)Nouveau défaut (8.4)Impact
innodb_io_capacity20010 000MySQL écrit plus agressivement les pages sales
innodb_io_capacity_max2 × io_capacity2 × io_capacity (= 20 000)Plafond d’I/O plus élevé
innodb_change_bufferingallnoneLe change buffer est désactivé
innodb_adaptive_hash_indexONOFFLe hash index adaptatif est désactivé
innodb_flush_methodfsyncO_DIRECTBypass du cache OS par défaut
innodb_log_buffer_size16 MiB64 MiBBuffer de redo log quadruplé
innodb_doublewrite_pages64128Plus de pages dans le doublewrite buffer
innodb_redo_log_capacity~100 Mo100 MoIdentique, mais le contrôle est maintenant unique

Le bond est spectaculaire. MySQL 8.4 considère que les serveurs modernes utilisent des SSD/NVMe capables de milliers d’IOPS. Si votre serveur utilise des disques mécaniques (HDD), baissez cette valeur :

SET PERSIST innodb_io_capacity = 1000; -- SSD SATA
SET PERSIST innodb_io_capacity = 200; -- HDD

Le change buffer tamponnait les modifications d’index secondaires pour les appliquer en batch. Avec la généralisation des SSD et l’augmentation de la RAM, le gain était devenu négligeable voire contre-productif. MySQL 8.4 le désactive par défaut.

L’index hash adaptatif construisait un index en mémoire au-dessus des index B-tree pour accélérer les lookups fréquents. En pratique, il consommait de la mémoire, provoquait de la contention sur les sémaphores, et n’apportait un gain que dans des cas précis. Gardez-le désactivé sauf si des benchmarks montrent un bénéfice.

innodb_dedicated_server : auto-dimensionnement sur serveur dédié

Section intitulée « innodb_dedicated_server : auto-dimensionnement sur serveur dédié »

innodb_dedicated_server n’est pas modifiable à chaud. Il doit être activé au démarrage du serveur, dans my.cnf :

[mysqld]
innodb_dedicated_server = ON

En MySQL 8.4, ce mode calcule automatiquement :

  • innodb_buffer_pool_size selon la RAM détectée :
RAM détectéeBuffer pool
< 1 Go128 MiB
1 à 4 Go50 % de la RAM
> 4 Go75 % de la RAM
  • innodb_redo_log_capacity selon le nombre de processeurs logiques : (logical processors / 2) GiB, plafonné à 16 GiB

Valeur par défaut : 151

Chaque connexion MySQL consomme un thread (mono-processus multi-threads, contrairement à PostgreSQL qui fork un processus). 151 connexions = 151 threads, chacun avec sa pile mémoire (thread_stack, 1 Mo par défaut) et ses buffers de session.

SHOW VARIABLES LIKE 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+

Bonnes pratiques :

  • Pour un serveur de développement ou un lab : le défaut de 151 suffit
  • Pour un serveur de production : ajustez selon votre charge réelle, sans dépasser 500-1000
  • Au-delà de 300-500 connexions : utilisez ProxySQL ou un pool de connexions applicatif
SET PERSIST max_connections = 300;

Ces paramètres contrôlent le délai avant fermeture d’une connexion inactive :

ParamètreS’applique àDéfaut
wait_timeoutConnexions non interactives (application)28 800 (8 heures)
interactive_timeoutConnexions interactives (client mysql)28 800 (8 heures)

8 heures d’inactivité avant fermeture, c’est très long. En production, réduisez :

SET PERSIST wait_timeout = 600; -- 10 minutes
SET PERSIST interactive_timeout = 3600; -- 1 heure

Quand une connexion se ferme, MySQL peut garder le thread en cache plutôt que de le détruire — la prochaine connexion le réutilise, économisant le coût de création.

Valeur par défaut : auto-dimensionné (-1 en interne) selon une formule basée sur max_connections, plafonnée à 100.

Vérifiez le ratio threads créés vs connexions :

SHOW GLOBAL STATUS LIKE 'Threads%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 2 |
| Threads_connected | 1 |
| Threads_created | 7 |
| Threads_running | 1 |
+-------------------+-------+

Si Threads_created augmente rapidement, augmentez thread_cache_size :

SET PERSIST thread_cache_size = 32;

Le binary log (binlog) enregistre toutes les modifications de données. Il est indispensable pour la réplication et la restauration point-in-time (PITR).

MySQL 8.4 utilise le format ROW par défaut — c’est le plus fiable pour la réplication :

FormatContenuRecommandation
ROWL’image avant/après de chaque ligne modifiéeRecommandé — déterministe
STATEMENTLa requête SQL originaleRisque de divergence source/replica
MIXEDSTATEMENT quand c’est sûr, ROW sinonCompromis rarement nécessaire

Durée de rétention des fichiers binlog avant suppression automatique :

Valeur par défaut MySQL 8.4 : 2 592 000 secondes (30 jours)

Pour un lab ou un serveur avec un stockage limité :

SET PERSIST binlog_expire_logs_seconds = 604800; -- 7 jours

sync_binlog et innodb_flush_log_at_trx_commit : durabilité

Section intitulée « sync_binlog et innodb_flush_log_at_trx_commit : durabilité »

Ces deux paramètres contrôlent ensemble la durabilité des transactions :

sync_binloginnodb_flush_log_at_trx_commitDurabilitéPerformance
11Maximale (aucune perte en cas de crash)Plus lent (2 écritures disque par commit)
12Bonne (perte possible de 1 seconde de binlog)Meilleur
00Minimale (perte possible en cas de crash)Maximum

Configuration recommandée pour la production :

SET PERSIST sync_binlog = 1;
SET PERSIST innodb_flush_log_at_trx_commit = 1;

C’est le réglage double durabilité — MySQL et InnoDB écrivent tous les deux sur disque à chaque commit. C’est le seul réglage qui garantit zéro perte de données en cas de crash.

Le log d’erreurs est toujours actif. Son emplacement :

SHOW VARIABLES LIKE 'log_error';
+---------------+---------------------------+
| Variable_name | Value |
+---------------+---------------------------+
| log_error | /var/log/mysql/error.log |
+---------------+---------------------------+

Le paramètre le plus utile en exploitation. Désactivé par défaut — activez-le immédiatement :

SET PERSIST slow_query_log = ON;
SET PERSIST long_query_time = 1; -- en secondes (1 seconde)
ParamètreDéfautRecommandation
slow_query_logOFFON — toujours en production
long_query_time10 (secondes !)1 ou même 0.5 pour être réactif
log_queries_not_using_indexesOFFMode investigation — voir note ci-dessous

Le fichier de log se trouve par défaut dans le datadir :

Fenêtre de terminal
ls -la /var/lib/mysql/*-slow.log

Pour analyser les requêtes lentes :

Fenêtre de terminal
mysqldumpslow -s t /var/lib/mysql/mysql-lab-slow.log | head -30

Le general log trace toutes les requêtes — utile pour le debug, dangereux en production (volume de logs excessif, impact sur les performances) :

SET GLOBAL general_log = ON; -- NE PAS persister
-- Débugguez votre problème...
SET GLOBAL general_log = OFF;

MySQL peut écrire les logs dans des fichiers ou dans des tables système :

SET PERSIST log_output = 'FILE'; -- défaut, recommandé pour la production
SET PERSIST log_output = 'TABLE'; -- écrit dans mysql.slow_log et mysql.general_log
SET PERSIST log_output = 'FILE,TABLE'; -- les deux

Le mode TABLE est pratique pour les requêtes SQL sur les logs, mais consomme plus de ressources.

Valeur par défaut MySQL 8.4 : * (toutes les interfaces, IPv4 et IPv6).

Sur notre lab Debian, le paquet Oracle configure bind_address = 127.0.0.1 dans mysqld.cnf — MySQL n’écoute alors que localement. C’est un choix du paquet, pas le défaut du serveur MySQL lui-même.

Pour ouvrir l’accès réseau, modifiez mysqld.cnf :

[mysqld]
bind_address = 0.0.0.0

MySQL 8.4 accepte plusieurs adresses séparées par des virgules :

[mysqld]
bind_address = 127.0.0.1,192.168.122.70

Par défaut, MySQL fait une résolution DNS inversée pour chaque connexion entrante. Sur un réseau interne sans DNS fiable, ça ajoute du délai. Désactivez-le :

SET PERSIST_ONLY skip_name_resolve = ON; -- nécessite un restart

Après activation, les comptes MySQL doivent utiliser des adresses IP au lieu de noms d’hôtes dans le GRANT.

SHOW VARIABLES et performance_schema.variables_info

Section intitulée « SHOW VARIABLES et performance_schema.variables_info »

Voir la valeur d’un paramètre :

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

Voir la source d’un paramètre (fichier, SET PERSIST, compilé) :

SELECT variable_name, variable_source, set_time, set_user
FROM performance_schema.variables_info
WHERE variable_name LIKE 'innodb_buffer%';
+-------------------------------+-----------------+----------------------------+----------+
| variable_name | variable_source | set_time | set_user |
+-------------------------------+-----------------+----------------------------+----------+
| innodb_buffer_pool_chunk_size | COMPILED | NULL | NULL |
| innodb_buffer_pool_instances | COMPILED | NULL | NULL |
| innodb_buffer_pool_size | PERSISTED | 2026-04-13 09:00:00.000000 | root |
+-------------------------------+-----------------+----------------------------+----------+

variable_source vous dit d’où vient la valeur : COMPILED (défaut de compilation), GLOBAL (my.cnf/mysqld.cnf), PERSISTED (mysqld-auto.cnf), DYNAMIC (SET GLOBAL de la session).

mysqld --validate-config : valider avant de redémarrer

Section intitulée « mysqld --validate-config : valider avant de redémarrer »

MySQL 8.4 valide la configuration sans démarrer le serveur :

Fenêtre de terminal
sudo mysqld --validate-config

Si un paramètre est invalide, la commande affiche l’erreur et sort avec un code non nul. Lancez toujours cette validation après avoir modifié mysqld.cnf manuellement, avant de redémarrer le service.

RAM totaleinnodb_buffer_pool_sizemax_connectionsinnodb_log_buffer_sizelong_query_time
2 Go1 Go100-20064 Mo1 s
4 Go2-3 Go200-30064 Mo1 s
8 Go4-5 Go200-50064 Mo0.5 s
16 Go10-12 Go300-500128 Mo0.5 s
32 Go20-24 Go300-1000128 Mo0.5 s
SymptômeCause probableSolution
Le serveur ne redémarre plus après un changement dans mysqld.cnfParamètre invalide ou syntaxe incorrectemysqld --validate-config pour identifier l’erreur. Corriger le fichier ou renommer mysqld-auto.cnf
SET PERSIST retourne ERROR 3615Le fichier mysqld-auto.cnf est corrompuSupprimez /var/lib/mysql/mysqld-auto.cnf et redémarrez
SHOW VARIABLES retourne une valeur différente de mysqld.cnfmysqld-auto.cnf a prioritéSELECT * FROM performance_schema.variables_info WHERE variable_name = 'xxx' pour trouver la source
Buffer pool hit ratio < 95 %Buffer pool trop petitAugmentez innodb_buffer_pool_size
Threads_created augmente rapidementThread cache insuffisantAugmentez thread_cache_size
Slow query log vide malgré slow_query_log = ONlong_query_time trop élevé (défaut 10 s)Baisser à 1 ou 0.5 seconde
  • Le buffer pool InnoDB est le paramètre le plus impactant — visez 50 à 70 % de la RAM sur un serveur dédié.
  • Contrairement à PostgreSQL, innodb_buffer_pool_size est dynamique — redimensionnable à chaud avec SET GLOBAL.
  • SET PERSIST écrit dans mysqld-auto.cnf (JSON) qui a priorité sur tous les fichiers .cnf — choisissez une seule méthode de gestion.
  • MySQL 8.4 a modernisé les défauts InnoDB : innodb_io_capacity = 10 000, change buffer désactivé, adaptive hash index désactivé. Ajustez innodb_io_capacity si vous utilisez des HDD.
  • Activez le slow query log dès le premier jour (long_query_time = 1) — c’est le premier outil pour trouver les requêtes lentes.
  • Le réglage sync_binlog=1 + innodb_flush_log_at_trx_commit=1 garantit zéro perte en cas de crash — le seul réglage acceptable pour les données critiques.
  • mysqld --validate-config vérifie la configuration sans démarrer le serveur — lancez-le avant chaque restart.
  • innodb_dedicated_server auto-dimensionne la mémoire — mais uniquement sur un serveur 100 % dédié à MySQL.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn