Das Transaktionsprotokoll für die Datenbank ist voll

108

Ich habe einen lang laufenden Prozess, der eine Transaktion für die gesamte Dauer offen hält.

Ich habe keine Kontrolle darüber, wie dies ausgeführt wird.

Da eine Transaktion für die gesamte Dauer offen gehalten wird, kann SQL Server beim Füllen des Transaktionsprotokolls die Größe der Protokolldatei nicht erhöhen.

Der Prozess schlägt also mit dem Fehler fehl "The transaction log for database 'xxx' is full".

Ich habe versucht, dies zu verhindern, indem ich die Größe der Transaktionsprotokolldatei in den Datenbankeigenschaften erhöht habe, erhalte jedoch den gleichen Fehler.

Ich bin mir nicht sicher, was ich als nächstes versuchen soll. Der Prozess läuft mehrere Stunden, daher ist es nicht einfach, Versuch und Irrtum zu spielen.

Irgendwelche Ideen?

Wenn jemand interessiert ist, ist der Prozess ein Organisationsimport in Microsoft Dynamics CRM 4.0.

Es gibt viel Speicherplatz, wir haben das Protokoll im einfachen Protokollierungsmodus und haben das Protokoll vor dem Start des Prozesses gesichert.

- = - = - = - = - UPDATE - = - = - = - = -

Vielen Dank für die bisherigen Kommentare. Folgendes hat mich zu der Annahme geführt, dass das Protokoll aufgrund der offenen Transaktion nicht wachsen würde:

Ich erhalte die folgende Fehlermeldung ...

Import Organization (Name=xxx, Id=560d04e7-98ed-e211-9759-0050569d6d39) failed with Exception:
System.Data.SqlClient.SqlException: The transaction log for database 'xxx' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases

Also ging ich nach diesem Rat zu " log_reuse_wait_desc column in sys.databases" und es hatte den Wert " ACTIVE_TRANSACTION".

Laut Microsoft: http://msdn.microsoft.com/en-us/library/ms345414(v=sql.105).aspx

Das bedeutet folgendes:

Eine Transaktion ist aktiv (alle Wiederherstellungsmodelle). • Zu Beginn der Protokollsicherung ist möglicherweise eine Transaktion mit langer Laufzeit vorhanden. In diesem Fall erfordert das Freigeben des Speicherplatzes möglicherweise eine weitere Protokollsicherung. Weitere Informationen finden Sie unter "Langfristig aktive Transaktionen" weiter unten in diesem Thema.

• Eine Transaktion wird zurückgestellt (nur SQL Server 2005 Enterprise Edition und spätere Versionen). Eine zurückgestellte Transaktion ist effektiv eine aktive Transaktion, deren Rollback aufgrund einer nicht verfügbaren Ressource blockiert ist. Informationen zu den Ursachen für zurückgestellte Transaktionen und zum Verschieben aus dem zurückgestellten Zustand finden Sie unter Zurückgestellte Transaktionen.

Habe ich etwas falsch verstanden?

- = - = - = - UPDATE 2 - = - = - = -

Der Prozess wurde gerade mit einer anfänglichen Protokolldateigröße von 30 GB gestartet. Dies dauert einige Stunden.

- = - = - = - Endgültiges UPDATE - = - = - = -

Das Problem wurde tatsächlich dadurch verursacht, dass die Protokolldatei den gesamten verfügbaren Speicherplatz belegt. Beim letzten Versuch habe ich 120 GB freigegeben und es hat immer noch alles verbraucht und ist letztendlich gescheitert.

Ich wusste nicht, dass dies zuvor geschah, da der Prozess, wenn er über Nacht ausgeführt wurde, bei einem Fehler zurückgesetzt wurde. Diesmal konnte ich die Größe der Protokolldatei vor dem Rollback überprüfen.

Vielen Dank für Ihre Eingabe.

Jimbo
quelle
re "... und habe das Protokoll gesichert" .... Wenn sich die Datenbank im einfachen Modus befindet, können Sie das Protokoll nicht sichern. Protokollsicherungen gelten nicht für den einfachen Modus. Ist es massenprotokolliert?
SqlACID
1
Ich habe die gesamte Datenbank gesichert und verkleinert, was dazu führte, dass das Protokoll auf 1 MB verkleinert wurde. Ich habe dann die Größe der Protokolldatei zunächst auf 20 GB und jetzt auf 30 GB erhöht.
Jimbo
In Verbindung stehender Beitrag - TempDB Log Space und ACTIVE_TRANSACTION
RBT

