Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server-Transaktionsprotokoll – Teil 1

Jede SQL Server-Datenbank enthält zusätzlich zu den Datendateien eine oder mehrere Transaktionsprotokolldateien. Protokolldateien zeichnen alle Transaktionen und Datenbankänderungen auf, die von jedem von ihnen vorgenommen wurden.

Dieser Artikel konzentriert sich auf das Transaktionsprotokoll und darauf, wie SQL Server Datenänderungen protokolliert, um die Daten für die Wiederherstellung nach einem Datenbankabsturz zu verwenden.

Einführung in die SQL Server-Transaktionsprotokolldatei

Wie wir uns erinnern, ist jede Transaktion „alles oder nichts“. Wenn ein Teil der Transaktion fehlschlägt, schlägt die gesamte Transaktion fehl und der Datenbankstatus bleibt unverändert.

SQL Server speichert einen Datensatz jeder in der Datenbank durchgeführten Transaktion in der Protokolldatei. Wenn ein Notfall zum Herunterfahren von SQL Server führt, verwendet es ein Transaktionsprotokoll, um die Datenbank in einen konsistenten Zustand mit Datenintegrität wiederherzustellen.

Nach dem Neustart startet SQL Server den Wiederherstellungsprozess nach einem Absturz. Es liest die Transaktionsprotokolldatei, um sicherzustellen, dass alle gültigen Daten in den Datendateien gespeichert sind, und nicht festgeschriebene Transaktionen werden rückgängig gemacht.

Während des normalen Betriebs verwendet SQL Server auch das Transaktionsprotokoll. Die in der Datei enthaltenen Informationen sind erforderlich, um zu ermitteln, was SQL Server tun muss, wenn eine Transaktion aufgrund eines Fehlers oder einer benutzerdefinierten ROLLBACK-Anweisung zurückgesetzt wird.

Wie SQL Server das Transaktionsprotokoll verwendet

Das Transaktionsprotokoll ist eine physische Datei mit der Erweiterung LDF . SQL Server erstellt es automatisch für jede neue Datenbank zusammen mit der primären Datendatei (.MDF ), die die Datenbankobjekte und die Daten selbst speichert.

Wann immer der T-SQL-Code ein Datenbankobjekt oder die darin enthaltenen Daten ändert, werden Details der Änderung als Protokolldatensatz in der Transaktionsprotokolldatei aufgezeichnet.

Der Protokolldatensatz enthält die Informationen einer bestimmten Änderung, die an der Datenbank vorgenommen wurde (z. B. Einfügen einer einzelnen Zeile). Daher haben wir eine Reihe von Protokolldatensätzen, um die Auswirkungen einer einzelnen Transaktion vollständig zu beschreiben.

Transaktionsprotokollarchitektur

Sequenznummern protokollieren

Ein Protokolldatensatz hat eine eindeutige, automatisch inkrementierende Protokollfolgenummer (LSN ), die es uns ermöglicht, diesen Datensatz im Transaktionsprotokoll zu finden. LSN beschreibt die Datenänderung und enthält folgende Informationen:

  • Operation und betroffene Zeile
  • die alten und neuen Versionen der Daten
  • die Transaktion, die die Änderung durchgeführt hat

LSN besteht aus drei Nummern:

LSN =::

Jede Datendateiseite hat eine LSN in ihrem Seitenkopf, die den neuesten Protokolldatensatz identifiziert, dessen Änderung auf der Seite widergespiegelt wird. Dies ist entscheidend für die Wiederherstellung nach einem Absturz.

Wenn die Wiederherstellung nach einem Absturz ausgeführt wird, vergleicht sie die LSNs von Protokolldatensätzen für festgeschriebene oder nicht festgeschriebene Transaktionen mit LSNs in Datendateiseiten, um zu bestimmen, ob für diese bestimmten Protokolldatensätze ein Wiederherstellen oder Rückgängigmachen erforderlich ist.

Wenn Sie eine Datenbank erstellen, empfiehlt es sich, die Größe des Transaktionsprotokolls anzugeben . Wenn Sie dies nicht tun, erstellt SQL Server automatisch das Transaktionsprotokoll mit der Standardgröße.

Die Standardgröße des Transaktionsprotokolls einer neuen Datenbank ist der größere von 0,5 MB oder 25 % der Gesamtgröße aller Datendateien, die in derselben CREATE DATABASE-Anweisung erstellt wurden.

Sie müssen sehr vorsichtig sein, da neue Teile des Transaktionsprotokolls immer nullinitialisiert werden . Wenn Sie die CREATE DATABASE-Anweisung verwenden, ohne die Größe der Protokolldatei anzugeben, und Sie beispielsweise eine Datenbank mit 1 TB erstellen, erstellt SQL Server das Transaktionsprotokoll mit 250 GB.

Da das Protokoll mit Null initialisiert werden muss, verwendet es die sofortige Dateiinitialisierung nicht. Dieses Feature wurde in SQL Server 2005 hinzugefügt, damit die Datendateien fast sofort erstellt oder erweitert werden können.

