MySQL vs Percona Server : paramètres par défaut plus sûrs — moins de réglages, moins de pannes

Cet article vous a aidé ?

La plupart des pannes de bases de données ne commencent pas par un bug spectaculaire. Elles commencent par un ajustement de configuration « raisonnable », une nouvelle forme de charge de travail, et l’hypothèse silencieuse que votre serveur se comportera comme le trimestre précédent.

Si vous exploitez MySQL en production assez longtemps, vous apprenez à la dure que « ça marche » n’est pas la même chose que « ça échoue de façon sûre ». C’est là que Percona Server (un fork compatible MySQL) a historiquement prouvé son utilité : des valeurs par défaut pragmatiques, une instrumentation supplémentaire et une préférence pour la survivabilité quand votre application traverse une mauvaise journée.

La décision : quand Percona vaut le coup (et quand ce n’est pas le cas)

Il y a deux raisons sensées de changer de distribution de base de données en production : vous voulez moins d’incidents, ou vous voulez diagnostiquer plus vite pendant les incidents. Percona Server tend à aider sur les deux points, principalement parce qu’il a historiquement été livré avec des fonctionnalités opérationnelles et une instrumentation que MySQL upstream n’incluait pas encore, mettait derrière des offres entreprises, ou nécessitait plus d’effort pour devenir exploitables.

Choisissez MySQL upstream quand

  • Vous avez besoin de la compatibilité la plus conservatrice. MySQL upstream (Oracle) définit la référence. Tout le monde teste d’abord contre lui.
  • Vous êtes déjà aligné sur le rythme de publication et les outils d’Oracle. Si votre organisation traite MySQL comme un produit fournisseur avec contrat de support formel et verrouillage strict des versions, simplifiez-vous la vie.
  • Votre maturité opérationnelle est suffisante pour que les « valeurs par défaut plus sûres » n’aient pas d’importance. Si vous avez déjà une gestion de configuration stricte qui reflète la réalité, des alertes sur la pression InnoDB, et des tests réguliers de crash, alors la distribution compte moins que la discipline.

Choisissez Percona Server quand

  • Vous voulez une meilleure observabilité prête à l’emploi. En pratique, la différence est souvent « on peut le voir » contre « on pense que c’est ça ».
  • Vous voulez des fonctionnalités opérationnelles qui réduisent les pièges. Historiquement : instrumentation renforcée, réglages de performance et compatibilité avec les outils de gestion des données au repos (surtout dans l’écosystème Percona).
  • Vous gérez des flottes. Quand vous exploitez des dizaines ou des centaines d’instances MySQL, le coût d’une mauvaise valeur par défaut se multiplie. L’orientation de Percona vers un comportement ami des opérations peut s’amortir en évitant un incident majeur.

Ce qu’il ne faut pas faire : changer de distribution pour un « hack » de performance. Si vous partez de cette intention, vous obtiendrez peut‑être un « gain de benchmark » puis le perdrez face à un cas limite de réplication, une surprise de sauvegarde, ou un redémarrage qui prend plus de temps que votre budget SLA complet.

Règle générale : si votre plus grande douleur est liée aux incidents et à l’analyse lente des causes, Percona Server est souvent le choix pragmatique. Si votre principale contrainte est « juridique et achats », restez sur MySQL upstream et investissez dans l’instrumentation et les runbooks.

Contexte historique et faits importants

Certaines informations sont triviaux. Celles-ci ne le sont pas. Elles influencent la façon dont les équipes gèrent le risque.

  1. MySQL AB a été acquis par Sun en 2008, puis Sun a été acquis par Oracle en 2010. L’écosystème de forks (Percona, MariaDB) s’est accéléré parce que les gens n’aiment pas l’incertitude autour des infrastructures fondamentales.
  2. Percona a commencé comme une société de performance et de support avant de livrer ses propres builds de serveur. Cette origine explique le choix de fonctionnalités axées sur l’opérateur.
  3. InnoDB est devenu le moteur de stockage par défaut de MySQL il y a des années, remplaçant le rôle de MyISAM. Ce changement a placé la récupération après crash et les réglages de durabilité au centre de la justesse opérationnelle.
  4. Performance Schema a commencé comme « intéressant mais lourd », puis est devenu une surface d’observabilité principale. Beaucoup d’équipes le laissent encore à moitié désactivé à cause d’idées reçues anciennes.
  5. Percona a popularisé des outils opérationnels autour de MySQL, en particulier les sauvegardes à chaud. Cela a façonné les attentes : les sauvegardes doivent être rapides, vérifiables et ne pas nécessiter d’indisponibilité.
  6. La réplication MySQL a évolué du mode statement-based au mode row-based et mixed. Ce n’était pas académique ; c’était une réponse à la dérive des données et à la non-déterminisme du monde réel.
  7. Le journal de redo d’InnoDB et son comportement de flush ont été ajustés à travers les versions majeures. Les valeurs par défaut de durabilité et de performance évoluent ; les conseils anciens peuvent être erronés aujourd’hui.
  8. MySQL 8 a changé la donne opérationnelle : dictionnaire de données, EXPLAIN amélioré, meilleur comportement par défaut des jeux de caractères. Cela a aussi modifié les risques de mise à niveau et les hypothèses des outils.
  9. Percona Server a historiquement exposé des compteurs d’état et des réglages supplémentaires. Quand vous diagnostiquer des blocages, des compteurs valent mieux que des suppositions.

