Verwenden markierter Transaktionen (vollständiges Wiederherstellungsmodell)

Dieses Thema ist nur für SQL Server-Datenbanken relevant, für die das vollständige oder massenprotokollierte Wiederherstellungsmodell verwendet wird.

Wenn Sie Aktualisierungen für zwei oder mehr Datenbanken, (zugehörige Datenbanken), ausführen, können Sie diese mithilfe von Transaktionsmarkierungen bis zu einem logisch konsistenten Punkt wiederherstellen. Bei dieser Wiederherstellung gehen jedoch alle Transaktionen verloren, für die nach der Markierung, die als Wiederherstellungspunkt verwendet wird, ein Commit ausgeführt wird. Das Markieren von Transaktionen empfiehlt sich nur, wenn Sie verbundene Datenbanken prüfen oder wenn Sie in Kauf nehmen, dass Transaktionen, für die kürzlich ein Commit ausgeführt wurde, verloren gehen.

Durch das routinemäßige Markieren zugehöriger Transaktionen in allen verbundenen Datenbanken werden eine Reihe allgemeiner Wiederherstellungspunkte in den Datenbanken erstellt. Die Transaktionsmarkierungen werden im Transaktionsprotokoll aufgezeichnet und in Protokollsicherungen eingebunden. Wenn ein Notfall eintreten sollte, können Sie die einzelnen Datenbanken bis zu dieser Transaktionsmarkierung und damit bis zu einem konsistenten Zeitpunkt wiederherstellen.

HinweisHinweis

Protokollsicherungen für die verschiedenen Datenbanken können unabhängig voneinander erstellt werden. Sie müssen auch nicht gleichzeitig ausgeführt werden.

Für das Wiederherstellen zugehöriger Datenbanken in den folgenden Szenarien ist es erforderlich, dass in allen verbundenen Datenbanken bereits markierte Transaktionen verfügbar sind:

  • Mindestens ein Transaktionsprotokoll ist beschädigt. Stellen Sie für den Datenbanksatz einen konsistenten Status zum Zeitpunkt der letzten Protokollsicherung wieder her.

  • Sie müssen für den gesamten Datenbanksatz einen gegenseitig konsistenten Status zu einem früheren Zeitpunkt wiederherstellen.

Wichtiger HinweisWichtig

Sie können verbundene Datenbanken nur bis zu einer markierten Transaktion wiederherstellen, nicht bis zu einem bestimmten Zeitpunkt.

Weitere Informationen zum Erstellen markierter Transaktionen finden Sie unter "Erstellen der markierten Transaktionen" weiter unten in diesem Thema.

Typisches Szenario zum Verwenden markierter Transaktionen

Ein typisches Szenario zum Verwenden markierter Transaktionen umfasst die folgenden Schritte:

  1. Erstellen Sie eine vollständige oder differenzielle Datenbanksicherung für die einzelnen verbundenen Datenbanken.

  2. Markieren Sie in allen Datenbanken einen Transaktionsblock.

  3. Sichern Sie das Transaktionsprotokoll für alle Datenbanken.

  4. Stellen Sie mithilfe von WITH NORECOVERY Datenbanksicherungen wieder her.

  5. Stellen Sie mithilfe von WITH STOPATMARK Protokolle wieder her.

Überlegungen zum Verwenden markierter Transaktionen

Beachten Sie Folgendes, bevor Sie benannte Markierungen in das Transaktionsprotokoll einfügen:

  • Transaktionsmarkierungen belegen Protokollspeicherplatz und sollten deshalb nur für Transaktionen verwendet werden, die eine wichtige Rolle bei der Wiederherstellungsstrategie für die Datenbank spielen.

  • Nachdem für eine markierte Transaktion ein Commit ausgeführt wurde, wird in die logmarkhistory-Tabelle in msdb eine Zeile eingefügt.

  • Wenn sich eine markierte Transaktion über mehrere Datenbanken auf demselben Datenbankserver oder auf verschiedenen Servern erstreckt, müssen die Markierungen in den Protokollen aller betroffenen Datenbanken aufgezeichnet werden.

Erstellen der markierten Transaktionen

Verwenden Sie die BEGIN TRANSACTION-Anweisung und die WITH MARK [description]-Klausel, um markierte Transaktionen zu erstellen. Der optionale description-Parameter ist eine Textbeschreibung der Markierung. Ein Markierungsname für die Transaktion ist erforderlich. Ein Markierungsname kann erneut verwendet werden. Im Transaktionsprotokoll werden der Markierungsname, die Beschreibung, die Datenbank, der Benutzer, datetime-Informationen und die Protokollfolgenummer (LSN, Log Sequence Number) aufgezeichnet. Die datetime-Informationen werden zusammen mit dem Markierungsnamen für die eindeutige Identifizierung der Markierung verwendet.

So erstellen Sie markierte Transaktionen in einem Datenbanksatz:

  1. Benennen Sie die Transaktion in der BEGIN TRAN-Anweisung, und verwenden Sie die WITH MARK-Klausel

    Die BEGIN TRAN new_mark_name WITH MARK-Anweisung kann innerhalb einer vorhandenen Transaktion geschachtelt werden. Der Wert von new_mark_name stellt den Markierungsnamen für die Transaktion dar, selbst wenn die Transaktion einen Transaktionsnamen umfasst.

    HinweisHinweis

    Wenn Sie eine zweite geschachtelte BEGIN TRAN...WITH MARK-Anweisung ausgeben, wird diese ausgelassen, führt allerdings zu einer Warnmeldung.

  2. Führen Sie eine Aktualisierung für alle Datenbanken im Datenbanksatz aus.

    Die Markierung für eine bestimmte Transaktion wird nur in Transaktionsprotokollen auf der Serverinstanz eingefügt, auf der die BEGIN TRAN...WITH MARK-Anweisung ausgeführt wird. Die Transaktionsmarkierung wird in das Transaktionsprotokoll der Datenbanken platziert, die von der markierten Transaktion auf dieser Serverinstanz aktualisiert wurden. Wenn sich die Datenbanken auf verschiedenen Serverinstanzen befinden, müssen auf den einzelnen Serverinstanzen identische Markierungen erstellt werden.

Beispiele

Im folgenden Beispiel wird das Transaktionsprotokoll bis zur Markierung in der markierten Transaktion mit dem Namen ListPriceUpdate wiederhergestellt.

USE AdventureWorks2008R2;
GO
BEGIN TRANSACTION ListPriceUpdate
   WITH MARK 'UPDATE Product list prices';
GO

UPDATE Production.Product
   SET ListPrice = ListPrice * 1.10
   WHERE ProductNumber LIKE 'BK-%';
GO

COMMIT TRANSACTION ListPriceUpdate;
GO

-- Time passes. Regular database 
-- and log backups are taken.
-- An error occurs in the database.
USE master
GO

RESTORE DATABASE AdventureWorks2008R2
FROM AdventureWorksBackups
WITH FILE = 3, NORECOVERY;
GO

RESTORE LOG AdventureWorks2008R2
   FROM AdventureWorksBackups 
   WITH FILE = 4,
   RECOVERY, 
   STOPATMARK = 'ListPriceUpdate';

Erzwingen einer Markierung für andere Server

Ein Transaktionsmarkierungsname wird nicht automatisch an einen anderen Server verteilt, wenn die Transaktion dort verteilt wird. Um die Weitergabe der Markierung an die anderen Server zu erzwingen, muss eine gespeicherte Prozedur geschrieben werden, die eine BEGIN TRAN name WITH MARK-Anweisung enthält. Diese gespeicherte Prozedur muss dann auf dem Remoteserver unter dem Gültigkeitsbereich der Transaktion auf dem ursprünglichen Server ausgeführt werden.

Angenommen, eine partitionierte Datenbank ist in mehreren Instanzen von SQL Server vorhanden. In jeder Instanz gibt es eine Datenbank namens coyote. Erstellen Sie zuerst in allen Datenbanken eine gespeicherte Prozedur, z. B. sp_SetMark.

CREATE PROCEDURE sp_SetMark
@name nvarchar (128)
AS
BEGIN TRANSACTION @name WITH MARK
UPDATE coyote.dbo.Marks SET one = 1
COMMIT TRANSACTION;
GO

Erstellen Sie anschließend die gespeicherte Prozedur sp_MarkAll, in der eine Transaktion enthalten ist, mit der in jeder Datenbank eine Markierung platziert wird. sp_MarkAll kann von jeder Instanz aus ausgeführt werden:

CREATE PROCEDURE sp_MarkAll
@name nvarchar (128)
AS
BEGIN TRANSACTION
EXEC instance0.coyote.dbo.sp_SetMark @name
EXEC instance1.coyote.dbo.sp_SetMark @name
EXEC instance2.coyote.dbo.sp_SetMark @name
COMMIT TRANSACTION;
GO

Zwei-Phasen-Commit

Das Ausführen eines Commits einer verteilten Transaktion verläuft in zwei Phasen: Vorbereitung und Commit. Wenn für eine markierte Transaktion ein Commit ausgeführt wird, wird der Commitprotokolleintrag für jede Datenbank in der markierten Transaktion an einem Punkt des Protokolls platziert, an dem in keinem der Protokolle zweifelhafte Transaktionen vorhanden sind. Damit wird sichergestellt, dass keine Transaktionen auftreten, für die in einem Protokoll das vollzogene Ausführen eines Commits angezeigt wird, während in einem anderen Protokoll das vollzogene Ausführen eines Commits nicht angezeigt wird.

Gehen Sie dazu während der Ausführung eines Commits für eine markierte Transaktion folgendermaßen vor:

  1. Die Vorbereitungsphase einer Markierungstransaktion hält alle neuen Vorbereitungen und Commits zurück.

  2. Nur Commits für bereits vorbereitete Transaktionen werden fortgesetzt.

  3. Die Markierungstransaktion wartet dann, bis alle vorbereiteten Transaktionen ausgeglichen wurden (mit Timeout).

  4. Die markierte Transaktion wird vorbereitet, und ein Commit wird ausgeführt.

  5. Das Zurückhalten neuer Vorbereitungen und Commits wird entfernt.

Das Zurückhalten, das durch markierte Transaktionen generiert wird, die sich über mehrere Datenbanken erstrecken, kann die Leistung des Servers hinsichtlich der Transaktionsverarbeitung beeinträchtigen.

Es wird davon abgeraten, markierte Transaktionen gleichzeitig auszuführen. Es kommt zwar selten vor, aber es ist möglich, dass der Commit einer verteilten markierten Transaktion einen Deadlock mit anderen verteilten Transaktionen verursacht, für die gleichzeitig ein Commit ausgeführt wird. Wenn dies passiert, wird die Markierungstransaktion als Deadlockopfer gewählt, und ein Rollback wird ausgeführt. In diesem Fall kann die Anwendung versuchen, die markierte Transaktion erneut auszuführen. Wenn mehrere markierte Transaktionen versuchen, gleichzeitig einen Commit auszuführen, steigt die Wahrscheinlichkeit eines Deadlocks.

Wiederherstellen bis zu einer markierten Transaktion

Informationen zum Wiederherstellen einer Datenbank, in der markierte Transaktionen enthalten sind, bis zu einer Markierung oder kurz vor einer bestimmten Markierung finden Sie unter Wiederherstellen bis zu einer markierten Transaktion.