MariaDB vs TiDB : promesses de migration vs réalité en production

Cet article vous a aidé ?

Vous ne migrez pas des bases de données parce que vous vous ennuyez. Vous migrez parce que vous heurtez un mur : montée en charge des écritures, latence inter-régions, surcharge opérationnelle, explosion du nombre de shards, ou une échéance de conformité qui se fiche de votre week-end.

MariaDB et TiDB apparaissent tous deux dans la discussion « on veut un comportement à la MySQL mais en mieux ». Le discours marketing est séduisant : garder SQL, gagner en scalabilité, réduire la douleur. La réalité en production est plus brute : modes de panne différents, réglages différents, et manières variées de ruiner votre rotation on-call. Parlons-en.

Ce que vous choisissez réellement (pas seulement une base de données)

« MariaDB vs TiDB » sonne comme une comparaison de produits. En production, c’est en fait un choix entre deux modèles opérationnels :

  • MariaDB est un moteur InnoDB mono-nœud familier avec des schémas de réplication matures (réplication asynchrone, semi-sync, GTID, et dans certaines déployations Galera). Vous pouvez l’exploiter de manière ennuyeuse et efficace. Vous pouvez aussi l’exploiter « de façon créative » et apprendre de nouveaux synonymes pour douleur.
  • TiDB est du SQL distribué : nœuds de calcul (TiDB), nœuds de stockage (TiKV), et un plan de contrôle (PD). Vous achetez de la scalabilité horizontale et de la HA par conception—plus la taxe de complexité d’un système distribué. Chaque question « simple » devient « quel niveau et quel composant ment ? »

Voici la décision que je préconise dans les organisations réelles :

  • Si votre goulot est un primaire ou quelques primaires chauds, mais que votre charge reste majoritairement OLTP mono-région, et que vous pouvez monter en vertical et via des replicas de lecture, MariaDB reste difficile à battre pour la simplicité opérationnelle.
  • Si vous vivez déjà en enfer de shards, ou si vous devez répartir les écritures sur plusieurs nœuds avec cohérence forte et une latence acceptable, TiDB peut être le choix adulte—à condition d’investir dans l’observabilité et la maturité SRE.

Une idée paraphrasée de Werner Vogels (CTO d’Amazon) qui tient toujours : tout échoue, tout le temps ; le travail consiste à concevoir pour que le système continue de fonctionner malgré tout (idée paraphrasée).

Cette maxime se traduit bien : MariaDB concerne l’ingénierie de frontières de panne soignées autour d’une vérité majoritairement mono-nœud. TiDB concerne l’ingénierie autour de pannes partielles constantes sur de nombreux nœuds.

Faits historiques rapides qui comptent vraiment

Quelques points de contexte qui changent la manière dont vous exploitez ces systèmes. Court. Concret. Utile.

  1. MariaDB a été forké depuis MySQL en 2009 après qu’Oracle a acquis Sun ; cette origine explique pourquoi la compatibilité est une priorité et pourquoi « essentiellement comme MySQL » fait partie de l’ADN de la marque.
  2. InnoDB est devenu le moteur par défaut de MySQL bien avant que beaucoup d’équipes n’arrêtent de penser en termes de MyISAM. Si votre application legacy suppose encore un verrouillage au niveau table, vous êtes déjà en mode difficile.
  3. Galera « multi‑master » est en réalité une réplication synchrone avec certification. Ce n’est pas magique. Elle échange la concurrence d’écriture contre un ordre global et peut punir les lignes chaudes.
  4. L’architecture de TiDB s’inspire du modèle Google Spanner/F1 (sans TrueTime). L’important est la séparation entre SQL sans état et KV stateful.
  5. TiKV utilise la réplication Raft. Cela implique des écritures en quorum, des enjeux de placement de leader, et des histoires du type « un disque lent peut ralentir une région ».
  6. PD (Placement Driver) est une dépendance réelle du plan de contrôle. Si vous le traitez comme « juste un autre service », vous le rencontrerez à 3 h du matin.
  7. La compatibilité MySQL est une cible mouvante pour TiDB. Une requête qui fonctionne n’est pas synonyme d’un comportement de production identique. La surface SQL n’est pas l’équivalence opérationnelle.
  8. Les changements de schéma en ligne dans l’écosystème MySQL ont évolué comme mécanisme d’adaptation. Outils et patterns existent parce que « ALTER TABLE » fait souffrir les gens depuis toujours.

Architecture en termes opérationnels : où vivent les dragons

MariaDB : un moteur, plusieurs façons de le répliquer

Le dépannage de performance MariaDB ressemble encore à la maison pour la plupart des SRE : CPU, innodb_buffer_pool, latence IO, contention de mutex, requêtes mauvaises, index manquants, et lag de réplication. Quand c’est en feu, c’est généralement concentré en un seul endroit.

Même en configurations clusterisées (Galera), votre unité de douleur reste « le nœud de base de données ». Vous pouvez le mesurer, l’isoler, le remplacer. Les points difficiles sont :

  • Sémantiques de réplication : asynchrone implique du lag et une possible perte au failover ; semi-sync réduit la perte mais augmente la latence ; Galera implique gestion des conflits et flow control.
  • Changements de schéma : le DDL en ligne existe, mais tout n’est pas en ligne, et les grandes tables rencontreront les bords tranchants.
  • Montée en charge des écritures : vous scalez les écritures en montant verticalement, réduisant l’amplification d’écriture, ou en changeant l’application. « Ajouter des nœuds » est principalement une histoire de lectures.

TiDB : nœuds SQL sans état + stockage Raft + plan de contrôle

TiDB répartit votre base de données en couches :

  • TiDB (couche SQL) : parse le SQL, planifie les requêtes, pousse le travail vers le bas, et gère les transactions distribuées.
  • TiKV (stockage) : stocke les données key/value en régions, chacune répliquée par Raft. Les leaders comptent. Le réseau compte. Le disque compte. La compaction compte.
  • PD : schedule les régions, équilibre les leaders, fournit les timestamps et les décisions de placement.

Cette séparation explique pourquoi TiDB peut monter en lecture et en écriture. Elle explique aussi pourquoi vous pouvez avoir un « incident base de données » où le CPU est correct, les requêtes semblent correctes, et le vrai coupable est un seul nœud TiKV avec un IO misérable, entraînant des élections de leader et des retries de transactions.

Vérité sèche : une base distribuée est une base de données plus un cursus de systèmes distribués que vous serez forcé de suivre pendant les incidents. L’examen est toujours minuté.

Blague #1 : Les bases distribuées sont formidables car elles transforment un disque lent en exercice de team-building entre trois services.

Promesses de migration vs ce qui casse en premier

Promesse : « C’est compatible MySQL, l’app fonctionne donc »

La compatibilité vous fait passer le parsing. Elle ne couvre pas le comportement en production :

  • Les plans de requête divergent. Une requête « correcte » sur MariaDB avec un optimiseur mono-nœud peut devenir une fête de scans distribués dans TiDB.
  • Les patterns de transaction comptent plus. Les transactions longues, les grosses mises à jour par lot, et les clés chaudes exposent la contention dans Raft et le comportement MVCC.
  • Le comportement DDL diffère. TiDB supporte des patterns de DDL en ligne, mais opérationnellement il faut toujours planifier la charge de backfill et le scheduling de PD.

Promesse : « TiDB supprime la complexité du sharding »

Oui, mais vous la troquez contre une complexité différente :

  • Hotspotting est le nouveau shard. Au lieu de « user_id modulo N », vous obtenez « ce leader de région fond ».
  • La planification de capacité est en couches. Les nœuds compute scale différemment des nœuds storage. Votre facture et votre goulot peuvent ne pas s’accorder.
  • Les dépendances opérationnelles s’élargissent. Vous exploitez désormais un plan de contrôle, une couche de stockage et des nœuds SQL sans état.

Promesse : « Le cluster MariaDB apporte HA et montée en charge »

HA ? Absolument, quand c’est fait correctement. Scalabilité d’écriture ? Avec prudence. Dans Galera, chaque nœud doit certifier les écritures ; les charges d’écriture lourdes peuvent souffrir de conflits et de flow control. La réplication asynchrone peut facilement scaler les lectures mais les écritures convergent toujours vers un primaire.

Promesse : « On peut migrer avec un temps d’arrêt minimal »

Vous le pouvez, mais le travail critique n’est pas la copie des données. C’est le travail de compatibilité comportementale :

  • modes SQL et conversions implicites de types
  • hypothèses sur le niveau d’isolation
  • usage de fonctions non déterministes
  • procédures stockées, triggers, et patterns DDL en bord de cas
  • runbooks opérationnels : sauvegardes, restaurations, basculements, DR

Réalités de production : performance, exactitude et sommeil

Réalité performance n°1 : la latence a de nouveaux planchers

MariaDB peut être très rapide pour l’OLTP à ligne unique quand les données sont dans le buffer pool et que vous n’êtes pas limité par l’IO. TiDB ajoute des sauts réseau et des commits en quorum. Cela ne signifie pas que TiDB est « lent » ; cela signifie que le p99 a une physique différente.

Si votre produit exige un p99 d’écritures inférieur à 5 ms dans une seule AZ, TiDB peut encore fonctionner, mais vous transpirerez sur le placement, la localité des leaders, et la conception des transactions. Si vous êtes déjà à 20–50 ms p99 parce que votre appli est bavarde, la surcharge de TiDB peut être masquée par de mauvaises décisions existantes.

Réalité performance n°2 : les hotspots sont inévitables

Dans MariaDB, les hotspots sont surtout du locking et de la contention d’index. Dans TiDB, les hotspots se manifestent souvent par :

  • Une région qui reçoit la majorité des écritures à cause de clés séquentielles
  • Un leader concentré sur un seul TiKV
  • Des patterns d’accès biaisés qui font PD courir après l’équilibrage en boucle

Réalité exactitude : les sémantiques « multi‑master » sont différentes

La réplication synchrone de Galera implique qu’une transaction doit être certifiée cluster-wide ; les conflits surviennent au commit, et la logique de retry importe. TiDB fournit la cohérence forte via la réplication Raft et MVCC, mais les transactions distribuées amplifient le coût de la contention et des transactions de longue durée.

Réalité opérationnelle : sauvegardes et restaurations, là où la confiance meurt

Toute base peut faire des sauvegardes. La question est : pouvez‑vous restaurer rapidement, correctement, et sous pression ? Les dumps logiques MariaDB sont portables mais peuvent être lents ; les backups physiques sont rapides mais demandent de la discipline. Les sauvegardes TiDB impliquent un large état distribué ; les restaurations doivent prendre en compte le placement, la charge et la compatibilité de version.

Blague #2 : Une sauvegarde est le fichier de Schrödinger : à la fois valide et inutile jusqu’à ce que vous fassiez une restauration.

Playbook de diagnostic rapide

Ceci est la séquence « arrêtez de débattre d’architecture et trouvez le goulot » que j’utilise. Faites‑la dans l’ordre. Ne jouez pas les créatifs tant que vous n’avez pas de preuves.

Première étape : est‑ce l’app, le réseau ou la base ?

  1. Vérifiez la répartition de latence de bout en bout. Si vous ne l’avez pas, récupérez‑la via le tracing applicatif ou au minimum comparez le temps DB vs le temps total de requête.
  2. Confirmez la saturation. CPU saturé ? IO wait ? retransmissions réseau ? Si rien n’est saturé, vous poursuivez la piste contention ou régression de plan.
  3. Confirmez le pattern de concurrence. Pics de connexions, pools de threads, profondeurs de files d’attente.

Deuxième étape : décidez si le goulot est « couche SQL » ou « couche stockage »

  • MariaDB : vérifiez les métriques InnoDB, le slow log, le buffer pool, le lag de réplication.
  • TiDB : vérifiez le CPU de TiDB et la durée des requêtes, puis le IO/CPU de TiKV et les métriques raftstore, ensuite le scheduling PD et l’équilibre des leaders.

Troisième étape : classez le mode de défaillance

  • Régression de plan : changement soudain de latence après un déploiement/changement de schéma.
  • Contention : waits de lock, deadlocks, stalls d’écriture Raft, régions chaudes.
  • Capacité : latence disque, dette de compaction, misses du buffer pool, stalls rocksdb de TiKV.
  • Plan de contrôle : PD indisponible, scheduling bloqué, problèmes de métadonnées.
  • Réplication/basculement : lag, élections, prévention de split brain qui s’active.

Quatrième étape : choisissez le levier « réduire la charge » le plus rapide pendant le diagnostic

  • Limiter le débit des endpoints les plus chauds.
  • Désactiver les jobs de fond coûteux.
  • Augmenter temporairement les timeouts des pools de connexion pour éviter les herds.
  • Dans TiDB, envisager de déplacer les leaders depuis un TiKV malade et réduire la pression sur les hotspots.

Tâches pratiques (commandes, sorties, décisions)

Ci‑dessous des tâches réelles que vous pouvez exécuter lors de la planification de migration, du debug de performance, et de la réponse aux incidents. Chaque tâche inclut : commande, sortie d’exemple, ce que cela signifie, et la décision à prendre.

Task 1: Confirm MariaDB version, server variables, and engine basics

cr0x@server:~$ mysql -h mariadb01 -uroot -p -e "SELECT VERSION(); SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW VARIABLES LIKE 'log_bin';"
Enter password:
VERSION()
10.11.6-MariaDB-1:10.11.6+maria~ubu2204
Variable_name	Value
innodb_buffer_pool_size	17179869184
Variable_name	Value
log_bin	ON

Signification : Vous êtes sur MariaDB 10.11, le buffer pool est de 16GiB, binlog activé.

Décision : Si vous dépendez de CDC ou de replicas asynchrones, conservez le binlog. Si vous êtes IO-bound et que vous n’avez pas besoin du binlog, c’est une conversation plus large—n’« optimisez » pas votre chemin de récupération.

Task 2: Spot top wait events and lock pain in MariaDB

cr0x@server:~$ mysql -h mariadb01 -uroot -p -e "SHOW ENGINE INNODB STATUS\G" | sed -n '1,120p'
Enter password:
*************************** 1. row ***************************
  Type: InnoDB
  Name:
Status:
=====================================
2025-12-30 10:41:23 0x7f5a2c1ff700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 28 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 714 srv_active, 0 srv_shutdown, 1082 srv_idle
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 24417
--Thread 140025024026368 has waited at row0lock.cc line 1134 for 12.00 seconds the semaphore:

Signification : Des threads attendent sur des verrous de ligne ; vous avez probablement de la contention ou une transaction qui garde des verrous trop longtemps.

Décision : Trouvez la transaction bloquante (tâche suivante) et décidez : la tuer, réduire la taille des batches, ajouter un index, ou réécrire le pattern de mise à jour.

Task 3: Identify long-running transactions in MariaDB

cr0x@server:~$ mysql -h mariadb01 -uroot -p -e "SELECT trx_id, trx_started, trx_mysql_thread_id, trx_query FROM information_schema.innodb_trx ORDER BY trx_started LIMIT 5\G"
Enter password:
*************************** 1. row ***************************
trx_id: 9A3F2B11
trx_started: 2025-12-30 10:12:01
trx_mysql_thread_id: 18841
trx_query: UPDATE orders SET status='CLOSED' WHERE customer_id=412993;

Signification : Une transaction est ouverte depuis ~30 minutes. Cela peut bloquer le purge et verrouiller d’autres writers.

Décision : Si c’est sûr, kill la session et corrigez la logique applicative pour éviter les transactions longues (commit plus souvent, batches plus petits).

Task 4: Confirm replication status and lag in MariaDB

cr0x@server:~$ mysql -h mariadb-replica01 -uroot -p -e "SHOW SLAVE STATUS\G" | egrep "Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master|Using_Gtid"
Enter password:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 37
Using_Gtid: Slave_Pos

Signification : Le réplica est sain mais à ~37 secondes de retard.

Décision : Si votre RTO/RPO de basculement ne tolère pas 37 secondes, vous avez besoin de semi-sync, d’un meilleur hardware, d’une charge d’écriture réduite, ou d’une topologie différente.

Task 5: Check binary log format for migration/CDC assumptions

cr0x@server:~$ mysql -h mariadb01 -uroot -p -e "SHOW VARIABLES LIKE 'binlog_format';"
Enter password:
Variable_name	Value
binlog_format	ROW

Signification : Binlog en mode ROW activé ; bon pour nombre de pipelines CDC.

Décision : Conservez ROW pour la correction à moins d’avoir une raison testée de faire autrement. Les binlogs basés sur statements plus des requêtes non déterministes sont la source de la « créativité des replicas ».

Task 6: Surface slow queries in MariaDB (with real evidence)

cr0x@server:~$ sudo tail -n 20 /var/log/mysql/slow.log
# Time: 2025-12-30T10:38:13.512345Z
# User@Host: app[app] @ 10.20.3.14 []
# Query_time: 2.871  Lock_time: 0.004 Rows_sent: 25  Rows_examined: 1820031
SELECT * FROM orders WHERE created_at >= '2025-12-01' ORDER BY created_at DESC LIMIT 25;

Signification : Grand scan (1.8M lignes examinées) pour retourner 25 lignes. Classique index manquant ou mauvais pattern d’accès.

Décision : Ajouter un index couvrant (par ex. sur created_at plus colonnes de filtre), ou repenser la requête pour éviter de trier de larges plages.

Task 7: Validate index usage with EXPLAIN in MariaDB

cr0x@server:~$ mysql -h mariadb01 -uroot -p -e "EXPLAIN SELECT * FROM orders WHERE created_at >= '2025-12-01' ORDER BY created_at DESC LIMIT 25\G"
Enter password:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: orders
type: ALL
possible_keys: idx_created_at
key: NULL
rows: 1900000
Extra: Using where; Using filesort

Signification : Scan complet de table et filesort ; index non utilisé.

Décision : Corriger l’index ou la requête. Si l’index existe mais n’est pas utilisé, vérifiez mismatch de collation/type, fonctions sur la colonne, ou statistiques de cardinalité dégradées.

Task 8: TiDB cluster health snapshot (control plane sanity)

cr0x@server:~$ tiup ctl:v8.5.0 pd -u http://pd01:2379 store
{
  "count": 3,
  "stores": [
    { "store": { "id": 1, "address": "tikv01:20160", "state_name": "Up" } },
    { "store": { "id": 2, "address": "tikv02:20160", "state_name": "Up" } },
    { "store": { "id": 3, "address": "tikv03:20160", "state_name": "Up" } }
  ]
}

Signification : PD est joignable ; les stores TiKV sont Up.

Décision : Si PD ne répond pas rapidement, arrêtez de blâmer le SQL. Stabilisez PD/quorum en premier ; tout dépend de lui.

Task 9: Detect hotspot regions in TiDB/TiKV (where “shards” hide)

cr0x@server:~$ tiup ctl:v8.5.0 pd -u http://pd01:2379 hot read
{
  "as_leader": [
    { "region_id": 74219, "store_id": 2, "hot_degree": 97, "flow_bytes": 183274112 }
  ]
}

Signification : Le store 2 est leader pour une région très chaude. Attendez-vous à une latence et un CPU inégaux sur ce nœud.

Décision : Analysez le pattern d’accès (clés séquentielles, inserts time-series, ou un seul tenant). Envisagez de splitter les régions, changer le design de clé, ou déplacer les leaders en mitigation.

Task 10: Check leader balance and scheduling in TiDB (PD doing its job?)

cr0x@server:~$ tiup ctl:v8.5.0 pd -u http://pd01:2379 scheduler show
[
  "balance-leader-scheduler",
  "balance-region-scheduler",
  "balance-hot-region-scheduler"
]

Signification : Les schedulers attendus sont activés.

Décision : Si balance-hot-region-scheduler manque/est désactivé, les hotspots persisteront. Activez‑le seulement si vous comprenez les effets secondaires sur la stabilité pendant les pics.

Task 11: Spot transaction retries and latch contention from TiDB SQL layer

cr0x@server:~$ mysql -h tidb01 -P4000 -uroot -e "SHOW STATUS LIKE 'tidb_txn_retry%'; SHOW STATUS LIKE 'tidb_server_execute%';"
Variable_name	Value
tidb_txn_retry_total	1842
Variable_name	Value
tidb_server_execute_duration_seconds_count	1298821

Signification : Retries de transaction non négligeables. Souvent signe de contention, conflits, ou réponses de stockage lentes.

Décision : Si les retries montent pendant les incidents, priorisez les vérifications d’hygiène du stockage et des hotspots plutôt que les discussions superficielles d’optimisation SQL.

Task 12: Confirm TiKV disk health and IO wait on a suspected bad node

cr0x@server:~$ ssh tikv02 "iostat -x 1 3 | tail -n +4"
Device            r/s     w/s   rMB/s   wMB/s  avgrq-sz avgqu-sz   await  %util
nvme0n1         210.4   488.7    12.1    44.8    121.3     8.72   15.90  98.7

Signification : Le disque est presque saturé (%util ~99) avec await élevé. Le TiKV sur ce nœud répondra lentement ; les leaders Raft ici pénaliseront tout le cluster.

Décision : Déplacez leaders/régions loin de ce store et corrigez le stockage (santé NVMe, filesystem, voisin bruyant, pression de compaction). Si c’est un volume cloud, vérifiez les crédits burst et les plafonds de débit.

Task 13: Validate TiDB query plan, not just query text

cr0x@server:~$ mysql -h tidb01 -P4000 -uroot -e "EXPLAIN ANALYZE SELECT * FROM orders WHERE created_at >= '2025-12-01' ORDER BY created_at DESC LIMIT 25;"
+---------------------------+---------+---------+-----------+----------------------------+
| id                        | estRows | actRows | task      | operator info              |
+---------------------------+---------+---------+-----------+----------------------------+
| TopN_5                    | 25.00   | 25      | root      | order by:created_at, limit |
| └─TableFullScan_7         | 1.90e+6 | 1.82e+6 | cop[tikv] | keep order:false           |
+---------------------------+---------+---------+-----------+----------------------------+

Signification : Un full scan se produit dans TiKV. Le système distribué réalise fidèlement la mauvaise opération.

Décision : Ajoutez l’index approprié ou réécrivez la requête. Si vous devez scanner, planifiez‑le hors‑pic et isolez via des contrôles de ressources ; ne laissez pas l’analytique se déguiser en OLTP.

Task 14: Check MariaDB disk usage and growth before a migration cutover

cr0x@server:~$ sudo du -sh /var/lib/mysql; sudo df -h /var/lib/mysql
182G	/var/lib/mysql
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  500G  412G   63G  87% /var/lib/mysql

Signification : Vous êtes à 87% d’utilisation disque. Ce n’est pas « acceptable ». C’est « une reconstruction d’index loin d’appeler l’équipe ».

Décision : Avant de lancer les outils de migration, étendez le disque ou nettoyez. Les migrations amplifient les besoins d’espace temporaire (DDL, backfill, logs, snapshots).

Trois mini-récits d’entreprise depuis le terrain

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

L’entreprise était en cours de migration de MariaDB vers TiDB. Le plan était conservateur : dual-write pendant un temps, lecture depuis MariaDB, puis basculement des lectures vers TiDB. L’équipe était fière de ses tests de compatibilité SQL ; la suite d’intégration passait ; les dashboards étaient verts.

Ils ont basculé un petit pourcentage du trafic de lecture vers TiDB. En une heure, le p99 a doublé pour une poignée d’endpoints. Rien de spectaculaire, juste ce genre de lente dégradation qui ruine les funnels de conversion et fait découvrir aux product managers le terme « régression base de données ».

L’hypothèse : « Si une requête est indexée dans MariaDB, elle se comportera de façon similaire dans TiDB. » La réalité : la requête utilisait un index composite dans MariaDB à cause d’un pattern de sélectivité particulier, mais le plan de TiDB a choisi un full scan sous cette distribution. C’était techniquement correct et fonctionnellement exact—juste opérationnellement mauvais.

Pendant le postmortem, la leçon douloureuse n’était pas « TiDB est mauvais ». C’était qu’ils n’avaient pas construit une porte de validation de plan. Ils testaient la correction, pas la performance. La correction a été ennuyeuse : capturer les requêtes principales, exécuter EXPLAIN ANALYZE sur les deux systèmes, et bloquer les migrations quand le plan changeait pour devenir coûteux sans approbation explicite.

Ce qui les a sauvés d’un replay : une règle unique : si une requête touche plus de X lignes ou effectue un full scan dans TiDB, elle nécessite soit un index, soit une réécriture, soit un plan d’isolation des ressources. Pas d’exceptions pour « mais ça a toujours été OK ».

Mini-récit 2 : L’optimisation qui a mal tourné

Une autre équipe faisait tourner MariaDB avec des replicas et avait un job de reporting périodique qui effectuait de larges scans par plage. Quelqu’un a décidé « d’optimiser » en déplaçant le job de reporting sur un replica et en augmentant le parallélisme. Le job a fini plus vite. Tout le monde a applaudi discrètement sur Slack.

Une semaine plus tard, un basculement est intervenu pendant un flapping réseau. Le replica promu était plus en retard que l’équipe ne le pensait parce que le job de reporting martelait l’IO et appliquait lentement les événements de réplication. Le basculement a réussi, mais ils ont servi des données un peu obsolètes assez longtemps pour que la finance le remarque, et la finance remarque de manière à obtenir des invites calendrier.

La cause racine n’était pas « faire du reporting sur un replica ». C’était la combinaison : augmentation de la charge IO, moins de marge pour l’application de réplication, et un process de basculement qui n’imposait pas de gate RPO (« ne pas promouvoir si lag > seuil »).

La correction n’était pas héroïque. Ils ont limités le débit du job de reporting, ajouté un replica analytique dédié avec du hardware différent, et fait en sorte que l’automatisation de basculement vérifie explicitement le lag de réplication. La leçon : les optimisations de performance qui ignorent les chemins de basculement sont juste des pannes avec meilleur PR.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la journée

Une entreprise exploitant TiDB avait une pratique ennuyeuse que personne n’aimait : des drills de restauration trimestriels. Pas un « on a lancé la commande de backup ». De vraies restaurations dans un environnement isolé, avec requêtes de validation et runbook chronométré.

Puis est venu le jour : une erreur humaine dans un script d’automatisation a supprimé la mauvaise table en production. Le changement a été détecté rapidement, mais les données ont disparu tout aussi rapidement. La panique a tenté d’entrer.

Ils ont exécuté le runbook. Restauration dans un nouveau cluster, validation des comptes de lignes et checksums pour les tables critiques, puis redirection de l’application pour le dataset affecté. Ce n’était pas instantané, mais c’était contrôlé. L’incident s’est mesuré en minutes d’indisponibilité, pas en angoisse existentielle.

Le postmortem n’était pas excitant. Pas de méchant. Pas de miracle. Juste la preuve que les disciplines ennuyeuses—drills de restauration, cibles RTO/RPO claires, procédures de bascule testées—battent l’ingéniosité. L’équipe a gardé son week-end, ce qui est le KPI le plus rare de tous.

Erreurs fréquentes (symptôme → cause racine → correction)

1) « TiDB est lent » (p95/p99 grimpe après migration)

Symptôme : Lectures et écritures plus lentes ; CPU non saturé ; l’app voit des retries/timeouts.

Cause racine : Placement cross-AZ/région inapproprié, leaders non locaux, ou latence disque sur un sous-ensemble de nœuds TiKV. Les commits distribués paient pour le membre quorum le plus lent.

Correction : Faire respecter la localité (labels/placement rules), confirmer la distribution des leaders, et réparer les nœuds de stockage lents. Mesurer la latence de commit raft et le disk await.

2) Replica MariaDB qui « laggue » aléatoirement pendant les pics

Symptôme : Seconds_Behind_Master monte en flèche ; lectures vieillissantes ; risque de basculement augmente.

Cause racine : Saturation IO du replica, transactions longues sur le primaire générant des rafales de binlog, ou contraintes d’application single-thread selon la config/charge.

Correction : Réduire l’amplification d’écriture (indexes, taille de batch), assurer de la marge IO sur les replicas, envisager la replication parallèle si applicable, et imposer des gates de basculement sur le lag.

3) Throughput Galera qui s’effondre quand la concurrence d’écriture augmente

Symptôme : Ajouter des nœuds n’augmente pas le throughput d’écriture ; conflits et flow control apparaissent ; latence explose.

Cause racine : Conflits de certification sur des lignes chaudes, trop d’écrivains concurrents, ou grosses transactions provoquant un overhead de coordination cluster-wide.

Correction : Réduire la contention d’écriture (changement de schéma, design de clé), découper les transactions, pinner les écritures sur un seul nœud (si acceptable), ou arrêter de prétendre que Galera est une panacée pour la montée en écriture.

4) Hotspot TiDB qui ne part jamais

Symptôme : Un nœud TiKV reste chaud ; PD « balance » mais la douleur persiste ; retries de transaction augmentent.

Cause racine : Clés séquentielles ou inserts monotoniques créant des hotspots de région ; absence de split suffisant des régions ; skews par tenant.

Correction : Changer le design de clé (éviter les primary keys monotoniques pour les tables chaudes), activer/pre-split pour les tables chaudes, isoler les tenants, et utiliser le scheduling des hotspots avec précaution.

5) Migration réussie, mais bugs d’exactitude apparaissent semaines après

Symptôme : Lignes manquantes/dupliquées occasionnelles, arrondis étranges, différences de sensibilité à la casse, ou surprises de timezone.

Cause racine : Différences de SQL mode, collation, conversions implicites, ou dépendance applicative sur un comportement indéfini.

Correction : Verrouiller les SQL modes et collations, ajouter des checks de validation des données, et éliminer la magie « string-to-int » et l’ambiguïté de timezone dans l’application.

6) La sauvegarde existe, la restauration échoue

Symptôme : La restauration prend bien plus de temps que prévu, ou échoue à cause de permissions, binlogs manquants, ou versions incompatibles.

Cause racine : Chemin de restauration non testé, snapshots incohérents, ou environnement de restauration sous-provisionné.

Correction : Drills de restauration réguliers, runbooks documentés, et planification de capacité pour le débit de restauration (réseau + disque + CPU).

Checklists / plan pas-à-pas

Checklist de décision : devez‑vous rester sur MariaDB ?

  • Votre charge d’écriture tient sur un primaire unique avec marge après tuning raisonnable.
  • Vous pouvez tolérer le lag des replicas ou accepter les compromis du semi-sync.
  • Votre douleur principale est la qualité des requêtes/index, pas le nombre de shards.
  • Vous voulez le modèle de panne le plus simple et la plus petite surface opérationnelle.

Checklist de décision : devez‑vous migrer vers TiDB ?

  • Vous avez besoin d’une montée en écriture au-delà d’un seul nœud sans sharding applicatif.
  • Vous pouvez investir dans l’observabilité : tracing, métriques par composant, et gestion de capacité.
  • Vous pouvez accepter une latence de base plus élevée en échange de scale et HA.
  • Vous êtes prêt à repenser les clés chaudes et les patterns de transaction.

Plan pas‑à‑pas de migration qui survit au contact avec la production

  1. Inventaire de la charge : top requêtes par latence et fréquence, tables les plus écrites, plus grosses tables par taille.
  2. Verrouillez les sémantiques : SQL mode, timezone, collation, attentes d’isolation.
  3. Planifiez les indexes en premier : validez les plans de requêtes dans le système cible pour les top N requêtes.
  4. Construisez la validation des données : counts, checksums par partition/plage, et invariants métier.
  5. Concevez le cutover : dual-write vs CDC ; définissez le rollback.
  6. Pratiquez le basculement et la restauration : pour les deux systèmes avant le flip en production.
  7. Faites un dark launch : mirroring des lectures ou shadow traffic ; comparez résultats et latences.
  8. Montez progressivement : 1% → 5% → 25% → 50% avec critères d’acceptation explicites.
  9. Gelez les changements risqués : pas de gros refactors de schéma pendant la montée sauf si vous aimez le drama.
  10. Documentez la responsabilité opérationnelle : qui pagine pour PD ? qui pagine pour les compactions lentes ? qui gère les gates de schéma ?

Checklist Runbook : à quoi ressemble « prêt pour la prod »

  • Le job de sauvegarde s’exécute avec succès monitoré et temps de restauration connu.
  • Drill de restauration réalisé dans les 90 derniers jours avec timings enregistrés.
  • Dashboards existent par couche (SQL, stockage, plan de contrôle) avec focus p95/p99.
  • Seuils d’alerte liés à l’impact utilisateur (latence, taux d’erreur), pas à des métriques de vanité.
  • Marge de capacité disponible : disque, IO, CPU, plus espace pour maintenance/compaction.

FAQ

1) TiDB est‑il un « remplaçant plug‑and‑play » pour MariaDB/MySQL ?

Pour beaucoup d’apps, c’est assez proche pour commencer les tests rapidement. Mais « plug‑and‑play » s’arrête à la performance et au comportement opérationnel. Traitez‑le comme une réécriture de vos hypothèses.

2) TiDB remplace‑t‑il le besoin de replicas de lecture ?

Il change le modèle. Vous scalez les nœuds SQL sans état TiDB pour le débit de lecture, mais vous devez toujours planifier les domaines de panne, le placement, et les voisins bruyants.

3) Galera est‑il une manière plus simple d’obtenir ce que TiDB offre ?

Non. Galera peut fournir HA et certaines formes d’écriture multi‑nœuds, mais ce n’est pas la même chose qu’une couche de stockage distribuée avec réplication Raft. Sous forte contention d’écritures, le modèle de certification de Galera peut pénaliser.

4) Quels workloads font briller TiDB ?

Besoins élevés de montée en écriture sans sharding applicatif, datasets volumineux en croissance horizontale, et workloads mixtes où scaler indépendamment lectures et écritures aide. Aussi : équipes capables d’exploiter des systèmes distribués correctement.

5) Quels workloads doivent rester sur MariaDB ?

OLTP mono‑région avec croissance prévisible, exigences de faible latence, et équipes qui privilégient la simplicité opérationnelle plutôt que la scalabilité horizontale des écritures. MariaDB reste un cheval de trait très compétent.

6) Quelle est la première surprise pour les équipes qui passent à TiDB ?

Les hotspots. Pas parce qu’ils n’existaient pas avant, mais parce qu’ils deviennent visibles comme « un leader de région fond », pas seulement « le primaire est occupé ».

7) Comment réfléchir aux différences de coût ?

MariaDB tend à coûter moins pour des charges modérées car vous achetez moins de nœuds et moins de réseau. TiDB coûte souvent plus en infrastructure mais peut coûter moins que l’ingénierie du sharding. Le bon modèle inclut le coût d’on‑call et le risque de migration, pas seulement le nombre de nœuds.

8) Puis‑je migrer avec quasiment zéro downtime ?

Oui, avec des patterns CDC/dual‑write et un cutover soigné. Le risque d’indisponibilité est rarement la copie ; c’est le dernier mile : dérive de schéma, régressions de plan, et surprises opérationnelles lors de la montée de trafic.

9) Quel est le test pré‑migration le plus utile ?

Exécutez les 50–200 meilleures requêtes de production sur le système cible avec une distribution de données proche de la production, et comparez les résultats d’EXPLAIN ANALYZE. Les tests de correction ne détecteront pas les désastres de plan.

10) Quelle habitude opérationnelle est la plus précieuse pour l’un ou l’autre système ?

Les drills de restauration. Pas optionnel. Pas un « on a vérifié que le fichier existe ». De vraies restaurations avec validation et étapes chronométrées.

Conclusion : prochaines étapes exécutables dès lundi

Si vous hésitez entre MariaDB et TiDB, décidez en fonction de ce que vous êtes prêts à exploiter. MariaDB récompense la simplicité disciplinée. TiDB récompense les équipes qui traitent les systèmes distribués comme un métier à part entière, pas un hobby accidentel.

Faites ceci ensuite :

  1. Récupérez vos requêtes les plus lourdes et faites des comparaisons de plans (MariaDB EXPLAIN, TiDB EXPLAIN ANALYZE).
  2. Appliquez le playbook de diagnostic rapide sur votre pire endpoint p99 et classez le goulot.
  3. Choisissez une stratégie de migration (CDC/dual‑write) et rédigez le plan de rollback avant d’écrire le plan de cutover.
  4. Planifiez un drill de restauration. Mettez‑le dans le calendrier. Rendez‑le réel.

Vous n’avez pas besoin d’une certitude parfaite. Vous avez besoin d’un risque contrôlé, d’une performance mesurée, et d’un système qui tombe de la manière que vous avez déjà répétée.

← Précédent
Compromis par un serveur de test : la défaillance classique en entreprise
Suivant →
OpenVPN « route addition failed » sur Windows : corrections de routage qui fonctionnent vraiment

Laisser un commentaire