Antworten:

19

Ist dies ein einmaliges Skript oder ein regelmäßig auftretender Job?

In der Vergangenheit habe ich für spezielle Projekte, die vorübergehend viel Speicherplatz für die Protokolldatei benötigen, eine zweite Protokolldatei erstellt und diese riesig gemacht. Sobald das Projekt abgeschlossen ist, haben wir die zusätzliche Protokolldatei entfernt.

Mike Henderson
quelle
Ich würde nicht sagen, dass es ein einmaliger Job ist, aber es ist selten, dass wir es tun müssen. Ich habe keine zweite Protokolldatei erstellt, aber die anfängliche Größe meiner aktuellen Protokolldatei auf 30 GB erhöht. Während meines letzten Laufs wurde es auf 20 GB eingestellt und es schlug immer noch fehl.
Jimbo
Wäre es irgendwie besser, eine zweite Protokolldatei zu haben, als eine große, da ich nur ein Laufwerk habe, mit dem ich arbeiten kann?
Jimbo
Wie ich mich jetzt erinnere, ermöglichte uns die zusätzliche Datei größtenteils den Zugriff auf ein anderes, größeres Laufwerk.
Mike Henderson
2
Wie groß sind die importierten Daten? Wenn Sie 30 GB Daten importieren, muss Ihre Protokolldatei möglicherweise mindestens so groß sein.
Mike Henderson
3
Die Protokollgröße ist der Schlüssel. Die aktuelle Aufgabe schlug erneut fehl und ich traute meinen Augen nicht, als ich die Größe der Protokolldatei an dem Punkt sah, an dem sie fehlschlug. Es verarbeitete nur die Hälfte der Konten und war bereits bei 53 GB. Es sieht so aus, als müsste ich irgendwo in der Nähe von weiteren 60-70 GB löschen, um diesen Vorgang abschließen zu können.
Jimbo
95

Um dieses Problem zu beheben, ändern Sie das Wiederherstellungsmodell in " Einfach" und dann " Dateiprotokoll verkleinern"

1. Datenbankeigenschaften> Optionen> Wiederherstellungsmodell> Einfach

2. Datenbankaufgaben> Verkleinern> Dateien> Protokoll

Getan.

Überprüfen Sie anschließend die Größe Ihrer Datenbankprotokolldatei unter Datenbankeigenschaften> Dateien> Datenbankdateien> Pfad

So überprüfen Sie das vollständige SQL Server-Protokoll: Öffnen Sie die Protokolldatei-Anzeige unter SSMS> Datenbank> Verwaltung> SQL Server-Protokolle> Aktuell

user3774600
quelle
10
Nein, das behebt das Problem nicht. Das Problem war, dass die Protokolldatei während eines langen Prozesses wuchs, bis der Speicherplatz knapp wurde. Dies wurde korrigiert, indem die Protokolldatei vorübergehend auf ein anderes Laufwerk verschoben wurde, auf dem 1 TB Speicherplatz verfügbar war. Sie können die Protokolldatei nicht verkleinern, während ein lang laufender Prozess ausgeführt wird, bei dem eine Transaktion geöffnet bleibt. Dieser Prozess war allein für das Dateiwachstum verantwortlich.
Jimbo
Wie @Jimbo bereits sagte, behebt dies das OP-Problem nicht. Es kann einige derzeit nicht genutzte Speicherplätze freigeben, aber sobald eine lange Transaktion erneut ausgeführt wird, wird der Speicherplatz wieder belegt (und wahrscheinlich noch früher fehlschlagen)
Marcel
Perfekt! Vielen Dank!
Yuri Monteiro
Das hat das Problem nicht behoben. Mein Protokoll hat nur 500 Bytes. Ich denke, dieses Problem hat begonnen, nachdem ich gestern ein Backup erstellt habe.
Ricardo França
Dies ist definitiv die Lösung, wenn Sie noch ein paar Megabyte auf dem vollen Laufwerk übrig haben.
Steve Bauman
36

Ich hatte diesen Fehler einmal und es war die Festplatte des Servers, auf der nicht mehr genügend Speicherplatz vorhanden ist.

PretoriaCoder
quelle
1
Lesen Sie die Updates des OP. Dies stellte sich als Problem heraus.
Colm
18

Haben Sie Autogrowth aktivieren und uneingeschränktes Dateiwachstum für die Protokolldatei aktiviert? Sie können diese über SSMS unter "Datenbankeigenschaften> Dateien" bearbeiten.

