Datenbankadministration für Sysadmins

Datenbankvorfälle diagnostizieren: Kette, Eingriff und seine Kosten

Der Aufruf zum Beenden der blockierenden Sitzung liefert true. Fünf Minuten später steht sie unverändert in der Übersicht, die Sperren bestehen fort — und niemand hat einen Fehler gemacht: Ohne Zeitgrenze bestätigt der Rückgabewert laut Dokumentation nur den Versand des Signals. Dieses Modul liest Blockierungsketten, trennt Verursacher von Folgen und rechnet die Kosten eines Eingriffs aus, bevor er erfolgt — denn kein Abbruch ist schneller als die Arbeit, die er rückgängig machen muss.

Lehrtext · 11 Abschnitte · zuletzt geprüft: 2026-09-12

Der Eingriff ist die zweite Entscheidung

Bei einem Datenbankvorfall steht fast immer dieselbe Frage im Raum: „Können wir die Sitzung nicht einfach beenden?“ Meistens kann man. Die Frage ist nur nicht, ob es geht, sondern was danach passiert — und diese zweite Frage lässt sich nicht mehr stellen, wenn der Eingriff schon erfolgt ist.

Bei einem Webserver ist ein Neustart billig: Der Prozess startet, der Zustand war ohnehin woanders. Bei einer Datenbank ist der Zustand das Produkt. Eine beendete Sitzung nimmt ihre offene Transaktion mit, und das Zurücknehmen dieser Transaktion ist eine eigene, oft gleich große Arbeit.

Der Satz, der dieses Modul zusammenfasstEs gibt keinen Eingriff, der schneller ist als die Arbeit, die er rückgängig machen muss. Wer eine Sitzung beendet, die seit 40 Minuten schreibt, hat nicht 40 Minuten gespart — er hat sie sich ein zweites Mal eingehandelt.

Was vor jedem Eingriff feststehen muss

Drei Angaben entscheiden über die Wahl der Maßnahme. Sie zu erheben dauert Minuten und ist fast immer schneller als der erste falsche Eingriff.

Wirkung
Wer ist betroffen — eine Auswertung, die Kasse, oder niemand? Ohne betroffenen Anwender ist es ein Messwert, kein Vorfall.
Zeitfenster
Seit wann? Und was hat sich in diesem Fenster geändert — eine Auslieferung, ein Wartungsauftrag, ein Datenimport?
Zustand
Blockiert etwas, oder ist alles langsam? Die beiden führen zu völlig verschiedenen Maßnahmen.

Die dritte Zeile ist die, die am häufigsten übersprungen wird. Eine Blockierung ist eine Sitzung, die auf eine andere wartet — dort gibt es einen Verursacher, und der Eingriff ist gezielt. Allgemeine Langsamkeit hat keinen Verursacher, den man beenden könnte; wer dort Sitzungen beendet, würfelt.

Der Unterschied ist messbar, nicht gefühltIn PostgreSQL trennt die Spalte wait_event_type die Fälle: Steht dort Lock, wartet die Sitzung auf eine andere Sitzung. Bei SQL Server nennt blocking_session_id in sys.dm_exec_requests die blockierende Sitzung direkt. Ist die Spalte leer beziehungsweise null, liegt keine Blockierung vor — oder sie lässt sich nicht ermitteln; beides fällt laut Dokumentation auf denselben Wert zusammen.

Die Kette lesen: wer blockiert wen

Blockierungen bilden Ketten. Zehn wartende Sitzungen sind in aller Regel ein Verursacher und neun Folgen. Der Fehler, der die Lage verschlimmert, besteht darin, die Folgen zu beenden.

Zehn wartende Sitzungen, ein Verursacher

Szenario

Die Anwendung meldet Hänger. In der Sitzungsübersicht warten zehn Sitzungen auf eine Sperre, eine elfte wartet auf nichts.

Anforderungen

  • Lesezugriff auf die Sitzungs- und Sperrsichten
  • Noch kein Eingriff — nur Feststellung

