Sauvegardes MariaDB vs SQLite : restauration simple vs PITR réel

Cet article vous a aidé ?

La façon la plus rapide de ruiner un mardi tranquille est de découvrir que votre « sauvegarde » n’est en réalité qu’un fichier copié une fois,
depuis un processus qui écrivait activement dedans, et que personne n’a jamais pratiqué la restauration. La deuxième façon la plus rapide
est de réaliser que vous avez besoin d’une récupération point-in-time (PITR) mais que vous n’avez jamais conservé les logs qui la rendent possible.

SQLite et MariaDB se situent aux extrémités opposées du spectre opérationnel. SQLite est un fichier. MariaDB est un serveur avec
des pièces mobiles, un journal d’écriture préalable, de la réplication et la possibilité de rembobiner le temps — si vous le configurez.
Ceci est un guide pratique sur des sauvegardes qui restaurent vraiment, pas des sauvegardes qui rassurent.

Ce que vous achetez vraiment : « restauration » vs « PITR »

« Sauvegarde » est un terme surchargé. Dans la plupart des organisations ça signifie « on a des octets ailleurs ». En production, ça veut dire :
nous pouvons restaurer le service et les données à un point acceptable, dans un délai acceptable, avec un risque prévisible.
Ce sont le RPO (combien de données vous pouvez perdre) et le RTO (combien de temps vous pouvez être indisponible) sans détour.

La superpuissance de SQLite est la simplicité : une base de données unique est un fichier. Si vous pouvez faire une copie cohérente et stocker des versions,
vous pouvez restaurer rapidement. Mais le PITR n’est pas une expérience native de première classe. Vous pouvez l’approcher avec des snapshots fréquents,
l’archivage WAL, ou un journal applicatif, mais ce n’est pas la même chose que rejouer un journal de transactions jusqu’à une seconde précise.

La superpuissance de MariaDB est précisément ce journal de transactions : les binlogs. Si vous conservez une base cohérente et
retenez les binlogs, vous pouvez restaurer « juste avant qu’on ait drop la table », ou « juste avant le déploiement fautif », dans la
résolution des événements et des positions de log. C’est plus de travail opérationnel, plus d’espace disque, plus de modes de défaillance,
et une bien meilleure réponse quand le métier demande : « Peut-on récupérer ce qu’on avait à 10:41 ? »

Restauration simple (suffisante quand…)

  • Vous pouvez tolérer de perdre les dernières N heures d’écritures (RPO en heures, pas en minutes).
  • Les écritures sont de faible volume et la base n’est pas le système de référence.
  • Le coût d’implémentation et d’exploitation du PITR dépasse le coût d’une perte occasionnelle.
  • Votre menace principale est une défaillance d’infrastructure, pas une erreur utilisateur ou un mauvais déploiement.

PITR réel (non négociable quand…)

  • Suppressions accidentelles, migrations fautives ou bugs applicatifs sont des menaces réalistes (et elles le sont).
  • Vous devez pouvoir récupérer « à une heure précise », pas seulement « à un jour ».
  • Vous avez besoin d’une récupération de niveau audit : explicable, reproductible et testable.
  • Données réglementées ou SLAs contractuels rendent « on a perdu une demi-journée » inacceptable.

Une vérité sèche : les sauvegardes sont une fonctionnalité de fiabilité. Traitez-les comme toute autre fonctionnalité de production — concevez, exploitez, testez et
mesurez. La « fonctionnalité » n’est pas le job de sauvegarde ; c’est le résultat de la restauration.

Idée paraphrasée de Werner Vogels (fiabilité/ops) : « Tout échoue, tout le temps ; concevez en supposant la défaillance. »
Vos sauvegardes sont le moment où vous admettez qu’il a raison.

