Die Matrix ist kurz. Der Betrieb ist lang.
Wer Teil 1 gelesen hat, weiß, was eine Failover Cluster Instance (FCI) schützt und was eine Availability Group (AG). Die nächste Frage ist konkreter: Was kann welche Variante in meiner Version und Edition, wovor schützt sie mich wirklich, und was kostet sie mich Tag für Tag? Die Antwort hat zwei Teile. Die Featurematrix passt auf eine Bildschirmseite. Die Betriebsfolgen, Commit-Latenz, Failover-Dauer, hängende Secondaries, Logins und Jobs, Patchen, füllen den Rest dieses Artikels. Und weil Microsoft zu Dauer und Latenz keine Zahlen nennt, haben wir im Lab gemessen.
Kurz gesagt
- Standard kann FCI mit zwei Knoten und die Basic AG mit zwei Replikaten und einer Datenbank. Alles, was Lesen oder Sichern auf einer Kopie heißt, ist Enterprise. SQL Server 2025 ändert daran nichts.
- RPO und RTO sind Anforderungen, keine Produktmerkmale. Bei einer AG lassen sie sich aus Sendewarteschlange, Redo-Rückstand und
last_commit_timeschätzen; bei einer FCI gibt es keinen Datenverlust, aber auch keine Messgröße für die Wiederanlaufzeit außer der Recovery selbst. - Synchron kostet jede Transaktion die Latenz der Leitung zur Secondary. Im Lab mit internem Netz stieg die Commit-Latenz im Median von 8 auf 16 Millisekunden; in der Praxis bestimmt die Strecke zwischen den Replikaten den Aufschlag.
- Ein Rollenwechsel in der AG dauert unter einer Sekunde, ein Instanzneustart rund zehn, und genau der Neustart ist der FCI-Failover. Dazu kommt bei beiden die Recovery offener Transaktionen; Accelerated Database Recovery (ADR) macht ihr Undo klein, und ein zu streng gesetztes
REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMITkann aus einem Sekunden-Failover eine Minute ohne Schreibzugriff machen. - Eine hängende Secondary ist ein Problem des Primary: Solange sie angehalten ist, wird dessen Log nicht abgeschnitten.
- Der tägliche Preis der AG sind die Instanzobjekte. Logins, Jobs, Linked Server und Konfiguration gehören zur Instanz und müssen auf jedem Replikat gepflegt werden. Die FCI kennt dieses Problem nicht, weil es nur eine Instanz gibt.
Die Matrix: FCI, Basic AG und volle AG für SQL Server 2017 bis 2025
Die Tabelle fasst die Editions- und Funktionsseiten von Microsoft für die vier Versionen zusammen. „Std“ ist Standard, „Ent“ Enterprise. Wo sich seit 2017 nichts geändert hat, steht nur ein Eintrag.
| Merkmal | FCI | Basic AG | Volle AG |
|---|---|---|---|
| Edition | Std (2 Knoten), Ent (bis 16 Knoten) | nur Std | nur Ent |
| Schutzebene | Instanz | eine Datenbank je Gruppe | Gruppe von Datenbanken |
| Datenkopien | eine, auf gemeinsamem Storage | zwei | eine je Replikat, bis zu neun Replikate |
| Synchron / asynchron | nicht anwendbar | beides möglich | beides, mehrere synchrone Replikate (Zahl je Version, siehe unten) |
| Automatisches Failover | ja, über die WSFC-Richtlinie | ja, bei synchronem Commit | ja, bei synchronem Commit und synchronisiertem Ziel; 2025: Fast Failover mit RestartThreshold 0 |
| Lesbare Secondary | nein, passive Knoten sind gestoppt | nein | ja; 2025 mit persistenten Statistiken |
| Backups auf der Secondary | nicht anwendbar | nein, auch keine Integritätsprüfungen | Log- und Copy-Only-Vollbackups; 2025 auch Voll- und Differentialbackups |
| Automatic Seeding | nicht anwendbar | ja | ja (seit 2016; Standard per T-SQL ist MANUAL) |
| Distributed AG | kann ein Replikat einer Distributed AG hosten, nur manuelles Failover | nein | ja, Ent; 2025 auch mit Contained AGs |
| Contained AG (Logins, Jobs in der Gruppe) | nicht anwendbar | nein | ab 2022, Ent |
Ohne Cluster (Cluster-Typ NONE) | nein | ab 2019 (2017: nur Ent als Read-Scale) | ab 2017, nur Lesen/Migration, keine Hochverfügbarkeit |
| Listener / Name | virtueller Netzwerkname, immer | Listener optional | Listener optional; ohne ihn keine Umleitung und kein Read-only-Routing |
| Query Store auf der Secondary | nicht anwendbar | nein | 2022 nur mit Ablaufverfolgungsflag, 2025 als Vorschau, nicht standardmäßig an |
| Was im Failover mitgeht | die ganze Instanz | nur die Datenbank | nur die Datenbanken der Gruppe (Contained AG: plus Logins und Jobs) |
| Dritte Variante zum Vergleich | Log Shipping: Std und Ent, manueller Rollenwechsel, verzögerter Restore als Schutz vor Anwenderfehlern |
Zwei Anmerkungen zu Zahlen, die oft gefragt werden. Synchrone Replikate: Microsoft nennt die Höchstzahl auf verschiedenen Seiten unterschiedlich, von drei bis sechs. Gesichert ist nur: 2017 weniger als ab 2019, und mehr als zwei. Wir nennen deshalb keine Zahl, bis wir sie selbst geprüft haben. FCI-Knoten: Die Editionsseiten aller vier Versionen sagen 16 für Enterprise; das ist die SQL-Server-Grenze, nicht die des Windows-Clusters.
RPO und RTO: Anforderungen, keine Produktmerkmale
RPO (Recovery Point Objective) ist die Zeitspanne an Daten, die Sie im Ernstfall verlieren dürfen. RTO (Recovery Time Objective) ist die Zeit, bis die Anwendung wieder läuft. Beides sind Ihre Vorgaben an die Architektur, keine Eigenschaften von FCI oder AG. Die Verfahren liefern nur Hebel, um die Vorgaben zu erreichen, und Messgrößen, um das zu prüfen.
Bei einer AG lässt sich beides schätzen, und Microsoft gibt die Formeln dafür an:
- Wiederanlaufzeit = Erkennung + Redo + Überhang. Der Überhang ist das Umschalten im Cluster und das Online-Schalten der Datenbanken, laut Microsoft meist kurz und konstant. Die Erkennung hängt an den Cluster-Einstellungen (Health-Check-Timeout 30 Sekunden, Lease 20 Sekunden, Sitzungs-Timeout 10 Sekunden als Standardwerte). Das Redo ist der Teil, den Sie beeinflussen:
redo_queue_sizegeteilt durchredo_rate, beides insys.dm_hadr_database_replica_statesin KB und KB/s. Eine Secondary, die mit dem Nachspielen des Logs nicht nachkommt, ist im Failover erst nach dem Aufholen nutzbar. Maßgeblich ist die Datenbank mit dem größten Rückstand. - Datenverlust = Sendewarteschlange geteilt durch Log-Erzeugungsrate.
log_send_queue_sizeist das Log, das der Primary noch nicht an die Secondary geschickt hat; bei synchronem Commit und synchronisierter Secondary ist es null, bei asynchronem Commit die eigentliche Risikogröße. Vereinfacht reicht der Abstand derlast_commit_timezwischen der Primary- und der Secondary-Zeile; Microsoft empfiehlt, diesen Abstand regelmäßig gegen das angestrebte RPO zu prüfen und zu alarmieren.
Bei einer FCI gibt es keine zweite Kopie und deshalb keinen Datenverlust, aber auch keine Warteschlange, die man beobachten könnte. Die Wiederanlaufzeit ist Dienststart plus Recovery jeder Datenbank: Analyse, Redo, Undo. Was sie treibt, sind die schmutzigen Seiten zum Zeitpunkt des Failovers (indirekte Checkpoints begrenzen sie) und die längste offene Transaktion. Wie groß dieser Effekt ist, zeigt der Abschnitt zur Failover-Dauer.
Die Abfrage 1 am Ende dieses Artikels liest genau diese Werte aus: Rolle, Modus, Sendewarteschlange, Redo-Rückstand, last_commit_time und den Log-Wartegrund, für Einzelinstanz, FCI und AG.
Synchron oder asynchron: was ein Commit kostet
Bei synchronem Commit bestätigt der Primary eine Transaktion erst, wenn die Secondary das Log hart geschrieben hat. Das ist die Garantie gegen Datenverlust, und ihr Preis ist Latenz: Jede schreibende Transaktion wartet einmal auf die Strecke zur Secondary und zurück, sichtbar als Wartetyp HADR_SYNC_COMMIT. Asynchron wartet der Primary nicht; die Secondary kann zurückliegen, und ein Failover dorthin ist nur erzwungen möglich.
Im Lab haben wir dieselbe Datenbank dreimal mit je 3.000 Einzelzeilen-Inserts im Autocommit beschrieben: zuerst außerhalb der AG, dann als synchrones Replikat mit REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 1, dann asynchron. Gemessen wurde die Latenz, die der Client je Commit sieht (Median aus drei Läufen je Variante, SQL Server 2022 CU27):
| Variante | p50 | p95 | p99 | Commits/s | HADR_SYNC_COMMIT je Commit |
|---|---|---|---|---|---|
| Einzelinstanz, nicht in der AG | 8,2 ms | 14,4 ms | 17,0 ms | 102 | – |
| AG synchron | 15,8 ms | 25,0 ms | 28,7 ms | 56 | 1,17 ms |
| AG asynchron | 14,3 ms | 20,5 ms | 25,5 ms | 68 | 0 |
Zwei Dinge fallen auf. Erstens kostete der synchrone Commit hier 7,6 Millisekunden je Transaktion zusätzlich, fast eine zweite Log-Härtung; die Wartestatistik HADR_SYNC_COMMIT zeigte davon nur gut eine Millisekunde. Wer den Preis der Synchronität sucht, sollte deshalb die Latenz beim Client messen, nicht nur die Waits. Zweitens war asynchron im Lab kaum schneller als synchron. Das ist ein Laborartefakt: Beide Replikate schreiben ihr Log auf dieselbe SSD, und die Secondary bremst den Primary beim Härten (unsere Erklärung, nicht isoliert nachgewiesen). Auf getrennten Datenträgern bestätigt der Primary asynchron sofort nach dem eigenen Log-Write.
Was die Zahlen nicht zeigen: Im Lab liegen beide Replikate auf derselben Maschine, verbunden über ein internes Docker-Netz. Das ist der Latenzboden der Mechanik. In der Praxis bestimmt die Leitung zwischen den Rechenzentren den Aufschlag, und zwar für jede einzelne schreibende Transaktion. Deshalb gehören synchrone Replikate an eine schnelle, kurze Strecke, asynchrone an die weite.
Ein Schalter verdient dabei besondere Aufmerksamkeit: REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT (ab 2017, Standard 0). Er legt fest, wie viele synchrone Secondaries ein Commit hart geschrieben haben müssen. Bei 0 arbeitet der Primary weiter, wenn die Secondary ausfällt, und markiert sie als nicht synchronisiert; die Garantie gegen Datenverlust ist in diesem Moment weg. Bei 1 oder mehr scheitern Commits auf dem Primary, sobald zu wenige synchrone Secondaries erreichbar sind: Die Daten sind sicher, die Anwendung steht. Das ist kein Fehler, sondern die Wahl zwischen Verfügbarkeit und Schutz, und sie gehört vor dem Ernstfall getroffen, nicht währenddessen. Im Lab lief die AG mit dem Wert 1; beim Trennen der Secondary wies der Primary Schreibvorgänge mit einem Quorumfehler ab.
Was ein Failover wirklich dauert: Rollenwechsel gegen Neustart
Teil 1 hat den Unterschied beschrieben: Bei der FCI startet die Instanz auf dem anderen Knoten neu und durchläuft für jede Datenbank die Recovery. Bei der AG hat die Secondary das Log schon nachgespielt; sie muss nur die Rolle übernehmen und offene Transaktionen zurückrollen. Microsoft sagt „meist Sekunden“ für die AG und „meist länger“ für die FCI, aber keine Zahl. Also haben wir gemessen, mit einer ehrlichen Einschränkung: Im Lab gibt es keinen Windows-Cluster und keine FCI. Als Stellvertreter für den FCI-Failover dient der Neustart der Instanz, denn genau das passiert auf dem neuen Knoten: Dienststart und Crash Recovery. Die Erkennungsphase des Clusters fehlt in beiden Messungen; sie kommt in der Praxis bei beiden Verfahren hinzu.
| Was gemessen wurde (SQL Server 2022 CU27, je drei Läufe) | bis die Datenbank schreibbar ist | davon Undo der offenen Transaktion |
|---|---|---|
| Neustart der Instanz (FCI-Stellvertreter: Prozess hart beendet und neu gestartet), ruhend | 9,3 s (9,2–9,4) | – |
| Neustart, offene Transaktion mit 100 MB Log, ADR aus | 9,6 s (9,6–9,6) | 0,43 s |
| Neustart, dieselbe Transaktion, ADR an | 9,8 s (9,5–10,1) | 0,03 s |
| Rollenwechsel der AG, ruhend | 0,72 s (0,71–0,78) | – |
| Rollenwechsel, offene Transaktion mit 100 MB Log, Pflicht-Secondary 1 | 70,6 s (69,7–71,8) | 2,4 s |
| Rollenwechsel, dieselbe Transaktion, Pflicht-Secondary 0 (zwei Läufe) | 0,9 s; die von der Transaktion gesperrten Zeilen nach rund 4 s | 2,4 s |
Beim Neustart dominierte der Dienststart: rund 6 Sekunden, bis die Instanz Verbindungen annahm, rund 8, bis die Benutzerdatenbank startete. Die offene Transaktion kostete im Undo 0,43 Sekunden ohne ADR und 0,03 mit ADR; bei 100 MB ist das neben dem Dienststart klein, aber die Undo-Zeit wächst ohne ADR mit der Transaktion, mit ADR bleibt sie konstant klein (wie groß der Unterschied bei großen Rollbacks wird, zeigt die Vertiefung ADR). Nebenbefund: Die Datenbank war jeweils schon schreibbar, bevor das Errorlog „Recovery completed“ meldete; das ist Fast Recovery der Developer Edition, die sich wie Enterprise verhält. Ein geordneter Stopp per SHUTDOWN war nicht schneller als der harte Abbruch, weil der Stopp selbst bis zu vier Sekunden brauchte.
Beim Rollenwechsel war der neue Primary ruhend nach 0,7 Sekunden schreibbar, ohne Datenverlust in allen acht Läufen. Mit offener Transaktion rollte der neue Primary diese in 2,4 Sekunden zurück, nahm aber 70 Sekunden lang keinen Schreibzugriff an. Der Grund ist nicht das Undo, sondern der Schalter: Mit REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 1 wartet der neue Primary, bis der alte als Secondary wieder synchronisiert ist, und der brauchte für seine Resynchronisierung mit zwei Datenbankneustarts gut eine Minute (warum genau so lange, haben wir nicht isoliert). Mit dem Wert 0 war der neue Primary nach 0,9 Sekunden schreibbar, lief dann aber dieselbe Minute ohne synchronisierte Kopie. Beides ist dieselbe Wahl wie im Abschnitt zur Commit-Latenz: Verfügbarkeit oder Schutz, und sie zeigt sich ausgerechnet im Failover.
Die Lehre daraus ist in beiden Richtungen nützlich. Für die FCI: Ihre Wiederanlaufzeit ist eine Recovery-Frage. Lange offene Transaktionen verlängern sie direkt, Accelerated Database Recovery (ab SQL Server 2019, auch in Standard) macht die Undo-Phase davon unabhängig, und Fast Recovery (nur Enterprise) bringt die Datenbank schon nach dem Redo online, während das Undo noch läuft. Für die AG: Der Rollenwechsel selbst ist schnell, sofern die Secondary synchronisiert ist und ihr Redo aufgeholt hat. Hängt das Redo, wartet der Failover darauf, und eine offene Transaktion auf dem alten Primary muss auch auf dem neuen zurückgerollt werden.
Wovor welche Variante schützt
Hochverfügbarkeit ist kein Zustand, sondern eine Liste von Ausfällen, gegen die man sich entschieden hat. Die Liste sieht für die drei Varianten so aus:
| Ausfall | FCI | Basic AG | Volle AG | Log Shipping |
|---|---|---|---|---|
| Knoten (Hardware, Betriebssystem, SQL-Dienst) | ja, automatisch | ja, automatisch bei synchronem Commit | ja, automatisch bei synchronem Commit | manuell |
| Storage | nein, es gibt nur eine Kopie | ja, eigene Kopie je Replikat; das Umschalten ist aber nur mit DB_FAILOVER = ON automatisch | ja, eigene Kopie; Umschalten wie Basic AG | ja, manuell |
| Standort (Rechenzentrum, Netz, Strom) | nur mit replizierter Speicherlösung und Knoten im zweiten Standort | ja, asynchron über die Entfernung, Failover erzwungen | ja, asynchron oder als Distributed AG; Failover erzwungen oder geplant | ja, manuell |
Anwender- oder Programmfehler (versehentliches DELETE) | nein, die Änderung ist sofort in der einen Kopie | nein, die Änderung wird sofort repliziert | nein, ebenso | ja, mit verzögertem Restore |
| Beschädigte oder verdächtige Datenbank | nein, die Instanz läuft ja | nur mit DB_FAILOVER = ON (Standard aus) | nur mit DB_FAILOVER = ON | manuell |
Zwei Zeilen verdienen einen zweiten Blick. Der Storage ist die Grenze der FCI: Fällt er aus oder liefert Fehler, hat sie nichts, worauf sie umschalten könnte; Microsoft verweist ausdrücklich auf den Schutz durch die Speicherlösung. Eine AG hat die zweite Kopie, aber Vorsicht: Ein Speicherfehler, der nur eine Datenbank trifft, löst ohne DB_FAILOVER = ON kein Failover aus, weil die Instanz aus Sicht des Clusters gesund bleibt; der Schalter steht standardmäßig aus. Und der Anwenderfehler ist die Grenze jeder Replikation: Eine Secondary ist keine Sicherung, weil sie den Fehler in Millisekunden übernimmt. Nur ein getestetes Backup oder ein verzögerter Restore fängt das ab; Teil 2 von Backup und Restore rechnet das gegen RPO und RTO.
Lesen und Sichern auf der Secondary
Das stärkste Argument für die volle AG ist, dass die Kopie arbeitet. Lesbare Secondaries nehmen Berichte und Auswertungen vom Primary; Backups auf der Secondary nehmen ihm die I/O-Last der Sicherung. Beides gibt es nur in Enterprise, und beides hat Kosten, die man kennen sollte:
- Lesbare Secondary: Abfragen laufen intern unter Snapshot-Isolation. Dafür erhält jede geänderte Zeile einen Aufschlag von 14 Byte, auf dem Primary ebenso wie auf der Secondary, mit möglichen Seitenteilungen. Zeilenversionen und temporäre Statistiken landen in der tempdb der Secondary. Lange Leseabfragen halten Schemasperren und können das Redo von DDL blockieren; dann wächst der Redo-Rückstand, und mit ihm die Wiederanlaufzeit. SQL Server 2025 überträgt Statistiken, die auf der Secondary entstehen, zum Primary, damit alle Replikate sie nutzen.
- Backups auf der Secondary: Bis SQL Server 2022 sind dort reguläre Log-Backups und Copy-Only-Vollbackups möglich, keine Differentialbackups. SQL Server 2025 erlaubt auch Voll- und Differentialbackups auf jeder Secondary. Die Backup-Präferenz der AG erzwingt SQL Server nicht; Ihre Backup-Jobs müssen sie mit
sys.fn_hadr_backup_is_preferred_replicaselbst auswerten. Ein Backup auf der Secondary hält auf dem Primary einen Thread, und ein Copy-Only-Backup blockiert auf der Secondary vorübergehend die Log-Abschneidung.
Die Basic AG kann nichts davon: kein Lesen, keine Backups, keine Integritätsprüfungen auf der Secondary. Die FCI hat keine zweite Kopie, auf der etwas laufen könnte. Wer Lesen oder Sichern auslagern will, hat damit die Editionsfrage schon beantwortet.
Instanzobjekte, Jobs und Logins: der tägliche Preis der AG
Eine AG repliziert Datenbanken. Alles, was zur Instanz gehört, repliziert sie nicht: Logins, Agent-Jobs, Linked Server, Credentials, Serverkonfiguration, Berechtigungen auf Serverebene, Resource-Governor-Einstellungen. Nach einem Failover ist die Datenbank da, aber der Login der Anwendung fehlt, der Wartungsjob läuft nicht oder läuft doppelt, und der Linked Server zeigt ins Leere. Der Betrieb einer AG heißt deshalb, diese Objekte auf jedem Replikat gleich zu halten: Logins mit identischen SIDs anlegen, Jobs mit einer Prüfung versehen, ob die Instanz gerade Primary ist, Konfigurationsänderungen überall nachziehen.
Seit SQL Server 2022 (Enterprise) nimmt die Contained Availability Group einen Teil davon ab: Sie führt Benutzer, Logins, Berechtigungen und Agent-Jobs in eigenen master- und msdb-Datenbanken der Gruppe, die mit umschalten. Jobs laufen dort nur auf dem Primary. Verbindungen gehen zwingend über den Listener der Contained AG; Replikation, SSIS-Pakete und Wartungspläne werden nicht unterstützt.
Die FCI hat dieses Thema nicht. Es gibt eine Instanz, sie zieht mit allem um, was in ihr steckt. Wer wenig Betriebsmannschaft hat und keine lesbare Kopie braucht, sollte dieses Argument nicht unterschätzen.
Wartung: Patchen, Rolling Upgrade, Failover-Übung
Beide Verfahren erlauben Wartung ohne vollständigen Stillstand, aber in unterschiedlicher Reihenfolge und mit unterschiedlicher Reichweite.
FCI: Das Setup aktualisiert die Knoten nacheinander, die passiven zuerst. Jeder aktualisierte Knoten fällt aus der Liste der möglichen Besitzer, bis die Instanz auf einen aktualisierten Knoten umgeschaltet wird; standardmäßig entscheidet das Setup, sobald die Hälfte der Knoten fertig ist. Die Ausfallzeit ist ein Failover plus die Laufzeit der Upgradeskripte. Nicht möglich ist, eine Standalone-Instanz nachträglich zur FCI zu machen oder eine FCI zur Standalone-Instanz zurückzustufen.
AG: Erst die Secondaries (Remote zuerst, dann lokal), dann ein geplanter Failover auf ein synchronisiertes Replikat, zuletzt der alte Primary. Vorher: Probe-Failover, Vollbackup, Integritätsprüfung, automatisches Failover an den synchronen Replikaten abschalten. Während ein Replikat höher gepatcht ist als der Primary, kann es keine lesbaren Abfragen und keine Backups liefern; die Backup-Präferenz sollte solange auf dem Primary stehen. Cluster-Aware Updating ist für AGs nicht unterstützt. Steht REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT auf 1 oder höher, kann der Primary während des Patchens kurz für Lesen und Schreiben ausfallen.
In beiden Fällen gilt: Ein Failover, den niemand geprobt hat, ist kein Schutz. Planen Sie ihn als wiederkehrende Übung, messen Sie dabei die Zeit bis zum ersten erfolgreichen Schreibzugriff, und prüfen Sie nach einer AG-Übung, dass alle Replikate wieder synchronisiert sind.
Wenn eine Secondary hängt: Log, Queue und Resynchronisierung
Eine Secondary kann aus vielen Gründen stehen bleiben: Netzstörung, Patchfenster, Plattenfehler, oder jemand hat die Datenbewegung mit ALTER DATABASE … SET HADR SUSPEND angehalten. Der Primary läuft weiter. Aber solange die Secondary-Datenbank angehalten ist, bleiben alle ihre Log-Records auf dem Primary aktiv: Das Transaktionslog lässt sich nicht abschneiden, auch nicht durch Log-Backups, und sys.databases zeigt als Wartegrund AVAILABILITY_REPLICA. Läuft das Log voll, sind auf dem Primary keine Änderungen mehr möglich. Die Abhilfen sind Platz schaffen, die Datenbewegung fortsetzen oder die Secondary-Datenbank aus der Gruppe nehmen. Was ein volles Log sonst noch anrichtet, steht im Artikel Transaktionslog voll.
Im Lab haben wir genau das nachgestellt: Secondary angehalten, auf dem Primary rund 160 MB Log erzeugt, Log-Backup ausgeführt. Das Backup lief fehlerfrei durch und gab nichts frei; das Log blieb zu 61 bis 65 Prozent gefüllt, log_reuse_wait_desc stand auf AVAILABILITY_REPLICA. Mit REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 1 hing außerdem jeder Schreibzugriff, bis der Client nach zehn Sekunden aufgab. Drei Beobachtungen für die Diagnose:
- Die Sendewarteschlange war während des Anhaltens
NULL, obwohl 160 MB Log fehlten. Als RPO-Maß taugt sie in diesem Zustand nicht; der Abstand derlast_commit_timezeigte den Rückstand korrekt mit 37 Sekunden. SYNCHRONIZEDheißt „Log gehärtet“, nicht „Redo fertig“. Eine Sekunde nachRESUMEmeldete der Primary die Secondary als synchronisiert, während dort noch bis zu 152 MB Redo ausstanden. Die Microsoft-Schätzung Redo-Warteschlange durch Redo-Rate (rund 1,6 Sekunden) passte zur gemessenen Dauer; nach gut zwei Sekunden waren beide Warteschlangen leer.- Die Primary-Sicht hinkt. Was der Primary über die Redo-Warteschlange der Secondary weiß, lag bis zu eine Sekunde hinter dem, was die Secondary selbst meldete. Für die Wiederanlaufzeit zählt die Secondary-Sicht.
Nach einem erzwungenen Failover gilt dasselbe für alle übrigen Replikate: Sie stehen auf SUSPENDED, bis jemand sie einzeln fortsetzt. Beim Fortsetzen werden Transaktionen, die der neue Primary nie bestätigt hat, zurückgerollt; was in der alten Kopie noch zu retten ist, muss vorher geborgen werden. Und eine synchrone Secondary, die sich länger als das Sitzungs-Timeout nicht meldet, markiert der Primary als DISCONNECTED; mit REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 0 warten die Transaktionen nicht auf sie, mit 1 oder höher scheitern sie stattdessen.
Anwendung: Name, Listener, Wiederverbindung
Bei der FCI verbinden sich Anwendungen mit dem virtuellen Netzwerknamen der Instanz; nach dem Failover ist er am neuen Knoten registriert, bestehende Verbindungen sind weg, neue landen bei derselben Instanz. Bei der AG übernimmt das der Listener, der immer auf den aktuellen Primary zeigt und mit ApplicationIntent=ReadOnly Leser auf eine lesbare Secondary umleiten kann. Er ist nicht zwingend; ohne ihn müssen Anwendungen den neuen Primary selbst finden. Über mehrere Subnetze hinweg gilt für beide MultiSubnetFailover=True, damit der Client alle Adressen parallel probiert.
Was beide Verfahren nicht ändern: Sie trennen beim Failover die Verbindungen. Eine Anwendung ohne Wiederverbindungslogik bleibt stehen, egal ob FCI oder AG. Retry mit Wartezeit, Idempotenz der Schreibvorgänge und ein Verbindungspool, der tote Verbindungen verwirft, gehören zur Hochverfügbarkeit dazu, auch wenn sie im Datenbankprojekt selten budgetiert werden.
Lagebild: Wo steht meine Verfügbarkeit gerade?
Die Abfrage liest in drei Ergebnissen, was dieser Artikel beschreibt: die Instanz (FCI oder nicht, HADR an oder aus), die Replikate mit Rolle und Modus, und je Datenbank Sendewarteschlange, Redo-Rückstand, last_commit_time und Log-Wartegrund. Auf einer Einzelinstanz bleiben die AG-Ergebnisse leer, die Abfrage läuft trotzdem fehlerfrei.
Abfrage: Lagebild Verfügbarkeit
/* PSG Stack · FCI vs. AG · Abfrage 1
Lagebild Verfügbarkeit: Instanz, Cluster, Availability-Group-Replikate und -Datenbanken
!!! WARNUNG — bitte vor dem Ausführen lesen !!!
- Nur lesend. Die Abfrage ändert keine Daten und keine Einstellung, startet kein Failover und
beendet keine Sitzung.
- Auf Produktion mit Augenmaß: Sie liest nur Katalogsichten und HADR-DMVs, das ist billig.
Trotzdem nicht in einer Schleife oder im Sekundentakt ausführen; für Dauerüberwachung gibt es
das AG-Dashboard bzw. Ihr Monitoring.
- Ausgabe prüfen, nicht blind übernehmen: Die Werte sind eine Momentaufnahme. Warteschlangen,
Raten und Zustände ändern sich laufend. Die Spalten rpo_schaetzung_s und rto_schaetzung_s
sind SCHÄTZUNGEN nach den Microsoft-Formeln (siehe unten), keine zugesagten Werte.
- Ausführen auf dem Primary: Nur dort sieht man die Zeilen ALLER Replikate. Auf einer Secondary
zeigt Teil 3 nur die eigene Kopie, die RPO-Schätzung bleibt dort leer.
- Rechte: VIEW SERVER STATE (ab SQL Server 2022 genügt VIEW SERVER PERFORMANCE STATE).
- MAXDOP 1: Jede Teilabfrage läuft seriell und belegt keine weiteren Kerne. Diagnose soll auch
auf einem gerade belasteten Server klein bleiben.
- Ab SQL Server 2017. Geprüft im PSG-Lab auf 2017, 2019, 2022 und 2025 (08.11.2026), im
AG-Paar mit SQL Server 2022 (CLUSTER_TYPE = NONE). Auf einer Instanz ohne AG bleiben Teil 2
und 3 leer, ohne Fehler. Eine echte FCI (Windows-Cluster) konnte im Lab nicht geprüft werden.
Ergebnisse:
1 Instanz: Version, Edition, ist sie eine FCI, ist HADR aktiv, auf welchem Knoten läuft sie
2 Replikate je Availability Group: Rolle, Commit-Modus, Failover-Modus, Verbindung, Zustand
3 Datenbanken je Replikat: Synchronisation, angehalten?, Warteschlangen, Raten, letzter
Commit, geschätzte RPO/RTO, worauf das Log wartet
Schätzformeln (Microsoft Learn, „Monitor performance for availability groups“):
RPO ≈ last_commit_time(Primary) − last_commit_time(Secondary) (vereinfachte Variante)
RTO ≈ redo_queue_size / redo_rate (nur der Redo-Anteil; Erkennung und Rollenwechsel kommen
hinzu, bei CLUSTER_TYPE = NONE gibt es gar kein automatisches Failover)
log_send_queue_size ist das, was bei einem Totalausfall des Primary verloren gehen kann.
*/
SET NOCOUNT ON;
/* 1 · Instanz
ist_fci = 1: Failover-Cluster-Instanz. Dann nennt fci_knoten alle Knoten, der aktive ist markiert.
hadr_aktiv = 1: Die Instanz darf Availability Groups betreiben (Always-On-Schalter).
hadr_dienst nur bei hadr_aktiv = 1 (SERVERPROPERTY meldet sonst trotzdem 1 = läuft, im Lab gesehen). */
SELECT @@SERVERNAME AS servername,
CAST(SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS nvarchar(128)) AS aktiver_knoten,
CAST(SERVERPROPERTY('Edition') AS nvarchar(128)) AS edition,
CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(128)) AS version,
CAST(SERVERPROPERTY('ProductUpdateLevel') AS nvarchar(128)) AS update_stand,
CAST(SERVERPROPERTY('IsClustered') AS int) AS ist_fci,
CAST(SERVERPROPERTY('IsHadrEnabled') AS int) AS hadr_aktiv,
CASE WHEN CAST(SERVERPROPERTY('IsHadrEnabled') AS int) = 0 THEN N'n/a (HADR aus)'
ELSE CASE CAST(SERVERPROPERTY('HadrManagerStatus') AS int)
WHEN 0 THEN N'nicht gestartet, Kommunikation ausstehend' WHEN 1 THEN N'läuft'
WHEN 2 THEN N'nicht gestartet, Fehler' ELSE N'n/a' END END AS hadr_dienst,
(SELECT STRING_AGG(CAST(n.NodeName AS nvarchar(max))
+ CASE WHEN n.is_current_owner = 1 THEN N' (aktiv)' ELSE N'' END
+ N' ' + n.status_description, N', ')
FROM sys.dm_os_cluster_nodes AS n) AS fci_knoten,
i.sqlserver_start_time AS instanz_start
FROM sys.dm_os_sys_info AS i
OPTION (MAXDOP 1);
/* 2 · Replikate
cluster_typ: WSFC (Windows-Cluster), EXTERNAL (z. B. Pacemaker) oder NONE (ohne Cluster, nur
Leseskalierung, kein automatisches Failover). pflicht_secondaries = REQUIRED_SYNCHRONIZED_
SECONDARIES_TO_COMMIT: so viele synchrone Secondaries müssen jeden Commit bestätigen. */
SELECT ag.name AS verfuegbarkeitsgruppe,
ag.cluster_type_desc AS cluster_typ,
ag.required_synchronized_secondaries_to_commit AS pflicht_secondaries,
ar.replica_server_name AS replikat,
CASE WHEN ars.is_local = 1 THEN N'ja' ELSE N'nein' END AS diese_instanz,
ars.role_desc AS rolle,
ar.availability_mode_desc AS commit_modus,
ar.failover_mode_desc AS failover_modus,
ar.seeding_mode_desc AS seeding,
ar.secondary_role_allow_connections_desc AS lesezugriff_secondary,
ars.connected_state_desc AS verbindung,
ars.operational_state_desc AS betriebszustand,
ars.synchronization_health_desc AS gesundheit,
ars.last_connect_error_description AS letzter_verbindungsfehler
FROM sys.availability_groups AS ag
JOIN sys.availability_replicas AS ar
ON ar.group_id = ag.group_id
LEFT JOIN sys.dm_hadr_availability_replica_states AS ars
ON ars.replica_id = ar.replica_id
ORDER BY ag.name, CASE ars.role_desc WHEN N'PRIMARY' THEN 0 ELSE 1 END, ar.replica_server_name
OPTION (MAXDOP 1);
/* 3 · Datenbanken je Replikat
Einheiten: Warteschlangen in KB, Raten in KB/s. angehalten = 1: Datenbewegung angehalten
(SUSPEND), das Log auf dem Primary kann dann nicht abgeschnitten werden (log_wartet_auf =
AVAILABILITY_REPLICA). failover_bereit = 1: diese Secondary ist synchronisiert, ein Failover
dorthin verliert keine Daten. rpo_/rto_schaetzung_s: siehe Kopf, nur Schätzungen.
Im Lab gesehen (SQL 2022 CU27): Während SUSPEND ist sendewarteschlange_kb NULL, obwohl Log fehlt;
dann zählt letzter_commit bzw. rpo_schaetzung_s. senderate_kb_s kann unplausibel hoch sein (Mittel
der letzten aktiven Periode) und SYNCHRONIZED heißt „Log gehärtet“, nicht „Redo fertig“: die
redo_warteschlange_kb kann dann noch Hunderte MB zeigen. */
SELECT ag.name AS verfuegbarkeitsgruppe,
DB_NAME(drs.database_id) AS datenbank,
ar.replica_server_name AS replikat,
CASE WHEN drs.is_primary_replica = 1 THEN N'PRIMARY' ELSE N'SECONDARY' END AS rolle,
drs.synchronization_state_desc AS synchronisation,
drs.synchronization_health_desc AS gesundheit,
CAST(drs.is_suspended AS int) AS angehalten,
drs.suspend_reason_desc AS grund_angehalten,
CAST(dcs.is_failover_ready AS int) AS failover_bereit,
drs.log_send_queue_size AS sendewarteschlange_kb,
drs.log_send_rate AS senderate_kb_s,
drs.redo_queue_size AS redo_warteschlange_kb,
drs.redo_rate AS redo_rate_kb_s,
drs.last_commit_time AS letzter_commit,
CASE WHEN drs.is_primary_replica = 0 AND p.last_commit_time IS NOT NULL
THEN CAST(DATEDIFF(millisecond, drs.last_commit_time, p.last_commit_time) / 1000.0
AS decimal(12, 1)) END AS rpo_schaetzung_s,
CASE WHEN drs.is_primary_replica = 1 THEN NULL
WHEN drs.redo_queue_size = 0 THEN CAST(0 AS decimal(12, 1))
WHEN drs.redo_rate > 0
THEN CAST(drs.redo_queue_size * 1.0 / drs.redo_rate AS decimal(12, 1)) END AS rto_schaetzung_s,
d.log_reuse_wait_desc AS log_wartet_auf
FROM sys.dm_hadr_database_replica_states AS drs
JOIN sys.availability_replicas AS ar
ON ar.replica_id = drs.replica_id
JOIN sys.availability_groups AS ag
ON ag.group_id = drs.group_id
LEFT JOIN sys.dm_hadr_database_replica_cluster_states AS dcs
ON dcs.replica_id = drs.replica_id
AND dcs.group_database_id = drs.group_database_id
LEFT JOIN sys.dm_hadr_database_replica_states AS p
ON p.group_database_id = drs.group_database_id
AND p.is_primary_replica = 1
AND p.is_local = 1
LEFT JOIN sys.databases AS d
ON d.database_id = drs.database_id
AND drs.is_local = 1
ORDER BY ag.name, datenbank, CASE WHEN drs.is_primary_replica = 1 THEN 0 ELSE 1 END, replikat
OPTION (MAXDOP 1);Beispielausgabe
Beispielausgabe aus dem Lab-Lauf (zwei SQL-Server-2022-Container als AG mit Cluster-Typ NONE, synthetische Daten, Namen aus dem Lab). Lage A: Die Secondary ist angehalten (angehalten = 1, SUSPEND_FROM_USER, failover_bereit = 0), das Log des Primary wartet auf AVAILABILITY_REPLICA, die RPO-Schätzung zeigt 36,7 Sekunden Rückstand, die Sendewarteschlange ist NULL, und die Senderate ist ein unplausibler Mittelwert der letzten aktiven Phase. Der Primary schreibt hier weiter, weil pflicht_secondaries für diesen Lauf auf 0 stand; mit 1 hingen die Schreibzugriffe (siehe oben). Lage B: beide Replikate synchronisiert, failover_bereit = 1, RPO und RTO 0, das Log wartet nur noch auf das nächste Log-Backup.
Lage A · Secondary angehalten (HADR SUSPEND), Abfrage auf dem Primary agp8547a7, 08.11.2026 19:52 UTC
=====================================================================================================
1 · Instanz
servername aktiver_knoten edition version update_stand ist_fci hadr_aktiv hadr_dienst fci_knoten instanz_start
---------- -------------- -------------------------- ----------- ------------ ------- ---------- ----------- ---------- -----------------------
agp8547a7 agp8547a7 Developer Edition (64-bit) 16.0.4295.3 CU27 0 1 läuft NULL 2026-11-08 19:40:49.123
2 · Replikate
verfuegbarkeitsgruppe cluster_typ pflicht_secondaries replikat diese_instanz rolle commit_modus failover_modus seeding lesezugriff_secondary verbindung betriebszustand gesundheit letzter_verbindungsfehler
--------------------- ----------- ------------------- --------- ------------- --------- ------------------ -------------- ------- --------------------- ---------- --------------- ----------- -------------------------
psg_ag none 0 agp8547a7 ja PRIMARY SYNCHRONOUS_COMMIT MANUAL MANUAL ALL CONNECTED ONLINE HEALTHY NULL
psg_ag none 0 ags8547a7 nein SECONDARY SYNCHRONOUS_COMMIT MANUAL MANUAL ALL CONNECTED NULL NOT_HEALTHY NULL
3 · Datenbanken je Replikat
verfuegbarkeitsgruppe datenbank replikat rolle synchronisation gesundheit angehalten grund_angehalten failover_bereit sendewarteschlange_kb senderate_kb_s redo_warteschlange_kb redo_rate_kb_s letzter_commit rpo_schaetzung_s rto_schaetzung_s log_wartet_auf
--------------------- ---------- --------- --------- ----------------- ----------- ---------- ----------------- --------------- --------------------- -------------- --------------------- -------------- ----------------------- ---------------- ---------------- --------------------
psg_ag ag_latency agp8547a7 PRIMARY SYNCHRONIZED HEALTHY 0 NULL 1 NULL NULL NULL NULL 2026-11-08 19:52:26.003 NULL NULL AVAILABILITY_REPLICA
psg_ag ag_latency ags8547a7 SECONDARY NOT SYNCHRONIZING NOT_HEALTHY 1 SUSPEND_FROM_USER 0 NULL 135634000 0 80349 2026-11-08 19:51:49.283 36.7 .0 NULL
=============================================================================================================
Lage B · beide Replikate synchronisiert, nach den Failover-Läufen ist ags8547a7 Primary, 08.11.2026 20:06 UTC
=============================================================================================================
1 · Instanz
servername aktiver_knoten edition version update_stand ist_fci hadr_aktiv hadr_dienst fci_knoten instanz_start
---------- -------------- -------------------------- ----------- ------------ ------- ---------- ----------- ---------- -----------------------
ags8547a7 ags8547a7 Developer Edition (64-bit) 16.0.4295.3 CU27 0 1 läuft NULL 2026-11-08 19:27:22.100
2 · Replikate
verfuegbarkeitsgruppe cluster_typ pflicht_secondaries replikat diese_instanz rolle commit_modus failover_modus seeding lesezugriff_secondary verbindung betriebszustand gesundheit letzter_verbindungsfehler
--------------------- ----------- ------------------- --------- ------------- --------- ------------------ -------------- ------- --------------------- ---------- --------------- ---------- -------------------------
psg_ag none 1 ags8547a7 ja PRIMARY SYNCHRONOUS_COMMIT MANUAL MANUAL ALL CONNECTED ONLINE HEALTHY NULL
psg_ag none 1 agp8547a7 nein SECONDARY SYNCHRONOUS_COMMIT MANUAL MANUAL ALL CONNECTED NULL HEALTHY NULL
3 · Datenbanken je Replikat
verfuegbarkeitsgruppe datenbank replikat rolle synchronisation gesundheit angehalten grund_angehalten failover_bereit sendewarteschlange_kb senderate_kb_s redo_warteschlange_kb redo_rate_kb_s letzter_commit rpo_schaetzung_s rto_schaetzung_s log_wartet_auf
--------------------- ---------- --------- --------- --------------- ---------- ---------- ---------------- --------------- --------------------- -------------- --------------------- -------------- ----------------------- ---------------- ---------------- --------------
psg_ag ag_latency ags8547a7 PRIMARY SYNCHRONIZED HEALTHY 0 NULL 1 NULL NULL NULL NULL 2026-11-08 20:04:52.277 NULL NULL LOG_BACKUP
psg_ag ag_latency agp8547a7 SECONDARY SYNCHRONIZED HEALTHY 0 NULL 1 0 885353 0 347608 2026-11-08 20:04:52.277 .0 .0 NULLHäufige Fragen
Reicht asynchroner Commit für ein zweites Rechenzentrum? Für Disaster Recovery ja, mit möglichem Datenverlust in Höhe der Sendewarteschlange. Automatisches Failover gibt es dorthin nicht, nur erzwungenes.
Kann ich in Standard eine lesbare Secondary haben? Nein. Die Basic AG erlaubt keinen Lesezugriff und keine Backups auf der Secondary. Lesbare Kopien sind Enterprise.
Warum wächst mein Log, obwohl ich Log-Backups mache? Prüfen Sie log_reuse_wait_desc in sys.databases. Steht dort AVAILABILITY_REPLICA, hält eine angehaltene oder zurückliegende Secondary das Log fest.
Wie lange dauert ein FCI-Failover wirklich? So lange wie Dienststart und Recovery, und die Recovery so lange wie die längste offene Transaktion. Mit ADR wird sie davon weitgehend unabhängig. Unsere Labwerte stehen oben; Ihre Zahl liefert nur eine Übung in Ihrer Umgebung.
Kann ich eine AG ohne Listener betreiben? Ja. Dann entfallen die automatische Umleitung nach dem Failover und das Read-only-Routing; die Anwendung muss den Primary selbst finden.
Brauche ich Fast Recovery, wenn ich ADR habe? Fast Recovery (Enterprise) bringt die Datenbank nach dem Redo online, ADR (ab 2019, auch Standard) macht das Undo nahezu sofort. In der Praxis nimmt ADR der Recovery den größten Zeitfresser; Fast Recovery bleibt ein zusätzlicher Vorteil der Enterprise Edition.
Wie es weitergeht
- Teil 3 · Wann lohnt sich Enterprise? Welche Anforderung die volle AG rechtfertigt, und die Lizenzregeln dahinter: passive Replikate, Software Assurance, was „passiv“ heißt.
- Teil 4 · Entscheidungshilfe: wenige Fragen, begründete Kandidaten, keine Entscheidung aus drei Klicks.
Wenn Sie vor der Entscheidung stehen
Die Matrix sagt, was geht. Ob es für Sie passt, entscheiden Ziele für Datenverlust und Wiederanlauf, Storage, Standorte, Lesebedarf und die Mannschaft, die das Ganze betreibt. Im Verfügbarkeits-Review unseres Health Checks vergleichen wir diese Ziele mit dem, was Ihre Umgebung heute erreicht, inklusive der Werte aus der Abfrage oben. Für Planung, Aufbau und Migration steht die Leistung Infrastruktur und Hochverfügbarkeit. Wir beraten ohne eigenes Lizenzverkaufsinteresse.
Quellen
Fachaussagen dieses Teils stützen sich auf Microsoft-Dokumentation, geprüft am 08.11.2026: Editions and Supported Features 2017, 2019, 2022 und 2025; Monitor Performance for Always On Availability Groups; sys.dm_hadr_database_replica_states; CREATE und ALTER AVAILABILITY GROUP; Suspend und Resume an Availability Database; Perform a Forced Manual Failover; Upgrading Always On Availability Group Replica Instances; Upgrade a SQL Server Failover Cluster Instance; Failover Policy for Failover Cluster Instances; Active Secondaries (Readable Secondary Replicas, Backup on Secondary Replicas); Contained Availability Groups; What's New in SQL Server 2025; Restore and Recovery Overview (Fast Recovery); Accelerated Database Recovery. Messwerte aus dem PSG-Lab vom 08.11.2026 auf SQL Server 2022 CU27; der Instanzneustart steht dort stellvertretend für den FCI-Failover, ein Windows-Cluster war nicht Teil des Labs.