Schritte

  1. Die Wartenden ausschließen: Wer selbst wartet, blockiert niemanden ursächlich. Gesucht ist die Sitzung, auf die gewartet wird und die selbst nicht wartet.
  2. Ihren Zustand ansehen. Steht dort active, arbeitet sie — dann ist Geduld oft die bessere Maßnahme als ein Abbruch.
  3. Steht dort idle in transaction, arbeitet sie nicht, hält aber ihre Sperren. Das ist der Fall, in dem ein Eingriff wirklich etwas löst — und meist ein Anwendungsfehler dahintersteckt.
  4. Erst jetzt klären, wem die Sitzung gehört und was sie begonnen hat. Der Anwendungsname und der Benutzer stehen in derselben Übersicht.

Merksatz: Neun der zehn Wartenden zu beenden ändert nichts an der Ursache — es erzeugt nur neun fehlgeschlagene Vorgänge zusätzlich zur bestehenden Blockade.

Die zwei Zustände, die den Eingriff entscheidenactive heißt: Die Sitzung rechnet. Ein Abbruch wirft die bisherige Arbeit weg. idle in transaction heißt: Die Sitzung hält Sperren, ohne Fortschritt zu machen — hier kostet der Abbruch am wenigsten und bringt am meisten. Die Unterscheidung steht in einer einzigen Spalte und wird trotzdem regelmäßig übersehen.

Die Sperrsicht — und was sie nicht zeigt

Neben der Sitzungsübersicht gibt es die Sperrsicht pg_locks. Sie führt laut Dokumentation eine Zeile je sperrbarem Objekt, angefordertem Sperrmodus und beteiligtem Prozess — dasselbe Objekt kann also mehrfach erscheinen, wenn mehrere Prozesse darauf halten oder warten. Ein Objekt ohne Sperre erscheint gar nicht.

granted = true
Der Prozess hält diese Sperre.
granted = false
Der Prozess wartet darauf. Das bedeutet, dass mindestens ein anderer Prozess einen konfliktierenden Modus hält oder ebenfalls wartet.
waitstart
Seit wann gewartet wird; null, solange die Sperre gehalten wird. Kann kurz nach Wartebeginn noch null sein, obwohl granted bereits falsch ist.
mode
Der gehaltene oder gewünschte Sperrmodus.
Der Befund, der die Suche sonst ins Leere laufen lässtZeilensperren erscheinen in dieser Sicht normalerweise nicht. Die Dokumentation erklärt warum: Informationen über Sperren auf Zeilenebene liegen auf der Platte, nicht im Arbeitsspeicher. Wartet ein Prozess auf eine Zeilensperre, erscheint er in der Sicht stattdessen als wartend auf die dauerhafte Transaktionskennung desjenigen, der die Zeilensperre gerade hält. Wer in pg_locks nach der gesperrten Zeile sucht, findet sie nicht — und schließt fälschlich, es gebe keine Blockade.

Auch die naheliegende Auswertung führt in die Irre. Die Dokumentation rät ausdrücklich davon ab, Blockierungsbeziehungen durch einen Verbund der Sicht mit sich selbst zu ermitteln: Man müsste dafür wissen, welche Sperrmodi miteinander in Konflikt stehen, und die Sicht gibt überdies nicht preis, welcher Prozess in einer Warteschlange vor welchem steht oder welche parallelen Arbeitsprozesse zu welcher Clientsitzung gehören. Empfohlen wird stattdessen die Funktion pg_blocking_pids(), die zu einem wartenden Prozess direkt die blockierenden nennt.

Und die Sicht ist nicht kostenlosUm konsistente Ergebnisse zu liefern, sperrt die Abfrage kurzzeitig die Sperrverwaltung selbst. Die Dokumentation hält fest, dass ein sehr häufiger Zugriff auf diese Sicht die Leistung beeinträchtigen kann. Als Bestandteil einer Überwachung im Sekundentakt ist sie deshalb die falsche Wahl — als gezielter Griff im Vorfall die richtige.

Bei SQL Server erfüllt sys.dm_tran_locks dieselbe Aufgabe; für die Zuordnung wartender Teilaufgaben kommt sys.dm_os_waiting_tasks dazu. Der kürzeste Weg bleibt dort aber die Spalte blocking_session_id in sys.dm_exec_requests.

Abbrechen oder Beenden — zwei verschiedene Eingriffe

PostgreSQL bietet zwei Funktionen an, die oft für Varianten derselben Sache gehalten werden. Sie sind es nicht, und der Unterschied ist im Ernstfall erheblich.