Ross McNab
quelle
Ja. Es ist auf 10% Autogrow eingestellt, ohne Einschränkungen. Das Problem ist, dass Autogrow nicht funktioniert, solange eine Transaktion offen ist.
Jimbo
1
Haben Sie eine Vorstellung davon, wie groß die Transaktion sein wird? Versuchen Sie, die Transaktionsprotokollgröße größer als diese Schätzung festzulegen. Wenn die Festplattenzuweisung kein Problem darstellt, weisen Sie zu Beginn ausreichend Speicherplatz für Daten und Protokolle zu. Es verbessert die Leistung. Lassen Sie uns nicht um 10% automatisch wachsen , sondern um einige GB, damit die Leistung gut genug ist.
Luis LL
3
SQL Server wird das Protokoll während einer Transaktion automatisch vergrößern, wenn mehr Speicherplatz zum Abschließen dieser Transaktion benötigt wird.
Ross McNab
Hallo Ross, ich habe meine Logik angegeben, um zu glauben, dass die offene Transaktion das Wachstum eines Updates der Frage verhindert. Bin ich falsch in meiner Argumentation?
Jimbo
1
@Jimbo SQL Server erfordert nicht, dass Sie es reserviert haben. Wenn Sie über Autogrow verfügen, führt SQL Server das Autogrow während der Transaktion durch. Wenn es groß genug ist, kann es viel Zeit sparen, sollte aber den Prozess nicht beeinträchtigen.
Luis LL
10

Dies ist ein Ansatz der alten Schule. Wenn Sie jedoch eine iterative Aktualisierung oder Einfügeoperation in SQL ausführen, die lange ausgeführt wird, empfiehlt es sich, regelmäßig (programmgesteuert) "Checkpoint" aufzurufen. Wenn Sie "checkpoint" aufrufen, schreibt SQL alle diese Nur-Speicher-Änderungen (schmutzige Seiten, sie werden aufgerufen) und im Transaktionsprotokoll gespeicherten Elemente auf die Festplatte. Dies hat zur Folge, dass Ihr Transaktionsprotokoll regelmäßig bereinigt wird, wodurch Probleme wie das beschriebene vermieden werden.

Brian
quelle
1
Leider habe ich keine Kontrolle darüber, wie der Prozess ausgeführt wird. Dynamics CRM ist eine Microsoft-Anwendung, und der Organisationsimportprozess ist Teil dieser Anwendung.
Jimbo
1

Im Folgenden wird das Protokoll abgeschnitten.

USE [yourdbname] 
GO

-- TRUNCATE TRANSACTION LOG --
DBCC SHRINKFILE(yourdbname_log, 1)
BACKUP LOG yourdbname WITH TRUNCATE_ONLY
DBCC SHRINKFILE(yourdbname_log, 1)
GO

-- CHECK DATABASE HEALTH --
ALTER FUNCTION [dbo].[checker]() RETURNS int AS BEGIN  RETURN 0 END
GO
Pinal
quelle
4
Hey Pinal, diese Funktionalität wurde vollständig aus SQL Server 2008 und höher entfernt: brentozar.com/archive/2009/08/…
Conor
3
Versuchen Sie in späteren Versionen BACKUP LOG <myDB> TO DISK = N'NUL: '
HansLindgren
1

Wenn Ihr Datenbankwiederherstellungsmodell voll ist und Sie keinen Wartungsplan für die Protokollsicherung hatten, wird dieser Fehler angezeigt, da das Transaktionsprotokoll aufgrund von voll ist LOG_BACKUP .

Dadurch wird jede Aktion in dieser Datenbank verhindert (z. B. Verkleinern), und das SQL Server-Datenbankmodul löst einen 9002-Fehler aus.

Um dieses Verhalten zu überwinden, empfehlen wir Ihnen, dies zu überprüfen. Das Transaktionsprotokoll für die Datenbank 'SharePoint_Config' ist aufgrund von LOG_BACKUP voll , das detaillierte Schritte zur Behebung des Problems enthält.

Jihan
quelle
0