Paramètres par défaut plus sûrs : ce que « plus sûr » signifie réellement

« Paramètres par défaut plus sûrs » n’est pas une déclaration morale. Il s’agit de la façon dont les systèmes se comportent sous contrainte et en cas d’échec : blocages disques, pression de checkpoint, transactions longues, retard de réplication, ou le classique « on a juste doublé le trafic ». La base de données qui échoue lentement et bruyamment est plus sûre que celle qui échoue vite et silencieusement.

Axe de sécurité 1 : durabilité prévisible

Le piège le plus courant en production avec MySQL est des compromis de durabilité cachés derrière des réglages de performance. Un nombre surprenant d’équipes ont tourné avec innodb_flush_log_at_trx_commit=2 ou sync_binlog=0 pour « la performance », puis ont découvert que leur RPO en cas de crash était « ce que le noyau décidait ».

Percona Server ne résout pas magiquement les mauvaises décisions de durabilité, mais les builds axés ops tendent à documenter et rendre visibles ces compromis plus clairement, et l’écosystème autour (comme Percona Monitoring) rend plus difficile de se convaincre qu’on est en sécurité alors que ce n’est pas le cas.

Axe de sécurité 2 : moins de réglages pour obtenir des performances sensées

La plupart des conseils de tuning MySQL en ligne sont fossilisés. Ils sont aussi écrits par des gens qui ne portent pas la sonnerie pour votre entreprise.

Des valeurs par défaut plus sûres sont celles où une machine correctement dimensionnée avec une configuration raisonnable ne chute pas brutalement lorsque la concurrence augmente. Une bonne valeur par défaut n’est pas « embarrassante sous charge ». Une excellente valeur par défaut « n’entraîne pas une panne si vous avez oublié un seul paramètre ».

Axe de sécurité 3 : visibilité sur le goulot réel

Si vous ne pouvez pas attribuer la latence au disque, aux verrous, aux défauts du buffer pool, à la contention du redo, ou à l’application de réplication, vous réglerez la mauvaise chose. Le grand avantage pratique de Percona Server a souvent été de fournir plus de leviers pour observer et mesurer, pas de défier la physique.

Première blague (vous en obtenez exactement deux) : une config MySQL sans commentaires est comme un parachute emballé par le « vous du futur ». Il fonctionne jusqu’au moment où vous en avez besoin.

Observabilité : la différence entre deviner et savoir

Quand la latence monte en flèche, les dirigeants demandent « est-ce que la base est down ? » Les ingénieurs demandent « est-ce le CPU, le stockage, les verrous ou la réplication ? » Votre succès se mesure à la rapidité à laquelle vous pouvez répondre à la seconde question, pas à la confiance avec laquelle vous répondez à la première.

Ce que vous voulez observer (par ordre)

  • Pression de concurrence : threads en cours, pics de connexions, échecs du thread cache, connexions avortées.
  • Santé d’InnoDB : taux de hit du buffer pool, pourcentage de pages sales, âge du checkpoint/pression redo, longueur de la history list.
  • Verrouillage : attentes de verrous sur lignes, attentes de verrous de métadonnées, transactions longues retenant des verrous.
  • IO : latence fsync, écritures du journal redo, lectures de fichiers de données, activité doublewrite.
  • Réplication : retard d’application, espace du relay log, mise en file des workers.

Où les équipes MySQL se trompent

Elles regardent le CPU, voient qu’il est bas, et déclarent la base « saine ». Puis elles regardent l’utilisation disque et voient qu’elle n’est pas saturée, et déclarent le stockage « sain ». Pendant ce temps, le vrai problème est la variance de latence fsync (p99), ou une seule transaction bloquant le purge, ou un verrou de métadonnées dû à un changement de schéma en ligne. Aucun de ces problèmes n’apparaît clairement dans « CPU% et disque% ».

La valeur ajoutée de Percona a souvent été : des compteurs plus actionnables, et une culture d’exposition des internals. MySQL upstream a comblé une partie de ce fossé au fil du temps, mais la différence de philosophie opérationnelle se voit encore dans ce qui est activé par défaut et dans la façon dont les données sont « évidentes ».

Une idée citée (paraphrase) : l’idée de Werner Vogels est que vous devriez « concevoir pour l’échec », en supposant que des éléments vont casser et que votre système doit continuer à fonctionner malgré tout.

