Aller au contenu
Courrier Cabinet Choisir un forfait

Sauvegarde de site web : règle 3-2-1, outils et test de restauration

Sauvegarde de site web : règle 3-2-1, outils et test de restauration

Une sauvegarde complète d’un site, c’est un dump de la base de données plus une archive des fichiers, dossier uploads compris, réalisés de façon cohérente, stockés à au moins deux endroits dont un hors du serveur web, et vérifiés par une restauration de test. Sur notre banc d’essai, la plupart des erreurs classiques ont produit une sauvegarde créée sans le moindre avertissement : le problème n’apparaissait qu’au moment de la restauration. Au programme : la règle 3-2-1 en termes simples, un tableau « quoi sauvegarder, avec quoi, à quelle fréquence, comment vérifier », des mesures pour mysqldump, la compression et restic, puis un test de restauration pas à pas.

Comment nous avons testé

Le 10 novembre 2026 sur un banc d’essai : conteneur Ubuntu 24.04.5 (2 vCPU, 8 Go de RAM), nginx 1.24.0, PHP-FPM 8.3.6, deux instances distinctes de MariaDB 10.11.14, WordPress 6.4.3 avec 6 001 articles, 450 photos (330 Mo) et une table de logs de 1,5 million de lignes ; le dump de la base pesait 404 Mo. Nous avons réalisé des dumps pendant que des « commandes » étaient écrites en continu, comparé gzip, zstd et xz, fait des sauvegardes restic 0.16.4 vers un répertoire séparé jouant le rôle de stockage distant, simulé la perte du disque et restauré le site dans une instance MariaDB vierge. Il s’agit du comportement du serveur de test, pas de données des serveurs RichHost.

La règle 3-2-1 pour un site en hébergement mutualisé

La règle 3-2-1, c’est trois copies de vos données, sur deux supports ou systèmes différents, dont une copie ailleurs. Pour un site en hébergement mutualisé, cela donne ceci. Copie un : le site en ligne lui-même. Copie deux : la sauvegarde que fait votre hébergeur et qu’il conserve hors du serveur web. Copie trois : votre propre sauvegarde chez un autre prestataire, dans un stockage cloud ou sur votre ordinateur. Ce qui compte n’est pas le nombre de copies mais leur indépendance : si les trois se trouvent sur un même disque ou sont accessibles depuis un même compte, vous avez une seule copie, en trois exemplaires.

Deux conditions de plus font fonctionner la règle. Conservez plusieurs jours ou semaines de sauvegardes, pas seulement la dernière, car on remarque parfois tard un piratage ou une corruption. Et testez chaque configuration par au moins une restauration, sinon vous ne savez pas si vous avez vraiment une sauvegarde.

Quoi sauvegarder, avec quoi, à quelle fréquence, comment vérifier

Quoi Outil Fréquence Vérification
Base de données (articles, commandes, utilisateurs, réglages) mariadb-dump ou mysqldump avec --single-transaction, puis zstd Quotidienne ; plusieurs fois par jour pour une boutique Dernière ligne « Dump completed », zstd -t, import de test et nombre de lignes
Uploads : photos, PDF, fichiers clients tar + zstd -3 ou restic Quotidienne ou après chaque gros envoi Nombre de fichiers dans la sauvegarde, quelques images au hasard s’ouvrent après restauration
Code : cœur, thèmes, extensions tar + zstd, git pour votre propre thème Avant chaque mise à jour Le site restauré répond 200, la connexion à l’administration fonctionne
Configuration : wp-config.php, .htaccess, tâches cron Avec les fichiers ; tâches cron listées dans un fichier texte Après chaque modification Les fichiers sont dans l’archive, les tâches correspondent aux actuelles
Mail, enregistrements DNS Zone DNS exportée en fichier texte, mail via votre client de messagerie ou le panneau Mensuelle et après modification Comparer la zone avec celle en ligne grâce à dig

Les tables de logs, de statistiques et de cache des extensions pèsent souvent plus que tout le contenu. Sur le banc, la table de logs représentait environ 350 Mo du dump de 404 Mo. La nettoyer rend les sauvegardes plus légères et plus rapides ; voir notre guide sur l’optimisation de la base de données.

Base de données : pourquoi --single-transaction compte

Un script créait des « commandes » en continu : une ligne dans wp_posts et quatre lignes dans wp_postmeta dans une même transaction, environ 45 commandes par seconde. Deux secondes plus tard, un dump démarrait dans l’un des trois modes.

