Instant File Initialization für SQL Server

7. März 2012

Große Datenbanken leben in großen Dateien. Manchmal müssen diese Dateien neu angelegt oder erweitert werden, z.B. bei neuen Datenbankinstanzen, Restores, Kapazitätserweiterungen und ähnlichem. Um diese Vorgänge zu beschleunigen, bietet der SQL Server seit Version 2005 ein interessantes Feature an.

Sofortige Dateiinitialisierung

Eigentlich handelt es sich um ein Betriebssystem-Feature, das seit Windows Server 2003 bzw. Windows XP vorhanden ist, nämlich die sofortige Dateiinitialisierung. Was hat es damit auf sich?

Normalerweise werden Windows-Dateien beim Erzeugen mit Nullen initialisiert. Bei großen Dateien kann das naturgemäß etwas dauern. Die Datenbankdateien des SQL Servers werden in ihrer internen Struktur jedoch ohnehin von dessen eigenem Page/Extent-System verwaltet, d.h. der SQL Server liest nichts, was er nicht vorher selbst geschrieben hat, weshalb die Initialisierung unnötig ist. OK, das ist nicht die ganze Wahrheit, aber dazu gleich mehr.

Für’s erste kann man mitnehmen, das sich mit diesem Feature eine ganze Reihe von Vorgängen signifikant verkürzen lässt. Bei einem Restore beispielsweise kann sich die benötigte Zeit fast verdoppeln, weil die Datendateien ohne die Instant Initialization zweimal geschrieben werden. Erst werden sie mit Nullen gefüllt, dann vom eigentlichen Restore überschrieben. Den ersten Schritt kann man mit diesem Feature komplett überspringen.

Geschwindigkeit auf Kosten der Sicherheit?

Schön, aber warum ist das nicht von vorneherein aktiviert, wenn es so nützlich ist? Weil es ein (kleines) Sicherheitsrisiko darstellt. Eine nicht initialisierte Datei kann Daten enthalten, die aus zuvor gelöschten Dateien stammen und jeder, der die Datei lesen darf, hat Zugriff auf diese Datenblöcke. Das ist im SQL Server Kontext i.d.R. kein Problem.

Auf einem Laufwerk, das für SQL Server Datendateien benutzt wird, haben andere Dateien nämlich ohnehin nichts verloren und Datenfragmente, die aus zuvor gelöschten anderen DB-Dateien stammen, waren bereits im Zugriff des SQL Service Accounts. Auslesen ließen sich solche Datenfragmente aus gelöschten Dateien übrigens mit dem (undokumentierten) DBCC PAGE Befehl, mit dem man beliebige Blöcke aus den SQL Datendateien lesen kann (entsprechende Rechte vorausgesetzt). Die Gefahr, das ehemals gelöschte Daten aber z.B. wieder in aktuellen Tabellen auftauchen, besteht jedoch nicht.

Wer ganz auf Nummer Sicher gehen will, löscht Dateien auf den betroffenen Laufwerken erst nach einmaligem Überschreiben mit Nullen – dafür gibt es diverse, frei verfügbare Tools. Löschen ist normalerweise weniger zeitkritisch als das Anlegen neuer Dateien.

Konfiguration

Wie schaltet man diese Feature nun an? Ganz einfach, man gibt dem SQL Server Service Account das Windows-Recht "Perform Volume Maintenance Task" (SE_MANAGE_VOLUME_NAME) und startet die Instanz neu. Der SQL Server prüft, ob er dieses Recht hat und nutzt davon abhängig automatisch das Initialisierungsfeature. Standardmäßig ist das Recht nur auf Administratoraccounts aktiv, während der SQL Server entweder unter einem eigens angelegten Service Account oder – ebenfalls beliebt – unter "Network Service" läuft.

Zu bemerken wäre noch, dass das Feature nur bei Datendateien greift, nicht bei Logdateien. Letztere werden auf jeden Fall initialisiert, da sie zyklisch beschrieben werden und keine feste Initialstruktur an einer bestimmten Stelle haben.