Wir können sehen, was los ist, wenn wir DATENBANK ERSTELLEN – die Null-Initialisierung unseres Protokolls erfolgt mit Trace-Flag 3004 die Meldungen über Null-Initialisierung und Trace-Flag 3605 ausgibt das ermöglicht das Drucken dieser Log-Meldungen durch das Trace-Flag 3004.

Die folgende Demo zeigt, wie Sie sehen können, wie die Protokolldatei auf Null gesetzt wird.

1. Führen Sie das folgende Skript aus, um sicherzustellen, dass wir keine Datenbank namens DBTest2014

haben
USE master;
GO
 
IF DATABASEPROPERTY(N'DBTest2014', N'Version')>0
  BEGIN
    ALTER DATABASE DBTest2014 SET SINGLE_USER
      WITH ROLLBACK IMMEDIATE;
    DROP DATABASE DBTest2014;
  END
GO

2. Aktivieren Sie Trace-Flags, um die Nullinitialisierung zu überwachen

DBCC TRACEON (3605, 3004, -1);
GO
3. Flush the error log
EXEC sp_cycle_errorlog;
GO

3. Erstellen Sie eine Datenbank

CREATE DATABASE DBTest2014 ON PRIMARY (
  NAME = N'DBTest2014',
  FILENAME = N'D:\DBTest2014_data.mdf')
LOG ON (
  NAME= N'DBTest2014_log',
  FILENAME= N'D:\DBTest2014_log.ldf',
  SIZE = 10MB,
  FILEGROWTH = 10 MB);
GO

4. Lesen Sie die Fehlerprotokolldatei

EXEC sys.xp_readerrorlog;
GO

Virtuelle Protokolldateien

Das Transaktionsprotokoll wird intern in eine Reihe von Blöcken aufgeteilt, die als virtuelle Protokolldateien bezeichnet werden (VLFs ), um die Verwaltung zu vereinfachen.

Jedes Mal, wenn ein Transaktionsprotokoll erstellt wird, gibt es eine bestimmte Anzahl von VLFs aus. Neu erstellte VLFs sind inaktiv und werden nicht verwendet. Ein aktives VLF kann nicht wiederverwendet werden, bis es durch Löschen des Protokolls inaktiv gemacht wird.

Es gibt jedoch eine Ausnahme – das erste VLF in einer neuen Datenbank ist immer aktiv, weil jedes Transaktionsprotokoll mindestens ein aktives VLF haben muss.

Jede Protokolldatei hat auch eine Dateikopfseite was 8 KB benötigt am Anfang der Transaktionsprotokolldatei. Die Datei-Header-Seite speichert Metadaten über die Datei, wie z. B. Größe und Einstellungen für die automatische Vergrößerung.

Die Anzahl und Größe von VLFs in einem neuen Teil des Transaktionsprotokolls werden von SQL Server bestimmt. Es ist unmöglich, es zu konfigurieren.

Wenn die neu hinzugefügte Größe ist:

  • <1 MB ist für die Diskussion irrelevant
  • <64 MB gibt es 4 neue VLFs (jeweils 1/4 der Wachstumsgröße)
  • 64 MB bis 1 GB gibt es 8 neue VLFs (jeweils 1/8 der Wachstumsgröße)
  • > 1 GB gibt es 16 neue VLFs (jeweils 1/16 der Wachstumsgröße)

Dies gilt für das anfänglich erstellte Transaktionsprotokoll und für jedes manuelle oder automatische Wachstum, das auftritt. Wenn Sie die Formel für die potenzielle Anzahl von VLFs und ihre potenzielle Größe kennen, hilft dies bei der Verwaltung des Protokolls. Zu wenige oder zu viele VLFs können Leistungsprobleme bei Transaktionsprotokollvorgängen verursachen.

VLF-Sequenznummer

Jedes VLF hat eine Sequenznummer, um das VLF innerhalb des Transaktionsprotokolls eindeutig zu identifizieren. Die Sequenznummer erhöht sich jedes Mal um eins, wenn das Protokollverwaltungssystem das nächste VLF aktiviert. Die Kette der Sequenznummern ergibt den aktuell aktiven Satz von VLFs.

Der Beginn des aktiven Teils des Transaktionsprotokolls beginnt mit einem VLF, das die niedrigste Folgenummer hat und noch aktiv ist. Inaktive VLFs haben Sequenznummern, aber sie sind nicht Teil des aktiven Teils des Protokolls.

Der aktive Teil des Protokolls enthält Protokolldatensätze, die aus irgendeinem Grund von SQL Server benötigt werden.

