Traiter les bogues non reproductibles

73

Supposons que votre équipe rédige un système logiciel qui fonctionne (de manière surprenante!).

Un jour, l'un des ingénieurs lance par erreur des requêtes SQL qui modifient certaines des données de la base de données, puis les oublient.

Après un certain temps, vous découvrez les données corrompues / erronées et tout le monde se demande quelle partie du code a provoqué ceci et pourquoi, en vain. En attendant, le chef de projet insiste pour que nous trouvions la partie du code qui l’a provoquée.

Comment gérez-vous cela?

Nik Kyriakides
la source
32
Si l'ingénieur l'a oublié, comment savez-vous que c'est ce qui s'est passé? Comment avez-vous été corrompu par une personne exécutant un script, et non par un bogue?
DaveG
18
Il a eu une épiphanie après un jour ou deux. C'est une hypothèse au cas où il ne se serait jamais souvenu de ce qui aurait facilement pu être le cas.
Nik Kyriakides
12
Ceci est hypothétique. Je suis sûr que le Premier ministre voudrait que nous poursuivions cela autant que possible s'il ne s'en souvenait jamais. Je sais que je le ferais.
Nik Kyriakides
59
xkcd.com/583 ;) [langue NSFW ]
Baldrickk
100
"Supposons que votre équipe rédige un système logiciel qui fonctionne bien." Arrêtez de me taquiner avec des fantasmes impossibles!
Paul D. Waite

Réponses:

134

Il est évident qu'aucun chef de projet n'investira une quantité de temps infinie dans un tel problème. Ils veulent éviter que la même situation ne se reproduise.

Pour atteindre cet objectif, même si l’on ne trouve pas la cause fondamentale d’un tel échec, il est souvent possible de prendre certaines mesures pour:

  • Détecter ces défaillances plus tôt au cas où elles se reproduiraient
  • Rendre moins probable le même échec se reproduira
  • Rendre le système plus robuste contre le type spécifique d'incohérence

Par exemple, une journalisation plus détaillée, une gestion des erreurs plus fine ou une signalisation d'erreur immédiate pourraient aider à éviter que la même erreur ne se reproduise ou à trouver la cause. Si votre système autorise l'ajout de déclencheurs de base de données, il est peut-être possible d'ajouter un déclencheur interdisant l'introduction de l'incohérence.

Pensez au type d’action approprié dans votre situation et suggérez-le à l’équipe; Je suis sûr que votre chef de projet sera ravi.

Un jour, l'un des ingénieurs lance par erreur des requêtes SQL qui modifient certaines des données de la base de données, puis les oublient.

Comme mentionné par d'autres, il est également judicieux d'interdire une telle procédure (si vous avez une influence sur le fonctionnement du système). Personne ne devrait être autorisé à exécuter des requêtes ad-hoc non documentées modifiant le contenu de la base de données. Si une telle requête est nécessaire, assurez-vous qu'il existe une stratégie permettant de stocker la requête avec sa date d'exécution, le nom de la personne qui l'a exécutée et la raison pour laquelle elle a été utilisée, dans un emplacement documenté.

Doc Brown
la source
8
@ NicholasKyriakides Probablement les deux. Toutes ces mesures sont de bon sens pour simplifier le débogage "différé". Ils ont probablement été écrits dans d'innombrables procédures.
Nic Hartley
29
Il arrive parfois que vous rencontriez un problème sérieux dans un système de production et que vous ne parveniez pas à en déterminer la cause malgré des efforts considérables. En fin de compte, vous l’attribuez aux rayons cosmiques et essayez d’améliorer les rapports (de sorte que si cela se reproduit, vous aurez une meilleure chance de trouver la cause) et les mesures d’atténuation (de sorte que si cela se reproduit, les dommages seront minimes) et de voir si cela se produit. répète.
David Schwartz
2
@Nicholas Kyriakides: expérience personnelle sur plusieurs décennies.
Doc Brown
4
Il convient également de noter qu'il est très possible que, même s'il y avait un bogue, il ne soit peut-être plus là. Le mieux que vous puissiez parfois faire est de corriger les données et d’améliorer les procédures et les tests afin d’éviter que le même problème ne se reproduise plus.
kutschkem
2
Pour résoudre des problèmes intermittents, il suffit de se connecter et de trouver un point d'étranglement capable de les détecter lorsqu'ils se produisent, puis de revenir en arrière pour identifier la source. Parfois, cela nécessite des choses désagréables, telles que des déclencheurs, ou le déploiement de code avec une journalisation d'erreur bruyante, simplement pour avoir une idée du moment / de l'emplacement de l'erreur.
AaronLS
51

