# Point-in-time recovery MySQL : restaurer une base WordPress à l’heure près

> Une commande DROP TABLE malencontreuse sur une boutique WordPress ne se répare pas avec une sauvegarde de la veille. Voici comment restaurer précisément jusqu'à la seconde qui précède l'incident.

- Auteur : Clément Hadrot
- Publié le : 2024-06-18
- Mis à jour le : 2024-06-18
- Catégorie : Hébergement &amp; serveurs
- URL : https://wpmoderne.dev.wordpress-developpement.fr/hebergement/point-in-time-recovery-mysql-restaurer-base-wordpress-heure-pres/

## L’essentiel

- Une sauvegarde classique perd tout ce qui s'est passé depuis son dernier export
- Les binlogs journalisent chaque modification, rejouables jusqu'à un instant précis
- log_bin doit être activé avant l'incident, pas après

Il est 14 h 12 un mardi. Un développeur, en pleine session de nettoyage sur l'environnement de production par erreur de terminal, exécute un `DROP TABLE wp_woocommerce_order_items;` destiné à l'environnement de staging. En quelques secondes, l'historique des articles de commande de la boutique disparaît. La dernière sauvegarde complète date de la veille à minuit : la restaurer effacerait quatorze heures de commandes passées ce jour-là, un coût inacceptable pour le client.

C'est exactement le scénario où une sauvegarde logique classique, traitée par ailleurs sur ce blog, montre sa limite structurelle : elle ne restaure qu'à l'instant où elle a été prise, jamais entre deux exports. La solution technique existe pourtant depuis longtemps dans MySQL et MariaDB sous le nom de point-in-time recovery, à condition qu'un prérequis ait été activé avant l'incident : la journalisation binaire.

## Le prérequis qu'il faut avoir activé à l'avance

Le point-in-time recovery s'appuie sur les binlogs (journaux binaires), qui enregistrent chronologiquement chaque modification apportée à la base : insertions, mises à jour, suppressions, changements de structure comme un `DROP TABLE`. Sans cette journalisation activée en amont, aucune restauration précise n'est possible après coup, seule la dernière sauvegarde complète reste disponible.

```
# Dans my.cnf, section [mysqld]
log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7
server_id = 1
```

Sur ce projet, la journalisation binaire avait heureusement été activée plusieurs mois auparavant dans le cadre d'une réplication déjà en place, ce qui a rendu la restauration précise possible. Sans cette configuration préexistante, cet article se serait terminé par une simple restauration de la sauvegarde de minuit et la perte assumée des commandes de la journée.

## La séquence de restauration

1. Restaurer d'abord la dernière sauvegarde complète (celle de minuit) sur une base de travail isolée, jamais directement en production.
2. Identifier la position exacte du binlog correspondant à l'instant juste avant le `DROP TABLE` fautif.
3. Rejouer les binlogs depuis la sauvegarde jusqu'à cette position précise, sans aller plus loin.
4. Vérifier l'intégrité des données restaurées sur la base de travail avant toute bascule en production.

> L'essentiel à retenir : Une sauvegarde classique perd tout ce qui s'est passé depuis son dernier export ; Les binlogs journalisent chaque modification, rejouables jusqu'à un instant précis ; log_bin doit être activé avant l'incident, pas après

```
# Lister les événements du binlog pour repérer l'instant du DROP TABLE
mysqlbinlog --base64-output=decode-rows -v /var/log/mysql/mysql-bin.000042 \
  | grep -B5 "DROP TABLE"

# Rejouer les binlogs jusqu'à une position précise (exclue)
mysqlbinlog --stop-position=48213107 /var/log/mysql/mysql-bin.000042 \
  | mysql -u root -p wordpress_restauration
```

La commande `mysqlbinlog` avec l'option `--stop-position` permet de rejouer précisément tous les événements jusqu'à la position indiquée, exclue, ce qui revient à s'arrêter juste avant l'instruction fautive. Trouver cette position exacte demande d'inspecter le binlog en texte pour repérer la ligne correspondant au `DROP TABLE`, puis de noter la position immédiatement précédente.

## Vérifier avant de rebasculer

Une fois la base de travail reconstituée, une vérification manuelle des dernières commandes visibles dans `wp_woocommerce_order_items` confirme que la restauration s'arrête bien juste avant l'incident, sans données manquantes ni doublons introduits par un rejeu partiel. Ce n'est qu'après cette vérification que la table restaurée est réintégrée dans la base de production, jamais en écrasant directement l'instance active sans validation intermédiaire.

| Méthode | Granularité de restauration | Prérequis |
| --- | --- | --- |
| Sauvegarde logique classique | À l'instant de l'export uniquement | Aucun |
| Point-in-time recovery | À la seconde ou à la transaction près | log_bin activé en amont |

> Activer `log_bin` un jour ordinaire, sans incident en vue, est le genre de décision invisible qui ne se justifie jamais... jusqu'au jour où elle sauve six heures de commandes clients en une seule commande `mysqlbinlog`.

## Ce que cette méthode ne remplace pas

Le point-in-time recovery n'est pas un substitut à une politique de sauvegarde régulière : sans sauvegarde complète récente comme point de départ, les binlogs seuls représenteraient un volume de rejeu bien trop important pour être praticable rapidement. C'est la combinaison des deux qui rend la restauration précise possible, pas l'un sans l'autre.

## En résumé

Restaurer une base WordPress à la seconde près après une suppression accidentelle n'est possible qu'à condition d'avoir activé la journalisation binaire bien avant l'incident. Le jour où une commande destructrice frappe la production, la combinaison d'une sauvegarde complète récente et des binlogs rejoués jusqu'à la position exacte évite de choisir entre restaurer une base obsolète ou perdre des heures d'activité réelle.
