Anton Zaides est un développeur qui écrit de temps en temps sur les défis auxquels sont parfois confrontés les chefs d'équipe. L'épisode s'est déroulé un samedi. La journée avançait sans particularité lorsque l'équipe d'assistance lui a envoyé un message pour l'informer qu'un de leurs clients a un problème. Il a estimé que c'était suffisamment important pour commencer le débogage. Après 15 minutes, il a compris le problème : des commandes corrompues avaient été créées dans la base de données et il fallait les supprimer.
Cela semble trivial, n'est-ce pas ?
La base de données effacées
Il y avait quelques centaines de commandes à supprimer, Anton a donc décidé de ne pas le faire manuellement mais d'écrire une courte requête SQL (drapeau rouge 🚩 )
C'était un peu plus complexe que ça, mais pour simplifier :
| Code SQL : | Sélectionner tout |
1 2 3 4 | UPDATE orders SET is_deleted = true WHERE id in (1, 2, 3) |
On mesure déjà l’ampleur du désastre…
J'ai appuyé sur CTRL+Entrée et j'ai exécuté la commande. Quand cela a pris plus d'une seconde, j'ai compris ce qui s'était passé. Le programme que j'ai utilisé (DBeaver) a vu la 3ème ligne vide et a ignoré la 4ème ligne.
Oui, j'ai supprimé toutes les commandes dans la base de données 😢
Je me sentais physiquement malade et impuissant.
J'ai appuyé sur CTRL+Entrée et j'ai exécuté la commande. Quand cela a pris plus d'une seconde, j'ai compris ce qui s'était passé. Le programme que j'ai utilisé (DBeaver) a vu la 3ème ligne vide et a ignoré la 4ème ligne.
Oui, j'ai supprimé toutes les commandes dans la base de données 😢
Je me sentais physiquement malade et impuissant.
Après une profonde inspiration, Anton savait qu'il devait agir, et vite. Il n’y avait aucune place pour faire plus d’erreurs ou perdre du temps.
La reprise s'est bien mieux faite :
* J'ai décidé de ne pas restaurer l'intégralité de la base de données, car je ne pouvais pas arrêter TOUS les systèmes, car nous en avons plusieurs indépendants. Je ne voulais pas perdre les modifications apportées lors du processus de récupération. Nous utilisons PostgreSQL géré par GCP, j'ai donc créé un nouveau clone avant la mise à jour. Ensuite, j'ai exporté uniquement les colonnes « id » et « is_deleted » du clone et j'ai importé le résultat dans la base de données de production. Ensuite, il s’agissait d’une simple requête update+select.
Donc 45 minutes d’arrêt facilement évitables…
- Arrêt des systèmes - ~5 minutes
- Création d'un clone de notre base de données avant le changement (heureusement, nous avions configuré une récupération ponctuelle) - ~ 20 minutes
- J'ai appelé mon manager pendant l'attente 😨
- J'ai mis à jour des informations de la base de données de production en fonction du clone* - ~15 minutes
- J'ai démarré nos systèmes - ~5 minutes
* J'ai décidé de ne pas restaurer l'intégralité de la base de données, car je ne pouvais pas arrêter TOUS les systèmes, car nous en avons plusieurs indépendants. Je ne voulais pas perdre les modifications apportées lors du processus de récupération. Nous utilisons PostgreSQL géré par GCP, j'ai donc créé un nouveau clone avant la mise à jour. Ensuite, j'ai exporté uniquement les colonnes « id » et « is_deleted » du clone et j'ai importé le résultat dans la base de données de production. Ensuite, il s’agissait d’une simple requête update+select.
Donc 45 minutes d’arrêt facilement évitables…
Cela peut sembler une erreur très stupide que vous ne ferez jamais (ou même que vous ne pourrez pas commettre – dans les grandes entreprises). C'est peut-être vrai. Le problème ne vient pas d'une mauvaise commande SQL. Une petite erreur humaine n’est jamais le vrai problème. Le fait que je lance cette commande n'est que la fin de toute une chaîne d'échecs.
- Travailler sur la production le week-end – pourquoi ? Dans ce cas-ci, ce n’était même pas si urgent. Personne ne m'a demandé de le réparer immédiatement. J'aurais facilement pu attendre lundi.
- Qui diable exécute quelque chose sur une base de données de production sans l'exécuter d'abord sur le contrôle qualité ?
- Pourquoi ai-je modifié manuellement la base de données et n'ai-je pas utilisé d'appel API ?
- Et s'il n'y avait pas d'API, pourquoi n'ai-je pas appelé un coéquipier et n'ai-je pas eu « 4 yeux » sur une action aussi sensible ?
- Et le pire : pourquoi n’ai-je pas utilisé les transactions ? C'est aussi simple que d'écrire « Begin », puis d'utiliser Rollback en cas d'erreur.
Les erreurs se superposent les unes aux autres. Si au moins l’une d’entre elles avait été évité, tout cela ne serait jamais arrivé. La réponse à la plupart des questions est que j’étais tout simplement trop confiant.
Au...
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.