Faits intéressants & contexte historique (pourquoi les paramètres par défaut paraissent bizarres)

  1. SQLite a été conçu en 2000 par D. Richard Hipp pour un usage embarqué — petit, portable, sans administration.
    Ce n’est pas « un petit MySQL ». C’est une bibliothèque avec un format de fichier.
  2. Le modèle single-writer de SQLite (avec plusieurs lecteurs) est un choix délibéré pour garder le verrouillage simple.
    Le mode WAL améliore la concurrence, mais il ne transforme pas SQLite en serveur.
  3. Le concept de « hot backup » de SQLite existe parce que copier un fichier de base actif peut être incohérent.
    Le chemin sûr de sauvegarde est une API et une fonctionnalité CLI de première classe.
  4. MariaDB a été fork de MySQL après l’acquisition de Sun par Oracle en 2010 ; beaucoup de comportements opérationnels (binlogs, InnoDB)
    restent compatibles en esprit, même si les fonctionnalités divergent.
  5. Les binlogs MySQL/MariaDB ont été conçus pour la réplication et sont devenus le pilier du PITR dans de nombreuses équipes.
    Le PITR est une heureuse conséquence du besoin « d’expédier les changements ailleurs ».
  6. La récupération de crash InnoDB (redo logs) n’est pas la même chose que le PITR. Les redo logs vous aident à retrouver un état cohérent après un crash,
    pas à revenir à un point précis avant une mauvaise requête.
  7. Les dumps logiques (mysqldump) étaient autrefois la méthode par défaut car ils sont portables et simples, mais ils sont lents à grande échelle,
    et les restaurations sont souvent plus lentes.
  8. Percona XtraBackup a popularisé les « hot physical backups » pour InnoDB en copiant des pages et en appliquant les logs ; MariaDB a son propre écosystème
    d’outils et des couches de compatibilité, mais l’idée opérationnelle reste la même.

Sauvegardes SQLite : restaurations de fichiers bien faites

La stratégie de sauvegarde SQLite consiste surtout à ne pas se mentir à soi-même en se disant « je vais juste copier le fichier ».
Si le processus écrit pendant que vous copiez, le fichier peut ne pas représenter un état valide et cohérent.
Parfois vous aurez de la chance. La production est l’endroit où la chance meurt.

Trois réalités SQLite à accepter tôt

  • Les sauvegardes sont cohérentes ou elles sont du théâtre. Une copie byte-identique prise au mauvais moment reste de la camelote.
  • WAL change l’histoire des sauvegardes. Si vous êtes en mode WAL, l’état de la DB est réparti entre le fichier principal et le fichier WAL.
    Sauvegarder l’un sans l’autre est le piège classique du « ça marche en staging ».
  • Le PITR n’est pas une case à cocher. Vous pouvez l’approcher via des snapshots fréquents (filesystem/ZFS/LVM),
    l’archivage WAL ou des logs d’événements applicatifs. Mais si la question est « restituer à 10:41:17 », la vie est plus difficile.

À quoi ressemble une bonne sauvegarde SQLite

Pour la plupart des déploiements embarqués, « bon » signifie :

  • Utiliser le mode WAL si vous avez besoin de concurrence, mais sauvegarder correctement dans ce cas.
  • Utiliser le mécanisme de sauvegarde en ligne de SQLite (VACUUM INTO ou .backup) pour des copies cohérentes.
  • Versionner les sauvegardes (noms horodatés ou IDs de snapshot).
  • Exécuter des contrôles d’intégrité sur les copies restaurées, pas sur la DB live sous charge.

Options « PITR-like » pour SQLite (choisissez et soyez honnête sur les limites)

SQLite n’expédie pas de binlog que vous pouvez rejouer à volonté. Voici les approximations pratiques :

  • Snapshots fréquents des fichiers DB. Fonctionne bien avec ZFS/btrfs/LVM. La « résolution PITR » est la fréquence des snapshots.
  • Archiver les fichiers WAL. Cela peut fournir une granularité fine, mais il faut un schéma discipliné et une procédure de restauration soignée.
    Beaucoup d’équipes s’arrêtent là et ne peuvent quand même pas rejouer proprement parce qu’elles n’ont pas capturé les frontières de checkpoint ou ont mal géré la rotation des WAL.
  • Journal d’événements au niveau applicatif. Si la DB est un cache ou un magasin local, peut-être pouvez-vous reconstruire depuis des événements en amont.
    Ce n’est pas du PITR ; c’est de la reconstruction. Ça peut être mieux — si l’amont est fiable.

Blague #1 : les sauvegardes SQLite ressemblent à des plantes d’intérieur — on les ignore pendant un mois, et soudain on Google « pourquoi c’est brun » à 2h du matin.

Sauvegardes MariaDB : base, incrémentale et PITR via binlogs

La conception des sauvegardes MariaDB est un système en trois parties : une sauvegarde de base cohérente, la conservation des binlogs,
et une procédure de restauration répétée. Sautez l’une de ces étapes et votre « PITR » n’est qu’une présentation PowerPoint.

Sauvegardes de base : logique vs physique

Internet adore les débats là-dessus. En production, vous choisissez selon la taille du jeu de données, le temps de restauration et les contraintes opérationnelles.

  • Sauvegarde logique (mariadb-dump / mysqldump) : Portable et simple. Plus lente, plus volumineuse, et les restaurations sont souvent douloureusement lentes.
    Utile pour petits jeux de données, migrations de schéma, ou quand vous avez besoin d’un format lisible par l’humain.
  • Sauvegarde physique (mariabackup / style xtrabackup) : Plus rapide pour les gros jeux de données, et les restaurations peuvent être beaucoup plus rapides.
    Nécessite compatibilité moteur/structure de fichiers et une manipulation plus attentive, mais c’est l’option sérieuse pour de gros volumes.

Binlogs : la différence entre « restaurer » et « rembobiner »

Les binlogs enregistrent les changements. Si vous les conservez, vous pouvez rejouer à partir d’une sauvegarde de base jusqu’à un moment choisi.
Si vous ne les conservez pas, vous ne pouvez pas. Il n’y a pas de pirouette, seulement des négociations.

Le PITR avec MariaDB ressemble typiquement à :

  1. Restaurer la base sur un nouveau serveur ou une instance isolée.
  2. Appliquer les binlogs jusqu’à un temps d’arrêt (ou une position) juste avant le sinistre.
  3. Valider la cohérence des données et le comportement applicatif.
  4. Basculez le trafic ou exportez les données corrigées vers la production.

La réplication n’est pas une sauvegarde (mais peut faire partie du plan)

La réplication reproduit les erreurs à la vitesse de la lumière. C’est son rôle. Un réplica peut aider si :

  • C’est une réplication retardée (lag intentionnel) et vous détectez l’incident avant que la fenêtre de retard ne se referme.
  • Vous pouvez arrêter rapidement le thread SQL et le traiter comme une « capsule temporelle ».
  • Vous avez encore des binlogs pour rejouer ou construire un clone propre.

Blague #2 : la réplication n’est pas une sauvegarde — c’est un chat de groupe où tout le monde répète immédiatement la mauvaise réponse.

La réalité du « PITR réel » (et ce que ça coûte)

Le PITR n’est pas « activer les binlogs ». C’est un contrat opérationnel :

  • Rétention : suffisamment de binlogs pour couvrir votre fenêtre de récupération (plus de marge).
  • Cadence des sauvegardes de base : assez fréquente pour que le temps de replay soit acceptable.
  • Synchronisation temporelle : horloges système cohérentes, fuseaux connus, et interprétation soignée des timestamps.
  • Pratique de restauration : mensuelle ou trimestrielle au minimum, avec timings et notes d’échec documentés.

Le coût caché le plus important est humain : la première fois que vous faites un replay de binlogs sous pression, vous découvrirez quelles hypothèses
étaient fausses. Si vous avez de la chance, vous les découvrez lors d’un exercice.

Tâches pratiques : commandes, sorties et décisions (12+)

Voici les tâches que j’exécute réellement (ou que je demande d’exécuter) pour évaluer la posture de sauvegarde ou exécuter une restauration.
Chacune contient : commande, sortie d’exemple, ce que ça signifie, et la décision à prendre.

Task 1 — SQLite : déterminer le journal mode (WAL change tout)

cr0x@server:~$ sqlite3 /var/lib/app/app.db 'PRAGMA journal_mode;'
wal

Sens : Le mode WAL est activé. Les écritures vont dans app.db-wal et les checkpoints fusionnent ces écritures dans le fichier principal.

Décision : Vous devez utiliser une méthode de hot-backup ou snapshotter à la fois l’état DB et WAL en toute sécurité. « cp app.db » n’est pas acceptable.

Task 2 — SQLite : faire une sauvegarde en ligne cohérente avec .backup

cr0x@server:~$ sqlite3 /var/lib/app/app.db ".backup '/backups/app.db.2025-12-30T0200Z'"

Sens : SQLite utilise l’API de backup pour produire une copie cohérente même si la DB est en usage.

Décision : Préférez ceci à une copie filesystem quand vous pouvez supporter l’I/O. Si c’est trop lent, passez aux snapshots.

Task 3 — SQLite : utiliser VACUUM INTO pour une sauvegarde compacte et cohérente

cr0x@server:~$ sqlite3 /var/lib/app/app.db "VACUUM INTO '/backups/app.compact.db';"

Sens : Produit un nouveau fichier de base de données, défragmenté et cohérent. Souvent plus petit, parfois beaucoup plus petit.

Décision : Utiliser pour des sauvegardes nocturnes quand la taille compte. Éviter en période de forte charge : c’est I/O intense.

Task 4 — SQLite : vérifier l’intégrité d’une copie restaurée (pas la DB live)

cr0x@server:~$ sqlite3 /backups/app.db.2025-12-30T0200Z "PRAGMA integrity_check;"
ok

Sens : Les vérifications internes de cohérence sont passées.

Décision : Traitez cela comme une porte d’entrée. Si ce n’est pas « ok », votre pipeline de sauvegarde est cassé jusqu’à preuve du contraire.

Task 5 — SQLite : vérifier la présence et la taille des WAL (indicateur de risque)

cr0x@server:~$ ls -lh /var/lib/app/app.db*
-rw-r----- 1 app app 1.2G Dec 30 01:59 /var/lib/app/app.db
-rw-r----- 1 app app 512M Dec 30 02:00 /var/lib/app/app.db-wal
-rw-r----- 1 app app  32K Dec 30 01:58 /var/lib/app/app.db-shm

Sens : Le WAL est volumineux. Un checkpoint peut être en retard ; les copies qui ignorent le WAL manqueront des transactions récentes.

Décision : Inspecter le checkpointing et la méthode de sauvegarde. Envisager de forcer un checkpoint dans une fenêtre contrôlée ou d’ajuster les paramètres WAL.

Task 6 — MariaDB : confirmer que le binlogging est activé

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

Sens : Le serveur génère des binlogs.

Décision : Si OFF, arrêtez de prétendre que vous avez du PITR. Activez-le, prévoyez un redémarrage si nécessaire, et définissez la rétention immédiatement.

Task 7 — MariaDB : vérifier le format des binlogs (row-based recommandé)

cr0x@server:~$ mariadb -e "SHOW VARIABLES LIKE 'binlog_format';"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+

Sens : Le logging en mode row enregistre les changements de ligne, généralement le plus sûr pour le PITR et la cohérence de réplication.

Décision : Préférez ROW pour le PITR. Si vous êtes en STATEMENT, préparez-vous à des non-déterminismes avec fonctions et triggers.

Task 8 — MariaDB : confirmer les paramètres de rétention des binlogs

cr0x@server:~$ mariadb -e "SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';"
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| binlog_expire_logs_seconds | 604800 |
+--------------------------+--------+

Sens : Les binlogs expirent après 7 jours (604800 secondes).

Décision : Faites correspondre la rétention à votre fenêtre de récupération requise plus le temps de détection. Si les incidents prennent deux semaines à être détectés, 7 jours, c’est du fantasme.

Task 9 — MariaDB : lister les binlogs disponibles (avez-vous de l’historique ?)

cr0x@server:~$ mariadb -e "SHOW BINARY LOGS;"
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mariadb-bin.000231 | 104857600 |
| mariadb-bin.000232 | 104857600 |
| mariadb-bin.000233 |  52428800 |
+------------------+-----------+

Sens : Des fichiers binlog existent et leurs tailles semblent plausibles.

Décision : Si la liste est courte ou vide, la plage PITR est courte ou inexistante. Corrigez la rétention et la stratégie d’archivage.

Task 10 — MariaDB : prendre une sauvegarde de base logique (petits jeux de données / portabilité)

cr0x@server:~$ mariadb-dump --single-transaction --routines --triggers --events --all-databases > /backups/mariadb.full.sql

Sens : Snapshot cohérent pour InnoDB via --single-transaction. Inclut routines/events/triggers.

Décision : Utiliser si le dataset est modeste et que le temps de restauration est acceptable. Si la restauration prend des heures et que votre RTO est en minutes, passez aux sauvegardes physiques.

Task 11 — MariaDB : prendre une sauvegarde physique avec mariabackup

cr0x@server:~$ mariabackup --backup --target-dir=/backups/mariadb/base --user=backup --password='REDACTED'
[00] 2025-12-30 02:05:12 completed OK!

Sens : Les fichiers ont été copiés avec les métadonnées nécessaires pour appliquer les logs.

Décision : Si cela échoue de façon intermittente, suspectez les permissions, la saturation I/O, ou un espace temporaire insuffisant. Corrigez ça avant de promettre du PITR.

Task 12 — MariaDB : préparer (appliquer les logs) avant restauration

cr0x@server:~$ mariabackup --prepare --target-dir=/backups/mariadb/base
[00] 2025-12-30 02:08:44 InnoDB: Shutdown completed; log sequence number 987654321

Sens : La sauvegarde est rendue cohérente ; les redo ont été appliqués.

Décision : Une sauvegarde non préparée n’est pas prête à être restaurée. Faites du « prepare réussi » une étape du pipeline.

Task 13 — MariaDB : capturer les coordonnées binlog au moment de la sauvegarde

cr0x@server:~$ mariadb -e "SHOW MASTER STATUS\G"
*************************** 1. row ***************************
             File: mariadb-bin.000233
         Position: 184467
     Binlog_Do_DB:
 Binlog_Ignore_DB:

Sens : Voici le fichier et la position binlog représentant le point cohérent avec votre snapshot (pour beaucoup de méthodes de backup).

Décision : Stockez ceci avec les métadonnées de la sauvegarde de base. Sans coordonnées, le replay de binlog devient de l’archéologie.

Task 14 — MariaDB : inspection à blanc des binlogs autour d’un temps d’incident

cr0x@server:~$ mysqlbinlog --start-datetime="2025-12-30 10:35:00" --stop-datetime="2025-12-30 10:45:00" /var/lib/mysql/mariadb-bin.000233 | head
# at 184467
#251230 10:36:01 server id 1  end_log_pos 184742 CRC32 0x9a3c1f2e  GTID 0-1-12345  trans
BEGIN
# at 184742
#251230 10:36:01 server id 1  end_log_pos 185120 CRC32 0x0e1d2b44  Table_map: `prod`.`orders` mapped to number 241

Sens : Vous pouvez voir les bornes de transaction et le timing des événements.

Décision : Identifiez la fenêtre de la transaction « mauvaise ». Décidez si vous stopperez par datetime ou par position/GTID pour la précision.

Task 15 — MariaDB : rejouer les binlogs jusqu’à un temps d’arrêt (exécution PITR)

cr0x@server:~$ mysqlbinlog --stop-datetime="2025-12-30 10:41:00" /backups/binlogs/mariadb-bin.000233 /backups/binlogs/mariadb-bin.000234 | mariadb

Sens : Rejoue les changements dans l’instance restaurée jusqu’au stop time.

Décision : Si vous voyez des erreurs, arrêtez. Décidez si vous appliquez sur la bonne base restaurée, et si les GTID ou server IDs ne sont pas en discordance.

Task 16 — MariaDB : vérifier le mode réplication/GTID avant de s’appuyer sur la récupération GTID

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

Sens : La stricte gestion GTID est activée ; le positionnement basé GTID est probablement fiable.

Décision : Si les GTID sont incohérents entre environnements, préférez fichier+position et gardez l’environnement de restauration isolé.

Task 17 — Sanity : mesurer le débit de restauration et décider si la cadence des backups doit changer

cr0x@server:~$ /usr/bin/time -f "elapsed=%E cpu=%P" mariadb < /backups/mariadb.full.sql
elapsed=01:42:18 cpu=86%

Sens : La restauration logique a pris ~1h42m sur ce matériel.

Décision : Si votre RTO est 30 minutes, il vous faut des restaurations physiques, des jeux de données plus petits par instance, ou une autre architecture. Ne négociez pas avec la physique.

Feuille de diagnostic rapide (trouver le goulot vite)

Quand les sauvegardes ou restaurations sont lentes ou échouent, ne devinez pas. Vérifiez d’abord les contraintes ennuyeuses. Elles sont généralement coupables.

Premièrement : stockage et saturation I/O

  • Vérifier l’espace disque (cibles de sauvegarde et source). Les erreurs de disque plein provoquent souvent de la « corruption » plus tard.
  • Vérifier l’attente I/O. Un « outil de backup lent » est souvent un volume saturé.
  • Vérifier les pics de latence filesystem. Les snapshot ou jobs de compaction peuvent ruiner les fenêtres de sauvegarde.

Deuxièmement : mécanismes de cohérence

  • SQLite : Sauvegardez-vous via l’API ou copiez-vous aveuglément des fichiers ? Capturez-vous correctement l’état WAL/shm ?
  • MariaDB : Utilisez-vous --single-transaction pour les backups logiques ? La sauvegarde physique est-elle préparée ?
  • Binlogs : Avez-vous les bonnes coordonnées binlog ? Les fichiers binlog nécessaires sont-ils encore retenus ?

Troisièmement : plomberie opérationnelle

  • Permissions et profils SELinux/AppArmor.
  • Confusion d’horloge/fuseau (stop-datetime appliqué dans le mauvais timezone est classique).
  • Goulots réseau vers le stockage objet ou cibles NFS.
  • Saturation CPU due à la compression (surtout quand vous « l’avez optimisée »).

Trois mini-récits d’entreprise depuis les tranchées des sauvegardes

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

Une entreprise moyenne exécutait un produit support client qui stockait l’état des files dans SQLite sur chaque nœud applicatif.
Ce n’était pas le système de référence — jusqu’à ce que ça le devienne discrètement. Une nouvelle fonctionnalité a commencé à écrire les « résultats finaux »
localement pour accélérer le rendu. Personne n’a mis à jour la classification des données. Ça arrive.

Les sauvegardes étaient un cron : cp app.db /mnt/backups/app.db. Ça avait l’air de marcher. Les restaurations fonctionnaient en sandbox,
parce que la charge en sandbox était légère et les checkpoints fréquents.

