Introduction
Un ticket disparaît après une suppression SQL accidentelle, mais la configuration de l’application reste correcte. Vous allez enregistrer un signet D1 Time Travel, reproduire la perte à l’aide d’un seul enregistrement synthétique, puis restaurer la même base de données tout en conservant un ticket non affecté.
Cet exercice autonome de récupération utilise une base de données distante temporaire et un Worker fourni, en lecture seule. Vous vérifierez l’état manquant avant la restauration, puis l’accès de l’application après celle-ci.
Utilisez votre propre compte d’apprentissage et une VM fraîche. La configuration prépare d’abord Node.js 22.22.0, puis exécute npm install pour installer Wrangler 4.131.1, installé localement au projet, ainsi que les dépendances nécessaires à l’évaluation dans /home/labex/project/ticket-database. Les versions des dépendances directes sont figées ; l’installation crée son propre fichier de verrouillage. Aucune connexion au cloud ni opération sur la base évaluée n’est effectuée pendant la configuration. Sur une machine personnelle, installez la même version de Wrangler avec npm install --save-dev wrangler@4.131.1 dans votre projet.
Cet exercice utilise de petits enregistrements synthétiques dans les limites de D1 Free allowances. L’utilisation existante du compte est comptabilisée dans ces limites. Aucun domaine acheté n’est nécessaire. Conservez cette VM jusqu’à ce que la suppression des ressources et la déconnexion aient toutes deux été vérifiées.
Autoriser cette VM et sélectionner le compte
Dans cette étape, vous connectez ce terminal vierge à votre propre compte d’apprentissage. Une simple connexion au Dashboard n’autorise pas la VM. L’autorisation D1 permet de créer, modifier et supprimer des bases de données ; l’autorisation Workers permet le déploiement ; l’autorisation KV permet à Wrangler d’inventorier les ressources lors du nettoyage. Examinez la page de consentement réelle, notamment l’accès en arrière-plan (Background Access), avant d’autoriser l’accès.
Ouvrez le projet préparé et vérifiez la version de la CLI :
cd /home/labex/project/ticket-database
npx wrangler --version
La commande doit afficher 4.131.1. Démarrez l’autorisation par appareil ; --device affiche un code à saisir dans le navigateur et --browser=false vous laisse choisir vous-même le navigateur :
npx wrangler login --device --browser=false --scopes account:read user:read d1:write workers_scripts:write workers_kv:write
Ouvrez l’URL affichée dans votre navigateur, saisissez le code actuel, confirmez votre compte d’apprentissage et les autorisations, puis autorisez l’accès. Attendez que le terminal confirme la réussite. Ne collez jamais de mots de passe ni de jetons dans les fichiers du projet.
npx wrangler whoami --json
Vérifiez loggedIn: true, puis lisez le name et l’id du compte, même si un seul compte est répertorié. Copiez l’ID voulu dans la configuration ci-dessous. La variable Shell suivante utilise 6 octets aléatoires, soit 12 caractères hexadécimaux, afin d’éviter les collisions avec les autres apprenants. Un document here-doc écrit le JSON entre les lignes JSON ; $RUN est développé à l’intérieur.
La barre oblique inverse devant $schema conserve cette clé JSON littérale ; $RUN est toujours remplacé par le nom unique de cette exécution.
RUN=labex-c04-d07-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
"\$schema": "./node_modules/wrangler/config-schema.json",
"name": "$RUN",
"account_id": "YOUR_ACCOUNT_ID",
"main": "src/index.js",
"compatibility_date": "2026-09-15",
"workers_dev": true,
"preview_urls": false
}
JSON
Remplacez YOUR_ACCOUNT_ID avant d’exécuter le bloc. Gardez ce terminal ouvert afin que RUN reste disponible. name identifie cette exécution ; account_id sélectionne le compte utilisé pour les opérations cloud. Le fichier est un fichier JSON classique, également valide en JSONC. Sa création ne déploie aucun Worker.
Établir un point de restauration connu
Dans cette étape, vous créez la base de données temporaire et une API de tickets fournie, accessible en lecture seule. Time Travel restaure sur place un état antérieur de la base de données. Il ne crée pas de base de remplacement et peut écraser les modifications effectuées après le point choisi. Utilisez-le ici uniquement sur cette ressource de laboratoire fraîchement créée.
Créez une base de données cloud temporaire. --binding DB fournit au code de l’application un nom court, --update-config enregistre son nom réel et son UUID dans wrangler.jsonc, et --use-remote=false conserve le développement en local :
npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false
Lisez le nom et l’ID créés, puis vérifiez la liaison enregistrée :
cat wrangler.jsonc
L’entrée DB doit désigner la base de données de cette exécution. Une liaison est une connexion configurée entre le code et une ressource. Son UUID identifie la base de données cloud, tandis que --local utilise une base de données SQLite distincte dans cette VM. Incluez toujours --local ou --remote dans les commandes SQL.
npx wrangler d1 execute DB --remote --file schema.sql
npx wrangler deploy
Copiez l’URL déployée et lisez les deux tickets synthétiques :
URL='YOUR_DEPLOYED_HTTPS_URL'
curl -i "$URL/tickets/1"
curl -i "$URL/tickets/2"
Le ticket 1 doit renvoyer le statut 200 (Cannot sign in, ouvert) et le ticket 2 le statut 200 (Invoice copy, fermé). Si le déploiement est encore en cours de propagation, répétez ces lectures pendant une minute au maximum, jusqu’à ce que le statut et le JSON correspondent.
Vérifiez les informations de la base de données, puis enregistrez son signet actuel comme artefact de récupération. Un signet est une position opaque dans l’historique de la base de données. La redirection avec > écrit la réponse JSON dans le fichier indiqué :
npx wrangler d1 info DB
npx wrangler d1 time-travel info DB --json > recovery.json
cat recovery.json
Vérifiez que la base utilise le backend de production et que recovery.json contient un champ bookmark non vide. Ne modifiez pas ce fichier pendant l’exercice. Time Travel est toujours activé pour D1 en production ; Free conserve les données pendant 7 jours et Paid pendant 30 jours. Cette récupération au cours de la même session ne nécessite que quelques minutes d’historique. Une ligne d’aide de la CLI mentionnant 30 jours ne remplace pas la durée de conservation de votre offre.
Reproduire une suppression accidentelle limitée
Dans cette étape, vous supprimez uniquement le ticket synthétique 1 de la base de données de ce laboratoire et vous prouvez le symptôme observé dans l’application. Commencez par vérifier wrangler.jsonc et faites correspondre DB au nom et à l’UUID que vous venez de créer. N’exécutez pas cette commande sur une base de données d’application existante.
cat wrangler.jsonc
npx wrangler d1 execute DB --remote --command "DELETE FROM tickets WHERE id = 1;"
Lisez l’API et l’enregistrement qui n’a pas été affecté :
curl -i "$URL/tickets/1"
curl -i "$URL/tickets/2"
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
Le ticket 1 doit renvoyer le statut 404 avec {"error":"not_found"}. Le ticket 2 doit toujours renvoyer sa réponse 200 d’origine ; la requête SQL ne doit contenir que le ticket 2. Une défaillance réseau ou une page 404 de la plateforme ne prouve pas que la suppression a eu lieu.
Terminez la vérification de cette étape avant de restaurer. Elle vérifie réellement l’état dans lequel la ligne est absente ; restaurer sans avoir observé l’échec ferait perdre les preuves de l’incident.
Restaurer l’historique et vérifier l’accès de l’application
Dans cette étape, vous restaurez la même base de données à partir du signet enregistré. Lisez recovery.json, copiez la chaîne bookmark exacte dans BOOKMARK, puis revérifiez l’identité de la base configurée :
cat recovery.json
BOOKMARK='YOUR_SAVED_BOOKMARK'
cat wrangler.jsonc
npx wrangler d1 time-travel restore DB --bookmark "$BOOKMARK"
La commande avertit qu’elle écrase les données et annule les requêtes en cours. Confirmez uniquement cette base de données temporaire. Attendez un message indiquant la réussite de la restauration ainsi qu’un signet d’annulation. Ne recréez pas la base, ne réimportez pas le schéma et n’insérez pas la ligne manquante : ces actions contourneraient la technique de récupération.
Interrogez la base restaurée et la liaison existante de l’application :
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
curl -i "$URL/tickets/1"
curl -i "$URL/tickets/2"
Les deux lignes d’origine et les deux réponses de l’API doivent être de nouveau présentes. Le Worker pointe toujours vers le même UUID et n’a besoin d’aucune liaison de remplacement. Si une lecture est momentanément indisponible pendant la restauration, répétez-la ; ne remplacez pas silencieusement la restauration par une nouvelle initialisation.
Dans le Dashboard, ouvrez la base de données D1 exacte, confirmez que son ID n’a pas changé et examinez les tickets restaurés dans une vue en lecture seule. Ce contrôle relie les données récupérées à la ressource ; les résultats SQL et API constituent les preuves fonctionnelles. Dans les Audit Logs du compte, filtrez Resource ID sur l’UUID de cette base et sélectionnez une plage couvrant la récupération. Cliquez sur l’horodatage de l’événement pour ouvrir ses détails, développez Resource et examinez type: database.time_travel.restore. Faites correspondre l’ID de la ressource et la réussite de l’opération avec la sortie de votre commande de restauration. Les enregistrements d’audit peuvent mettre du temps à apparaître ; ne concluez pas à un échec si la liste est temporairement vide. Les vérifications des données prouvent l’état récupéré, tandis que la sortie réelle de la restauration et l’événement d’audit documentent l’opération de récupération.