Durabilité et sécurité au crash : ce que vous échangez contre la vitesse

En production, « durable » n’est pas une case à cocher. C’est un accord entre InnoDB, le journal binaire, le système de fichiers, le noyau, l’hyperviseur, et parfois une couche de stockage réseau qui vous rassure poliment.

Les réglages clés qui déterminent votre RPO

  • innodb_flush_log_at_trx_commit : contrôle à quel point InnoDB fsync le redo au commit.
  • sync_binlog : contrôle à quel point le binlog est fsyncé.
  • binlog_format et les réglages GTID : influencent la correction de la réplication et le comportement en cas de basculement.

À quoi ressemblent des « paramètres par défaut plus sûrs »

Les valeurs par défaut plus sûres favorisent la correction après un crash plutôt que le benchmark. Si vous gérez des systèmes financiers ou d’inventaire, ne soyez pas malin. Si vous gérez un workload de type cache avec une perte de données acceptable, documentez-le explicitement, mesurez votre RPO et assurez-vous que la direction en a accepté la portée.

La vérité terne : vous pouvez acheter de la performance en affaiblissant la durabilité, mais vous ne pouvez pas acheter l’intégrité après coup. Les sauvegardes aident, mais elles ne résolvent pas le split-brain, la dérive de réplication, ou l’écart entre « confirmé au client » et « persisté sur disque ».

Réplication et basculement : moins de surprises

La réplication est l’endroit où « ça marche en staging » va mourir. La charge est différente, les requêtes sont plus laides, et quelqu’un exécutera inévitablement un DDL d’urgence au pire moment possible.

Préférences opérationnelles qui réduisent la douleur

  • Utilisez GTID quand c’est approprié. Cela rend les outils de basculement moins fragiles et réduit l’archéologie du « quelle position de binlog ? ».
  • Privilégiez la réplication en mode row-based pour la correction. La réplication statement-based est un objet de musée : intéressante, mais pas l’endroit où placer votre logique métier.
  • Gardez le retard de réplication visible et exploitable. Le lag n’est pas un chiffre ; c’est un symptôme. Mesurez les files d’application, les blocages des workers et les verrous sur les réplicas.

Percona Server a historiquement amélioré l’expérience ici en rendant l’état de la réplication plus diagnostiquable. Même si MySQL upstream a réduit cet écart, l’écosystème Percona suppose souvent que vous regarderez réellement les internals de réplication. Cette hypothèse est saine.

Stockage et réalités des systèmes de fichiers (ce que les SRE apprennent à 3 h du matin)

MySQL est un moteur de stockage déguisé en SQL. Il se soucie profondément du comportement de fsync, de l’amplification d’écriture et de la variance de latence. Il a aussi une longue mémoire : une mauvaise décision de stockage peut vous hanter pendant des mois car la « solution » exige un mouvement de données ou une indisponibilité.

La variance de latence bat le débit (de la pire façon)

La plupart des pannes attribuées à « le disque est lent » sont en réalité « le disque est occasionnellement lent ». La moyenne semble correcte, le p95 est correct, le p99 est un film d’horreur. InnoDB est sensible aux pauses dans le flush du journal et au checkpointing. Quand cette pause survient, les threads s’accumulent, les temps de réponse explosent, et votre on-call regarde des tableaux de bord qui ont l’air normaux — jusqu’au moment où ce n’est plus le cas.

Systèmes de fichiers et options

Que vous utilisiez ext4 ou xfs, NVMe local ou stockage réseau, l’incontournable est que fsync doit se comporter. Si vous utilisez la virtualisation ou du stockage en réseau, validez que les flushs sont réels. Certaines couches reconnaissent les écritures avec enthousiasme alors qu’elles ne sont pas encore persistées. Ce n’est pas « rapide ». C’est « incident futur ».

Deuxième blague : la seule chose plus optimiste qu’une prévision commerciale est un contrôleur de stockage affirmant que son cache est « essentiellement durable ».

Trois mini-histoires de la vie en entreprise

1) Incident causé par une mauvaise hypothèse : « Un commit signifie que c’est sur le disque »

Une entreprise SaaS de taille moyenne utilisait MySQL pour la facturation et les factures. Leur base primaire vivait sur un bloc virtuel avec un backend de stockage géré par un fournisseur. Il performait magnifiquement aux benchmarks. La latence était faible, le débit élevé, tout le monde rentrait chez soi à l’heure.

Pendant un incident de datacenter, la VM a redémarré. MySQL est revenu proprement, mais l’application a commencé à signaler des « factures manquantes » sur une fenêtre temporelle étroite. Rien d’énorme au début. Puis les tickets de support se sont accumulés, et la finance a remarqué des divergences entre les callbacks des prestataires de paiement et le grand livre interne.

L’équipe avait configuré innodb_flush_log_at_trx_commit=2 pour réduire la pression des fsync et laissé sync_binlog=0 parce que « fsync du binlog coûte cher ». Ils avaient aussi supposé que la couche de stockage avait un cache sur batterie et persisterait les écritures en toute sécurité. La plateforme du fournisseur avait bien du caching, mais ses garanties de durabilité pendant un basculement n’étaient pas celles supposées par l’équipe. Certaines écritures reconnues n’ont jamais été persistées.

La correction a été ennuyeuse et douloureuse : remettre les réglages de durabilité à des valeurs sûres, valider les sémantiques de flush du stockage, et accepter le coût de performance. Ils ont aussi ajouté une section au runbook intitulée « Quel est notre RPO réel ? » parce que personne ne pouvait y répondre sérieusement avant l’incident.

2) Optimisation qui s’est retournée contre eux : « Un buffer pool plus grand règle tout »

Une plateforme analytique interne avait une instance MySQL gérant un mélange d’écritures OLTP et de lectures lourdes. La rotation on-call en avait assez des ralentissements occasionnels durant les rapports mensuels. Quelqu’un a proposé le classique : augmenter innodb_buffer_pool_size jusqu’à ce que le dataset « tienne en mémoire ».

Ils ont gonflé le buffer pool à une grosse fraction de la RAM, ne laissant qu’une faible marge pour le cache du noyau, les threads d’arrière-plan, les pics de connexion et l’agent de monitoring. L’instance est devenue plus rapide — jusqu’au premier jour chargé après le changement.

Sous une forte concurrence, le noyau a commencé à swaper un peu. Pas beaucoup, juste assez. La latence MySQL est devenue non linéaire. Les threads se sont bloqués, le retard de réplication a augmenté, et le replica de secours a aussi souffert car il partageait le même modèle de tuning. L’équipe avait « optimisé » la mémoire et s’était involontairement fabriqué une panne liée au swap.

La reprise a été simple : réduire le buffer pool, limiter les connexions, s’assurer que le swap est soit désactivé soit étroitement surveillé, et définir des marges mémoire explicites. La leçon a duré : un changement de tuning qui améliore la latence moyenne peut détruire la latence extrême et la disponibilité.

3) Une pratique ennuyeuse mais correcte qui a sauvé la mise : exercices réguliers de restauration

Une entreprise de retail gérait une flotte MySQL multi-tenant. Ils n’étaient pas sophistiqués. Ce qu’ils faisaient, en revanche, c’était une invitation calendrier : une fois par sprint, quelqu’un restaurait une sauvegarde de production dans un environnement isolé et exécutait une vérification de cohérence plus quelques validations côté application.

Un mardi, un développeur a déployé une migration qui a accidentellement supprimé un index puis lancé un job de backfill qui mettait à jour les lignes dans un ordre pathologique. Le primaire a survécu, mais le retard de réplication a explosé. Un replica est resté en retard de plusieurs heures, et la procédure classique « promouvoir un replica » a cessé d’être rassurante.

Ils ont choisi de restaurer depuis la dernière sauvegarde vers une nouvelle instance puis d’appliquer les binlogs jusqu’à un point sûr. Ça a fonctionné en grande partie parce qu’ils l’avaient pratiqué. Ils savaient aussi combien de temps prenaient les restaurations sur leur matériel, quels étaient les points d’échec courants, et quelles vérifications de cohérence détectaient vraiment des problèmes.

La fenêtre d’indisponibilité a été douloureuse, mais bornée. L’équipe n’a pas inventé un processus de récupération sous stress. Elle en a exécuté un qu’elle avait répété, ce qui est la chose la plus proche de la magie opérationnelle.

Tâches pratiques : commandes, sorties et décisions

Voici des tâches réelles que vous pouvez exécuter aujourd’hui. Chacune inclut : une commande, une sortie exemple, ce que cela signifie, et la décision que vous en tirez. Elles sont indépendantes de la distribution sauf indication contraire. L’objectif n’est pas de mémoriser des commandes ; c’est d’acquérir l’habitude de mesurer avant de tuner.

Task 1: Confirm what you’re actually running (version and distro)

cr0x@server:~$ mysql --version
mysql  Ver 8.0.36-28 for Linux on x86_64 (Percona Server (GPL), Release 28, Revision 1234567)

Ce que ça signifie : Vous ne pouvez pas comparer le comportement entre serveurs si vous ne connaissez pas le build exact. Les versions mineures changent les valeurs par défaut et les internals.

Décision : Verrouillez délibérément les versions. Si vous déboguez, reproduisez sur la même version mineure avant d’imputer le problème à la charge.

Task 2: Inspect effective runtime variables (not what you think is in my.cnf)

cr0x@server:~$ mysql -e "SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'; SHOW VARIABLES LIKE 'sync_binlog';"
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 1     |
+---------------+-------+

Ce que ça signifie : Vous utilisez des réglages de durabilité stricts.

Décision : Conservez-les sauf si vous avez une exception RPO signée et que vous avez testé le comportement de crash sur votre stockage.

Task 3: Check whether Performance Schema is enabled

cr0x@server:~$ mysql -e "SHOW VARIABLES LIKE 'performance_schema';"
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| performance_schema | ON    |
+--------------------+-------+

Ce que ça signifie : Vous avez accès aux tables d’observabilité modernes pour les événements d’attente, les statements et les stages.

Décision : S’il est OFF, arrêtez de naviguer à l’aveugle. Activez-le lors de la prochaine fenêtre de maintenance sauf si vous avez une raison mesurée de ne pas le faire.

Task 4: Identify top statements by total latency (where time really went)

cr0x@server:~$ mysql -e "SELECT DIGEST_TEXT, COUNT_STAR, ROUND(SUM_TIMER_WAIT/1000000000000,2) AS total_s FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 3\G"
*************************** 1. row ***************************
DIGEST_TEXT: SELECT * FROM orders WHERE user_id = ? ORDER BY created_at DESC LIMIT ?
COUNT_STAR: 982134
total_s: 18643.51
*************************** 2. row ***************************
DIGEST_TEXT: UPDATE inventory SET qty = qty - ? WHERE sku = ?
COUNT_STAR: 371223
total_s: 9221.09
*************************** 3. row ***************************
DIGEST_TEXT: SELECT COUNT(*) FROM events WHERE tenant_id = ? AND created_at > ?
COUNT_STAR: 8122
total_s: 3112.44

Ce que ça signifie : Les deux premières requêtes dominent le temps total. La troisième est coûteuse par appel (faible compte, total élevé).

Décision : Travailler l’indexation et la forme des requêtes vaut mieux que tweaker le serveur. Corrigez la troisième requête d’abord si elle provoque la latence en queue.

Task 5: See current InnoDB health and the “real story” behind stalls

cr0x@server:~$ mysql -e "SHOW ENGINE INNODB STATUS\G"
...
Buffer pool size   262144
Free buffers       1024
Database pages     258000
Modified db pages  42000
...
Log sequence number  987654321098
Log flushed up to    987654320900
Last checkpoint at   987654300000
...
History list length  183421
...

Ce que ça signifie : Les pages dirty sont élevées, le checkpoint est en retard, et la history list est importante. Le purge peut être en retard (souvent dû à des transactions longues).

Décision : Cherchez des transactions longues et corrigez-les. Si c’est chronique, revoyez la taille du redo log et les schémas d’écriture.

Task 6: Find long transactions holding back purge

cr0x@server:~$ mysql -e "SELECT trx_id, trx_started, trx_state, trx_rows_locked, trx_rows_modified, trx_query FROM information_schema.innodb_trx ORDER BY trx_started ASC LIMIT 3\G"
*************************** 1. row ***************************
trx_id: 123456789
trx_started: 2025-12-30 02:11:09
trx_state: RUNNING
trx_rows_locked: 0
trx_rows_modified: 148220
trx_query: UPDATE events SET processed=1 WHERE tenant_id=42 AND processed=0
...

Ce que ça signifie : Une mise à jour longue modifie beaucoup de lignes et gonfle probablement l’undo/history.

Décision : Découpez les jobs par lots en commits plus petits ; ajoutez du throttling ; pensez à l’indexation pour éviter des scans larges qui maintiennent des verrous trop longtemps.

Task 7: Catch metadata locks (the silent outage)

cr0x@server:~$ mysql -e "SELECT * FROM performance_schema.metadata_locks WHERE LOCK_STATUS='PENDING' LIMIT 5\G"
*************************** 1. row ***************************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: app
OBJECT_NAME: users
LOCK_TYPE: EXCLUSIVE
LOCK_STATUS: PENDING
OWNER_THREAD_ID: 812
OWNER_EVENT_ID: 45678

Ce que ça signifie : Quelque chose veut un verrou de table exclusif et est bloqué. Cela peut geler le trafic de façon étrange.

Décision : Identifiez la session bloquante (join aux threads) et décidez de la tuer ou d’attendre. Planifiez les DDL correctement.

Task 8: Check replication lag and whether it’s IO or SQL/apply bound

cr0x@server:~$ mysql -e "SHOW REPLICA STATUS\G"
...
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Seconds_Behind_Source: 187
Relay_Log_Space: 2147483648
...
Last_SQL_Error: 
...

Ce que ça signifie : La réplication tourne, mais l’application est en retard. L’espace du relay log est important, ce qui suggère un backlog.

Décision : Cherchez des verrous sur le replica, des requêtes lentes dans l’application, ou une configuration de réplication parallèle insuffisante. Ne basculez pas sur un replica en retard.

Task 9: Identify connection storms and thread saturation

cr0x@server:~$ mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_%';"
+-------------------+--------+
| Variable_name     | Value  |
+-------------------+--------+
| Threads_cached    | 12     |
| Threads_connected | 1450   |
| Threads_created   | 983221 |
| Threads_running   | 198    |
+-------------------+--------+

Ce que ça signifie : Beaucoup de connexions, création de threads élevée au fil du temps. Le thread cache peut être trop petit ou l’application churne des connexions.

Décision : Corrigez le pooling en priorité. Ensuite ajustez thread_cache_size et imposez un max_connections sensé avec du backpressure.

Task 10: Check if you’re hitting file descriptor limits (classic under load)

cr0x@server:~$ sudo systemctl show mysql -p LimitNOFILE
LimitNOFILE=65535

Ce que ça signifie : mysqld a une limite de descripteurs. Sous forte charge et beaucoup de tables, des limites basses causent « Too many open files ».

Décision : Augmentez les limites si nécessaire, mais réduisez aussi le churn d’ouverture de tables et évitez des comptes de connexions absurdes.

Task 11: Check disk latency at the OS level (not “util%”)

cr0x@server:~$ iostat -x 1 3
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.41    0.00    4.10    6.33    0.00   77.16

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
nvme0n1         312.0  1240.0  9012.0 38200.0  18.45   0.62  96.12

Ce que ça signifie : await est élevé (18ms) pendant que l’utilisation est proche du maximum. Cela peut expliquer des pauses fsync et la latence des commits.

Décision : Si c’est persistant, vous avez besoin d’un stockage plus rapide, moins d’amplification d’écriture (revue de schéma/index), ou d’une réduction de la concurrence. Le tuning ne sauvera pas un périphérique saturé.

Task 12: Validate that MySQL is actually flushing (and how often)

cr0x@server:~$ mysql -e "SHOW GLOBAL STATUS LIKE 'Innodb_os_log_fsyncs'; SHOW GLOBAL STATUS LIKE 'Innodb_os_log_written';"
+---------------------+----------+
| Variable_name       | Value    |
+---------------------+----------+
| Innodb_os_log_fsyncs| 18273421 |
+---------------------+----------+
+-----------------------+-------------+
| Variable_name         | Value       |
+-----------------------+-------------+
| Innodb_os_log_written | 91234567890 |
+-----------------------+-------------+

Ce que ça signifie : Des fsync fréquents ont lieu ; c’est normal pour la durabilité. La question est de savoir s’ils sont lents.

Décision : Corrélez avec les pics de latence et la latence disque au niveau OS. Si le nombre de fsync est bas mais que l’appli est « rapide », vous pourriez être accidentellement non durable.

Task 13: Look for table cache pressure (hidden CPU overhead)

cr0x@server:~$ mysql -e "SHOW GLOBAL STATUS LIKE 'Open_tables'; SHOW GLOBAL STATUS LIKE 'Opened_tables'; SHOW VARIABLES LIKE 'table_open_cache';"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 4000  |
+---------------+-------+
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| Opened_tables | 12833422 |
+---------------+----------+
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| table_open_cache | 4096  |
+------------------+-------+

Ce que ça signifie : Opened_tables est énorme ; vous ouvrez constamment des tables, ce qui ajoute une surcharge.

Décision : Augmentez table_open_cache si la mémoire le permet, et corrigez les charges qui génèrent un churn excessif de tables (par ex. trop de partitions ou de tables temporaires).

Task 14: Capture a one-shot “what’s running right now” snapshot

cr0x@server:~$ mysql -e "SHOW FULL PROCESSLIST;"
Id	User	Host	db	Command	Time	State	Info
812	app	10.0.2.41:51122	app	Query	12	Sending data	SELECT * FROM orders WHERE user_id=...
901	app	10.0.2.17:42311	app	Query	45	Waiting for table metadata lock	ALTER TABLE users ADD COLUMN ...
1002	repl	10.0.3.9:60012	NULL	Binlog Dump	81234	Master has sent all binlog to slave; waiting for more updates	NULL

Ce que ça signifie : Un DDL bloque des requêtes via un verrou de métadonnées, et au moins une requête passe du temps à « Sending data » (souvent un scan / un gros résultat ou un client lent).

Décision : Arrêtez les DDL ad hoc en heures de production. Utilisez des approches de changement de schéma en ligne et vérifiez le comportement des verrous. Corrigez la requête/index pour le scan.

Guide de diagnostic rapide

Voici l’ordre d’opérations « arriver au goulet en quelques minutes ». N’improvisez pas. Quand vous improvisez, vous poursuivez la métrique la plus bruyante, pas la bonne.

Première étape : saturation, attente, ou un seul bloqueur ?

  • Vérifiez la concurrence : Threads_running, Threads_connected, churn de connexions.
  • Regardez le processlist pour des bloqueurs évidents : attentes de verrou de métadonnées, requêtes longues, états « Locked ».
  • Vérifiez l’état de réplication (si les lectures proviennent de réplicas) : le lag peut ressembler à « la base est lente » alors qu’en réalité « le replica est en retard ».

