it-swarm.com.de

Umgang mit nicht reproduzierbaren Fehlern

Angenommen, Ihr Team schreibt ein Softwaresystem, das (ziemlich überraschend) einwandfrei funktioniert.

Eines Tages führt einer der Ingenieure fälschlicherweise einige SQL-Abfragen aus, die einige der DB-Daten ändern, und vergisst sie dann.

Nach einiger Zeit entdecken Sie die beschädigten/fehlerhaften Daten und jeder kratzt sich am Kopf, welcher Teil des Codes dies verursacht hat und warum, ohne Erfolg. In der Zwischenzeit besteht der Projektmanager darauf, dass wir den Teil des Codes finden, der ihn verursacht hat.

Wie gehst du damit um?

72
Nik Kyriakides

Es ist offensichtlich, dass kein Projektmanager unendlich viel Zeit in ein solches Problem investieren wird. Sie wollen verhindern, dass die gleiche Situation erneut auftritt.

Um dieses Ziel zu erreichen, ist es oft möglich, Maßnahmen zu ergreifen, auch wenn man die Grundursache für einen solchen Fehler nicht finden kann

  • Erkennen Sie solche Fehler früher, falls sie erneut auftreten
  • Machen Sie es weniger wahrscheinlich, dass derselbe Fehler erneut auftritt
  • Machen Sie das System robuster gegen die spezifische Art von Inkonsistenz

Eine detailliertere Protokollierung, eine detailliertere Fehlerbehandlung oder eine sofortige Fehlersignalisierung können beispielsweise dazu beitragen, zu verhindern, dass derselbe Fehler erneut auftritt, oder die Grundursache zu ermitteln. Wenn Ihr System das Hinzufügen von Datenbank-Triggern zulässt, können Sie möglicherweise einen Trigger hinzufügen, der die Einführung der Inkonsistenz verhindert.

Überlegen Sie, welche Art von Aktion in Ihrer Situation angemessen sein könnte, und schlagen Sie dies dem Team vor. Ich bin sicher, Ihr Projektmanager wird sich freuen.

Eines Tages führt einer der Ingenieure fälschlicherweise einige SQL-Abfragen aus, die einige der DB-Daten ändern, und vergisst sie dann.

Wie von anderen erwähnt, ist es auch eine gute Idee, ein solches Verfahren zu verbieten (wenn Sie Einfluss auf die Funktionsweise des Systems haben). Niemand darf undokumentierte Ad-hoc-Abfragen ausführen, die den Datenbankinhalt ändern. Wenn eine solche Abfrage erforderlich ist, stellen Sie sicher, dass eine Richtlinie zum Speichern der Abfrage zusammen mit dem Ausführungsdatum, dem Namen der Person, die sie ausgeführt hat, und dem Grund, warum sie verwendet wurde, an einem dokumentierten Ort vorhanden ist.

134
Doc Brown

Dies ist kein Fehler

Zumindest nicht auf Ihrem Code. Es ist ein Fehler in Ihrem Prozess. Ihr Projektmanager sollte sich viel mehr Sorgen um Ihren Prozess machen als um Ihren Code.

Wie gehst du damit um?

Ganz einfach , indem Ingenieure nicht die Produktionsdatenbank oder gemeinsam genutzte Entwicklungsdatenbanken ändern lassen .


Angenommen, dies ist eine gemeinsam genutzte Entwicklungsdatenbank:

Wenn möglich, vermeiden Sie im Idealfall zunächst eine gemeinsam genutzte Datenbank . Verwenden Sie stattdessen Datenbanken pro Entwickler, die nur von kurzer Dauer sind. Dies sollte mit Skripten automatisiert werden, da sonst die Testkosten zu hoch werden und es einen Anreiz gibt, Dinge nicht zu testen. Sie können diese Datenbanken entweder auf der Workstation des Entwicklers oder auf einem zentralen Server haben.

Wenn Sie aus irgendeinem Grund unbedingt eine gemeinsam genutzte Datenbank haben MÜSSEN, sollten Sie fixtures - verwenden. Dies ist im Wesentlichen etwas, das die Datenbank jedes Mal in einen bekanntermaßen guten Zustand versetzt, wenn Sie sie verwenden müssen. Dadurch wird vermieden, dass Entwickler von den Änderungen anderer Personen gebissen werden.