Wenn Sie zum ersten Mal eine neue Datenbank erstellen, beginnen die VLF-Sequenznummern nicht bei 1. Sie beginnen mit der höchsten VLF-Sequenznummer im Transaktionsprotokoll der Modelldatenbank, plus 1 . Es ist unmöglich, dass die VLF-Sequenznummern ausgehen. SQL Server verfügt über Code, der das Herunterfahren der Instanz erzwingt, wenn eine VLF-Folgenummer jemals auf Null umbricht (wenn die nächste VLF-Folgenummer kleiner als die vorherige ist).

VLF und Protokollblöcke

Innerhalb von VLFs gibt es Protokollblöcke unterschiedlicher Größe. Die Mindestgröße des Protokollblocks beträgt 512 Bytes und Protokollblöcke wachsen auf eine maximale Größe von 60 KB an . Die Größe wird gesetzt, wenn einer der folgenden Fälle eintritt:

  • Eine Transaktion generiert einen Protokolldatensatz, um den Abbruch einer Transaktion abzuschließen
  • Die Protokollblockgröße erreicht 60 KB, ohne dass eine Transaktion festgeschrieben oder abgebrochen wird

Innerhalb eines Protokollblocks (im Diagramm farbig dargestellt) befinden sich Protokolldatensätze. Protokolldatensätze haben auch eine variable Größe. Das Diagramm zeigt, dass Protokolldatensätze von mehreren gleichzeitigen Transaktionen innerhalb desselben Protokollblocks vorhanden sein können. Die Protokolldatensätze werden in der Reihenfolge gespeichert, die ähnlich wie eine Datenseitendatei geschrieben wird.

Jedes VLF enthält einen VLF-Header mit folgenden Informationen:

  • Ob das VLF aktiv ist oder nicht.
  • Die Protokollsequenznummer, als das VLF erstellt wurde.
  • Die aktuellen Paritätsbits für alle 512-Byte-Blöcke im VLF.

Die Paritätsbits beginnen bei 64 für die allererste Verwendung von VLF. Wenn VLF inaktiv wird, aber weiter reaktiviert wird, werden die Paritätsbits zu 128. Diese werden während der Wiederherstellung nach einem Absturz verwendet.

Transaktionsprotokolldetails untersuchen – DBCC LOGINFO

Die einzige Möglichkeit, sich die Struktur des Transaktionsprotokolls anzusehen, besteht darin, das undokumentierte DBCC LOGINFO zu verwenden Befehl. Die Syntax für den Befehl lautet:

DBCC LOGINFO [({'dbname | dbid'})]

Wenn Sie dbname nicht angeben und dbid , wird es Ihnen den Protokollinhalt für die aktuelle Datenbank ausgeben.

Das Ergebnis ist eine Zeile für jedes VLF, das sich im Transaktionsprotokoll für diese Datenbank befindet. Die zurückgegebenen Felder sind:

  • RecoveryUnitId — in SQL Server 2012 hinzugefügt, aber derzeit nicht verwendet
  • Datei-ID — ID der Transaktionsprotokolldatei innerhalb einer Datenbank.
  • Dateigröße — VLF-Größe in Byte.
  • StartOffset — Anfangs-Offset des VLF in der Transaktionsprotokolldatei, in Bytes
  • FSeqNr — Die VLF-Sequenznummer
  • Status — Ob VLF aktiv ist oder nicht (0 =inaktiv, 2 =aktiv, 1 – wird nicht verwendet)
  • Parität — aktuelle Paritätsbits (64 oder 128 oder 0, wenn VLF noch nie aktiv war)
  • LSN erstellen — die LSN, als das VLF erstellt wurde (0 =das VLF wurde erstellt, als die Transaktionsprotokolldatei ursprünglich erstellt wurde). Alle anderen VLFs, die nach der anfänglichen Erstellung der Transaktionsprotokolldatei hinzugefügt wurden, haben eine CreateLSN ungleich Null.

Wir können den folgenden Befehl für den DBTest2014 ausführen Datenbank, die wir zuvor erstellt haben:

DBCC LOGINFO (N'DBTest2014');
GO

Sehen Sie sich das Ergebnis an:

DBCC SQLPERF (LOGSPACE)

Die einzige Möglichkeit in Transact-SQL, die Menge des verwendeten Protokolls zu untersuchen, ist DBCC SQLPERF. Die Syntax für den Befehl lautet:

DBCC SQLPERF
(
     [ LOGSPACE ]
     |
          [ "sys.dm_os_latch_stats" , CLEAR ]
     |
     [ "sys.dm_os_wait_stats" , CLEAR ]
)
     [WITH NO_INFOMSGS ]

Der Befehl gibt eine Ergebnismenge mit einer Zeile pro Datenbank zurück:

  • Datenbankname
  • Protokollgröße (MB)
  • Verwendeter Protokollspeicherplatz (%)
  • Status:immer auf Null gesetzt

In meiner Umgebung der folgende Befehl:

DBCC SQLPERF (LOGSPACE);
GO

Gibt das folgende Ergebnis zurück:

Im nächsten Artikel werden wir Protokollaufzeichnungen untersuchen.