Deuxième étape : variance de latence IO ou contention CPU ?

  • Niveau OS : iostat -x pour await et %util ; vmstat 1 pour la file d’exécution et le swap.
  • Niveau MySQL : InnoDB status pour le checkpointing, les pages dirty, la longueur de la history list ; événements d’attente du Performance Schema.

Troisième étape : pathologie de verrous/transactions ?

  • Transactions longues : requête information_schema.innodb_trx.
  • Attentes de verrous sur lignes : InnoDB status et Performance Schema waits.
  • Verrous de métadonnées : entrées pending dans performance_schema.metadata_locks.

Quatrième étape : régression de requête ?

  • Top statements par digest de latence.
  • Plans EXPLAIN pour les pires coupables.
  • Vérifiez les index manquants ou les changements de paramètres qui provoquent des plans différents.

Discipline opérationnelle : Capturez toujours un snapshot (processlist, état de réplication, InnoDB status, iostat) avant de « corriger » quoi que ce soit. Sinon vous détruisez vos preuves.

Erreurs courantes : symptômes → cause racine → correction

1) Symptom: sudden global latency spikes, CPU low

Cause racine : pauses fsync (flush du redo) dues à la variance de latence du stockage ou à un périphérique saturé.

Correction : Validez avec iostat -x l’await et la pression de checkpoint/redo d’InnoDB. Réduisez l’amplification d’écriture, améliorez le stockage, et évitez de laisser la « durabilité off » comme solution permanente.

2) Symptom: queries hang during a deploy, then recover suddenly

Cause racine : contention de verrous de métadonnées due à un DDL (ALTER TABLE) qui attend derrière une transaction longue.

Correction : Identifiez les verrous en attente dans performance_schema.metadata_locks ; tuez la session bloquante si c’est sûr ; planifiez les DDL avec des méthodes en ligne et des timeouts.

3) Symptom: replication lag grows after adding an index

Cause racine : DDL ou job de backfill génère un gros volume d’écritures ; l’appli du replica devient IO-bound ou bloquée par des verrous.

Correction : Throttlez les migrations, utilisez un changement de schéma en ligne, ajustez la réplication parallèle seulement après mesure. Ne promouvez pas un replica en retard.

4) Symptom: “Too many connections” and flapping availability

Cause racine : tempête de connexions applicatives, absence de pooling, ou incident amont provoquant des retries.

Correction : Imposer du backpressure (réduire max_connections en dessous de « infini »), corriger le pooling, et définir des timeouts sensés. Des limites de connexion élevées cachent des bugs applicatifs jusqu’à la panne de la base.

5) Symptom: steady slowdown over days, then periodic freezes

Cause racine : transactions longues empêchant le purge ; la history list augmente ; pression sur l’undo tablespace.

Correction : Découpez les lots, évitez les sessions interactives qui gardent des transactions ouvertes, surveillez les trx longs, et corrigez le pattern applicatif.

6) Symptom: replica is “running” but reads are stale

Cause racine : retard du replica masqué par le routage ou le monitoring qui vérifie seulement « SQL thread running ».

Correction : Alarmez sur Seconds_Behind_Source plus les métriques de file d’application. Routez les lectures avec prise en compte du lag.

7) Symptom: after crash, data is inconsistent across primary and replicas

Cause racine : réglages non durables (flush/binlog) combinés à un crash ; ou format/requêtes de réplication non sûrs.

Correction : Utilisez des réglages de durabilité sûrs sauf dérogation explicite, privilégiez la réplication row-based, et validez la récupération après crash avec des tests de chaos.

Listes de contrôle / plan pas à pas

If you’re evaluating Percona Server for “safer defaults”

  1. Inventoriez les versions et les fonctionnalités dont vous dépendez. Notez les plugins d’authentification, l’usage des GTID, le chiffrement, les outils de sauvegarde et le monitoring.
  2. Déployez une instance canary avec un stockage proche de la production et rejouez le trafic si possible.
  3. Activez Performance Schema et collectez des bases (résumés de digest, événements d’attente, métriques InnoDB).
  4. Effectuez des tests de crash qui imitent votre pire journée : kill -9 mysqld, reboot VM, détacher le stockage (en labo), et vérifiez le comportement de récupération et le RPO.
  5. Validez les sauvegardes et restaurations avec la taille réelle des données et l’objectif RTO.
  6. Plan de montée/retour : prouvez que vous pouvez monter et redescendre dans votre fenêtre de maintenance. Si vous ne le pouvez pas, vous n’êtes pas prêt.

If you’re staying on upstream MySQL but want “Percona-like safety”

  1. Cessez d’utiliser des guides de tuning obsolètes. Revérifiez les valeurs par défaut pour votre version exacte.
  2. Rendez la durabilité explicite. Fixez innodb_flush_log_at_trx_commit et sync_binlog intentionnellement ; documentez le RPO.
  3. Activez l’observabilité. Performance Schema ON, slow log configuré, analyse de digest automatisée.
  4. Construisez un runbook de diagnostic rapide (le playbook ci‑dessus) et entraînez-vous.
  5. Entraînez les restaurations. Si vous ne savez pas restaurer, vous n’avez pas de sauvegardes ; vous avez des fichiers coûteux.
  6. Protégez la base de données de l’application. Limites de connexions, timeouts, retries sensés et limitation de débit durant les incidents.