Mode de dump Commandes sans données dans la sauvegarde Plus longue attente en écriture
Sans verrous (--skip-lock-tables), 3 essais 3, 7 et 5 0,17 s
Par défaut (--lock-tables) 0 3,84 s : toutes les écritures ont attendu la fin du dump
--single-transaction --quick, 3 essais 0, 0 et 0 0,18 s

Sans verrous, le dump lit les tables l’une après l’autre : wp_postmeta avant wp_posts. Les commandes enregistrées entre ces deux lectures se sont retrouvées dans la sauvegarde sans montant, sans e-mail et sans moyen de paiement. Un tel dump s’importe sans erreur, et vous ne le découvrez que lorsqu’un client pose une question sur sa commande. Le mode par défaut garde la sauvegarde cohérente, mais bloque les écritures pendant toute la durée du dump : sur une base plus grosse, cela signifie des minutes pendant lesquelles la boutique ne peut pas prendre de commandes. --single-transaction prend un instantané InnoDB cohérent sans verrouiller. Cela ne protège pas les tables MyISAM : convertissez donc les anciennes en InnoDB.

mariadb-dump --single-transaction --quick --default-character-set=utf8mb4 wp > db.sql
tail -1 db.sql
-- Dump completed on 2026-11-10 14:51:46

Sans charge, les deux modes ont pris le même temps : 3,2-3,9 secondes pour 404 Mo. La différence n’apparaît que lorsque la base reçoit des écritures, c’est-à-dire, pour une boutique, pendant les heures d’activité.

Fichiers : quel compresseur choisir

Chaque compresseur a tourné sur un seul thread avec les mêmes données.

Compresseur Fichiers du site, 388 Mo Dump de la base, 404 Mo
gzip -6 16,6 s, 341,7 Mo (88 %) 9,2 s, 85,9 Mo (21 %)
zstd -3 1,5 s, 343,4 Mo (88 %) 1,9 s, 79,8 Mo (20 %)
zstd -19 149,4 s, 333,8 Mo (86 %) 350,1 s, 64,8 Mo (16 %)
xz -6 207,2 s, 335,0 Mo (86 %) 289,3 s, 64,3 Mo (16 %)

Les photos JPEG sont déjà compressées : l’archive des fichiers ne rétrécit presque pas, quel que soit l’outil. Le dump, lui, est divisé par cinq. zstd -3 offre le meilleur compromis : 5 à 11 fois plus rapide que gzip, avec un fichier un peu plus petit. Les niveaux maximaux de zstd et xz n’ont gagné qu’environ 15 Mo de plus sur le dump, au prix de cinq minutes de temps CPU, une charge inutile sur un hébergement mutualisé.

Sauvegardes incrémentales : ce qu’apporte la déduplication de restic

restic et borg découpent les données en blocs et ne stockent que les nouveaux. La première sauvegarde du site avec le dump faisait 791 Mo (427 Mo dans le dépôt, car restic compresse). Ensuite :

  • Un nouvel article, une photo de 454 Ko et 20 commandes : la deuxième sauvegarde a ajouté 4,6 Mo.
  • Suppression des 1 000 lignes les plus anciennes de la table de logs, comme le font les extensions de nettoyage : la troisième sauvegarde a ajouté 359,6 Mo, presque tout le dump.
  • Même modification, mais avec un dump à une ligne par INSERT (--skip-extended-insert) : 7,6 Mo ajoutés.
Graphique du banc d’essai : la première sauvegarde restic a ajouté 791 Mo, la suivante après un nouvel article 4,6 Mo, après un nettoyage des logs 359,6 Mo et avec un dump à une ligne par INSERT 7,6 Mo
Volume ajouté par chaque nouvelle sauvegarde restic sur le banc d’essai

Un dump classique regroupe des centaines de lignes dans chaque instruction INSERT. Supprimer des lignes au début d’une table décale les limites de toutes les instructions suivantes, et restic considère le reste du fichier comme nouveau. Un dump à une ligne par INSERT se déduplique bien, mais il y a un prix : sur le banc, son import a pris 507 secondes au lieu de 35. Si vous payez le stockage au volume et restaurez rarement, le compromis en vaut la peine ; si la vitesse de restauration compte, gardez le dump classique et conservez moins de versions. Nous n’avons pas mesuré borg : il ne démarrait pas dans le conteneur de test à cause d’une version de Python incompatible, les chiffres concernent donc uniquement restic.

export RESTIC_REPOSITORY=sftp:backup@storage.example.net:/restic
export RESTIC_PASSWORD_FILE=~/.restic-pass
restic init
restic backup ~/backup/db.sql ~/web/example.com/public_html
restic forget --keep-daily 14 --keep-weekly 8 --prune
restic check