pg_cancel_backend(pid)
Bricht die aktuell laufende Abfrage der Sitzung ab. Die Sitzung bleibt bestehen, die Verbindung der Anwendung auch. Gesendet wird ein SIGINT.
pg_terminate_backend(pid)
Beendet die gesamte Sitzung. Die Verbindung der Anwendung bricht ab, eine offene Transaktion wird zurückgerollt. Gesendet wird ein SIGTERM.

Die Reihenfolge ist damit vorgegeben: Erst abbrechen, und nur wenn das nicht reicht, beenden. Ein Abbruch trifft genau die störende Abfrage; ein Beenden trifft zusätzlich alles, was die Anwendung auf dieser Verbindung sonst noch vorhatte, und hinterlässt je nach Verbindungsverwaltung einen Fehler, den die Anwendung nicht erwartet.

Wer das darfBeide Funktionen sind laut Dokumentation auch dann erlaubt, wenn die aufrufende Rolle Mitglied der Rolle ist, deren Sitzung getroffen wird, oder die Rechte der Rolle pg_signal_backend besitzt. Sitzungen von Superusern können jedoch nur Superuser abbrechen oder beenden. Ein Überwachungs- oder Bereitschaftskonto braucht also entweder die passende Mitgliedschaft oder diese Rolle — sonst scheitert der Eingriff genau dann, wenn er gebraucht wird.

Die Rückmeldung, die nichts bestätigt

Der Aufruf zum Beenden liefert einen Wahrheitswert zurück, und dieser Wert wird fast immer falsch gelesen.

Wörtlich aus der DokumentationWird keine Zeitgrenze angegeben oder ist sie null, gibt die Funktion `true` zurück, unabhängig davon, ob der Prozess tatsächlich endet — sie zeigt nur an, dass das Senden des Signals erfolgreich war. Wird eine Zeitgrenze in Millisekunden größer als null angegeben, wartet die Funktion, bis der Prozess wirklich beendet ist oder die Zeit abgelaufen ist. Endet er, gibt sie true zurück; bei Zeitüberschreitung wird eine Warnung ausgegeben und false zurückgegeben.

Der voreingestellte Aufruf bestätigt also den Versand eines Signals, nicht dessen Wirkung. Wer daraufhin „erledigt“ meldet und die Sperre besteht weiter, hat nichts falsch gemacht außer die Rückmeldung zu überdehnen. Der Prozess kann mitten in einem Rollback stecken, der Minuten dauert.

Die Konsequenz ist einfach und wird trotzdem selten gezogen: Entweder eine Zeitgrenze mitgeben und den Rückgabewert dann ernst nehmen — oder nach dem Aufruf in der Sitzungsübersicht nachsehen, ob die Prozesskennung verschwunden ist. Die Bestätigung liegt in der Beobachtung, nicht im Rückgabewert.

Kurzcheck

pg_terminate_backend hat true geliefert, die blockierende Sitzung steht aber weiter in der Übersicht. Was ist der wahrscheinlichste Grund?

  • Das Signal wurde gesendet, der Prozess räumt noch auf
  • Der Aufruf hat die falsche Prozesskennung getroffen
  • Die Sicht aktualisiert sich nur alle paar Minuten

Treffer. Richtig. Ohne Zeitgrenze bestätigt der Rückgabewert nur den Versand. Ein Prozess mit großer offener Transaktion braucht für das Zurücknehmen so lange, wie die Arbeit gedauert hat.

Der Rollback ist die zweite Hälfte der Arbeit

Was nach einem Beenden passiert, ist kein Aufräumen im Sinne von Wegräumen, sondern das Rückwärtsausführen aller Änderungen der offenen Transaktion. Das ist echte Schreibarbeit mit echtem Protokollaufkommen.

Daraus folgt eine Faustregel, die im Vorfall unbequem ist: Je länger eine schreibende Transaktion schon läuft, desto teurer wird ihr Abbruch. Bei einem Massenupdate, das seit einer Stunde läuft, kann das Zurücknehmen eine weitere Stunde dauern — und während dieser Stunde hält die Sitzung ihre Sperren weiter. Der Eingriff, der die Blockade beenden sollte, verlängert sie.