Puis un incident : un nœud a redémarré en heures de pointe. Après le redémarrage, l’app plantait en lisant certaines lignes.
L’équipe a essayé de restaurer depuis le fichier copié. Même plantage. Ils ont essayé des copies plus anciennes. Certaines fonctionnaient, d’autres non.
Les sauvegardes étaient une roulette russe.

La cause racine était simple : le mode WAL avait été activé des mois plus tôt pour réduire le blocage des writers, mais la « sauvegarde » ne copiait que le fichier principal.
Parfois le WAL contenait des transactions critiques non checkpointées. Le fichier copié seul était incohérent avec les attentes de l’application.

La correction fut tout aussi simple, et légèrement humiliante : remplacer cp par l’API de backup de SQLite, et ajouter une étape de vérification d’intégrité sur l’artefact.
Ils ont aussi documenté que le WAL existe et n’est pas optionnel. L’incident parlait moins de SQLite que de la supposition erronée qu’une copie de fichier équivaut à une sauvegarde de base.

Mini-récit 2 : l’optimisation qui s’est retournée contre eux

Une autre organisation utilisait MariaDB pour une plateforme métier. Les sauvegardes physiques étaient solides, mais la fenêtre de backup a commencé à empiéter sur les heures critiques.
Quelqu’un a eu l’idée lumineuse de compresser plus fortement pour réduire les coûts de stockage et accélérer les uploads vers le stockage distant.

La compression a réduit les octets sur disque. Elle a aussi saturé le CPU pendant des heures et augmenté l’attente I/O parce que le pipeline n’était plus « vitesse de copie » mais « vitesse CPU ».
Le serveur DB a commencé à montrer des pics de latence pendant les backups, et l’équipe applicative s’est plainte que « MariaDB est lent à nouveau ».

Ils ont répondu en réduisant la pression du buffer pool InnoDB et en ajustant les caches de requêtes (oui, vraiment). La latence s’est empirée.
Le vrai problème était que le processus de backup concurrençait le trafic de production pour les cycles CPU et le cache.

Le revers est arrivé pendant un exercice de restauration. La décompression est devenue le goulot. Les gains théoriques de bande passante n’avaient aucune importance
parce que le RTO était dominé par le temps CPU nécessaire pour décompresser. La restauration a manqué l’objectif interne de beaucoup.

Le postmortem fut peu glorieux : utiliser une compression plus légère ou aucune pour le chemin de restauration « hot », garder la compression lourde pour les archives froides,
et exécuter les backups sur un replica ou un hôte dédié si possible. Le stockage est moins cher que le downtime ; de plus, votre DAF ne prend pas les pages à 3h du matin.

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

Une équipe de services financiers utilisait MariaDB avec des contrôles de changement stricts. Ils faisaient une chose qui paraissait presque désuète :
chaque mois, ils effectuaient un drill complet de restauration dans un environnement isolé, puis exécutaient une suite de requêtes connues pour valider les totaux métier.
Ce n’était pas amusant. C’était planifié. C’était documenté. Les gens râlaient.

Un vendredi, un ingénieur a exécuté une migration de schéma incluant un script de nettoyage de données. Le script avait un bug : il a matché plus de lignes que prévu.
La production a commencé à perdre des enregistrements « valables ». Le monitoring n’a pas immédiatement alerté car le QPS et les taux d’erreur étaient normaux. Les données étaient juste… fausses.

Ils ont détecté le problème via une détection d’anomalies applicative et ont stoppé l’hémorragie rapidement. Maintenant la question :
« Peut-on restaurer juste avant la migration ? » C’est là que les équipes découvrent si le PITR est réel.

Ils ont restauré la dernière sauvegarde physique sur une instance fraîche, appliqué les binlogs jusqu’à quelques minutes avant la migration en utilisant un stop-datetime,
vérifié les totaux via les mêmes requêtes du drill mensuel, et basculé. Tout le processus avait été pratiqué ; personne n’apprenait mysqlbinlog sous pression.

Le drill mensuel ennuyeux n’a pas seulement sauvé des données. Il a sauvé du temps de décision. Tout le monde faisait déjà confiance au runbook, aux timings et aux checks de validation.
C’est à ça que ressemble la « maturité opérationnelle » quand ce n’est pas une diapositive.

Erreurs courantes : symptômes → cause racine → correctif

1) « La restauration SQLite fonctionne parfois, parfois elle corrompt »

Symptômes : Le fichier restauré s’ouvre de façon intermittente ; changements récents manquants ; « database disk image is malformed ».

Cause racine : Sauvegarde en copiant le fichier principal pendant que la DB est en mode WAL ou en écriture active ; on ignore -wal et -shm.

Correctif : Utiliser .backup ou VACUUM INTO. Si vous utilisez des snapshots FS, snapshotter atomiquement et inclure l’état WAL ; exécuter des checks d’intégrité sur les artefacts.

