Wissen

Praxis-Artikel und Buchkapitel zu SQL-Performance, Sicherheit und Hochverfügbarkeit – alle frei verfügbar.

Beratung

Festpreis-Analyse mit Bericht und Handlungsempfehlung – oder strategische Begleitung bei Architektur, Migration und Hochverfügbarkeit.

Fachbücher

Die fünfbändige Reihe „Ulis SQL-Bibliothek“ – Band 1 verfügbar. Leseprobe herunterladen!

Tools

UB.SimSQL: SQL-Server-Lastsimulator mit regelbasierten Konfigurationsempfehlungen. Lokal, ohne Cloud, ohne Abo.

Schulungen

Online-Workshops zu Performance, Sicherheit und Entwicklung – kompakt, hands-on, ohne MOC-Folienschlacht.

SQL Server Transaktionslog voll

Warum Fehler 9002 dankbarer ist, als er aussieht – und wie log_reuse_wait_desc den Weg zur Lösung weist.

Transaktionslog vollgelaufen

Schreibvorgänge stoppen mit Fehler 9002. Die Diagnose über log_reuse_wait_desc, alle relevanten Werte mit Lösungsweg — und die zwei Anti-Patterns, die alles schlimmer machen.

Es ist Donnerstagnachmittag, 16:38 Uhr, bei Sparfuchs & Partner. Die Buchhaltung will den Tagesabschluss buchen — und bekommt eine Fehlermeldung, die niemand kennt: „Das Transaktionsprotokoll für die Datenbank ist voll.“ Sekunden später meldet auch das Lager, dass keine Warenbewegungen mehr gespeichert werden. Der Server läuft, die CPU ist entspannt, der Speicher reicht — und trotzdem geht nichts mehr, weil der SQL Server schlicht nicht mehr schreiben kann. Fehler 9002. Und während jemand schon reflexhaft fragt, ob man nicht einfach das Recovery-Model umstellen oder das Log „kleinmachen“ kann, lautet die einzig richtige erste Handlung: den Server fragen, warum das Log nicht freigegeben wird.

Willkommen bei einem der häufigsten und zugleich am elegantesten diagnostizierbaren Notfälle aus dem SQL-Server-Notarztwagen (die Triage-Übersicht liegt unter /sql-server-notarztwagen/). Ein volles Transaktionslog ist deshalb so dankbar, weil der SQL Server die Ursache fast immer selbst beim Namen nennt — in einer einzigen Spalte namens log_reuse_wait_desc. Dieser Beitrag zeigt dir, wie du diesen einen Befund abfragst, was die wichtigsten Werte bedeuten und wie du sie sicher löst — und vor allem die zwei verlockenden Anti-Patterns, die im Notfall alles nur schlimmer machen.

Was „das Log ist voll“ technisch bedeutet

Das Transaktionslog ist das Gedächtnis des SQL Servers für jede Änderung. Nach dem Prinzip „erst schreiben, dann tun“ landet jede Datenänderung zuerst im Log, bevor sie in der eigentlichen Datendatei wirksam wird — das garantiert, dass nach einem Absturz alles sauber wiederhergestellt oder zurückgerollt werden kann. Genau deshalb ist ein volles Log so fatal: Wenn das Log keinen Platz mehr hat, kann keine Änderung mehr ins Log geschrieben werden, und damit ist jeder Schreibvorgang blockiert. Lesen geht meist noch, aber Inserts, Updates und Deletes stoppen schlagartig mit Fehler 9002. Der Server lebt, aber er ist gelähmt.

Der entscheidende Denkfehler, den man im Notfall vermeiden muss: „Log voll“ heißt nicht automatisch, dass die Festplatte voll ist. Viel häufiger ist die Platte noch halb leer, aber der SQL Server kann den vorhandenen Log-Raum nicht wiederverwenden. Das Log funktioniert nämlich ringförmig: Abgeschlossene, gesicherte Bereiche werden zur Wiederverwendung freigegeben, sodass das Log immer im Kreis weiterschreiben kann, ohne ewig zu wachsen. Blockiert aber irgendetwas diese Freigabe, füllt sich das Log bis zum Anschlag — obwohl rein physisch noch Platz wäre. Die Frage ist also fast nie „warum ist die Platte voll“, sondern „warum gibt der Server den Log-Raum nicht frei“.