Remplacez l’adresse du dépôt par la vôtre. Gardez le mot de passe du dépôt hors du serveur : sans lui, personne ne peut déchiffrer la sauvegarde, vous y compris.

Restauration de test : comment vérifier qu’une sauvegarde fonctionne

Nous avons reproduit le pire scénario : arrêt de la base de données, suppression de tout le répertoire « serveur », sauvegardes locales comprises, puis restauration du site depuis restic dans une nouvelle instance MariaDB avec un dossier de site vide.

restic restore latest --target /srv/restore
Summary: Restored 3523 files/dirs (789.971 MiB) in 0:02
mariadb -e "CREATE DATABASE wp"
mariadb wp < db.sql
curl -s -o /dev/null -w "%{http_code}\n" http://bench.test:8122/
200
curl -sI "http://bench.test:8122/wp-json/wp/v2/posts?per_page=1" | grep -i x-wp-total
X-WP-Total: 6002

Du début jusqu’à la réponse 200, il a fallu 23 secondes : 4 pour les fichiers, 19 pour l’import de la base. Le nombre d’articles et de commandes ainsi que l’ID le plus élevé correspondaient au site en ligne, la nouvelle photo est revenue avec la même somme de contrôle et les titres en alphabet non latin étaient intacts. Notre première tentative a d’ailleurs échoué par notre propre faute : restic a enregistré les chemins exactement tels que nous les avions passés, et les fichiers ont atterri dans un autre dossier que celui attendu par le script. C’est précisément le genre de détail qu’une restauration de test révèle.

Une vérification mensuelle minimale :

  1. Vérifier l’intégrité de l’archive : zstd -t, gzip -t ou restic check.
  2. S’assurer que le dump se termine par « Dump completed ».
  3. Importer le dump dans une base de test séparée et comparer le nombre d’articles, de commandes et d’utilisateurs avec le site en ligne.
  4. Déployer les fichiers sur un sous-domaine de test, vérifier la réponse 200, la connexion à l’administration et quelques anciennes images.
  5. Noter le temps nécessaire : c’est votre véritable durée de rétablissement.

C’est au fond la même procédure que pour migrer WordPress vers un autre hébergeur, sans le changement de domaine.

Quatre défaillances reproduites sur le banc

Sauvegarde sans le dossier uploads

Une archive créée avec --exclude=wp-content/uploads pesait 15 Mo au lieu de 361 Mo. Après restauration, la page d’accueil répondait 200 et l’API REST listait les 6 002 articles, mais chaque photo renvoyait 404 : 450 pièces jointes dans la base, 0 fichier sur le disque. Le site paraît vivant jusqu’à ce qu’on ouvre un article. On exclut souvent les uploads pour respecter une limite de taille : vérifiez donc le nombre de fichiers dans votre sauvegarde.

Sauvegardes uniquement sur le même serveur

Quand le répertoire « serveur » a disparu, le dump, l’archive des fichiers et les sommes de contrôle placées à côté sont partis avec le site : No such file or directory. Seule la copie dans un stockage séparé a sauvé le site. Ne gardez jamais non plus d’archives dans la racine web du site, où n’importe qui peut les télécharger par URL. Des droits 700 sur le dossier et 600 sur les fichiers suffisent pour un répertoire de sauvegardes.

Fichier tronqué

Une sauvegarde coupée à 60 % (disque plein ou transfert interrompu) échoue à zstd -t avec « Read error (39) : premature end » ; gzip signale « unexpected end of file ». Un dump non compressé est pire : l’import s’est arrêté sur ERROR 1064, mais il avait déjà créé 7 tables sur 13 et 3 825 lignes sur 9 304 dans wp_posts. Les tables des utilisateurs et des catégories manquaient, si bien que personne ne pouvait se connecter. Un dump tronqué se repère facilement : la ligne « Dump completed » manque à la fin.

Mauvais jeu de caractères ou mauvaise collation

Un dump réalisé avec --default-character-set=latin1 s’est terminé sans erreur, mais dans 5 986 titres sur 6 001, le texte cyrillique s’est transformé en points d’interrogation. Cette perte est définitive : les bons octets ne sont tout simplement pas dans le fichier. Autre variante : un dump sans la ligne SET NAMES importé par un client fonctionnant en latin1 (comme le client mariadb sur le banc dans une session sans locale UTF-8). Les titres sont sortis en caractères illisibles du type « ДоÑтавка », alors que le même fichier s’importait correctement avec --default-character-set=utf8mb4. Nous avons émulé le troisième cas en remplaçant dans le dump la collation par celle que MySQL 8 crée par défaut : MariaDB 10.11 a répondu ERROR 1273 (HY000): Unknown collation: 'utf8mb4_0900_ai_ci' et n’a créé aucune table. La solution : remplacer la collation par une collation prise en charge, par exemple utf8mb4_unicode_520_ci, puis relancer l’import.

