Erhöht das Abfeuern eines unbefristeten WAITFOR die Größe der Protokolldatei?
16
In der letzten Version meiner App habe ich einen Befehl hinzugefügt, der ihn auffordert zu warten, wenn etwas in der Service Broker-Warteschlange eintrifft:
WAITFOR(RECEIVE CONVERT(int, message_body)AS Message FROM MyQueue)
Die Datenbankadministratoren haben mir mitgeteilt, dass die Stammgrößen seit dem Hinzufügen durch das Dach gegangen sind. Könnte das richtig sein? Oder sollte ich woanders suchen?
Bei jeder aktiven offenen Transaktion wird das Protokoll festgehalten, wodurch das Abschneiden verhindert und möglicherweise Wachstum verursacht wird. Wenn Sie eine Transaktion starten, in das Protokoll schreiben und dann für immer warten, in der Hoffnung, dass Sie irgendwann eine Nachricht erhalten, haben Sie das Protokoll angeheftet und es wächst.
In letzter Zeit habe ich Leuten empfohlen, die WAITFOR in der aktivierten Prozedur zusammen mit der Schleife zu meiden. Stellen Sie einfach einen RECIEVe aus und fertig, lassen Sie den Aktivierungsmechanismus für Sie durchlaufen (es tut dies) und warten Sie nicht, sondern nur RECEIVE.
Die WAITFOR-Variante von RECEIVE erstellt intern einen Sicherungspunkt. Dies erzeugt ein Protokoll (mindestens 3 Protokollsätze) und fixiert das Protokoll tatsächlich, während es wartet. Eine lange Wartezeit (oder schlimmer noch eine unendliche) wäre eine sehr schlechte Übung.
Würde WAITFOR (...) TIMEOUT 3600000das Problem lösen? ZB stündlich freigeben.
AngryHacker
2
Ihr Log wird in einer Stunde sehr wachsen . WAITFOR (REC EIVE) ist für Intervalle wie 5 Sekunden
gedacht
1
Sie sollten auch untersuchen, warum Ihre Transaktion tatsächlich aktiv ist (hat Protokoll geschrieben). Das typische Service Broker-Muster gibt vor RECEIVE keinen Schreibzugriff aus.
Remus Rusanu
1
Ich verstehe deinen letzten Kommentar nicht. Die Transaktion ist aktiv, weil ich eine ausgestellt habe. WAITFOR (RECEIVE...Könnten Sie erweitern? Vielleicht habe ich falsch verstanden.
AngryHacker
8
begin transaction; waitfor(receive...)Während des Wartens werden keine Protokolldatensätze generiert (die Transaktion wird nicht "aktiviert"), und das Protokoll wird daher nicht gepinnt. Nur begin transaction;[insert|update|delete];waitfor(receive...)bewirkt, dass die Transaktion aktiviert wird (Protokolldatensätze generiert) und somit das Protokoll während des Wartens tatsächlich gepinnt wird.
Remus Rusanu
5
Wenn ich unter SQL Server 2008 R2 ein WAITFOR (RECEIVE) ausführe und dann DBCC OPENTRAN ausführe, wird die Transaktion als aktiv angezeigt, auch wenn keine vorherigen Aktualisierungen vorhanden sind.
Richtig, die WAITFOR erstellt intern einen Sicherungspunkt und dies löst das Schreiben des Protokolls aus, sodass es das Protokoll an seinem Platz fixiert.
@binki Dieser Kommentar bezieht sich auf SQL Server 2005. Dies gilt für 2008 R2. Sie verhalten sich in Bezug auf dieses Problem anders, wenn ich mich richtig erinnere.
WAITFOR (...) TIMEOUT 3600000
das Problem lösen? ZB stündlich freigeben.WAITFOR (RECEIVE...
Könnten Sie erweitern? Vielleicht habe ich falsch verstanden.begin transaction; waitfor(receive...)
Während des Wartens werden keine Protokolldatensätze generiert (die Transaktion wird nicht "aktiviert"), und das Protokoll wird daher nicht gepinnt. Nurbegin transaction;[insert|update|delete];waitfor(receive...)
bewirkt, dass die Transaktion aktiviert wird (Protokolldatensätze generiert) und somit das Protokoll während des Wartens tatsächlich gepinnt wird.Wenn ich unter SQL Server 2008 R2 ein WAITFOR (RECEIVE) ausführe und dann DBCC OPENTRAN ausführe, wird die Transaktion als aktiv angezeigt, auch wenn keine vorherigen Aktualisierungen vorhanden sind.
quelle