Availability Groups und misaligned log IOs

Mal wieder ein Artikel, in dem ich jede Menge englische Begriffe verwende und mir nicht die Mühe mache, sie zu übersetzen, da sie außerdem wahrscheinlich sowieso auf englisch in irgendwelchen Logs auftauchen. Hier geht es um die Schwierigkeiten, die man im Zusammenhang mit Availability Groups bekommen kann, wenn die Hardware nicht so ganz gleich ist.

In meinem Fall geht es um einen 3-Knoten Cluster, wobei zwei Knoten als Failover-Instanz laufen und der dritte Knoten für Ausfallsicherheit in einem zweiten Rechenzentrum verwendet wird. Die ersten beiden Knoten teilen sich den Zugriff auf ein SAN, beim dritten Knoten dachten wir darauf verzichten zu können und verwendeten schöne neue lokale Platten.

Die Fehlermeldung

Recht bald nach der Einrichtung der Availability Group und Inbetriebname der Datenbank mit asynchroner Verarbeitung für das etwas entfernt stehende Rechenzentrum, erschienen im Log des dritten Knotens Meldungen in dieser Art:

There have been 12800 misaligned log IOs which required falling back to synchronous IO.  The current IO is on file e:\MSSQL11.MSSQLSERVER\MSSQL\Data\databasename_Log.LDF

Dank der Mithilfe von Microsoft konnte ich mich über die Hintergründe und Ursache dieser Meldung informieren.

Hintergründe

Es war recht schnell klar, dass es sich um Unterschiede im physikalischen Layout der Platten handelt. Zur Erinnerung: Auf der einen Seite haben wir SAN, auf der anderen Seite neue lokale Platten.

Mit dem Kommandozeilen-Tool fsutil kann man sich die Details des Layouts anzeigen lassen:

fsutil fsinfo ntfsinfo G:
...
Bytes Per Sector  :               512
Bytes Per Physical Sector :       4096
Bytes Per Cluster :               65536
Bytes Per FileRecord Segment    : 1024
...

Hierbei besteht das Laufwerk G: aus den lokalen Platten. Man merke hier die Bytes Per Physical Sector mit 4096. Das ist bei neueren Platten durchaus üblich.

Zum Vergleich die Angaben zum SAN:

...
Bytes Per Sector  :               512
Bytes Per Physical Sector :       <not Supported>
Bytes Per Cluster :               4096
Bytes Per FileRecord Segment    : 1024
...

Die Ursache

SQL Server verwendet die DeviceIoControl Funktion um die physikalische Sector Größe der Platten zu bestimmen, auf denen die SQL Dateien liegen. Diese Funktion schlug bei den SAN Disks auf der primären Seite fehl (Bytes Per Physical Sector : „<not Supported>“) und so verwendete SQL Server den Standardwert von 512 Bytes für die Sektorgröße der primären Datenbank, während auf der sekundären Seite 4096 Byte angezeigt werden. Deshalb bekamen wir die Warnung, weil diese Werte nicht zusammen passten. Falls es nicht gerade ein Spiegelungs-Szenario gewesen wäre, hätte SQL Server diese Angabe während des Startups der Datenbank auf dem sekundären Server korrigiert, damit sie mit der physikalischen Größe der Platte übereinstimmte. (Wenn man eine Datenbank auf dem SAN anlegt und diese dann auf den lokalen Platten des sekundären Servers wiederherstellt, kann man im Errorolog entsprechende Meldungen sehen.).
Um diesen Fehler zu beheben, muss man entweder den SAN-Treiber dazu bringen die korrekte Größe anzuzeigen und diese muss dann auch noch mit der Größe der lokalen Platten übereinstimmen, oder man verwendet anstelle der lokalen Platten auch auf dem sekundären Server SAN-Storage.

Die Lösung

Wir konnten unseren SAN-Treiber nicht dazu zu bewegen, wirkliche Werte anzuzeigen und hatten außerdem die Aussage des SAN-Teams, dass wir höchstens dort 512 zu sehen bekämen. Daher haben wir den dritten Knoten des Clusters auch auf SAN umgestellt, welches wir glücklicherweise auch im zweiten Rechenzentrum zur Verfügung haben.

Interessanterweise reichte es aus, die Platte mit den Transaktionslogs auf physikalischer Ebene mit dem primären Server auszurichten. Die Datendateien (MDF) liegen weiterhin auf den lokalen Platten.