Ein Vorgang "ALTER INDEX ALL REBUILD" unter SQL Server 2012 schlug fehl, weil im Transaktionsprotokoll nicht genügend Speicherplatz vorhanden war. Die Indizes wurden nie reorganisiert oder neu erstellt, sodass die Fragmentierung bei fast allen von ihnen über 80% beträgt.
Die Datenbank verwendet ein einfaches Wiederherstellungsmodell. Ich nahm an, dass nach jeder Indexoperation, die von der "ALL" -Form des Befehls ausgeführt wird, die Transaktionsprotokolldaten vor der nächsten Indexwiederherstellung gelöscht werden. Funktioniert das tatsächlich so oder werden die Neuerstellungen des Index so protokolliert, als wären sie Teil einer einzelnen Transaktion?
Mit anderen Worten, könnte ich das Wachstum des Transaktionsprotokolls reduzieren, indem ich ein Skript schreibe, um jede Neuerstellung einzeln durchzuführen? Gibt es noch andere Faktoren zu berücksichtigen?
quelle
Antworten:
1) Protokolllöschung: Das SIMPLE-Wiederherstellungsmodell löscht das Protokoll nicht nach jeder Transaktion, sondern an Kontrollpunkten. ( Link für mehr Infos)
2a) REBUILD ALL: Ja, REBUILD ALL funktioniert als einzelne Transaktion. Die Index-Neuerstellungen in haben ihre eigenen Transaktionen, aber die gesamte Operation wird erst am Ende vollständig festgeschrieben. Ja, Sie können das Wachstum von Protokolldateien einschränken, indem Sie einzelne Indizes neu erstellen (und möglicherweise CHECKPOINT-Befehle absetzen).
2b) Beweis! Hier haben Sie ein Demo-Skript. (Build in 2016 dev) Richten Sie zuerst eine Test-Datenbank mit Tabelle und Indizes ein:
Jetzt können Sie die Protokollaktivität zwischen REBUILD ALL und der einzelnen Neuerstellung vergleichen
Beachten Sie, dass die erste offene Transaktion (Transaktions-ID 0000: 000002fa für mich) erst am Ende von REBUILD ALL festgeschrieben wird. Bei den indexweisen Neuerstellungen werden sie jedoch nacheinander festgeschrieben.
quelle
Derzeit handelt es sich um eine Einzeltransaktion.
quelle
Die Frage ist trivial für eine Offline- Neuerstellung. Natürlich ist eine einzelne Transaktion. Stellen Sie sich das Chaos vor, das entstehen würde, wenn die Operation jeden Index in eine eigene Transaktion aufteilt, da sie die Sperren beim Festschreiben freigeben und sie dann erneut erwerben müsste . Während die SCH-M-Sperre für die kritische Tabelle aufgehoben wurde, können Indizes gelöscht und neue Indizes erstellt werden. Wie würde die Anweisung solche Fälle behandeln? Ganz zu schweigen davon, dass die Tabelle zwischen den beiden Transaktionen gelöscht und sogar neu erstellt werden kann! Einschließlich des Falls, wenn die Tabelle gelöscht und eine andere Tabelle mit derselben Objekt-ID erstellt wird (ja, das kann passieren) ...
Was passiert, wenn Sie die Frage erweitern, was passiert, wenn die Indexerstellung eine Online- Neuerstellung ist? Ist es eine einzelne Transaktion oder viele? Die Antwort ist komplex, da es sich tatsächlich um mehrere interne Transaktionen handelt . Der entscheidende Punkt ist jedoch, dass es eine übergreifende Archivierungstransaktion gibt, die den gesamten Vorgang (die ALTER-Anweisung) abdeckt und die Anmeldung fixiert (kann nicht abgeschnitten werden). Daher muss der Vorgang entsprechend geplant werden, um ~ 1,6-fache Daten zuzulassen Größe für den vollständigen Wiederherstellungsmodus oder 0,2-fache Datengröße für den BULK_LOGGED / SIMPLE-Modus. Weitere Informationen finden Sie im verlinkten Dokument.
Sie können argumentieren, warum der Offline-Build nicht dieselben internen Transaktionen verwendet wie der Online-Modus und den Vorgang aufteilt? Die Probleme, die ich beim Ändern / Löschen einer Tabelle zwischen den einzelnen Indexoperationen angesprochen habe (z. B. "Schemastabilität" der Tabelle), würden weiterhin erfordern, dass eine umfassende Transaktion vorhanden ist, die ein SCH-S für die Tabelle für die gesamte Dauer der Anweisung enthält. Da diese Transaktion den SCH-S auch während der Wiederherstellung enthalten muss, muss er protokolliert werden. In diesem Fall wird ein BEGIN XACT-Protokolldatensatz erstellt, der das Protokoll pinnt und das Abschneiden für die gesamte Dauer der Anweisung verhindert. Ich weiß, dass dieses spezielle Problem im Zeitrahmen von SQL 2016-2017 behoben wurde (aufgrund von Problemen mit der Größe des SQL Azure-Protokolls),
bin mir jedoch nicht sicher, welche Fortschritte erzielt wurden. Sieht so aus, als wäre es jetzt in der Vorschau:Resumable Online Index Rebuild ist in der öffentlichen Vorschau für SQL Server 2017 CTP 2.0 .quelle
Ja, ich hatte das gleiche Problem mit einem sehr großen Tisch. Immer wenn ich ALTER INDEX ALL herausgab, wuchs das Transaktionsprotokoll stark, aber wenn ALTER INDEX einzeln herausgegeben wurde, war die Verwendung des Protokollspeicherplatzes geringer.
quelle
Die frühere Antwort von Remus, dass für die Online-Indizierung das 1,6-fache der Indexgröße im vollständigen Wiederherstellungsmodus erforderlich ist, ist nicht korrekt. Der Anteil des Transaktionsprotokollierungsspeichers, der erforderlich ist, um einen Index online unter FULL neu zu erstellen, kann viel höher sein, und wir haben festgestellt, dass der Index um ein Vielfaches größer ist, insbesondere wenn der neu erstellte Index komprimiert wird, da die Transaktionsprotokollierung nicht komprimiert wird. Dies allein sollte klarstellen, dass die Transaktionsprotokollierung während einer Online-Neuerstellung unter FULL mindestens ein paar Mal so groß sein kann wie der Index. Fügen Sie in tlog einen Datensatz-Overhead hinzu, der nicht vollständig von Microsoft dokumentiert ist, sondern häufig auf 60 Byte pro Zeile geschätzt wird, und die proportionale Größe der Protokollierung während einer Online-Indexwiederherstellung bei vollständiger Wiederherstellung kann ein Vielfaches der Größe des neu erstellten Index betragen, insbesondere wenn Der Index ist komprimiert
quelle
Rdfozz ist richtig. Auf diese Weise können Sie am besten entscheiden, ob Ihr größter Index basierend auf dem aktuellen Speicher neu erstellt werden kann. Führen Sie einfach aus,
dm_exec_requests
während der Vorgang ausgeführt wird (oder SQL Profiler), um festzustellen, ob alle Indizes neu erstellt werden. Ich würde auch in Betracht ziehen, das Wiederherstellungsmodell in ein Massenprotokoll zu ändern. Dies ist, was ich tue und es gibt immer noch Transaktionsprotokollsicherungen während des Fensters. Siehe unten stehenden Artikel https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspxquelle