MariaDB vs PostgreSQL : vitesse de restauration — comment obtenir un RTO < 15 minutes

Cet article vous a aidé ?

La vitesse de restauration est l’endroit où la théorie des bases de données rencontre la dure réalité de la latence du stockage, de la contention CPU et du « attendez, laquelle de ces sauvegardes est la bonne ? » panique. Votre RTO n’est pas un chiffre de tableur. C’est le temps entre le premier pager et le moment où votre application cesse de se comporter comme un distributeur automatique hanté.

Si vous avez besoin d’un RTO inférieur à 15 minutes, vous ne « optimisez pas les restaurations ». Vous concevez le chemin entier sauvegarde+récupération comme un système de production : prévisible, mesurable, répété et impitoyablement ennuyeux.

Ce que « RTO < 15 minutes » signifie réellement

Le RTO est le temps pour restaurer le service, pas le temps pour « terminer la restauration ». Si votre service a besoin de la base de données et que votre base de données a besoin de pool de connexions, DNS, secrets et compatibilité de schéma, tout cela entre en jeu. Une restauration de base de données de 9 minutes devient une panne de 30 minutes si vous avez encore :

  • Un rattrapage WAL/binlog de 12 minutes parce que vous avez oublié que vous faites du PITR.
  • Un « warm-up » de cache de 6 minutes parce que votre application retrouve la performance depuis le froid.
  • Un délai humain de 10 minutes parce que les étapes de restauration vivent dans la tête de quelqu’un.

Pour un RTO < 15 minutes, supposez que vous n’aurez pas le temps de réfléchir. Vous devez pouvoir exécuter un arbre de décision pré-bâti, avec une capacité pré-provisionnée, et vous devez savoir (pas espérer) que la sauvegarde est valide.

Les mathématiques inconfortables

15 minutes, c’est 900 secondes. Si votre répertoire de données physique fait 800 GB, vous ne le restaurez pas depuis un stockage objet à 200 MB/s. Pas à moins que la physique ne soit aussi dans votre rotation on-call.

Atteindre 15 minutes signifie généralement une de ces architectures :

  • Standby chaud / promotion de réplica (restauration = promotion + redirection).
  • Rollback via snapshot (restauration de snapshot ZFS/LVM/EBS et attachement).
  • Restauration physique vers nœuds préchauffés (le transfert de données est local ou déjà staged).
  • Jeu de données suffisamment petit pour qu’une vraie restauration tienne dans la fenêtre (rare dans les systèmes adultes).

Les dumps logiques pour les grands systèmes servent aux migrations et à l’archéologie. Ce ne sont pas votre plan RTO 15 minutes.

Chemins de restauration : MariaDB vs PostgreSQL (ce qui va vite, ce qui ne va pas)

La restauration la plus rapide est généralement « ne pas restaurer »

Pour MariaDB comme pour PostgreSQL, la récupération la plus rapide est la promotion d’un réplica déjà à jour. Si vous pouvez respecter votre RPO avec la réplication asynchrone, tant mieux. Sinon, payez pour la réplication synchrone ou acceptez un plus grand périmètre d’impact.

Physique vs logique : la bifurcation

Restauration logique (mysqldump/mariadb-dump, pg_dump) est lente parce qu’elle rejoue du SQL, reconstruit des index et force beaucoup de travail CPU déjà fait une première fois. Elle tend aussi à être limitée en mono-thread aux mauvais endroits.

Restauration physique (MariaDB : Mariabackup ; PostgreSQL : pgBackRest, pg_basebackup, restauration au niveau fichier) est rapide parce que l’on copie principalement des fichiers, puis on applique la récupération.

Profil de vitesse de restauration MariaDB

  • Voie rapide : sauvegarde physique Mariabackup, préparée à l’avance, copy-back sur stockage rapide, puis crash recovery InnoDB / application des redo au démarrage.
  • Où ça coince : étape de prepare (si différée), I/O du copy-back, et recovery InnoDB si les logs sont énormes ou si le comportement fsync est conservateur.
  • PITR : appliquer les binary logs (binlog) après restauration de la base. Cela peut être rapide ou douloureusement sériel selon le volume d’écriture et les limites d’application mono-thread dans votre configuration.

Profil de vitesse de restauration PostgreSQL

  • Voie rapide : restaurer une sauvegarde physique (pgBackRest restore ou basebackup), démarrer l’instance, rejouer le WAL jusqu’à consistance ou une cible (PITR), promouvoir.
  • Où ça coince : vitesse de replay WAL (I/O et CPU), débit de la commande de restauration (récupération des segments WAL), et configuration des checkpoints/redo.
  • PITR : peut être très rapide si l’archive WAL est locale et parallélisée ; peut être misérable si le WAL est distant et sérialisé ou si la cible de récupération est loin en arrière.

Conseil opinionné : si vous avez besoin d’un RTO < 15 minutes, concevez pour la promotion ou le rollback via snapshot. Si la conformité exige « restaurer depuis une sauvegarde », utilisez au moins des sauvegardes physiques et préplacez-les sur le stockage cible avant d’en avoir besoin.

Faits et historique qui importent dans la vitesse de restauration

  1. Le WAL de PostgreSQL est central depuis les années 1990 ; la sécurité au crash et le PITR ont été intégrés tôt, et la récupération consiste fondamentalement à « rejouer les logs jusqu’à consistance ».
  2. InnoDB est devenu le moteur par défaut de MySQL à la 5.5, et MariaDB a hérité de cette lignée. La vitesse de restauration dépend largement de « à quelle vitesse InnoDB peut se rendre cohérent à nouveau ».
  3. pg_dump est délibérément logique et portable ; excellent pour les migrations et les sauts de version, et catastrophique pour un RTO serré à l’échelle.
  4. Mariabackup est un fork de Percona XtraBackup, conçu pour des sauvegardes physiques à chaud sans arrêter les écritures. La phase de « prepare » existe parce qu’il faut rendre la sauvegarde cohérente.
  5. Les replication slots de PostgreSQL empêchent la suppression des WAL tant qu’un consommateur en a besoin ; super pour la durabilité, pénible si vous oubliez un slot abandonné et que votre disque se remplit en pleine crise.
  6. La réplication MySQL/MariaDB a historiquement eu du mal avec l’application parallèle dans certains workloads ; les améliorations modernes aident, mais l’application des binlogs reste un spoiler fréquent de RTO.
  7. Les systèmes de fichiers copy-on-write (ZFS, btrfs) ont changé la donne pour des rollbacks rapides via snapshot—lorsqu’ils sont bien utilisés. Mal utilisés, ils inventent aussi de nouvelles façons de saturer les IOPS.
  8. PostgreSQL 9.6 a amélioré le replay WAL et le vacuum d’une manière qui aide indirectement les temps de récupération sous charge d’écriture (moins de bloat, moins de churn, meilleur comportement en arrière-plan après restauration).
  9. MariaDB et PostgreSQL dépendent tous deux des sémantiques fsync ; la vitesse de restauration peut être dominée par les garanties de durabilité du stockage plus que par le code de la base.

Les goulots d’étranglement de restauration que vous ne pouvez pas ignorer

1) Déplacer des octets : bande passante et IOPS

La restauration physique est un problème de copie de fichiers plus replay de récupération. Si vos données sont sur HDD ou stockage réseau avec une latence imprévisible, votre RTO ressemble à une prévision météo.

Pour être sous 15 minutes, vous voulez :

  • SSD/NVMe pour le volume de la base de données.
  • Mise en stage locale du dernier backup de base.
  • Débit séquentiel prévisible et assez d’IOPS aléatoires pour l’application WAL/redo.

2) Replay de récupération : comportement du WAL vs redo log

La récupération PostgreSQL rejoue le WAL. MariaDB/InnoDB rejoue les redo et applique les changements aux pages de données. Les deux sont sensibles à :

  • Combien de pages dirty doivent être réconciliées.
  • Fréquence des checkpoints et taille des buffers de log.
  • Taux de fsync et amplification d’écriture.

3) CPU et choix de compression

La compression est un piège classique : elle aide le réseau et le stockage, puis tue silencieusement le CPU lors de la récupération. Si vous compressez fortement les sauvegardes, assurez-vous que les hôtes de restauration ont la marge CPU et que vous pouvez paralléliser la décompression.

Blague #1 : La compression, c’est comme une adhésion à la salle de sport — l’acheter fait plaisir, l’utiliser pendant une urgence devient personnel.

4) « Restauré » n’est pas synonyme de « utilisable »

Même après le démarrage de la base, vous pouvez être à l’arrêt :

  • PostgreSQL : long crash recovery ou replay ; puis tempêtes d’autovacuum ; puis cache à froid.
  • MariaDB : InnoDB buffer pool froid ; adaptive hash index se réchauffe ; réplication se reconstruit ; requêtes échouent à cause d’instabilité des plans.

5) Métadonnées : privilèges, extensions et dérive

Les restaurations logiques échouent bruyamment si des extensions ou rôles manquent. Les restaurations physiques échouent silencieusement quand votre config diverge, l’instance démarre avec des paramètres différents et votre application observe des changements de comportement sous charge.

Une idée paraphrasée de Werner Vogels (CTO Amazon) : Concevez des systèmes en supposant que des choses échoueront ; la fiabilité vient de la préparation et de l’automatisation, pas de l’espoir.

Playbook de diagnostic rapide

Ceci est la séquence on-call quand le temps de restauration explose et que vous devez trouver le goulot en minutes, pas en postmortem.

Première étape : restaurez-vous des octets ou rejouez-vous des logs ?

  • Si vous copiez encore des fichiers : vous avez un problème de bande passante/chemin I/O.
  • Si la BD « démarre » mais n’est pas « prête » : vous avez un problème de replay de récupération ou de checkpointing.
  • Si elle est « prête » mais l’app est down : vous avez un problème de connectivité, d’identifiants ou de warm-up.

Deuxième étape : vérifiez la latence du stockage, pas le débit

Les restaurations effectuent souvent des bursts d’écritures petites. La latence vous tue en premier. Vous pouvez avoir un gros chiffre en MB/s et quand même perdre des minutes sur des fsync.

Troisième étape : vérifiez si le PITR est le goulet

Le PITR est non négociable pour certaines organisations. Très bien. Mais il doit être conçu : WAL/binlog archivés localement, récupération parallèle, et une décision testée « jusqu’où remonter ».

Quatrième étape : confirmez que vous ne vous sabotez pas avec la configuration

Pendant restore/recovery, certains paramètres doivent être temporairement plus agressifs, puis revertés. Si vous n’avez jamais planifié cela, vous restez avec des valeurs par défaut qui privilégient la sécurité plutôt que la vitesse (ce qui est justifié, mais ne respecte pas votre RTO).

Cinquième étape : validez l’intégrité de la sauvegarde tôt

Si votre sauvegarde est corrompue, chaque minute passée à « tuner » est une minute pendant laquelle vous ne basculez pas sur un réplica ou un snapshot. Validez vite, changez de stratégie vite.

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

Ces tâches sont conçues pour être exécutées pendant la planification et pendant un incident. Chacune inclut : commande, ce que la sortie signifie, et quelle décision prendre ensuite. Utilisez-les comme colonne vertébrale du runbook.

Task 1: Measure raw disk throughput (sequential) on the restore target

cr0x@server:~$ sudo fio --name=seqread --filename=/var/lib/postgresql/fio.test --size=4G --bs=1M --iodepth=16 --rw=read --direct=1 --numjobs=1
seqread: (groupid=0, jobs=1): err= 0: pid=22341: Thu Dec 31 10:11:12 2025
  read: IOPS=1650, BW=1650MiB/s (1730MB/s)(4096MiB/2481msec)

Signification : Un BW élevé indique que la copie séquentielle ne sera pas votre goulot. Si vous voyez <300 MiB/s sur des attentes SSD/NVMe, vous êtes sur la mauvaise classe de stockage ou il est mal partagé.

Décision : Si le BW est faible, arrêtez de planifier une « restauration depuis zéro ». Prévoyez une promotion de réplica ou une restauration par snapshot.

Task 2: Measure fsync-heavy latency (random write) on the restore target

cr0x@server:~$ sudo fio --name=randwrite --filename=/var/lib/mysql/fio.test --size=2G --bs=4k --iodepth=64 --rw=randwrite --direct=1 --numjobs=4 --time_based --runtime=30
randwrite: (groupid=0, jobs=4): err= 0: pid=22410: Thu Dec 31 10:12:02 2025
  write: IOPS=42000, BW=164MiB/s (172MB/s), lat (usec): avg=610, max=22000

Signification : Une latence moyenne en centaines de microsecondes est correcte. Des millisecondes sous charge vont étirer le crash recovery et le replay WAL.

Décision : Si la latence est mauvaise, réduisez la pression concurrente de récupération (limitez les jobs de restore), déplacez WAL/binlog sur un volume plus rapide, ou basculez sur un nœud avec meilleur stockage.

Task 3: Check PostgreSQL recovery state and replay progress

cr0x@server:~$ sudo -u postgres psql -c "select pg_is_in_recovery(), now() as ts, pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();"
 pg_is_in_recovery |              ts               | pg_last_wal_receive_lsn | pg_last_wal_replay_lsn
-------------------+-------------------------------+-------------------------+------------------------
 t                 | 2025-12-31 10:13:11.552781+00 | 4A/9B2C1F20             | 4A/9B29A4D8
(1 row)

Signification : Receive LSN en avance sur replay LSN signifie que le replay est en retard (lié au CPU/I/O). Si receive LSN est NULL, vous ne recevez pas de WAL (problème d’archive/stream).

Décision : Si le replay accuse du retard, vérifiez la latence disque et les réglages de recovery ; si vous ne recevez pas de WAL, corrigez la récupération d’archive ou la connectivité de réplication.

Task 4: Inspect PostgreSQL logs for recovery bottlenecks

cr0x@server:~$ sudo tail -n 30 /var/log/postgresql/postgresql-16-main.log
2025-12-31 10:12:58.123 UTC [21011] LOG:  starting PostgreSQL 16.2 on x86_64-pc-linux-gnu
2025-12-31 10:12:58.456 UTC [21011] LOG:  entering standby mode
2025-12-31 10:13:05.990 UTC [21011] LOG:  redo starts at 4A/9A000028
2025-12-31 10:13:11.770 UTC [21011] LOG:  consistent recovery state reached at 4A/9B0000A0
2025-12-31 10:13:11.771 UTC [21011] LOG:  restored log file "000000010000004A0000009B" from archive

Signification : « restored log file … from archive » répété lentement suggère que la récupération d’archive est le goulet (réseau, latence stockage objet). Si redo démarre puis bloque avec des checkpoints, le stockage est en difficulté.

Décision : Si la récupération d’archive est lente, stagez les WAL localement ou activez la récupération WAL parallèle via vos outils de sauvegarde.

Task 5: Check pgBackRest restore and WAL archive health

cr0x@server:~$ sudo -u postgres pgbackrest info
stanza: prod
    status: ok
    cipher: none
    db (current)
        wal archive min/max (16): 000000010000004A00000090/000000010000004A000000A1
        full backup: 2025-12-31 03:00:02+00
            size: 612.3GB, repo size: 201.7GB
            backup reference list: 

Signification : Une full backup récente existe, la plage WAL archive est présente. Si status n’est pas ok ou si WAL min/max est stale, votre PITR peut être impossible.

Décision : Si l’archive WAL n’est pas saine, arrêtez de promettre du PITR. Promouvez un réplica ou restaurez au dernier point valide.

Task 6: Identify PostgreSQL checkpoint pressure (post-restore performance cliff)

cr0x@server:~$ sudo -u postgres psql -c "select checkpoints_timed, checkpoints_req, buffers_checkpoint, buffers_backend, stats_reset from pg_stat_bgwriter;"
 checkpoints_timed | checkpoints_req | buffers_checkpoint | buffers_backend |          stats_reset
------------------+-----------------+--------------------+-----------------+-------------------------------
              112 |              87 |           98122310 |          442190 | 2025-12-31 09:40:00+00
(1 row)

Signification : Un nombre élevé de checkpoints_req suggère des checkpoints forcés (souvent dû à un max_wal_size trop petit ou des rafales d’écriture). Cela peut ralentir la récupération et le trafic initial.

Décision : Augmentez max_wal_size et ajustez checkpoint_timeout/checkpoint_completion_target pour lisser l’I/O — surtout sur les nœuds de recovery.

Task 7: Check MariaDB InnoDB recovery behavior and crash recovery time clues

cr0x@server:~$ sudo tail -n 40 /var/log/mysql/error.log
2025-12-31 10:11:22 0 [Note] InnoDB: Starting crash recovery.
2025-12-31 10:11:22 0 [Note] InnoDB: Reading tablespace information from the .ibd files...
2025-12-31 10:12:10 0 [Note] InnoDB: 5.6.0 started; log sequence number 987654321
2025-12-31 10:12:10 0 [Note] InnoDB: Completed initialization of buffer pool
2025-12-31 10:12:54 0 [Note] InnoDB: Crash recovery finished.

Signification : Si le crash recovery prend des minutes, c’est une partie de votre RTO. Les durées plus longues sont souvent corrélées à de grands redo logs, un volume élevé de pages dirty ou un fsync lent.

Décision : Si le crash recovery est systématiquement long, ajustez checkpointing/flush et assurez-vous que les redo logs et les données résident sur un stockage à faible latence.

Task 8: Validate MariaDB physical backup readiness (prepared vs not)

cr0x@server:~$ sudo mariabackup --prepare --target-dir=/backups/mariadb/full-2025-12-31
[00] 2025-12-31 10:14:03 completed OK!

Signification : « completed OK » signifie que la sauvegarde est maintenant cohérente et prête pour un copy-back rapide. Si vous retardez le prepare jusqu’au moment de l’incident, vous venez de dépenser votre RTO en paperasserie.

Décision : Gardez toujours la dernière sauvegarde déjà préparée (ou préparez-la immédiatement après création) si vous visez des restaurations sous 15 minutes.

Task 9: Restore MariaDB from prepared backup (copy-back) and verify ownership

