GitHub-Datenbankausfall am 13. September: wie ein Aufräumjob die Primärdatenbank sättigte

Abstrakter Strom aus Lichtpartikeln und Datenstroemen im tiefdunklen Raum
Deine Reaktion:

07:33 Uhr UTC, 13. September: Ein interner Datenbereinigungsjob bei GitHub beginnt, in einen geteilten Datenbank-Cluster zu schreiben. Drei Stunden und elf Minuten später, um 10:44 Uhr UTC, laufen alle Dienste wieder. Dazwischen liegt ein Ausfall, der große Teile der Plattform erfasst hat. Der Incident Report von GitHub trägt den Titel „Incident with several GitHub Services“ und beschreibt den Ablauf. Der Blog surfingcomplexity hat ihn nachgezeichnet und mehrere bekannte Risikomuster herausgearbeitet.

Der Bericht ist kurz und benennt den Fehlermechanismus in wenigen Absätzen. Die Kette lässt sich Schritt für Schritt nachvollziehen, ohne Spekulation. Spannend ist weniger der einzelne Fehler als das Zusammenspiel: eine unvollständige Gesundheitsmetrik, zu großzügige Timeouts und ein Retry-Verhalten, das die Lage verschärft statt entspannt. Betroffen ist am Ende jeder, der ein System mit zentraler Datenbank betreibt.

Der Ablauf am 13. September: vom Aufräumjob zur Sättigung

GitHub betreibt einen Datenbank-Cluster in klassischer SQL-Bauweise: ein Primärknoten, der alle Schreiboperationen verarbeitet, plus mehrere Lesereplikate. Dieser Cluster trägt Online-Verkehr. Er speichert Berechtigungsdaten, die fast jede authentifizierte Anfrage liest. Parallel schrieb ein Offline-Job, also ein Prozess ohne Nutzerverkehr, in dieselbe Datenbank, um nicht mehr benötigte Daten zu entfernen. Gesteuert wurde seine Schreibrate von einer Schutzvorrichtung, die ein einziges Signal beobachtete: den Rückstand der Replikate gegenüber dem Primärknoten. Das Signal blieb während der gesamten Dauer unauffällig.

Was der Mechanismus nicht sah: Der Primärknoten selbst lief auf seine Belastungsgrenze zu. Als er die maximal zulässigen Client-Verbindungen erreichte, konnten neue Datenbankaufrufe nicht mehr bedient werden. In MySQL sind das der Parameter max_connections und der Fehler ER_CON_COUNT_ERROR mit der Meldung „Too many connections“. Die betroffenen Anfragen scheiterten aber nicht schnell. Sie blieben hängen, weil die Timeouts zu lang konfiguriert waren. So sammelten sich laufende Anfragen in den Webservern an und verbrauchten Ressourcen, bis auch diese Server gesättigt waren und die Fehler flächendeckend auftraten. Ein Retry-Loop rund um die Token-Erstellung schickte die fehlschlagenden Schreibvorgänge immer wieder los und hielt die Datenbank in der Sättigung, statt ihr Erholung zu lassen.

Um 08:50 Uhr UTC erklärte das Monitoring den Vorfall. Weil die Wirkung breit war und die Token-Erstellung die Lage verstärkte, dauerte es eine Weile, bis die Lastquelle identifiziert war. Die Ersthelfer drosselten interne Last und pausierten den Bereinigungsjob. Um 10:44 Uhr UTC hatten sich alle Dienste erholt. Zwischen Auslöser und Wiederherstellung liegen gut drei Stunden, und der größte Teil davon entfiel nicht auf die Behebung, sondern auf das Verstehen.

Replica Lag als blindes Auge: gemessen wurde das Falsche

Für diese Art Fehler gibt es in der Resilienz-Engineering-Literatur einen Begriff: Gray Failure, ein Fehler, der für das Monitoring unsichtbar bleibt, während die Nutzer ihn längst spüren. Die internen Metriken sehen gut aus, die Anwender sind unzufrieden. Der Autor beschreibt das als Fehleinschätzung der Sicherheitsgrenze. Man weiß nie genau, wo sie liegt, bis man sie überschreitet — und das Überschreiten ist teuer. Also schätzt man sie, hält Abstand und übersieht dabei zwangsläufig einige der vielen Grenzen, die ein System gleichzeitig hat.

Man kann sich das wie ein Straßennetz vorstellen, dessen Messstelle an einer Nebenstraße hängt, während der Engpass an der Hauptzufahrt entsteht. Solange die Nebenstraße flüssig läuft, meldet die Anlage Entwarnung, auch wenn sich vor der Hauptzufahrt längst ein Stau aufbaut. Genau so war es hier: Die Replikate waren gesund, der Rückstand blieb unter der Schwelle. Die Sättigung saß am Primärknoten, und dort schaute niemand hin. Eine Metrik kann technisch korrekt sein und trotzdem die falsche Frage beantworten. Das ist keine Nachlässigkeit, sondern eine strukturelle Eigenschaft verteilter Systeme.

Der Blogbeitrag lässt an dieser Stelle Fragen offen. Wie genau führten die erschöpften Verbindungen zu Timeouts auf den Webservern? Der Autor vermutet Connection-Pooling: Ein Teil der Pool-Verbindungen war belegt, Clients warteten auf eine freie Verbindung, die nicht mehr kam. Und wie konnte ein einzelner Bereinigungsjob den Primärknoten über die Verbindungsgrenze treiben? Wie nah war die Datenbank schon vorher am Limit? Diese Lücken sind selbst ein Hinweis darauf, wie schwer sich solche Vorfälle im Rückblick rekonstruieren lassen.

Maximale Verbindungen, Timeouts und der Retry-Loop

Timeouts gehören zum Werkzeugkasten verteilter Systeme, aber sie sind asymmetrisch. Zu kurze Timeouts fallen im Normalbetrieb sofort auf: Man sieht die Abbrüche und verlängert sie. Zu lange Timeouts erzeugen kaum ein Signal. Vielleicht bemerkt man eine träge Oberfläche und sucht an der falschen Stelle. Oft gibt es bis zum ersten Vorfall keinen Hinweis darauf, dass irgendwo großzügig gerundet wurde. Lange Timeouts erhöhen die Zahl gleichzeitig laufender Anfragen und damit den Ressourcenverbrauch. Sie sind ein Sättigungsrisiko, das still im System liegt.

Mit Retries ist es ähnlich zwiespältig. Sie sind unverzichtbar, weil vorübergehende Fehler alltäglich sind, und sie verbergen diese Fehler vor den Nutzern. In einer Sättigungslage kippt die Wirkung ins Gegenteil: Wenn ein Dienst immer wieder dieselben fehlschlagenden Schreibvorgänge sendet, hält er die Datenbank unter Dauerlast und verhindert genau die Erholung, die er herbeiführen will. Für dieses Muster gibt es den Begriff Retry Storm. Timeouts wie Retries sind in der Theorie bewährte Schutzmaßnahmen und in der Praxis zwei Einstellungen, die kaum jemand überprüft, solange nichts brennt.

Aufräumen ist ein wiederkehrendes Risiko

Wer genug Incident Reports gelesen hat, erkennt ein Muster: Bereinigungsarbeiten tauchen überproportional häufig als Auslöser auf. Mal misslingt ein Aufräumjob, weil das zu entfernende Objekt noch in Gebrauch ist. Mal verhält sich eine längst ungenutzte Komponente gegenüber einem anderen Teil des Systems unerwartet. Und manchmal trägt umgekehrt das Ausbleiben von Aufräumarbeiten zum Vorfall bei, weil Altlasten weiterwirken. Beide Richtungen sind real und beide kosten.

Idealerweise stammt alle Abfragelast auf Produktionsdatenbanken aus Produktionsverkehr. Deshalb laufen Analyseabfragen üblicherweise auf getrennten Systemen. Es gibt aber Fälle, in denen das nicht geht: Wenn ein Job die Onlinedaten selbst verändern soll, muss er gegen die Onlinedatenbank laufen. Genau das war hier der Fall. Ein Datenbereinigungsjob, der ungenutzte Datensätze entfernt, ist eine gewollte Änderung am Bestand — und damit unvermeidlich eine Lastquelle im selben System, das gerade Nutzerverkehr bedient. Nicht aufzuräumen ist ein Risiko, aufzuräumen ebenfalls. Es bleibt eine Abwägung.