Selon votre situation, que faire

Si Faites
Blog ou site vitrine, modifications hebdomadaires Sauvegardes de l’hébergeur plus votre propre sauvegarde hebdomadaire de la base et des fichiers ailleurs, une restauration de test chaque trimestre
Boutique ou site qui prend des commandes Dump avec --single-transaction plusieurs fois par jour, fichiers chaque jour, une restauration de test chaque mois
Les sauvegardes dépassent la limite de stockage restic ou borg avec déduplication et nettoyage des tables de logs, sans exclure les uploads
Passage de MySQL 8 à MariaDB Tester l’import avant de basculer le domaine ; en cas d’ERROR 1273, remplacer la collation dans le dump
Le site est déjà piraté ou en panne Trouver d’abord la cause et sauvegarder l’état actuel, puis restaurer une sauvegarde antérieure à l’incident
Vous ne savez pas quand la dernière sauvegarde a tourné Mettre en place une alerte en cas de sauvegarde manquante et faire une restauration de test aujourd’hui

Si le site est déjà en panne, commencez par chercher la cause dans les logs du serveur : c’est souvent une extension ou un disque plein, et revenir à la sauvegarde d’hier ne ferait qu’effacer les nouvelles commandes. Lancez votre script de sauvegarde à heure fixe grâce aux tâches cron de votre hébergement, ajoutez un contrôle de « Dump completed » et de zstd -t, et laissez la surveillance du serveur vous alerter en cas d’échec.

Les sauvegardes chez RichHost

Toutes les offres d’hébergement RichHost incluent des sauvegardes continues dans le cloud : une copie conservée hors du serveur web. Pour respecter la règle 3-2-1, ajoutez votre propre sauvegarde ailleurs et testez-la de temps en temps par une restauration sur un sous-domaine de test. Le support répond aux questions sur les sauvegardes de 10 h à 20 h, heure de Kyiv, généralement en 30 minutes environ.

FAQ

Les sauvegardes de mon hébergeur suffisent-elles ?

Pour la plupart des incidents, oui, mais la règle 3-2-1 exige une copie indépendante de plus. Elle vous sauve lorsque le problème touche votre compte ou la facturation, ou lorsque vous avez besoin d’une version plus ancienne que celles que conserve l’hébergeur.

À quelle fréquence sauvegarder son site ?

Aussi souvent que la quantité de données que vous pouvez vous permettre de perdre l’exige. Pour un blog, une sauvegarde quotidienne ou hebdomadaire suffit ; une boutique a besoin de plusieurs dumps de base par jour. Les fichiers changent moins souvent que la base et peuvent être sauvegardés moins fréquemment.

Peut-on faire un dump de la base pendant que le site tourne ?

Oui, avec --single-transaction pour les tables InnoDB. Sur le banc, un tel dump n’a perdu aucune commande et n’a pas bloqué les écritures, alors qu’un dump sans verrous perdait les données de 3 à 7 commandes à chaque essai.

Comment tester une sauvegarde sans casser le site en ligne ?

Restaurez-la dans une base séparée et sur un sous-domaine de test, jamais par-dessus le site en ligne. Comparez le nombre d’articles et de commandes, ouvrez quelques pages et images, et connectez-vous à l’administration.

Sur le même sujet

Tous les articles
Limites de l’hébergement mutualisé : ce qui bloque et comment vérifier
Dépannage d’hébergement28.03.2026

Limites de l’hébergement mutualisé : ce qui bloque et comment vérifier

Ce qui limite vraiment un hébergement mutualisé « illimité » : inodes, processus PHP simultanés, CPU, mémoire, connexions à la base de…

Site inaccessible : que faire dans les 10 premières minutes
Dépannage d’hébergement27.03.2026

Site inaccessible : que faire dans les 10 premières minutes

Site inaccessible, que faire ? Nous avons cassé un site WordPress de test de dix façons et dressé un tableau des symptômes,…

Votre connexion n’est pas privée : corriger les erreurs NET::ERR_CERT
Dépannage d’hébergement05.04.2026

Votre connexion n’est pas privée : corriger les erreurs NET::ERR_CERT

Pourquoi le navigateur affiche « Votre connexion n'est pas privée » et ce que signifient NET::ERR_CERT_DATE_INVALID, COMMON_NAME_INVALID et AUTHORITY_INVALID : testé sur…