Ce n'est pas un bug

Du moins pas sur votre code. C'est un bug dans votre processus . Votre chef de projet devrait être beaucoup plus préoccupé par votre processus que votre code.

Comment gérez-vous cela?

Tout simplement, en ne laissant pas les ingénieurs modifier les bases de données de production ou de développement partagées .


En supposant qu'il s'agisse d'une base de données de développement partagée:

Idéalement, évitez autant que possible d' avoir une base de données partagée . Au lieu de cela, avoir des bases de données par développeur qui sont de courte durée. Cela devrait être automatisé avec des scripts, sinon le coût du test devient trop important et il y a une incitation à ne pas tester les choses. Vous pouvez avoir ces bases de données sur le poste de travail du développeur ou sur un serveur central.

Si, pour quelque raison que ce soit, vous DEVEZ absolument disposer d'une base de données partagée, vous devez utiliser des fixtures , ce qui permet de définir l'état de la base de données à chaque fois que vous en avez besoin. Cela évite aux développeurs de se faire piquer par les changements d'autres personnes.

Si vous devez appliquer des modifications permanentes à la base de données, vous devez les valider pour votre contrôle de source . Configurez votre base de données de manière à ce que les développeurs ne soient pas autorisés à y écrire directement et ayez un programme qui extrait les modifications du contrôle de source et les applique.

Enfin, d'après votre description de la manière dont vous déboguez, il semble que vous n'utilisez pas CI . Utilisez CI . C'est un peu pénible à installer, mais cela vous fera gagner beaucoup de temps à long terme, sans parler de vous empêcher de vous inquiéter des bogues de base de données non reproductibles. Vous n'aurez plus qu'à vous soucier de Heisenbugs maintenant!


En supposant qu'il s'agisse d'une base de données de production:

Si vos développeurs modifient des bases de données de production, beaucoup de choses se sont mal passées, même si les modifications sont absolument correctes.

Les développeurs ne doivent jamais accéder aux bases de données de production . Il n'y a absolument aucune raison de le faire et tant de choses qui peuvent très mal tourner .

Si vous devez réparer quelque chose dans une base de données de production, commencez par sauvegarder, restaurer cette sauvegarde sur une instance (de développement) différente , puis utilisez cette base de développement. Une fois que vous pensez avoir un correctif prêt (sur le contrôle de source!), Vous recommencez la restauration, appliquez le correctif et visualisez le résultat. Ensuite, après avoir à nouveau sauvegardé des éléments (et idéalement empêché les mises à jour simultanées), vous corrigez l'instance de production, idéalement par le biais d'un correctif logiciel.

Si vous avez besoin de tester quelque chose dans une base de données de production, non. Quels que soient les tests que vous devez faire, vous devriez le faire dans une instance de développement. Si vous avez besoin de données pour effectuer les tests, vous les récupérez.

goncalopp
la source
12
Votre solution recommandée est donc le voyage dans le temps?
Benubird
7
Bien que ce soit une solution décente pour l'exemple donné, la question a un contexte beaucoup plus général de gestion des bugs impossibles à reproduire et des gestionnaires qui souhaitent les poursuivre. Cela peut concerner bien plus que des problèmes de base de données et de gestion des autorisations. J'ai l'impression que cette réponse ne répond pas réellement à la question voulue, mais uniquement à l'exemple donné.
Kyle Wardle
@ KyleWardle D'accord. Je pense que la réponse de Doc Brown couvre assez bien le cas général (journalisation détaillée et traitement des erreurs, conditions de protection). J'ai surtout ajouté le mien parce que je n'avais vu personne avoir mentionné les échecs de processus qui avaient conduit au problème en premier lieu
goncalopp
2
@Benubird Je pense que la réponse se résume à "la façon dont vous traitez cela empêche que cela ne se reproduise". Je ne pense pas que vous puissiez "résoudre" une base de données de production corrompue du point de vue du génie logiciel.
dimanche
1
Vous n'allez pas changer de code pour mettre des données dans la base de données dev. Partout où j'ai travaillé, y compris dans de grandes entreprises, les développeurs sont libres d'insérer des données de test et d'utiliser les mêmes informations d'identification que l'application.
David Conrad
13