Was Ersthelfer brauchen, wenn die Lastquelle unklar ist

Bei einem Vorfall zählt zuerst die Wiederherstellung, nicht die Ursachenforschung. Lässt sich das Problem schnell einer fehlerhaften Auslieferung zuordnen, wird sie zurückgerollt und die Sache ist erledigt. In einer Sättigungslage ist das selten so einfach. Man erkennt meist schnell, welcher Dienst überlastet ist — oft eine Datenbank —, aber nicht, wer die Last erzeugt. Diese Unterscheidung war auch bei GitHub der zeitintensive Teil.

Für solche Situationen brauchen Responder zwei Fähigkeiten, und zwar sofort: Lastquellen schnell identifizieren, also sehen, welche Abfragen von wem kommen, und Last manuell abwerfen, indem einzelne Abfragen oder Quellen blockiert werden. Beides lässt sich nicht improvisieren. Wer diese Werkzeuge während des Vorfalls zum ersten Mal sucht, hat sie nicht. Sie müssen vorher gebaut, getestet und dokumentiert sein. Dieser Teil der Incident-Vorsorge entscheidet über die Dauer eines Ausfalls.

Dass die Ersthelfer interne Last abwarfen und den Job pausierten, war folgerichtig. Das behebt nicht die Ursache, stellt aber die Dienstfähigkeit wieder her und schafft Raum für die eigentliche Analyse. Der Abstand zwischen Auslöser und Wiederherstellung zeigt, wie viel Zeit allein das Verstehen kostet.

Was GitHub ändert — und was das konkret bedeutet

GitHub kündigt im Bericht mehrere Maßnahmen an. Hintergrundjobs gegen kundennahe Datenbanken werden künftig standardmäßig gedrosselt. Automatisches Pausieren und Alarmieren soll sich nicht mehr nur an Replica Lag orientieren, sondern an der Last des Primärservers. Laufende Hintergrundarbeit wird neben den Datenbank-Gesundheitssignalen sichtbar, sodass Responder sie aus demselben Dashboard pausieren können. Zusätzlich werden Retries im Pfad der Token-Ausgabe begrenzt, Timeouts auf Anfrageebene eingeführt und der Cluster aufgeteilt, um den Single Point of Failure zu beseitigen.

Fast alle diese Punkte erhöhen die Komplexität. Mehr Signale, mehr Automatik, mehr Drosselung, mehr Aufteilung. Das ist keine Überkonstruktion, sondern die ehrliche Antwort auf einen Fehler, der aus einer zu schmalen Beobachtung entstanden ist. Jede zusätzliche Sicherung ist zugleich ein neuer beweglicher Teil, der selbst ausfallen kann. Das Thema bleibt deshalb ein fortlaufender Prozess.

Für jedes Team mit einer zentralen Datenbank heißt das: Prüfe, welche Gesundheitsmetrik dein Backoff tatsächlich steuert, und ob sie den Engpass erfassen kann. Prüfe die Timeouts, die niemand angefasst hat, seit der Dienst gebaut wurde. Prüfe, ob ein Retry-Pfad bei anhaltender Sättigung aufhört oder weiterhämmert. Und prüfe, ob du während eines Vorfalls Last abwerfen kannst, ohne vorher Code zu schreiben. Die Grenze, an der ein System kippt, kennt man erst, wenn man sie überschritten hat. Vorher bleibt die Entscheidung, wie viel Abstand man hält — und wie viele der möglichen Grenzen man dabei im Blick hat.

Quelle: surfingcomplexity.blog

Deine Reaktion:
Artikel teilen:
Krötzsch-Check0 — 100
Fakten 85
Relevanz 80
Hype 20
Einschätzung 75
Redaktion 50 Stand 50 · noch keine Stimmen
Ist das Hype?
Sebastian Krötzsch
Autor

Sebastian Krötzsch

Sebastian Krötzsch schreibt auf sebask.de über Künstliche Intelligenz, Automatisierung, digitale Systeme und die Frage, was davon im Alltag wirklich nützlich ist. Ohne Buzzword-Nebel, dafür mit klarem Blick auf Praxis, Tools und echte Wirkung.