Und genau diese Frage beantwortet der SQL Server selbst — in der Spalte log_reuse_wait_desc der Systemsicht sys.databases. Sie enthält ein einziges Schlüsselwort, das exakt benennt, worauf die Log-Freigabe gerade wartet: LOG_BACKUP (es fehlt die Log-Sicherung), ACTIVE_TRANSACTION (eine offene Transaktion blockiert), AVAILABILITY_REPLICA (ein Always-On-Replica hinkt) und einige mehr. Dieser eine Wert verwandelt die Diagnose von Raterei in eine gezielte Abfrage — man muss nicht vermuten, woran es liegt, der Server sagt es. Das ist in der SQL-Server-Welt eher die Ausnahme als die Regel: Bei den meisten Notfällen muss man die Ursache mühsam aus Symptomen erschließen. Beim vollen Log dagegen hängt direkt ein Schild an der Tür, auf dem steht, was klemmt. Genau deshalb ist dieser Notfall trotz seiner dramatischen Wirkung — der ganze Schreibbetrieb steht — einer der dankbarsten überhaupt: Wer den einen Befund liest und seine Bedeutung kennt, hat das Problem meist in wenigen Minuten und ohne jedes Risiko gelöst. Die Kunst liegt nicht im Finden der Ursache, sondern allein darin, der Versuchung der falschen Abkürzungen zu widerstehen.

Der entscheidende Aha-Moment

Log voll ≠ Platte voll. Meist ist physisch noch Platz, aber der Server kann den Log-Raum nicht wiederverwenden.
log_reuse_wait_desc nennt den Grund. Ein Wort sagt, worauf die Freigabe wartet — LOG_BACKUP, ACTIVE_TRANSACTION usw.
Erst diesen Wert lesen, dann gezielt handeln — niemals blind schrumpfen oder das Recovery-Model umstellen.

Der Entscheidungsbaum nach log_reuse_wait_desc

Der ganze Notfall hängt an einem Wort. Der folgende Baum zeigt, was die wichtigsten Werte von log_reuse_wait_desc bedeuten, wie du jeden löst — und die zwei Anti-Patterns, die du um jeden Preis vermeidest:

Die Skripte: den Grund lesen und gezielt lösen

Schritt 1 — Den einen Befund abfragen

Die wichtigste Abfrage des ganzen Notfalls — sie zeigt für jede Datenbank, ob und worauf die Log-Freigabe wartet:

— DER Schluessel: warum wird das Log nicht freigegeben?

SELECT name AS Datenbank,

recovery_model_desc AS RecoveryModel,

log_reuse_wait_desc AS WartetAuf

FROM sys.databases

WHERE database_id > 4

ORDER BY name;

 

— Wie voll ist das Log konkret?

SELECT DB_NAME(database_id) AS Datenbank,

total_log_size_in_bytes / 1024 / 1024 AS LogGroesseMB,

used_log_space_in_percent AS BelegtProzent

FROM sys.dm_db_log_space_usage;

Der Wert in WartetAuf bestimmt alles Weitere. Steht dort LOG_BACKUP, ist die Lösung eine Log-Sicherung. Steht dort ACTIVE_TRANSACTION, musst du die offene Transaktion finden. Steht dort NOTHING, ist das Log gerade nicht blockiert — dann ist die Datei schlicht zu klein für die Last und muss vergrößert (oder die Last verkleinert) werden. Die zweite Abfrage liefert dazu den Füllstand in Prozent und die absolute Größe — wichtig, um zwischen „randvoll und blockiert“ und „klein, aber gerade noch atmend“ zu unterscheiden. Ein Log bei 99 Prozent mit einem klaren LOG_BACKUP-Befund ist ein anderer Fall als eines, das bei 100 Prozent steht, weil eine einzelne riesige Operation es überfordert — die Kombination aus Befund und Füllstand zeichnet das vollständige Bild.

Schritt 2 — Der häufigste Fall: LOG_BACKUP lösen

Bei LOG_BACKUP ist die Lösung sicher und einfach: eine Log-Sicherung gibt den Raum sofort frei, ohne Datenverlust:

— Log-Sicherung gibt den Log-Raum sofort wieder frei

BACKUP LOG [MeineDB]

TO DISK = 'B:\sql\MeineDB_LOG.trn'

WITH COMPRESSION;

 

— Danach pruefen: ist used_log_space_in_percent gesunken?

SELECT DB_NAME(database_id) AS DB, used_log_space_in_percent

FROM sys.dm_db_log_space_usage;

Schritt 3 — ACTIVE_TRANSACTION: den Verursacher finden

— Aelteste offene Transaktion der aktuellen Datenbank

DBCC OPENTRAN;

 

— Detailliert: welche Session haelt welche Transaktion wie lange offen?

SELECT st.session_id,

at.transaction_begin_time,

DATEDIFF(MINUTE, at.transaction_begin_time, GETDATE()) AS OffenMin,

es.login_name, es.host_name, es.program_name

FROM sys.dm_tran_active_transactions AS at

JOIN sys.dm_tran_session_transactions AS st

ON st.transaction_id = at.transaction_id

JOIN sys.dm_exec_sessions AS es

ON es.session_id = st.session_id

ORDER BY at.transaction_begin_time;

Die älteste Transaktion mit der höchsten OffenMin ist der Übeltäter. Prüfe über program_name und host_name, woher sie kommt — oft eine hängende Anwendung oder eine vergessene, offen gelassene Transaktion in einem Abfragefenster. Beenden mit Bedacht: Das Rollback einer großen Transaktion kann selbst dauern und Log-Raum brauchen.

Die wichtigsten log_reuse_wait_desc-Werte im Überblick

Diese Werte decken die allermeisten Fälle ab — jeder mit seiner eigenen, klaren Lösung:

LOG_BACKUP — die fehlende Log-Sicherung

Der häufigste Wert. Die Datenbank läuft im FULL-Model, aber es fehlt die Log-Sicherung. Lösung: BACKUP LOG. Tritt es wiederholt auf, fehlt ein regelmäßiger Log-Backup-Job — ein Fall für die Backup-Strategie (/sql-server-backup-strategie/).

ACTIVE_TRANSACTION — die offene Transaktion

Eine lange offene oder vergessene Transaktion hält das Log fest. Lösung: über DBCC OPENTRAN finden, Verursacher prüfen, mit Bedacht beenden. Keine Log-Sicherung hilft hier.

AVAILABILITY_REPLICA — der hinkende Always-On-Replica

Ein Secondary in der Verfügbarkeitsgruppe kommt mit der Synchronisierung nicht hinterher, deshalb darf das Log auf dem Primary nicht freigegeben werden. Lösung: die Sync-Strecke prüfen — ausführlich im Always-On-Beitrag (/sql-server-always-on-sync/).

REPLICATION — die hängende Replikation

Transaktionsreplikation, deren Log-Reader-Agent nicht hinterherkommt oder steht, hält das Log fest. Lösung: den Status der Replikation und ihrer Agenten prüfen und die Aufstauung auflösen.

NOTHING — das Log ist schlicht zu klein

Steht dort nichts, ist das Log gerade nicht blockiert — es ist nur zu klein für die Last (etwa eine große einmalige Datenoperation). Hier ist das kontrollierte Vergrößern der Logdatei oder das Aufteilen der Operation in kleinere Häppchen die richtige Antwort, nicht das Suchen nach einem Blockierer.