Warum „einfach den Dienst neu starten“ das nicht abkürztEin Neustart macht das Zurücknehmen nicht überflüssig — er verschiebt es in die Wiederherstellungsphase beim Hochfahren. Die Datenbank ist dann nicht teilweise, sondern vollständig nicht verfügbar, und die Arbeit fällt trotzdem an. Aus einer Blockade wird so ein Ausfall.

Die nützliche Gegenfrage lautet deshalb: Ist Warten billiger? Eine Sitzung, die zu 90 Prozent durch ist, läuft in wenigen Minuten durch. Dieselbe Sitzung abzubrechen kostet die bisherige Laufzeit noch einmal. Diese Abwägung setzt allerdings voraus, dass man den Fortschritt kennt — und genau das ist bei einem laufenden Befehl oft nicht feststellbar. Wo der Fortschritt unbekannt ist, entscheidet die Geschäftswirkung, nicht die Technik.

SQL Server: `KILL`, Fortschritt und die Falle des zweiten Versuchs

SQL Server kennt nur einen Befehl für den Eingriff, dafür aber eine Möglichkeit, den Fortschritt des Zurücknehmens abzufragen — und eine dokumentierte Falle, die genau dann zuschlägt, wenn man ungeduldig wird.

Nach einem KILL zeigt sp_who für die betroffene Sitzung in der Spalte cmd den Wert KILLED/ROLLBACK, solange das Zurücknehmen läuft. Den Fortschritt liefert KILL <sitzung> WITH STATUSONLY: Der Bericht nennt laut Dokumentation den abgeschlossenen Anteil des Zurücknehmens in Prozent und die geschätzte Restzeit in Sekunden. Dieser Aufruf beendet nichts und rollt nichts zurück — er zeigt nur den Stand.

Die Falle, die die Dokumentation ausdrücklich benenntDenselben Statusbericht bekäme man auch, indem man schlicht dasselbe KILL noch einmal absetzt. Davon rät die Dokumentation ausdrücklich ab: Wird das Zurücknehmen zwischenzeitlich fertig und die Sitzungskennung einer neuen Aufgabe zugewiesen, bevor das zweite `KILL` ausgeführt wird, beendet dieses den neuen Prozess. Wer aus Ungeduld ein zweites Mal beendet, trifft unter Umständen eine völlig unbeteiligte Sitzung. Der sichere Weg ist WITH STATUSONLY.

Sitzungskennungen werden also wiederverwendet. Das ist der eigentliche Lehrsatz dieses Abschnitts, und er gilt über SQL Server hinaus: Eine Kennung, die man sich vor fünf Minuten notiert hat, identifiziert möglicherweise heute etwas anderes. Jeder wiederholte Eingriff gehört deshalb auf einer frisch erhobenen Liste geprüft, nicht auf einer notierten.

Was man nicht beendet

Nicht jede Sitzung in der Übersicht ist ein zulässiges Ziel, und einige sind es technisch, aber nicht fachlich.

  • Systemprozesse. Die Dokumentation hält fest, dass Systemprozesse und Prozesse, die eine erweiterte gespeicherte Prozedur ausführen, nicht beendet werden können.
  • Die eigene Sitzung. Ein KILL auf den eigenen Prozess ist laut Dokumentation nicht möglich — was im Ernstfall zu einer verwirrenden Fehlermeldung führt, wenn man die Kennung verwechselt hat.
  • Wartende Sitzungen. Sie sind die Folge, nicht die Ursache. Sie zu beenden erzeugt fehlgeschlagene Vorgänge und löst die Blockade nicht.
  • Hintergrundvorgänge der Engine. Aufräumvorgänge sehen aus wie lang laufende Last und sind meist genau das, was gerade laufen sollte. Wer sie abbricht, verschiebt Arbeit in die Zukunft und vergrößert sie.
Die Ausnahme, die man kennen solltePostgreSQL macht für Aufräumprozesse eine ausdrückliche Sonderregel: Rollen mit den Rechten von pg_signal_autovacuum_worker dürfen diese abbrechen oder beenden, obwohl sie sonst als Superuser-Sitzungen gelten. Dass es diese eigene Rolle gibt, ist selbst ein Hinweis — der Eingriff ist vorgesehen, aber bewusst von den übrigen getrennt.