Minimal “safer defaults” config posture (conceptual)

Ce n’est pas une configuration complète, car votre matériel et votre charge importent. C’est une posture : priorisez la durabilité, la visibilité et la concurrence contrôlée avant de courir après des micro-optimisations.

  • Durabilité : réglages de flush sûrs sauf dérogation explicite.
  • Observabilité : Performance Schema ON, slow log ON avec des seuils sensés.
  • Concurrence : imposer max connections ; utiliser du pooling ; surveiller threads_running.
  • Réplication : GTID quand approprié ; réplication row-based ; alertes de lag.
  • Sauvegardes : automatisées, vérifiées et restaurables dans le RTO.

FAQ

Is Percona Server a drop-in replacement for MySQL?

Généralement proche, mais la promesse « drop-in » est à vérifier. Testez les plugins d’authentification, la réplication, les outils de sauvegarde et tout mode SQL particulier dont vous dépendez.

Will Percona Server automatically be faster?

Pas automatiquement. Vous pouvez gagner grâce à l’instrumentation et à certaines améliorations du moteur, mais la majeure partie de la performance dépend du schéma, des requêtes et de l’IO. Attendez‑vous à « plus facile à diagnostiquer », pas à « vitesse gratuite ».

What does “safer defaults” mean in real outage terms?

Cela signifie que vous avez moins de risque de perdre des données confirmées après un crash, moins de risque de vous retrouver bloqué par des verrous invisibles, et plus de chances de voir rapidement le goulot réel.

Does enabling Performance Schema hurt performance?

Il y a un overhead, mais les déploiements modernes MySQL 8 le gardent souvent activé. Mesurez sur votre workload ; désactiver pour sauver un petit pourcentage et perdre le diagnostic est généralement un mauvais échange.

Should I set innodb_flush_log_at_trx_commit=2 for performance?

Seulement si vous avez explicitement accepté la perte de données en cas de crash et validé ce que cela signifie sur votre stockage. Beaucoup d’équipes le mettent « temporairement » et le gardent pendant des années jusqu’à ce que la réalité réclame son dû.

Is replication lag always a database problem?

Non. C’est souvent un problème de workload (une migration lourde), ou d’infrastructure (pauses IO), ou de schéma/indexation qui rend l’application coûteuse.

How do I know if my bottleneck is locks vs IO?

Les verrous apparaissent comme des attentes dans le processlist et le Performance Schema, plus des transactions longues. L’IO apparaît par une élévation de l’await disque/pauses fsync et la pression des checkpoints InnoDB.

What’s the single best “boring” practice to reduce outages?

Les exercices réguliers de restauration. Si vous savez restaurer rapidement et de façon fiable, vous pouvez survivre à un mauvais déploiement, un incident de stockage ou une erreur humaine inévitable.

Do I need Percona tools if I run Percona Server?

Non, mais l’écosystème est cohérent. Même sur MySQL upstream, les outils Percona (monitoring/sauvegarde) peuvent améliorer la maturité opérationnelle si vous les adoptez avec soin.

Conclusion : prochaines étapes à exécuter

Si vous voulez moins d’incidents, arrêtez de traiter MySQL comme une boîte noire et cessez de faire du tuning un trait de personnalité. Que vous choisissiez MySQL upstream ou Percona Server, la stratégie gagnante est la même : durabilité plus sûre, concurrence contrôlée et observabilité impitoyable.

  1. Mesurez l’existant : capturez les variables, l’InnoDB status, les top digests, l’état de la réplication et la latence IO OS.
  2. Corrigez les gros problèmes en premier : régressions de requêtes, index manquants, tempêtes de connexions et transactions longues.
  3. Rendez la durabilité intentionnelle : fixez les valeurs de flush/binlog selon un RPO documenté, pas selon le folklore.
  4. Choisissez une distribution selon les résultats opérationnels : si Percona Server vous apporte un diagnostic plus rapide et moins de pièges dans votre environnement, adoptez-le via un déploiement canary.
  5. Répétez les scénarios de défaillance : exercices de restauration et tests de crash battent l’optimisme à chaque fois.

La meilleure base de données est celle qui échoue de façons que vous comprenez vite — et dont vous pouvez récupérer avant que vos clients ne s’en aperçoivent.

← Précédent
Ray tracing en 2026 : pourquoi c’est encore difficile — et inévitable
Suivant →
Ubuntu 24.04 : blocages de disque sous charge — paramètres de timeout qui évitent les arrêts complets (Cas n°30)

Laisser un commentaire