Cet exemple montre les deux tickets d’origine après récupération dans la même base. Le nom généré identifie cette exécution d’exemple ; votre nom et votre UUID seront différents. La capture montre les lignes restaurées. Les vérifications SQL/API établissent le rétablissement de l’accès, tandis que la sortie réelle de la commande Time Travel et l’événement d’audit correspondant confirment l’opération de récupération.

L’en-tête utilise l’action générique create. Dans la section Resource développée, type: database.time_travel.restore identifie la récupération. Vérifiez la réussite, l’UUID exact de la base et l’heure ; ces valeurs correspondent à cette exécution d’exemple.
Supprimer les ressources temporaires
Dans cette étape, vous supprimez uniquement les ressources de ce laboratoire, alors que la VM est encore autorisée. Terminez d’abord toutes les vérifications fonctionnelles. Conservez la configuration jusqu’à la fin de la vérification de la suppression.
npx wrangler delete
Dans la confirmation, vérifiez qu’il s’agit uniquement du nom du Worker de cette exécution.
npx wrangler d1 delete DB
Examinez l’invite et confirmez qu’il s’agit uniquement de la base de données de cette exécution. Listez ensuite les bases de données :
npx wrangler d1 list --json
Le nom et l’UUID de la base que vous avez notés doivent être absents d’une réponse réussie. D’autres ressources peuvent rester présentes. Une erreur d’authentification ou de réseau ne permet pas de conclure : rétablissez l’accès et répétez la lecture avant de continuer. Effectuez la vérification de cette étape tant que vous êtes encore connecté.
Mettre fin à l’autorisation de cette VM
Dans cette étape, vous mettez fin à l’autorisation uniquement après la réussite de la vérification indépendante de la suppression. La déconnexion supprime l’autorisation Wrangler enregistrée sur cette VM ; fermer une VM ne constitue pas à lui seul un nettoyage cloud.
npx wrangler logout
npx wrangler whoami --json
La commande doit afficher loggedIn: false. Cette requête non authentifiée peut se terminer avec un code différent de zéro ; c’est attendu uniquement si la réponse structurée indique explicitement que vous êtes déconnecté. Terminez la vérification, puis fermez l’environnement du laboratoire.
Résumé
Vous vous êtes exercé à récupérer une suppression accidentelle de ticket. Vous avez vérifié les résultats observables de la base de données, conservé explicitement le compte sélectionné et l’état local, puis supprimé les ressources temporaires avant de vous déconnecter.