Ich habe den Fehler festgestellt: "Das Transaktionsprotokoll für die Datenbank '...' ist aufgrund von 'ACTIVE_TRANSACTION' voll, während alte Zeilen aus Tabellen meiner Datenbank gelöscht wurden, um Speicherplatz freizugeben. Ich habe festgestellt, dass dieser Fehler auftreten würde, wenn die Anzahl der Zeilen an Das Löschen war in meinem Fall größer als 1000000. Anstatt 1 DELETE-Anweisung zu verwenden, habe ich die Löschaufgabe mithilfe der DELETE TOP (1000000) .... -Anweisung aufgeteilt.

Beispielsweise:

anstatt diese Aussage zu verwenden:

DELETE FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())

Verwenden Sie die folgende Anweisung wiederholt:

DELETE TOP(1000000) FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())
Linh Dao
quelle
0

Mein Problem wurde mit mehrfacher Ausführung von begrenzten Löschungen wie gelöst

Vor

DELETE FROM TableName WHERE Condition

Nach dem

DELETE TOP(1000) FROM TableName WHERECondition
Amir Astaneh
quelle
-1

Die Antwort auf die Frage besteht nicht darin, die Zeilen aus einer Tabelle zu löschen, sondern es ist der temporäre Speicherplatz, der aufgrund einer aktiven Transaktion belegt wird. Dies geschieht meistens, wenn eine Zusammenführung (Upsert) ausgeführt wird, bei der versucht wird, ein Update einzufügen und die Transaktionen zu löschen. Die einzige Möglichkeit besteht darin, sicherzustellen, dass die Datenbank auf ein einfaches Wiederherstellungsmodell eingestellt ist, und die Datei auf den maximalen Speicherplatz zu erhöhen (Hinzufügen einer weiteren Dateigruppe). Obwohl dies seine eigenen Vor- und Nachteile hat, sind dies die einzigen Optionen.

Die andere Möglichkeit besteht darin, die Zusammenführung (Upsert) in zwei Vorgänge aufzuteilen. einer, der das Einfügen vornimmt, und der andere, der das Aktualisieren und Löschen vornimmt.

Rohit Reddy
quelle
Wenn Sie die Frage lesen, wissen Sie, dass sich die Datenbank zu diesem Zeitpunkt bereits im einfachen Wiederherstellungsmodus befand. Dies hilft nicht, wenn Sie eine lange offene Transaktion haben. Die Datei wächst weiter, bis die Transaktion festgeschrieben oder zurückgesetzt wird. Lesen Sie die erste Zeile der Frage "Ich habe einen lang laufenden Prozess, der eine Transaktion für die gesamte Dauer offen hält."
Jimbo
-1

Versuche dies:

USE YourDB;  
GO  
-- Truncate the log by changing the database recovery model to SIMPLE.  
ALTER DATABASE YourDB
SET RECOVERY SIMPLE;  
GO  
-- Shrink the truncated log file to 50 MB.  
DBCC SHRINKFILE (YourDB_log, 50);  
GO  
-- Reset the database recovery model.  
ALTER DATABASE YourDB
SET RECOVERY FULL;  
GO 

Ich hoffe, es hilft.

Saadat
quelle
Dies war eines der ersten Versuche und wird sogar im Fragentext erwähnt. Dies löst nicht das Problem, dass eine einzelne offene Transaktion das Protokoll ausfüllt und den gesamten verfügbaren Speicherplatz nutzt. Dieser gesamte Prozess fand im einfachen Modus statt. Sie sind jedoch einer von vielen Menschen, die genau diese Antwort angeboten haben, nachdem sie die Frage nicht gelesen haben ...
Jimbo
-1

Hier ist mein Heldencode. Ich habe mich diesem Problem gestellt. Und verwenden Sie diesen Code, um dies zu beheben.

 USE master;

    SELECT 
        name, log_reuse_wait, log_reuse_wait_desc, is_cdc_enabled 
    FROM 
        sys.databases 
    WHERE 
        name = 'XX_System';

    SELECT DATABASEPROPERTYEX('XX_System', 'IsPublished');


    USE XX_System;
    EXEC sp_repldone null, null, 0,0,1;
    EXEC sp_removedbreplication XX_System;


    DBCC OPENTRAN;
    DBCC SQLPERF(LOGSPACE);
    EXEC sp_replcounters;



    DBCC SQLPERF(LOGSPACE);
narawit1601
quelle
Bitte setzen Sie Ihre Antwort immer in einen Kontext, anstatt nur Code einzufügen. Sehen Sie hier für weitere Details.
gehbiszumeis
-1

Versuche dies:

Starten Sie nach Möglichkeit die Dienste MSSQLSERVER und SQLSERVERAGENT neu .

Lemraj
quelle