Was du auf keinen Fall tun solltest

  • Nicht: Das Recovery-Model auf SIMPLE umstellen, um Platz zu schaffen. Das kappt die Log-Sicherungskette und zerstört jedes Point-in-Time-Recovery und das Tail-Log-Backup. Du tauschst ein lösbares Log-Problem gegen ein klaffendes Loch in der Wiederherstellbarkeit — das merkst du erst, wenn das nächste Backup gebraucht wird.
  • Nicht: Blind DBCC SHRINKFILE als Dauerlösung verwenden. Schrumpfst du ein Log, das gleich wieder wächst, entsteht Datei-Fragmentierung, die Performance kostet — und das Symptom kehrt zurück. Shrink ist eine seltene Aufräummaßnahme nach behobener Ursache, nie die Lösung selbst.
  • Nicht: Raten, statt log_reuse_wait_desc zu lesen. Der Server nennt den Grund beim Namen. Wer ohne diesen Befund herumprobiert, behandelt das falsche Problem — eine Log-Sicherung hilft bei ACTIVE_TRANSACTION nicht, das Transaktions-Suchen bei LOG_BACKUP nicht.
  • Nicht: Eine große offene Transaktion reflexhaft killen. Das Rollback kann selbst lange dauern und zusätzlichen Log-Raum verbrauchen — im schlimmsten Fall verschärfst du die Lage. Erst verstehen, was die Transaktion tut, dann mit Bedacht entscheiden.
  • Die drei häufigsten Anfängerfehler

    1. Sofort auf SIMPLE umstellen — und damit die Wiederherstellbarkeit opfern, um einen Notfall zu lösen, den eine Log-Sicherung sauber gelöst hätte.
    2. Das Log blind schrumpfen — und ein Schrumpfen-Wachsen-Karussell mit Fragmentierung in Gang setzen, das die Ursache nie berührt.
    3. Ohne log_reuse_wait_desc loslegen. Der Befund ist gratis und eindeutig — ihn zu ignorieren heißt, blind das falsche Problem zu behandeln.

    Nachsorge: damit es nicht wiederkommt

    Ein einmal vollgelaufenes Log ist fast immer ein Symptom einer Lücke in der Routine — und die schließt man in der Nachsorge. Drei Schritte: Erstens, bei wiederholtem LOG_BACKUP den Log-Sicherungs-Job einrichten oder sein Intervall verkürzen — wer alle 15 Minuten das Log sichert, läuft praktisch nie voll und begrenzt nebenbei den Datenverlust im Ernstfall. Zweitens, die Logdatei sinnvoll dimensionieren: ein Log, das ständig wachsen muss, ist langsam und fragmentiert; besser einmal auf die realistische Größe bringen und dort belassen. Drittens, das Recovery-Model bewusst wählen — FULL für transaktionale Datenbanken mit Log-Sicherungen, SIMPLE nur als bewusste Entscheidung für tagverträgliche Datenbanken, nie als Notfall-Trick. Ein Sonderfall ist das BULK_LOGGED-Model für die Dauer großer Massenoperationen: Es protokolliert solche Operationen minimal und hält damit das Log-Wachstum bei einem großen Import oder Index-Rebuild in Grenzen, ohne die Sicherungskette zu kappen — ein gezieltes Werkzeug für geplante Wartungsfenster, nicht der Dauerzustand. Wie all das in eine durchdachte Sicherungsplanung passt, zeigt der Backup-Strategie-Beitrag.

    Vertiefung in der Buchreihe

    Transaktionslog-Mechanik, Recovery-Modelle und Backup-Architektur füllen in der Buchreihe „SQL Server in der Praxis“ eigene Kapitel — alle Bände in der Übersicht auf der SQL-Pillar-Seite unter /sql-server/.

    Empfohlene Bände

    Band 1: Performance & Troubleshooting — das Heimatbuch dieses Beitrags: Transaktionslog-Mechanik, die log_reuse_wait_desc-Werte und die Diagnose offener Transaktionen.
    Band 3: Hochverfügbarkeit & Disaster Recovery — die Recovery-Modelle, Log-Sicherungsketten und das Zusammenspiel von Log und Backup-Strategie.

    Verwandte Notfälle im Notarztwagen

    Ein volles Log hat enge Nachbarn — diese Beiträge sind die nächste Station:

  • Backup schlägt fehl — Fehleranalyse (/sql-server-backup-schlaegt-fehl/) — wenn die Log-Sicherung selbst nicht läuft und deshalb das Log volläuft.
  • SQL Server hängt vollständig (/sql-server-haengt-vollstaendig/) — wenn der Schreibstopp den ganzen Server lahmlegt: der Notausgang DAC.
  • Datenbank im Status Recovery Pending (/sql-server-recovery-pending/) — verwandter Recovery-Notfall, oft auch mit Log- oder Speicher-Bezug.
  • Backup-Strategie planen (/sql-server-backup-strategie/) — die strukturelle Vorsorge, die das volle Log gar nicht erst entstehen lässt.
  • Drei Wege, wenn das Log jetzt gerade voll ist

    Akut-Hotline

    Wenn das Log in diesem Moment voll ist und keine Buchung mehr durchgeht: anrufen. Halte den einen Befund bereit — den Wert aus log_reuse_wait_desc — und das Recovery-Model der Datenbank. Mit diesen zwei Informationen ist die Lösung meist in Minuten klar: bei LOG_BACKUP eine Log-Sicherung, bei ACTIVE_TRANSACTION die gezielte Behandlung der offenen Transaktion — sicher und ohne den Griff zu SIMPLE oder Shrink, der alles schlimmer macht.

    Festpreis-Analyse

    Wenn das Log immer wieder volläuft und du die Ursache strukturell abstellen willst? Die Festpreis-Analyse liefert sie: Ich prüfe die Log-Sicherungsstrategie und ihre Intervalle, die Recovery-Modelle, die Logdatei-Dimensionierung und etwaige Dauer-Blockierer wie hinkende Replicas — und liefere einen Bericht mit priorisierten Maßnahmen, der den nächsten Schreibstopp verhindert. Zum vereinbarten Festpreis, ohne Stundenzähler.

    Selbst-Diagnose-Kit

    Für alle, die den nächsten Log-Notfall selbst sicher lösen wollen: Das Diagnose-Kit bündelt die Skripte aus diesem Beitrag — die log_reuse_wait_desc-Abfrage, die Füllstands-Prüfung, die Suche nach offenen Transaktionen — plus den Entscheidungsbaum zum Ausdrucken und eine Werte-Tabelle, die jeden log_reuse_wait_desc-Wert seiner Lösung zuordnet. Damit liest du im Ernstfall den Befund und handelst gezielt, statt zu raten.

    Ein letzter Tipp

    Prüfe heute, solange alles läuft, eine einzige Sache: Haben deine wichtigen Datenbanken im FULL-Recovery-Model einen regelmäßigen Log-Sicherungs-Job — und wie lang ist sein Intervall? Eine Abfrage, eine Minute. Wenn dort kein Log-Backup-Job läuft oder er nur einmal am Tag greift, hast du gerade die häufigste Ursache eines vollgelaufenen Logs gefunden, bevor sie zuschlägt. Ein Job alle 15 Minuten löst das Problem im Ruhezustand — und begrenzt nebenbei den Datenverlust im Ernstfall.

    Häufige Fragen (FAQ)

    Diese Sektion ist auf häufige Suchanfragen abgestimmt. Sie hilft dir, schnell den Punkt zu finden, der dir gerade akut weiterhilft — und sie ist gleichzeitig die Eingabe für das FAQPage-Schema auf der Seite.

    Was bedeutet die Fehlermeldung LOG_FULL?

    Sie bedeutet, dass das Transaktionslog der Datenbank vollständig gefüllt ist und keinen Platz mehr für neue Einträge hat — meist sichtbar als Fehler 9002. Weil der SQL Server jede Datenänderung erst ins Log schreibt, bevor sie wirksam wird, stoppen ab diesem Moment schlagartig alle Schreibvorgänge: Inserts, Updates, Deletes scheitern, und ein Server, der nicht mehr schreiben kann, wirkt wie eingefroren. Wichtig zu verstehen: Ein volles Log heißt nicht zwangsläufig, dass die Festplatte voll ist — viel häufiger kann der Server den vorhandenen Log-Raum nur nicht wiederverwenden, weil etwas die Freigabe blockiert. Genau das verrät die Spalte log_reuse_wait_desc, der Schlüssel zur Diagnose.

    Wie verkleinere ich das Transaktionslog richtig?

    Zuerst die Ursache beheben, dann erst — und nur falls wirklich nötig — verkleinern. Die richtige Reihenfolge: Über log_reuse_wait_desc herausfinden, warum das Log nicht freigegeben wird; den eigentlichen Grund beseitigen (meist eine fehlende Log-Sicherung mit BACKUP LOG); und erst danach, wenn die Datei dauerhaft zu groß ist und nicht wieder so groß wachsen wird, mit DBCC SHRINKFILE verkleinern. Der häufige Fehler ist, sofort zu schrumpfen, ohne die Ursache zu klären — dann wächst das Log gleich wieder, und das wiederholte Schrumpfen-und-Wachsen erzeugt Datei-Fragmentierung, die die Performance kostet. Shrink ist eine seltene Aufräummaßnahme, keine Lösung für ein volles Log.

    Warum kann das Log nicht abgeschnitten werden?

    Weil etwas die Wiederverwendung des Log-Raums blockiert — und was genau, sagt dir die Spalte log_reuse_wait_desc in sys.databases. Das Log wird normalerweise in Abschnitten freigegeben, sobald die darin enthaltenen Transaktionen gesichert und abgeschlossen sind. Bleibt diese Freigabe aus, häuft sich der nicht wiederverwendbare Raum, bis das Log voll ist. Die häufigsten Blockade-Gründe: Es fehlt die Log-Sicherung (LOG_BACKUP), eine lange offene Transaktion hält einen Abschnitt fest (ACTIVE_TRANSACTION), ein Always-On-Replica oder die Replikation hinkt hinterher. Der Wert ist die exakte Diagnose — man muss nicht raten, der Server nennt den Grund beim Namen.

    Was bedeutet log_reuse_wait_desc = LOG_BACKUP?

    Es ist der mit Abstand häufigste Fall und bedeutet: Das Log wartet auf seine Sicherung. Die Datenbank läuft im FULL- (oder BULK_LOGGED-) Recovery-Model, in dem das Log erst nach einer Log-Sicherung freigegeben wird — und genau diese Sicherung fehlt oder läuft nicht oft genug. Die Lösung ist denkbar einfach und sicher: eine BACKUP LOG ausführen. Sie gibt den Log-Raum sofort wieder frei, ohne Datenverlust und ohne die Log-Kette zu zerstören. Tritt LOG_BACKUP wiederholt auf, fehlt ein regelmäßiger Log-Sicherungs-Job oder sein Intervall ist zu lang — das ist dann ein Fall für die Backup-Strategie, nicht nur den akuten Griff.

    Was bedeutet log_reuse_wait_desc = ACTIVE_TRANSACTION?

    Es bedeutet, dass eine offene, nicht abgeschlossene Transaktion einen Teil des Logs festhält und seine Freigabe verhindert — oft eine vergessene Transaktion, die nie mit COMMIT oder ROLLBACK beendet wurde, oder eine sehr lange laufende Operation. Anders als bei LOG_BACKUP hilft hier keine Log-Sicherung; du musst die blockierende Transaktion finden und beenden. Über DBCC OPENTRAN oder die passenden DMVs identifizierst du die älteste offene Transaktion und die zugehörige Session, prüfst, was sie tut, und entscheidest, ob du sie beenden kannst. Vorsicht beim Beenden: Ein Rollback einer großen Transaktion kann selbst dauern und Log-Raum brauchen — also mit Bedacht, nicht reflexhaft.

    Darf ich das Recovery-Model auf SIMPLE umstellen?

    Nur als bewusste, dauerhafte Entscheidung für Datenbanken, die kein Point-in-Time-Recovery brauchen — niemals als schneller Trick, um ein volles Log loszuwerden. Im SIMPLE-Model räumt der Server das Log selbst auf, das stimmt; aber damit kappst du jede Log-Sicherungskette und verlierst die Fähigkeit, auf einen beliebigen Zeitpunkt wiederherzustellen sowie das rettende Tail-Log-Backup. Wer im akuten Notfall auf SIMPLE umstellt, um Platz zu schaffen, tauscht ein lösbares Log-Problem gegen ein klaffendes Loch in der Wiederherstellbarkeit — und merkt es oft erst, wenn das nächste Backup gebraucht wird. Das volle Log gehört durch eine Log-Sicherung gelöst, nicht durch SIMPLE.

    Wie finde ich offene Transaktionen?

    Am schnellsten mit DBCC OPENTRAN, das die älteste offene Transaktion der aktuellen Datenbank samt Session-ID und Startzeit zeigt — ideal, um den Übeltäter bei ACTIVE_TRANSACTION zu finden. Für mehr Detail und über alle Datenbanken hinweg nutzt du die DMVs sys.dm_tran_active_transactions und sys.dm_tran_session_transactions, verknüpft mit den Session- und Request-Sichten, um zu sehen, welche Session welche Transaktion wie lange offen hält und was sie zuletzt ausgeführt hat. Hast du den Verursacher, prüfst du, ob er sich sauber abschließen lässt, oder ob die Session beendet werden muss — wobei ein Rollback selbst Zeit und Log-Raum kosten kann. Die konkreten Abfragen stehen in diesem Beitrag.