Une base de données de production doit disposer d'une journalisation des accès complets et de contrôles d'accès basés sur les rôles. Ainsi, vous devriez avoir des preuves tangibles quant à la façon dont l'OMS a fait quoi à la base de données, déplaçant ainsi l'attention du code sur la sécurité opérationnelle.

Don Gilman
la source
2
Il semble qu'ils ne sachent pas exactement quand la corruption des données s'est produite, ce qui pourrait compliquer la tâche de déterminer les journaux sur lesquels ils doivent enquêter.
Nathanael
3
Malheureusement, en repérant l'un de ceux-ci, nous avons découvert qu'il était également impossible de supprimer les journaux. (Oui, c'est vrai. Le bogue était réel.)
Joshua
Lorsque vous associez des enregistrements à des tâches planifiées pour vérifier l’intégrité des données, même une nuit, les problèmes peuvent être signalés à l’avance et résolus. Si vous voulez être vraiment prudent, exigez une évaluation par les pairs pour les changements.
Keith
Partout où j'ai travaillé, les développeurs se connectent à la base de données avec les mêmes informations d'identification que l'application, de sorte que la journalisation des accès ne montre que le moment où cet identifiant a été modifié, et non par un humain. Je suppose que vous pouvez comparer l’horodatage aux journaux d’application pour voir si l’application faisait quoi que ce soit qui écrirait dans la base de données à ce moment-là.
David Conrad
@ DavidConrad: Pourquoi les développeurs ont-ils accès aux informations d'identification que l'application utilise en production? Vous devez utiliser une sorte de gestion secrète de sorte que ces informations d'identification ne puissent même pas être lues, sauf par votre compte de service d'application, à partir de serveurs d'applications de production.
Daniel Pryden
6

Dans ce cas, vous avez finalement trouvé la cause, mais en supposant que vous ne l'ayez pas fait ...

D'abord, analysez ce qui a changé. Si le système fonctionnait correctement auparavant, un examen attentif de tout ce qui a été fait récemment pourrait révéler le changement à l'origine du bogue. Examinez systématiquement votre contrôle de version, vos systèmes de déploiement / CI et votre contrôle de configuration pour voir si quelque chose a changé. Exécutez git bisect ou un mécanisme équivalent pour effectuer une recherche binaire. Vérifier les journaux. Cherchez des journaux que vous ne saviez pas que vous aviez. Parlez à toutes les personnes ayant accès au système pour voir si elles ont déjà fait quelque chose. Pour votre problème, si vous êtes suffisamment approfondi dans ce processus, cela devrait permettre de révéler les requêtes SQL oubliées.

Deuxièmement, l'instrumentation. Si vous ne trouvez pas directement la cause d'un bogue, ajoutez-y une instrumentation pour recueillir des données sur le problème. Demandez-vous "si je pouvais reproduire ce bogue sur commande, que voudrais-je regarder dans le débogueur", puis le consigner. Répétez au besoin jusqu'à ce que vous compreniez mieux le problème. Comme le suggère Doc Brown, ajoutez une journalisation pour les états pertinents pour le bogue. Ajoutez des assertions qui détectent des données corrompues. Par exemple, si votre bogue est un blocage d'application, ajoutez un mécanisme de journalisation des incidents. Si vous en avez déjà un, tant mieux, ajoutez des annotations aux journaux des incidents pour enregistrer l'état potentiellement pertinent pour l'incident. Déterminez si des problèmes de simultanéité peuvent être impliqués et effectuez un test pour garantir la sécurité des threads .

Troisièmement, la résilience. Les bogues étant inévitables, demandez-vous comment vous pouvez améliorer la résilience de vos systèmes pour faciliter la résolution du bogue. Vos sauvegardes pourraient-elles être améliorées (ou existantes)? Meilleure surveillance, basculement et alerte? Plus de redondance? Meilleure gestion des erreurs? Découpler les services dépendants les uns des autres? Pouvez-vous améliorer vos processus d'accès aux bases de données et aux requêtes manuelles? Au mieux, ces choses rendront les conséquences de votre bogue moins graves, et au pire, ce sont probablement de bonnes choses à faire de toute façon.

Zach Lipton
la source
5
  1. Expliquez à votre chef de projet que, selon vous, la cause la plus probable est un accès manuel à la base de données.
  2. S'ils veulent toujours que vous recherchiez le code qui a causé cela, allez jeter un autre coup d'œil au code.
  3. Revenez dans quelques heures (ou à un autre moment approprié) et dites que vous ne trouvez aucun code qui aurait pu causer cela. Par conséquent, vous croyez toujours que la cause la plus probable est un accès manuel à la base de données.
  4. S'ils veulent toujours que vous cherchiez le code, demandez-leur combien de temps ils aimeraient vous voir consacrer à cela. Rappelez-leur subtilement que vous ne travaillerez pas sur la fonctionnalité X, le bogue Y ou l'amélioration Z pendant cette opération.
  5. Passez autant de temps qu’ils le demandent. Si vous pensez toujours que la cause la plus probable est un accès manuel à la base de données, dites-leur ceci.
  6. S'ils veulent toujours que vous recherchiez le code, faites remonter le problème, car il s'agit clairement d'une utilisation improductive du temps de votre équipe.

Vous voudrez peut-être aussi envisager d’ajouter des processus supplémentaires pour réduire le risque que l’accès manuel à la base de données provoque ce type de problème à l’avenir.

Philip Kendall
la source
1
Je ne savais pas que l'un des ingénieurs effectuait une mise à jour manuelle + les ingénieurs n'exécutaient presque jamais de requêtes directement sur la base de données. Celui-ci vient de le faire, de manière ponctuelle, et l'a oublié. Nous avons passé une journée + à nous préparer à passer une semaine complète à découvrir ce qui ne va pas. Ma question est la suivante: que se passe-t-il si vous ne trouvez pas la cause et ne pouvez pas suggérer quelle pourrait être la cause potentielle?
Nik Kyriakides
5
"Ma question est la suivante: que se passera-t-il si vous ne trouvez pas la cause et que vous ne pouvez pas suggérer la cause potentielle?" C'est la raison exacte pour laquelle le drapeau "ne résoudra pas - ne peut pas dupliquer" a été inventé.
esoterik
4

Je travaillais sur l'équipe de développement d'un produit de base de données mainframe lorsqu'un client a signalé qu'il possédait une base de données corrompue. Une corruption dans le sens où l'état interne des bits sur le disque signifiait que la base de données n'était pas lisible via le logiciel de base de données. Dans le monde du mainframe, les clients vous paient des millions de dollars et vous devez prendre cela au sérieux. Voilà ce que nous avons fait:

Étape 0: aidez le client à se remettre en route en réparant la base de données.

Étape 1: en examinant le fichier sur disque au niveau hexagonal, nous avons déterminé que la corruption était systématique: il y avait de nombreux cas de la même corruption. Cela a donc été définitivement causé au niveau du logiciel de base de données. En effet, il était suffisamment systématique pour que nous puissions exclure les problèmes de multi-threading.

Après avoir éliminé de nombreuses autres théories, nous nous sommes tournés vers un utilitaire pouvant être utilisé pour la réorganisation physique de la base de données. Il semble que ce soit le seul code ayant accès aux données au bon niveau. Nous avons ensuite découvert un moyen d’exécuter cet utilitaire, avec des options soigneusement sélectionnées, qui reproduisait le problème. Le client n'a pas été en mesure de confirmer ou de nier que c'était ce qu'il avait fait, mais comme c'était la seule explication que nous puissions trouver, nous avons décidé que c'était la cause probable, et ils n'avaient guère d'autre choix que d'accepter notre diagnostic. .

Étape 2: Nous avons ensuite apporté deux modifications au logiciel: (a) il est plus difficile de provoquer cet effet par inadvertance via une interface utilisateur "oui je sais ce que je fais", et (b) l’introduction d’un nouveau fichier journal de sorte que si Si cela se reproduisait, nous aurions un enregistrement des actions des utilisateurs.

Donc, fondamentalement, (a) réparez les dégâts et rétablissez la course réelle, (b) trouvez la cause première, (c) faites tout ce qui est nécessaire pour éviter que cela ne se reproduise, ou pour permettre un diagnostic facile si cela se reproduisait.

Michael Kay
la source
3

D'après mon expérience, ce que veut votre patron, c'est une assurance de niveau que cela ne se reproduira plus. Si aucun code n’est en cause, car cela est garanti par les tests unitaires. Supposons donc que vous avez déjà une couverture de tests sur votre base de code, la solution devrait donc ajouter «testing» à votre base de données. Je citerai Don Gilman, car il a cloué là:

Une base de données de production doit disposer d'une journalisation des accès complets et de contrôles d'accès basés sur les rôles. Ainsi, vous devriez avoir des preuves tangibles quant à la façon dont l'OMS a fait quoi à la base de données, déplaçant ainsi l'attention du code sur la sécurité opérationnelle.

Mais aussi, vous devriez avoir une procédure standard pour changer les données en production. Par exemple, aucun administrateur de base de données ne devrait modifier les données, aucun développeur ne devrait exécuter le changement lui-même et, comme défini dans la SOP, se demander mutuellement formellement le changement par courrier ou par ticket.

Il doit y avoir une citation comme celle-ci quelque part, sinon vous pouvez me citer:

Il existe une excellente raison pour que les chefs ne soient pas responsables du nettoyage des toilettes.

CesarScur
la source
1

Il y a plusieurs choses à faire avec des bogues non reproductibles.

  1. Créer un ticket pour cela

Créez un ticket et enregistrez tout ce que vous pouvez penser dans le ticket. Vérifiez également si ce "bogue" a déjà été enregistré et liez les tickets ensemble. Éventuellement, vous obtiendrez assez de tickets pour établir un modèle permettant de reproduire le bogue. Cela inclut les solutions de contournement utilisées pour tenter de l'éviter. Même s'il s'agit du seul cas, s'il y a une première fois, il y aura éventuellement une deuxième fois. Lorsque vous trouvez la cause, fermez le ticket avec une explication de la cause pour que vous ayez une idée précise de ce qui se passera si cela se reproduit (correction perdue lors d'une mauvaise fusion)

  1. Faire une analyse de durcissement

Regardez le système, ce qui a échoué et comment il a échoué. Essayez de trouver des zones du code qui peuvent être mises à jour pour réduire les risques d'échec. Quelques exemples...

  • Remplacez le code ad hoc par un appel dédié (comme execute(<query>)avecexecuteMyStoredProcedure(<params>)
  • Exécutez des scripts de vérification nocturnes pour vérifier l'intégrité des données (afin que cela puisse être détecté dans les prochaines 24h)
  • Ajouter / améliorer la journalisation et l'archivage (sauvegarde).
  • Modifier les limites de sécurité inappropriées (par exemple, les personnes / programmes qui ne lisent que des données ne disposent pas de l'autorisation d'écriture; ne permettent pas aux développeurs qui ne sont pas responsables de la production de se connecter aux serveurs de production)
  • Ajouter vérification des données / assainissement là où il manque

Cela ne corrigera peut-être pas le bogue, mais même s'il ne le fait pas, le système est maintenant plus stable / sécurisé et donc rentable.

  1. Ajouter des alertes système

Un peu partie de 2, mais quelque chose est arrivé, et vous devez savoir quand cela se produit à nouveau. Vous devez créer des scripts / programmes de contrôle d'intégrité pour surveiller le système, afin que les administrateurs puissent être alertés dans les 24 heures suivant la remontée du bogue (moins il y a de retard, mieux c'est, dans les limites du raisonnable). Cela facilitera beaucoup le nettoyage. (Notez qu'en plus des journaux de la base de données, le système d'exploitation doit également identifier les personnes qui s'y connectent, ainsi que toutes les actions non lues qu'ils effectuent. À tout le moins, il devrait exister des journaux réseau du trafic sur cette machine)

Tezra
la source
0

Votre problème n'a pas été causé par une défaillance de votre logiciel, mais par quelqu'un qui manipule la base de données. Si vous appelez un "bogue" un problème, celui-ci est facilement reproductible: tout ira toujours mal lorsque quelqu'un fera des choses stupides dans la base de données. Et il existe des moyens d'éviter ce "bogue", en interdisant la modification manuelle de la base de données ou en utilisant un logiciel non testé, et en contrôlant strictement qui peut modifier la base de données.

Si vous appelez uniquement un "bogue" un défaut dans votre base de données, vous n'avez pas de bogue irréproductible, vous n'avez aucun bogue. Vous pouvez avoir un rapport de bogue, mais vous avez aussi la preuve que le problème n’a pas été causé par un bogue. Ainsi, vous pouvez fermer le rapport de bogue, non pas comme "irréversible", mais quelque chose comme "base de données endommagée". Il n’est pas rare d’avoir des rapports de bogues où l’investigation montre qu’il n’y en a pas, mais qu’un utilisateur a mal utilisé le logiciel, que ses attentes étaient fausses, etc.

Dans ce cas, vous savez toujours qu'il y a un problème que vous ne voulez pas répéter, vous devez donc procéder comme dans le premier cas.

gnasher729
la source