Wenn Sie dauerhafte Änderungen an der Datenbank vornehmen müssen, sollten Sie diese in Ihre Quellcodeverwaltung übernehmen . Richten Sie Ihre Datenbank so ein, dass Entwickler nicht berechtigt sind, direkt darauf zu schreiben, und verfügen Sie über ein Programm, das Änderungen aus der Quellcodeverwaltung abruft und anwendet.

Aus Ihrer Beschreibung, wie Sie Dinge debuggen, geht hervor, dass Sie CI nicht verwenden. Verwenden Sie CI . Das Einrichten ist etwas mühsam, spart aber auf lange Sicht SO viel Zeit, ganz zu schweigen davon, dass Sie sich keine Gedanken über nicht reproduzierbare Datenbankfehler machen müssen. Sie müssen sich nur Sorgen machen über heisenbugs jetzt!


Angenommen, dies ist eine Produktionsdatenbank:

Wenn Ihre Entwickler Produktionsdatenbanken ändern, sind viele Dinge schrecklich schief gelaufen, auch wenn die Änderungen absolut korrekt sind.

Entwickler sollten niemals auf Produktionsdatenbanken zugreifen . Es gibt absolut keinen Grund dafür und so viele Dinge, die sehr schief gehen können sehr.

Wenn Sie fix Etwas in einer Produktionsdatenbank benötigen, sichern Sie zuerst diese Sicherung, stellen Sie sie auf einer anderen (Entwicklungs-) Instanz wieder her und dann diese Entwicklungsdatenbank herumspielen. Sobald Sie glauben, einen Fix bereit zu haben (zur Quellcodeverwaltung!), Führen Sie die Wiederherstellung erneut durch, wenden den Fix an und sehen das Ergebnis. Nachdem Sie die Daten erneut gesichert haben (und im Idealfall gleichzeitige Updates verhindert haben), reparieren Sie die Produktionsinstanz, idealerweise über einen Software-Patch.

Wenn Sie testen etwas in einer Produktionsdatenbank benötigen ... nein, tun Sie nicht. Welche Tests Sie auch durchführen müssen, sollten Sie in einer Entwicklungsinstanz durchführen. Wenn Sie einige Daten benötigen, um die Tests durchzuführen, erhalten Sie diese Daten dort.

50
goncalopp

Eine Produktionsdatenbank sollte über eine vollständige Zugriffsprotokollierung und rollenbasierte Zugriffssteuerung verfügen. Daher sollten Sie genaue Beweise dafür haben, wer WAS WANN in der Datenbank getan hat, um die Aufmerksamkeit vom Code auf eine schlechte Betriebssicherheit zu lenken.

13
Don Gilman

In diesem Fall haben Sie letztendlich die Ursache herausgefunden, aber Ihre Hypothese angenommen, dass Sie nicht ...

Analysieren Sie zunächst, was sich geändert hat. Wenn das System zuvor einwandfrei lief, kann ein genauer Blick auf alles, was kürzlich getan wurde, die Änderung aufdecken, die den Fehler verursacht hat. Überprüfen Sie systematisch Ihre Versionskontrolle, CI/Bereitstellungssysteme und Konfigurationskontrolle, um festzustellen, ob sich etwas geändert hat. Führen Sie git bisect oder einen äquivalenten Mechanismus aus, um eine binäre Suche durchzuführen. Überprüfen Sie die Protokolle. Suchen Sie nach Protokollen, von denen Sie nicht wussten, dass Sie sie haben. Sprechen Sie mit allen Personen, die Zugriff auf das System haben, um festzustellen, ob sie in letzter Zeit etwas unternommen haben. Wenn Sie in diesem Prozess gründlich genug sind, sollte dies hoffentlich die vergessenen SQL-Abfragen aufdecken.

