Hilfe aus dem Transaction Log
Heute wollen wir mal mit Hilfe des Apex Log 2011 einen Blick in das Transaction Log werfen und schauen, ob wir damit Transaktionen sichtbar machen können, bzw. alte Daten wiederherstellen können.
Inserts, Updates und Deletes
Wir starten mit dem folgenden kleinen Skript, welches eine Tabelle anlegt, Zeilen einfügt, Zeilen ändert und am Ende eine Zeile wieder löscht:
CREATE TABLE tbl_Artikel (Artikel integer, Preis DECIMAL(10,2), CONSTRAINT xpktbk_Artikel PRIMARY KEY CLUSTERED (Artikel));
INSERT INTO tbl_Artikel(Artikel, Preis)
VALUES(1,10.2),
(2,15.3),
(3,40.2),
(4,50.7);
BEGIN TRAN
UPDATE tbl_Artikel SET Preis = Preis * 1.1;
COMMIT TRAN
DELETE FROM tbl_Artikel
WHERE Artikel = 3;
Schaut man sich das aktuelle Transaction Log (oder auch die vorhandenen Backups) mit Apex Log 2011 einmal genauer an, erhält man die folgende Auflistung:
Im Detail sieht ein Insert dann wie auf dem folgenden Bild aus. Die Page ID und Slot ID ergeben zusammen den genauen Ort des Datensatzes. Für jeden Satz gibt es eine Slot ID. In der Slot Array am Ende jeder Page steht zu jeder Slot ID der Offset drin, wieweit der Satz vom Anfang der Seite entfernt ist.
Die eigentlichen Daten kann man sich im Reiter Operation Details anzeigen lassen.
Ein Update unterscheidet sich nicht wesentlich vom Insert ...
... hier werden lediglich die Inhalte vor und nach der Änderung aufgeführt.
Interessanter wird es dann wieder bei einem DELETE. Dieses betrifft die Artikelnummer 3, welches nach unserer oben beschriebenen Logik im Slot 2 landet, da diese von 0 an beginnend durchnummeriert werden.
Falls ich nun in die Verlegenheit komme und dieses DELETE wieder rückgängig machen möchte, hilft mir der Reiter Undo Script.
Aber unter Umständen will ich ja auch genau das Statement noch einmal ausführen. Auch das ist möglich, da der Reiter Redo Script genau dieses bereithält. Ergänzt werden hier von Apex lediglich einige Fehlerbehandlungen.
Die Slot Array
Als nächstes führen wir mal ein Update auf die Zeile mit der Artikelnummer 4 aus:
UPDATE tbl_Artikel
SET Preis = 100
WHERE Artikel = 4;
Wir haben jetzt ein Update auf den Artikel mit der Nummer 4 durchgeführt. Der war zu Anfang im Slot 3 gelandet. Durch die Löschung von Artikel 3 sind alle dahinterliegenden Sätze (zumindest in der Slot Array) weiter nach vorne gewandert. Die Page selber wird nicht sofort reorganisiert um Platz frei zu machen. Der UPDATE trifft nun also die Slot ID 2, die durch das letzte DELETE frei geworden ist! Sehr interessante und ausführliche Beschreibungen der Anatomie von Seiten und Zeilen findet man bei Paul Randal.
Nach diesem zweiten Update auf die Zeile mit Artikelnummer 4 schauen wir uns mal die Row History an. Dies kann das Tool von Apex eigentlich nur durch die Kombination der Informationen aus dem Transaction Log gewinnen.
An den eigenen Haaren aus dem Sumpf ziehen
Sich an den eigenen Haaren aus dem Sumpf zu ziehen, hat bisher nur Münchhausen fertig bekommen. Aber auch wenn wir vor der Situation sind, dass eigentlich alles verloren ist, können wir uns noch weiterhelfen.
Stellen wir uns also vor, dass unsere schöne frisch angelegte Artikeltabelle einfach gelöscht wurde. Und zwar nicht nur mit TRUNCATE, sondern sogar komplett mit DROP TABLE. Im Transaction Log wird nur ein simpler Eintrag zu finden sein, der anzeigt, dass alle Datenseiten der Tabelle freigegeben wurden, die Metadaten wurden entsorgt. Das Objekt existiert nicht mehr.
Dieser Umstand ist auch eine Ursache dafür, warum wir nicht einfach eine Datenbank komplett zurückrollen können. Es bietet sich uns nur der längere Weg über einen Restore der Datenbank-Sicherung, der letzten differentiellen Sicherung und aller benötigten Log Sicherungen. Wenn ein DROP TABLE oder TRUNCATE TABLE vollständig aufgezeichnet würden, könnten wir ein einormes Wachstum des Transaction Logs beobachten und auch die benötigte Zeit für diese Aktion würde gewaltig anwachsen.
Ab diesem Zeitpunkt hat das Tool von Apex auch keine Chance mehr die Informationen aus dem Log vernünftig aufbereitet anzuzeigen:
Alle Angaben zu dem Objekt werden als UNKNOWN angezeigt. Redo Scripte lassen sich nicht mehr generieren, da es keine Informationen über die Metadaten des Objektes gibt. Aber hier haben die Entwickler weitergedacht und bieten uns die Möglichkeit, nachdem die Tabelle neu angelegt wurde, die Object-ID des Transaction Logs auf eine real existierende Tabelle zu mappen:
Sofort erscheinen die Informationen wieder in der Auswertung und Redo Scripte können erstellt werden. Über diesen Weg könnte man also alle Datensätze der Tabelle wiederherstellen:
Falls natürlich das erste CREATE der Tabelle bereits Jahre her ist, wird man über diesen Weg lediglich die Informationen herausfinden können, die in den vorliegenden Transaction Log Sicherungen enthalten sind. Der einfache Weg wird dann evtl. doch der Restore der Datenbank für einen bestimmten Zeitpunkt sein.
Was gibt es sonst noch?
Apex Log 2011 kann natürlich noch viele Filter anwenden, damit man nur die Daten auf den Schirm bekommt, die man auch wirklich sehen möchte. Dies umfasst zum einen Objekt-Filter, aber auch Statement-Filter für DDL und DML. Natürlich kann man auch genau den Zeitraum eingrenzen, der untersucht werden soll.
Wer mal in die Verlegenheit kommt, so ein Tool einsetzen zu müssen, sollte auf jeden Fall mal bei Apex vorbeischauen, zumal es die Testversion für 14 Tage kostenlos gibt.
Print article | This entry was posted by cmu on 17.02.12 at 13:58:00 . Follow any responses to this post through RSS 2.0. |