cr0x@server:~$ sudo systemctl stop mariadb
cr0x@server:~$ sudo rm -rf /var/lib/mysql/*
cr0x@server:~$ sudo mariabackup --copy-back --target-dir=/backups/mariadb/full-2025-12-31
[00] 2025-12-31 10:15:44 completed OK!
cr0x@server:~$ sudo chown -R mysql:mysql /var/lib/mysql

Signification : Le succès du copy-back est nécessaire mais pas suffisant. Un mauvais ownership empêchera le démarrage ou causera des échecs de permission étranges.

Décision : Si ownership/SELinux/AppArmor est incorrect, corrigez-le immédiatement. Ne « voyez pas si ça démarre ». Ça ne démarrera pas, et vous perdrez du temps.

Task 10: Confirm MariaDB is accepting connections and not stuck in recovery

cr0x@server:~$ sudo systemctl start mariadb
cr0x@server:~$ mysql -uroot -e "select @@version, @@innodb_flush_log_at_trx_commit, @@sync_binlog\G"
@@version: 10.11.6-MariaDB
@@innodb_flush_log_at_trx_commit: 1
@@sync_binlog: 1

Signification : Le serveur est up et les configs sont visibles. Si la connexion bloque, vérifiez le journal d’erreurs pour crash recovery ou des stalls fsync.

Décision : Pour des nœuds de restauration d’urgence, vous pouvez temporairement assouplir la durabilité (voir plus loin) si votre organisation l’accepte — puis revertir.

Task 11: Estimate PostgreSQL restore time by measuring decompression and copy

cr0x@server:~$ time sudo -u postgres pgbackrest --stanza=prod restore --type=immediate --target-action=promote
real    6m42.118s
user    2m10.044s
sys     1m02.991s

Signification : « real » est le temps mur. Si le user time est énorme, la décompression/chiffrement est liée au CPU. Si le sys time est élevé, le noyau et l’I/O sont en cause.

Décision : CPU-bound : ajoutez des cœurs, changez la compression, parallélisez. I/O-bound : disques plus rapides, dépôt local, moins de sauts réseau.

Task 12: Check whether PostgreSQL is waiting on WAL archive retrieval

cr0x@server:~$ sudo -u postgres psql -c "select now(), wait_event_type, wait_event, state, query from pg_stat_activity where pid = pg_backend_pid();"
              now              | wait_event_type | wait_event | state  |                query
------------------------------+-----------------+------------+--------+-------------------------------------
2025-12-31 10:17:12.118+00    | Activity        | WALRead    | active | select now(), wait_event_type, ...
(1 row)

Signification : Wait WALRead pendant la recovery indique souvent une lenteur d’I/O ou de fetch d’archive.

Décision : Si le WAL est distant, rapprochez l’archive ou passez au streaming depuis une source live ; si local, investiguez la latence disque.

Task 13: Spot a forgotten PostgreSQL replication slot that’s bloating WAL (pre-incident hygiene)

cr0x@server:~$ sudo -u postgres psql -c "select slot_name, active, restart_lsn from pg_replication_slots;"
   slot_name   | active | restart_lsn
---------------+--------+-------------
 analytics_etl | f      | 4A/01000000
(1 row)

Signification : Un slot inactif retient du WAL. Avec le temps, cela gonfle le volume WAL, allonge le PITR et peut remplir les disques au pire moment.

Décision : Si le consommateur est mort, supprimez le slot après avoir confirmé que c’est sûr. Puis corrigez la gestion des consommateurs.

Task 14: Check MariaDB binlog availability for PITR and the clock you’re racing

cr0x@server:~$ mysql -uroot -e "show binary logs;"
Log_name        File_size
binlog.000221   104857600
binlog.000222   104857600
binlog.000223   51239871

Signification : Les binlogs existent et leurs tailles suggèrent une rotation active. Si les logs manquent parce que la rétention est trop courte, le PITR est une illusion.

Décision : Définissez la rétention des binlogs en fonction de la fenêtre PITR maximale que vous promettez. Ensuite, surveillez-la comme si c’était de la production (parce que ça l’est).

Task 15: Validate restore success by checking core invariants (PostgreSQL)

cr0x@server:~$ sudo -u postgres psql -c "select count(*) from pg_class; select now();"
 count
-------
  4182
(1 row)

              now
-------------------------------
2025-12-31 10:18:55.11002+00
(1 row)

Signification : Vous ne prouvez pas la correction, mais vous prouvez que le catalogue est lisible et que le serveur répond. Ajoutez ensuite des checks applicatifs.

Décision : Si une requête échoue avec des messages de corruption, arrêtez. Passez à la promotion d’un réplica ou à une autre sauvegarde immédiatement.

Task 16: Validate restore success by checking core invariants (MariaDB)

cr0x@server:~$ mysql -uroot -e "show engine innodb status\G" | head -n 25
*************************** 1. row ***************************
Type: InnoDB
Name:
Status:
=====================================
2025-12-31 10:19:21 0x7f2c4c1fe700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 4 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 12 srv_active, 0 srv_shutdown, 245 srv_idle

Signification : InnoDB est opérationnel. Vous pouvez aussi voir s’il effectue encore beaucoup de travail de fond. S’il thrash, attendez-vous à un comportement applicatif lent même si la « restauration est terminée ».

Décision : Envisagez de réduire temporairement le trafic applicatif ou d’activer le mode lecture seule jusqu’à stabilisation, selon votre modèle de service.

Trois mini-récits de la vie en entreprise

Mini-récit 1 : La panne causée par une mauvaise hypothèse

L’entreprise était en pleine migration : un monolithe sur MariaDB, un nouveau service sur PostgreSQL. L’équipe SRE avait un objectif RTO propre et une réalité brouillonne. Tout le monde était d’accord sur « nous avons des backups », ce qui équivaut en entreprise à dire « nous avons des parapluies » en pleine tempête.

L’hypothèse était simple : les dumps logiques sont « suffisants » parce que le dataset « n’est pas si grand ». Personne n’avait réellement chronométré une restauration de bout en bout. Le runbook on-call disait : récupérer le dernier dump depuis le stockage objet, restaurer, appliquer les migrations, pointer l’app.

Puis un incident de stockage a détruit un volume primaire. L’équipe a lancé la restauration à partir du dump. Ça a traîné, CPU saturé, disque sollicité, et l’horloge a continué à tourner. La création d’index a dominé. Ensuite les migrations applicatives ont apporté plus de verrous et plus de temps. Au bout d’une heure, ils avaient une base. Après encore du temps, l’app pouvait l’utiliser. Le RTO n’a pas été manqué de quelques minutes ; il a été manqué pendant toute une réunion.

Le postmortem ne parlait pas d’un ajustement héroïque. Il disait qu’il fallait admettre que les dumps ne sont pas une stratégie de restauration à l’échelle. Ils ont mis en place des sauvegardes physiques, construit un standby chaud et commencé à chronométrer des restaurations mensuelles. La correction était plutôt ingrate. C’est pour ça que ça a marché.

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

Une autre organisation était fière de son efficacité de stockage. Ils compressaient tout de façon agressive : backups de base, archives WAL, tout. Les coûts ont baissé. Les tableaux de bord étaient propres. Les finances ont brièvement applaudi.

Pendant un incident réel, ils ont restauré PostgreSQL depuis une sauvegarde compressée vers un nœud avec moins de cœurs que la production. Sur le papier c’était « ok », parce que ce nœud n’existait qu’en cas d’urgence. En réalité, la décompression est devenue le goulot. La restauration a pris assez de temps pour que l’équipe commence à « optimiser » en direct : changer les paramètres de compression en cours, redémarrer des processus, et transformer une procédure prévisible en danse interprétative.

Ils ont récupéré la base, mais leur objectif RTO était parti. La plus grosse douleur : les économies de stockage étaient réelles, mais minuscules comparées au coût de la panne et à la réputation. Ils ont rééquilibré : compression modérée, plus de parallélisme, et nœuds de restauration dimensionnés pour les charges de restauration, pas pour l’état steady-state.

Blague #2 : Rien ne dit « nous sommes prêts » comme découvrir que votre boîte de récupération ressemble à une patate avec un câble réseau.

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

Une société proche des paiements utilisait à la fois MariaDB et PostgreSQL pour différents services. Leur habitude la plus précieuse n’était pas un outil. C’était un rituel : chaque semaine, un ingénieur exécutait une répétition de restauration dans un environnement isolé, en utilisant exactement les mêmes commandes que le runbook d’incident.

Ils suivaient trois temps : temps pour provisionner compute et stockage, temps pour restaurer la base, et temps pour atteindre « app healthy ». Ils notaient aussi les raisons d’échec — permissions, segments WAL manquants, dérive de schéma, secrets cassés — et les corrigeaient avec la cruauté calme qu’inspire un drill récurrent.

Quand un incident est survenu (volume corrompu plus mise à jour kernel foireuse, parce que la réalité aime les combos), la restauration n’était pas parfaite. Mais elle était pratiquée. Ils ont exécuté le playbook, vu immédiatement le lag de l’archive WAL, basculé sur la promotion du réplica et été de retour dans la fenêtre.

Personne n’a écrit un message Slack héroïque après. C’est comme ça qu’on sait que ça a marché.

Erreurs courantes : symptômes → cause racine → correction

Cette section est celle que vous lisez quand la restauration est « presque terminée » pour la cinquième fois.

1) Symptom: restore starts fast, then crawls at 5–10% CPU

  • Cause racine : latence I/O et stalls fsync, souvent à cause d’un stockage partagé ou d’un crédit de rafale épuisé.
  • Correction : Déplacez données et WAL/redo sur SSD/NVMe faible latence ; réduisez les voisins bruyants ; vérifiez le budget IOPS ; envisagez snapshot rollback ou promotion de réplica.

2) Symptom: PostgreSQL stuck “restoring log file … from archive” slowly

  • Cause racine : goulet de récupération d’archive WAL (latence stockage objet distant, fetch sérialisé ou réseau bridé).
  • Correction : Utilisez un repo/cache local pour le WAL, activez la récupération parallèle des WAL dans vos outils, ou stream depuis un upstream live si disponible.

3) Symptom: MariaDB startup takes forever after copy-back

  • Cause racine : crash recovery InnoDB appliquant les redo lentement ; souvent combinaison de settings de log et latence stockage.
  • Correction : Gardez les backups préparés ; assurez-vous que redo log et données sont sur un stockage rapide ; revoyez innodb_flush_log_at_trx_commit et sync_binlog pour le nœud de récupération si acceptable.

4) Symptom: “backup restored” but application errors explode

  • Cause racine : La restauration a monté la BD, mais pas l’environnement : mauvais utilisateurs, extensions manquantes, dérive de config ou DNS/connection strings obsolètes.
  • Correction : Automatisez des tests smoke post-restore ; gérez rôles/extensions via gestion de configuration ; imposez des configs immuables pour les cibles de restauration.

5) Symptom: PITR fails halfway through with missing WAL/binlog

  • Cause racine : rétention trop courte, archivage non surveillé, ou un gap créé lors d’un incident précédent.
  • Correction : Surveillez la continuité d’archive ; alertez sur les segments manquants ; définissez la rétention pour correspondre à la fenêtre de récupération promise ; pratiquez des restaurations pour en prouver la validité.

6) Symptom: restores are fast in tests, slow in real incidents

  • Cause racine : Les tests s’exécutent sur des hôtes vides et un stockage calme ; les incidents arrivent sous contention et modes dégradés.
  • Correction : Testez les restaurations sous charge et avec une contention I/O réaliste ; réservez de la capacité de restauration ; gardez des « recovery nodes » dimensionnés et chauds.

Checklists / plan étape par étape

Étape par étape : atteindre un RTO sous 15 minutes (le chemin pratique)

  1. Choisissez votre stratégie de récupération selon la taille du dataset. Si votre répertoire de données est assez grand pour que sa copie prenne plus de 10 minutes, arrêtez de prétendre. Utilisez promotion de réplica ou snapshots.
  2. Standardisez sur des sauvegardes physiques pour les deux moteurs. MariaDB : Mariabackup. PostgreSQL : pgBackRest (ou un équivalent physique). Les dumps deviennent secondaires.
  3. Stagez la sauvegarde de base la plus récente localement. Votre nœud de restauration ne devrait pas télécharger des centaines de gigas via un réseau best-effort pendant un incident.
  4. Gardez les backups « prêts à restaurer ». Pour MariaDB, cela signifie backups préparés. Pour PostgreSQL, cela signifie manifestes/checksums vérifiés et une archive qui contient réellement ce dont vous avez besoin.
  5. Ingéniez le PITR comme un système de première classe. L’archivage WAL/binlog doit être surveillé, retenu et testé. Traitez les gaps comme un Sev-2, pas comme un « on verra plus tard ».
  6. Provisionnez des nœuds de récupération pour la charge de restauration. La restauration est bursty : I/O élevé, CPU élevé (décompression), beaucoup d’opérations métadonnées. Dimensionnez pour ça, pas pour le QPS moyen.
  7. Séparez les volumes données et logs quand c’est utile. PostgreSQL : gardez le WAL sur du stockage rapide. MariaDB : les fichiers de log et les données bénéficient d’une faible latence ; la séparation peut réduire la contention.
  8. Rédigez un runbook d’une page avec un arbre de décision. « Si l’archive WAL est lente, promouvoir le réplica. » Rendez-le exécutable à 3h du matin.
  9. Automatisez la bascule de service. Mises à jour DNS/VIP, chaînes de connexion, reload des poolers. Votre RTO meurt dans les étapes glue.
  10. Répétez mensuellement avec un chronomètre. Mesurez les trois temps : restore de base, recovery jusqu’à consistance, app healthy. Corrigez d’abord le plus gros goulot.

Tactiques de configuration qui aident généralement (et quand être prudent)

Ce ne sont pas des boutons universels « rendre plus rapide ». Ce sont des leviers. Tirez-les avec intention, idéalement seulement sur des nœuds de recovery ou pendant des fenêtres de récupération.

  • PostgreSQL : Assurez-vous que la récupération d’archive WAL est rapide (cache local) ; ajustez les checkpoints pour votre workload ; évitez un max_wal_size trop petit sur des systèmes à forte écriture ; dimensionnez shared_buffers de façon sensée (trop grand peut ralentir le redémarrage à cause d’un plus grand comportement de buffers dirty).
  • MariaDB : Gardez les backups préparés ; évitez des réglages de flush pathologiques qui créent un crash recovery énorme ; assurez une stratégie de warm-up du buffer pool si vous en dépendez ; envisagez de retarder une partie de la durabilité uniquement si votre posture de risque le permet.

FAQ

1) Lequel restaure plus vite : MariaDB ou PostgreSQL ?

Aucun ne « gagne » universellement. La restauration physique + replay WAL de PostgreSQL est extrêmement prévisible quand l’archive WAL est saine et locale. La restauration physique de MariaDB peut être très rapide, mais le comportement de recovery InnoDB et l’application des binlogs peuvent vous surprendre. Votre stockage et votre stratégie PITR décident du gagnant plus que la marque du moteur.

2) Puis-je atteindre 15 minutes de RTO avec mysqldump ou pg_dump ?

Seulement pour de petits jeux de données et des schémas simples. Dès que les index et contraintes deviennent significatifs, le temps de restauration logique explose. Pour un RTO strict, utilisez des sauvegardes physiques, des snapshots ou la promotion de réplica.

3) Quel est le facteur unique le plus important dans le temps de restauration ?

Pour les restaurations physiques : la latence du stockage (I/O fsync-heavy) et le débit de replay des logs (WAL/redo). Pour le PITR : la vitesse de récupération d’archive et sa continuité.

4) Comment les snapshots se comparent aux sauvegardes physiques ?

Les snapshots (EBS/ZFS/LVM) peuvent être la « restauration » la plus rapide si elles sont crash-consistentes et que votre base les tolère (généralement avec recovery). Elles sont aussi faciles à mal utiliser : snapshotter le mauvais ensemble de volumes, ou oublier qu’il faut des snapshots cohérents entre données et volumes WAL.

5) WAL/binlog devraient-ils être sur des disques séparés ?

Souvent oui, quand cela réduit la contention et donne aux logs une latence plus faible. Mais des disques séparés ne corrigent pas des disques lents. Un NVMe rapide peut battre deux volumes réseau médiocres tous les jours de la semaine.

6) La compression aide-t-elle la vitesse de restauration ?

Elle aide le temps de transfert et l’empreinte de stockage, mais peut nuire au temps de restauration si le CPU est le goulot ou si c’est mono-thread. Une compression modérée avec parallélisme est habituellement le compromis idéal pour des systèmes focalisés RTO.

7) Comment prouver que mon RTO est réel ?

Chronométrez une répétition complète : provision → restore → recovery/PITR → checks de santé applicative → cutover. Faites-le sous une charge réaliste et avec les mêmes personnes qui seront on-call.

8) Que dois-je surveiller pour protéger la vitesse de restauration ?

La continuité d’archive WAL/binlog, le succès et la validation des backups, le lag de réplication, la latence stockage, l’espace disque libre (incluant croissance WAL), et le « temps de répétition de restauration » comme SLO de première classe.

9) Si je peux promouvoir un réplica, ai-je encore besoin de sauvegardes ?

Oui. Les replicas protègent contre certains incidents (mort d’un nœud). Les sauvegardes protègent contre d’autres échecs (erreur opérateur, corruption de données, déploiements foireux, ransomware). Le RTO vient des replicas ; la récupération depuis de mauvaises données vient des backups.

Prochaines étapes que vous pouvez faire cette semaine

  • Chronométrez une restauration pour MariaDB et PostgreSQL dans un environnement de staging, de bout en bout, avec un chronomètre. Notez où le temps passe : copie, prepare, replay WAL/binlog, disponibilité applicative.
  • Exécutez les tests de latence stockage (fio random write) sur vos nœuds de recovery réels. Si la latence est mauvaise, votre objectif RTO est de la fiction tant que le stockage n’a pas changé.
  • Validez les entrées PITR : vérifiez la plage d’archive WAL (PostgreSQL) ou la rétention des binlogs (MariaDB). Mettez des alertes sur les gaps.
  • Transformez votre runbook en arbre de décision : « restaurer depuis backup » vs « promouvoir réplica » vs « rollback snapshot ». Rendez explicites les compromis.
  • Planifiez une répétition mensuelle de restauration et traitez les échecs comme des incidents de production. Si vous ne pouvez pas restaurer un mardi, vous ne restaurerez pas un dimanche.

Un RTO < 15 minutes n’est pas un exercice de tuning. C’est un choix de culture opérationnelle : sauvegardes physiques, artefacts stageés, stockage rapide et répétitions qui font du chemin ennuyeux la voie par défaut. Faites cela, et les restaurations deviennent une procédure. Sinon, elles deviennent une histoire.

← Précédent
Vulkan : apprécié pour la vitesse, détesté pour la complexité
Suivant →
Pics de latence ZFS : la checklist pour identifier la cause

Laisser un commentaire