Zweitens Instrumentierung. Wenn Sie die Ursache eines Fehlers nicht direkt finden können, fügen Sie Instrumente hinzu, um Daten über das Problem zu sammeln. Fragen Sie sich, ob ich diesen Fehler auf Befehl reproduzieren könnte, was ich im Debugger sehen möchte, und protokollieren Sie ihn dann. Wiederholen Sie diesen Vorgang nach Bedarf, bis Sie das Problem besser verstanden haben. Fügen Sie, wie von Doc Brown vorgeschlagen, die Protokollierung für den Fehler relevante Zustände hinzu. Fügen Sie Zusicherungen hinzu, die beschädigte Daten erkennen. Wenn Ihr Fehler beispielsweise ein Anwendungsabsturz ist, fügen Sie einen Absturzprotokollierungsmechanismus hinzu. Wenn Sie bereits eine haben, fügen Sie den Absturzprotokollen Anmerkungen hinzu, um den Status aufzuzeichnen, der möglicherweise für den Absturz relevant ist. Überlegen Sie, ob Parallelitätsprobleme auftreten können, und Test zur Ausübung der Thread-Sicherheit .

Drittens Ausfallsicherheit. Fehler sind unvermeidlich. Fragen Sie sich daher, wie Sie Ihre Systeme so verbessern können, dass sie widerstandsfähiger sind, damit die Wiederherstellung nach dem Fehler einfacher ist. Könnten Ihre Backups verbessert werden (oder vorhanden sein)? Bessere Überwachung, Failover und Alarmierung? Mehr Redundanz? Bessere Fehlerbehandlung? Abhängige Dienste voneinander entkoppeln? Können Sie Ihre Prozesse in Bezug auf Datenbankzugriff und manuelle Abfragen verbessern? Im besten Fall werden diese Dinge die Folgen Ihres Fehlers weniger schwerwiegend machen, und im schlimmsten Fall sind sie wahrscheinlich sowieso gute Dinge, die Sie tun können.

6
Zach Lipton
  1. Erklären Sie Ihrem Projektmanager, dass Sie der Meinung sind, dass die Ursache höchstwahrscheinlich der manuelle Datenbankzugriff ist.
  2. Wenn Sie weiterhin nach dem Code suchen sollen, der dies verursacht hat, schauen Sie sich den Code noch einmal an.
  3. Kommen Sie in ein paar Stunden (oder zu einem anderen geeigneten Zeitpunkt) zurück und sagen Sie, dass Sie keinen Code finden können, der dies verursacht hätte. Daher glauben Sie immer noch, dass die wahrscheinlichste Ursache der manuelle Datenbankzugriff ist.
  4. Wenn sie noch möchten, dass Sie nach dem Code suchen, fragen Sie, wie viel Zeit Sie dafür aufwenden sollen. Erinnern Sie sie subtil daran, dass Sie dabei nicht an Feature X, Bug Y oder Enhancement Z arbeiten.
  5. Verbringen Sie so viel Zeit, wie sie verlangen. Wenn Sie immer noch der Meinung sind, dass die wahrscheinlichste Ursache der manuelle Datenbankzugriff ist, teilen Sie dies mit.
  6. Wenn sie noch möchten, dass Sie nach dem Code suchen, eskalieren Sie das Problem, da dies eindeutig zu einer unproduktiven Nutzung der Zeit Ihres Teams geworden ist.

Möglicherweise möchten Sie auch überlegen, ob Sie zusätzliche Prozesse hinzufügen sollten, um die Wahrscheinlichkeit eines manuellen Datenbankzugriffs zu verringern, der in Zukunft zu solchen Problemen führt.

5
Philip Kendall

Ich habe im Entwicklungsteam für ein Mainframe-Datenbankprodukt gearbeitet, als ein Kunde berichtete, dass er eine beschädigte Datenbank hatte. Eine Beschädigung in dem Sinne, dass der interne Zustand der Bits auf der Platte dazu führte, dass die Datenbank über die Datenbanksoftware nicht lesbar war. In der Mainframe-Welt zahlen Kunden Ihnen Millionen US-Dollar, und Sie müssen dies ernst nehmen. Das haben wir gemacht:

Schritt 0: Helfen Sie dem Kunden, wieder in Betrieb zu gehen, indem Sie die Datenbank reparieren.

Schritt 1: Durch Untersuchen der Datei auf der Disc auf Hex-Ebene stellten wir fest, dass die Beschädigung systematisch war: Es gab viele Fälle derselben Beschädigung. Es wurde also definitiv auf der Ebene der Datenbanksoftware verursacht. In der Tat war es so systematisch, dass wir das Gefühl hatten, Multithreading-Probleme ausschließen zu können.

Nachdem wir viele andere Theorien eliminiert hatten, haben wir uns auf ein Dienstprogramm konzentriert, das für die physische Reorganisation der Datenbank verwendet werden kann. Es schien der einzige Code zu sein, der auf der richtigen Ebene Zugriff auf die Daten hatte. Wir haben dann eine Möglichkeit gefunden, dieses Dienstprogramm mit sorgfältig ausgewählten Optionen auszuführen, die das Problem reproduzierten. Der Kunde konnte nicht bestätigen oder leugnen, dass dies das war, was er getan hatte, aber da dies die einzige Erklärung war, die wir finden konnten, entschieden wir, dass dies die wahrscheinliche Ursache war, und er hatte keine andere Wahl, als unsere Diagnose zu akzeptieren .

Schritt 2: Wir haben dann zwei Änderungen an der Software vorgenommen: (a) Es wurde schwieriger, diesen Effekt versehentlich durch eine Benutzeroberfläche "Ja, ich weiß, was ich tue" zu verursachen, und (b) Einführung einer neuen Protokolldatei, damit if Wenn es jemals wieder passiert ist, haben wir eine Aufzeichnung der Benutzeraktionen.

Im Grunde genommen (a) den Schaden reparieren und den Live-Betrieb wiederherstellen, (b) die Grundursache finden, (c) alles Notwendige tun, um ein erneutes Auftreten zu verhindern oder eine einfache Diagnose zu ermöglichen, falls es erneut auftritt.

4
Michael Kay

Meiner Erfahrung nach möchte Ihr Chef ein gewisses Maß an Sicherheit, dass dies nicht erneut auftritt. Wenn kein Code die Ursache war, da dies durch Unity-Tests sichergestellt wird. Wenn Sie also bereits eine Testabdeckung für Ihre Codebasis haben, sollte die Lösung Ihrer Datenbank "Tests" hinzufügen. Ich zitiere Don Gilman, weil er dort genagelt hat:

Eine Produktionsdatenbank sollte über eine vollständige Zugriffsprotokollierung und rollenbasierte Zugriffssteuerung verfügen. Daher sollten Sie genaue Beweise dafür haben, wer WAS WANN in der Datenbank getan hat, um die Aufmerksamkeit vom Code auf eine schlechte Betriebssicherheit zu lenken.

Sie sollten jedoch auch über eine Standardarbeitsanweisung zum Ändern von Daten in der Produktion verfügen. Zum Beispiel sollte kein DBA Daten ändern, kein Entwickler sollte die Änderung selbst ausführen und sie sollten, wie in der SOP definiert, die Änderung formell per Post oder Ticket voneinander verlangen.

Es muss irgendwo ein solches Zitat geben, wenn nicht, können Sie mich darauf zitieren:

Es gibt einen guten Grund dafür, dass Köche nicht für die Reinigung der Toiletten verantwortlich sind.

3
CesarScur

Es gibt verschiedene Dinge, die mit nicht reproduzierbaren Fehlern gemacht werden müssen.

  1. Erstellen Sie ein Ticket dafür

Erstellen Sie ein Ticket und protokollieren Sie alles, was Sie sich im Ticket vorstellen können. Überprüfen Sie auch, ob dieser "Fehler" zuvor protokolliert wurde, und verknüpfen Sie die Tickets miteinander. Möglicherweise erhalten Sie genügend Tickets, um ein Muster für die Reproduktion des Fehlers festzulegen. Dies schließt Workarounds ein, mit denen versucht wird, dies zu vermeiden. Selbst wenn dies die einzige Instanz ist, wird es beim ersten Mal irgendwann ein zweites Mal geben. Wenn Sie die Ursache gefunden haben, schließen Sie das Ticket mit einer Erklärung der Ursache, damit Sie eine genaue Vorstellung davon haben, was passiert ist, wenn es erneut passiert (Fehlerbehebung bei fehlerhafter Zusammenführung).

  1. Führen Sie eine Härtungsanalyse durch