2) « PITR MariaDB échoué : fichier binlog manquant »

Symptômes : Erreurs mysqlbinlog : impossible d’ouvrir le binlog ; trous dans la séquence ; restauration interrompue.

Cause racine : Rétention des binlogs trop courte ; rotation/nettoyage mal configurés ; binlogs stockés seulement localement et perdus avec le serveur.

Correctif : Augmenter binlog_expire_logs_seconds pour couvrir la fenêtre détection+récupération ; archiver les binlogs sur un stockage durable ; alerter sur les séquences manquantes.

3) « La sauvegarde logique a réussi, mais la restauration est incohérente »

Symptômes : Erreurs de clés étrangères ; données partielles ; tables manquantes de lignes « qui devraient être là ».

Cause racine : Dump fait sans --single-transaction sur InnoDB ; écritures concurrentes ont produit un snapshot non-atomique.

Correctif : Utiliser --single-transaction et éviter de dumper des tables non transactionnelles sans plan ; envisager des backups physiques pour des moteurs mixtes.

4) « Le PITR restaure au mauvais moment »

Symptômes : Les données incluent des changements qui auraient dû être exclus ; changements manquants qui auraient dû être présents.

Cause racine : Confusion de fuseau horaire ; dérive d’horloge serveur ; stop-datetime interprété différemment que prévu ; ignorance des transitions DST.

Correctif : Utiliser UTC pour serveurs et runbooks ; enregistrer les temps d’incident en UTC ; envisager d’arrêter par position/GTID quand la précision importe.

5) « Les sauvegardes réussissent, mais les restaurations sont trop lentes pour le RTO »

Symptômes : Restauration prend des heures ; la décompression domine le temps ; l’équipe app parle de « perte de données acceptable » pendant l’incident.

Cause racine : Stratégie optimisée pour le coût de stockage, pas pour le temps de restauration ; restorations logiques utilisées à grande échelle ; environnement de restauration sous-dimensionné.

Correctif : Mesurer les restaurations, puis redessiner : backups physiques, hôtes de restauration plus rapides, parallélisme, ou sharding. Garder les backups hot dans un format adapté à la restauration.

6) « Les sauvegardes provoquent des pics de latence en production »

Symptômes : Latence des requêtes augmentée pendant les fenêtres de sauvegarde ; CPU saturé ; attente I/O élevée.

Cause racine : Processus de sauvegarde qui concurrence I/O/CPU ; compression lourde sur le primaire ; snapshots déclenchant du copy-on-write intense.

Correctif : Exécuter les sauvegardes sur des replicas ; limiter CPU/I/O pour les jobs de backup ; déplacer les jobs de compaction hors des pics ; tester les caractéristiques de performance des snapshots.

Listes de contrôle / plan pas à pas

Checklist décisionnelle : choisir restauration SQLite « simple » vs PITR MariaDB « réel »

  • Les données sont-elles autoritatives ? Si oui, favorisez MariaDB (ou une autre base serveur) avec PITR.
  • Faut-il annuler une erreur utilisateur ? Si oui, vous voulez du PITR. Les snapshots seuls sont généralement trop grossiers.
  • À quelle vitesse faut-il restaurer ? Si en minutes, évitez les chemins de restauration logique lents.
  • Pouvez-vous exécuter et surveiller une base serveur ? Si non, SQLite avec des sauvegardes disciplinées et snapshots fréquents peut être plus honnête.

Étapes SQLite : une sauvegarde qui restaure vraiment

  1. Confirmer le journal mode et si le WAL est en présence.
  2. Utiliser .backup ou VACUUM INTO pour créer un artefact cohérent.
  3. Stocker les sauvegardes avec versioning (noms horodatés ou IDs de snapshot).
  4. Exécuter PRAGMA integrity_check; sur l’artefact.
  5. Pratiquer la restauration : remplacer le fichier DB, démarrer l’app, exécuter une requête de santé minimale.
  6. Décider de votre résolution « PITR-like » : snapshot horaire ? toutes les 5 minutes ? Soyez explicite.

Étapes MariaDB : base backup + binlogs pour le PITR

  1. Activer les binlogs et sélectionner le format ROW.
  2. Définir la rétention pour correspondre aux exigences métier ; archiver les binlogs hors hôte si l’hôte peut mourir.
  3. Prendre des sauvegardes périodiques de base (physiques pour gros volumes).
  4. Enregistrer les coordonnées binlog (fichier/position ou GTID) avec les métadonnées de la sauvegarde de base.
  5. Drill de restauration : restaurer la base dans une instance isolée, appliquer les binlogs jusqu’à un temps choisi, valider avec des requêtes, documenter les timings.
  6. Opérationnaliser : alertes pour trous de binlog, échecs de sauvegarde, échecs de test de restauration.