Beweise sichern, bevor sie verschwinden

Fast alles, was einen Vorfall erklärt, steht in flüchtigen Sichten. Wird die Sitzung beendet, ist sie aus der Übersicht verschwunden — und mit ihr der Abfragetext, der Anwendungsname und der Wartegrund. Die Ursachenanalyse am nächsten Tag findet dann nichts mehr vor.

Die Reihenfolge ist deshalb: erst erfassen, dann eingreifen. Eine einzige Abfrage auf die Sitzungsübersicht, deren Ergebnis in eine Datei oder ins Ticket geht, kostet Sekunden und ist hinterher nicht mehr nachholbar.

  • Die vollständige Sitzungsliste mit Zustand, Wartegrund, Startzeit der Transaktion, Benutzer und Anwendungsname.
  • Die Blockierungsbeziehungen, also wer auf wen wartet.
  • Den Abfragetext der verursachenden Sitzung — im Bewusstsein, dass er voreingestellt bei 1024 Byte abgeschnitten ist.
  • Den Zeitpunkt des Eingriffs selbst, damit spätere Protokolleinträge zuzuordnen sind.
Was im Nachhinein hilft, wenn es vorher eingeschaltet warlog_lock_waits erzeugt laut Dokumentation einen Protokolleintrag, sobald eine Sitzung länger als deadlock_timeout auf eine Sperre wartet. Voreingestellt ist die Einstellung aus. Sie einzuschalten ist eine Vorsorgemaßnahme, keine Diagnose — aber sie ist der Unterschied zwischen einer rekonstruierbaren und einer unerklärlichen Blockade von vorletzter Woche.

Die Reihenfolge unter Druck

Wirkung bestätigen — wer ist betroffen?Blockierung von allgemeiner Langsamkeit trennenVerursacher finden, Wartende ausschließenBeweise sichern, bevor etwas verschwindetAbbrechen vor Beenden — und Wirkung nachsehen
Beweis vor Eingriff

Der letzte Halbsatz trägt den ganzen Ablauf. Kein Rückgabewert und keine Erfolgsmeldung ersetzt den Blick in die Sitzungsliste danach. Beide Systeme geben Bestätigungen zurück, die weniger bedeuten, als sie zu bedeuten scheinen — die eine bestätigt nur den Versand eines Signals, die andere lässt sich durch eine neu vergebene Kennung täuschen.

Preis dieser ReihenfolgeSie kostet im Vorfall die teuerste Währung: Minuten, während der Dienst steht und jemand danebensteht. Sie ist trotzdem richtig, weil der falsche Eingriff nicht nur nichts löst, sondern die Lage verschlechtert — durch einen Rollback, der länger dauert als das Problem, oder durch eine beendete Sitzung, die mit dem Vorfall nichts zu tun hatte. Wer die Wirkung bereits kennt, darf die erste Stufe abkürzen; die vierte nicht.
AbgrenzungDie Instrumente selbst — welche Sicht was zeigt, Momentaufnahme gegen kumulative Zähler — stehen im Modul über das Beobachten des Datenbankzustands. Warum Sperren überhaupt entstehen und wie lange sie gehalten werden, steht im Modul über Transaktionen und Isolationsstufen. Vorfallskoordination, Eskalation und Kommunikation als Handwerk stehen im Track monitoring-incident-operations. Hier ging es allein um den Eingriff an der Datenbank und seine Folgen.

Jetzt anwenden

Diesen Stoff gibt es als Modul mit bewerteten Entscheidungs-Checks — dieselbe Einführung, danach die Übungen.

Zum Modul →
Quellen & Aktualität7 Primärquellen · zuletzt geprüft:
  1. 01postgresql.org/docs/current/functions-admin.html
  2. 02postgresql.org/docs/current/monitoring-stats.html
  3. 03postgresql.org/docs/current/explicit-locking.html
  4. 04postgresql.org/docs/current/view-pg-locks.html
  5. 05postgresql.org/docs/current/runtime-config-logging.html
  6. 06learn.microsoft.com/en-us/sql/t-sql/language-e…ts/kill-transact-sql
  7. 07learn.microsoft.com/en-us/sql/relational-datab…equests-transact-sql