Schauen Sie sich das System an, was fehlgeschlagen ist und wie es fehlgeschlagen ist. Versuchen Sie, Bereiche des Codes zu finden, die aktualisiert werden können, um die Wahrscheinlichkeit eines Fehlers zu verringern. Einige Beispiele...

  • Ersetzen Sie den Ad-hoc-Code durch einen dedizierten Aufruf (wie execute(<query>) durch executeMyStoredProcedure(<params>)
  • Führen Sie nächtliche Überprüfungsskripte aus, um die Datenintegrität zu überprüfen (damit dies beim nächsten Mal innerhalb von 24 Stunden erkannt werden kann).
  • Protokollierung und Archivierung hinzufügen/verbessern (Sichern).
  • Ändern Sie unangemessene Sicherheitsbeschränkungen (z. B. Personen/Programme, die nur Daten lesen, haben keine Schreibberechtigung; Entwickler, die nicht für die Produktion verantwortlich sind, dürfen sich nicht bei den Produktionsservern anmelden).
  • Fügen Sie Datenüberprüfung/-hygiene hinzu, wenn diese fehlen

Dies behebt den Fehler möglicherweise nicht, aber selbst wenn dies nicht der Fall ist, ist das System jetzt stabiler/sicherer, sodass es sich dennoch auszahlt.

  1. Fügen Sie Systemwarnungen hinzu

Ein bisschen Teil von 2, aber etwas ist passiert, und Sie müssen wissen, wann es wieder passiert. Sie sollten einige Integritätsprüfungsskripte/-programme erstellen, um das System zu überwachen, damit Administratoren innerhalb von 24 Stunden nach dem erneuten Auftreten des Fehlers benachrichtigt werden können (je weniger Verzögerung, desto besser, innerhalb eines angemessenen Rahmens). Dies erleichtert die Bereinigung erheblich. (Beachten Sie, dass das Betriebssystem zusätzlich zu den Protokollen der Datenbanken auch protokollieren sollte, wer sich anmeldet, und alle nicht gelesenen Aktionen, die sie ausführen. Zumindest sollten Netzwerkprotokolle des Datenverkehrs zu diesem Computer vorhanden sein.)

1
Tezra

Ihr Problem wurde nicht durch einen Fehler in Ihrer Software verursacht, sondern durch jemanden, der an der Datenbank herumfummelt. Wenn Sie Fehler als "Fehler" bezeichnen, ist Ihr Fehler leicht reproduzierbar: Es wird immer schief gehen, wenn jemand dumme Dinge mit der Datenbank macht. Es gibt Möglichkeiten, diesen "Fehler" zu vermeiden, indem die Datenbank nicht manuell oder mit nicht getesteter Software geändert werden kann und streng kontrolliert wird, wer die Datenbank ändern kann.

Wenn Sie Fehler in Ihrer Datenbank nur als "Fehler" bezeichnen, haben Sie keinen nicht reproduzierbaren Fehler, Sie haben überhaupt keinen Fehler. Möglicherweise haben Sie einen Fehlerbericht, aber Sie haben auch Hinweise darauf, dass das Problem nicht durch einen Fehler verursacht wurde. Sie können den Fehlerbericht also nicht als "nicht reproduzierbar", sondern als "beschädigte Datenbank" schließen. Es ist nicht ungewöhnlich, Fehlerberichte zu haben, bei denen Untersuchungen ergeben, dass kein Fehler vorliegt, aber ein Benutzer die Software falsch verwendet hat, die Erwartungen des Benutzers falsch waren usw.

In diesem Fall wissen Sie immer noch, dass es ein Problem gab, das Sie nicht wiederholen möchten. Führen Sie daher die gleichen Maßnahmen wie im ersten Fall aus.

0
gnasher729