FAQ

1) SQLite peut-il faire un PITR « réel » ?

Pas au sens MariaDB. SQLite n’offre pas un journal de transactions de première classe que vous pouvez rejouer jusqu’à un point arbitraire.
Vous pouvez approcher avec des snapshots fréquents et une gestion soignée des WAL, mais appelez cela pour ce que c’est : une récupération basée sur snapshots.

2) Si j’utilise des snapshots filesystem, puis-je simplement snapshotter le fichier SQLite ?

Seulement si vous comprenez le journal mode. En mode WAL, il vous faut un snapshot crash-consistent de la DB plus l’état WAL.
Le défaut le plus sûr est d’utiliser l’API de backup de SQLite, à moins que les snapshots soient atomiquement coordonnés et testés.

3) La réplication MariaDB suffit-elle pour récupérer d’erreurs ?

Non. La réplication reproduit fidèlement les erreurs. Elle peut aider si vous avez une réplication retardée ou si vous arrêtez rapidement un réplica,
mais le PITR dépend toujours des binlogs et d’une sauvegarde de base.

4) Ai-je besoin de backups physiques pour faire du PITR sur MariaDB ?

Non. Il vous faut une sauvegarde de base cohérente plus les binlogs. La base peut être logique ou physique.
La physique est souvent la seule façon d’atteindre un RTO agressif à grande échelle.

5) Pourquoi ne pas juste lancer mysqldump chaque nuit et s’en tenir là ?

Les dumps nocturnes vous donnent un point de restauration quotidien. C’est acceptable si votre RPO est un jour et que la perte de données est tolérable.
Si vous devez « annuler ce qui s’est passé à 10:41 », il vous faut les binlogs et la discipline opérationnelle qui va avec.

6) Combien de temps garder les binlogs ?

Conservez-les pour au moins votre fenêtre de récupération requise plus la fenêtre de détection plus une marge.
Si vous détectez typiquement les problèmes en 72 heures mais parfois en 10 jours, dimensionnez pour 10 jours, pas pour votre meilleur cas.

7) Quelle est la façon la plus fiable de savoir que mes sauvegardes fonctionnent ?

Les restaurer. Régulièrement. Automatiquement si possible. Une sauvegarde sans test de restauration est un espoir, pas un contrôle.

8) Puis-je appliquer des binlogs directement en production pour « annuler » une erreur ?

Généralement : ne le faites pas. Faites le PITR dans une instance isolée, validez, puis basculez ou exportez sélectivement les données corrigées.
Manipuler la production directement pendant un incident est la façon la plus sûre de transformer une erreur en trilogie.

9) Pourquoi le replay de binlog échoue-t-il parfois avec des clés dupliquées ou des tables manquantes ?

Parce que votre sauvegarde de base ne correspond pas au flux binlog que vous rejouez (mauvaises coordonnées, mauvais serveur, mauvais dataset),
ou vous avez restauré une sauvegarde partielle. Considérez les métadonnées de backup comme faisant partie de la sauvegarde, pas comme du décor optionnel.

10) Que dois-je surveiller pour la santé des sauvegardes ?

Le succès des jobs de sauvegarde est le minimum. Surveillez : anomalies de taille des artefacts, résultats des checks d’intégrité, timings des drills de restauration,
couverture de rétention des binlogs, et l’espace libre sur les sources et cibles de stockage.

Conclusion : quoi faire la semaine prochaine

Si vous utilisez SQLite, arrêtez de copier le fichier comme s’il s’agissait d’un JPEG. Utilisez l’API de backup, vérifiez l’intégrité de l’artefact, et choisissez une cadence de snapshot que vous pouvez défendre.
Si vous avez besoin des sémantiques PITR réelles, admettez que SQLite n’est pas conçu pour ce travail et migrez le système de référence vers une base serveur — ou construisez un journal d’événements qui peut reconstruire la vérité.

Si vous utilisez MariaDB, rendez le PITR réel : assurez-vous que les binlogs sont activés, retenus et archivés ; prenez des sauvegardes de base cohérentes ; enregistrez les coordonnées ;
et répétez des drills de restauration. Faites un exercice de restauration ce mois-ci. Chronométrez-le. Notez ce qui vous a surpris. Puis corrigez ces surprises pendant que personne ne vous page.

← Précédent
Proxmox « Impossible de supprimer le nœud » : suppression sûre d’un nœud d’un cluster
Suivant →
HBM dans les GPU grand public : rêve ou inéluctable ?

Laisser un commentaire