Wartungspläne für Microsoft SQL Server

von | Sep. 26, 2025 | Fachartikel, SQL Server | 0 Kommentare

Table of Contents
2
3

Consulting, Beratung

Wartungspläne für Microsoft SQL Server

Management Summary

  • Wartung sichert Verfügbarkeit und Datenintegrität: Geplante Wartungsarbeiten in SQL Server zielen darauf ab, die Verfügbarkeit von Datenbanken hoch zu halten und Datenintegrität zu gewährleisten. Sie minimieren Ausfallzeiten und Risiken und stellen sicher, dass RPO/RTO-Vorgaben (maximal tolerierter Datenverlust bzw. Wiederherstellungszeit) eingehalten werden. Regelmäßige Integritätsprüfungen (DBCC CHECKDB), konsistente Backup-Strategien und proaktive Leistungsoptimierung (z. B. Indexpflege) sind hierfür unverzichtbar.
  • Empfohlene Standard-Pipeline: Für eine typische Produktionsumgebung hat sich ein nächtlicher Wartungsablauf bewährt. Eine stichpunktartige Pipeline könnte wie folgt aussehen:
  • Kontinuierliche Transaktionslog-Sicherungen (z. B. alle 15 Minuten) während des Tages, um das RPO einzuhalten.
  • Tägliche Integritätsprüfung aller Datenbanken (DBCC CHECKDB) – möglichst auf einem separaten Server oder einer sekundären Kopie, um die Primärlast gering zu halten.
  • Indexpflege nach Bedarf: Indizes mit hoher Fragmentierung (über ~30 %) Rebuild (Neuaufbau, möglichst online); moderate Fragmentierung (ca. 5–30 %) Reorganize (Neuorganisation). Statistiken danach aktualisieren, aber nur für Indizes, die reorganisiert wurden (bei Rebuild erfolgt die Statistikaktualisierung automatisch mit).
  • Vollsicherung (Full Backup) der Datenbanken nach Abschluss der Indexpflege. Dieses Timing stellt sicher, dass die Sicherung konsistenten, optimierten Daten enthält und folgende Differenzialsicherungen klein bleiben.
  • Aufräumen und Überprüfen: Anschließend alte Backup-Dateien und Wartungs-Historien löschen sowie Backup-Verifizierung (RESTORE VERIFYONLY) oder ein Test-Restore zeitversetzt durchführen (z. B. auf einem Testsystem am Morgen), um die Wiederherstellbarkeit zu prüfen.
  • Häufige Fehler vermeiden: Viele Probleme in der Praxis sind auf ungenügende Wartung zurückzuführen. Beispiele:
  • Fehlende Log-Backups: Im Full- oder Bulk-Logged-Recovery-Modell führt dies zu unkontrolliertem Log-Wachstum und gefährdet die Point-in-Time-Wiederherstellung. Lösung: strikter Log-Backup-Zeitplan (minütlich bis stündlich nach Bedarf).
  • Ungünstige Reihenfolge der Jobs: Etwa das Aktualisieren von Statistiken vor dem Index-Rebuild (wodurch die Arbeit des Statistik-Updates durch den Rebuild hinfällig wird) oder Voll-Backup vor einer umfangreichen Indexpflege (führt zu großen Differenzialsicherungen danach). Lösung: Pipeline-Reihenfolge beachten (siehe oben) – zunächst Integritäts-Checks und Optimierungen, dann Backup.
  • Ignorierte Prüfwarnungen: Warnungen von DBCC CHECKDB (z. B. Fehler 824) oder SQL Server-Alerts (z. B. Log voll) werden oft übersehen. Lösung: Einrichtung von Benachrichtigungen (E-Mail über SQL Agent Operator) und regelmäßiges Prüfen von Logs/Reports.
  • “Shrink” Missbrauch: Das häufige Schrumpfen von Datenbanken oder Logs verursacht Fragmentierung und Leistungsprobleme. Lösung: Shrink nur in absoluten Ausnahmefällen einsetzen und anschließend neu organisieren.
  • Kein Restore-Test: Backups werden gemacht, aber nie testweise zurückgesichert. Im Ernstfall stellt sich heraus, dass Sicherungen unbrauchbar sind oder Wiederherstellung zu lange dauert. Lösung: Regelmäßige Test-Wiederherstellungen und Überprüfung der Backup-Checksummen/VERIFYONLY.
  • Ungepatchte Wartungsskripte: Verwendung veralteter Maintenance-Plan-Implementierungen oder veralteter Drittanbieter-Skripte ohne Anpassung an aktuelle SQL-Versionen kann zu Fehlern führen. Lösung: Wartungsroutinen kontinuierlich pflegen und an neue Versionen/Features anpassen.

Grundlagen

Wartungsarten

Nicht alle Wartungsmaßnahmen sind gleich – man unterscheidet mehrere Wartungsarten mit unterschiedlichen Zielen:

  • Präventive Wartung: Vorbeugende Maßnahmen, die Probleme verhindern sollen, bevor sie auftreten. Beispiele: regelmäßige Integritätsprüfungen (um stille Korruption früh zu entdecken), Indexoptimierung (um Leistungsabfall durch Fragmentierung vorzubeugen) und das Aktualisieren von Statistiken (für stabile Abfragepläne). Auch das Einspielen von Updates/Patches in Wartungsfenstern gehört hierzu.
  • Korrektive Wartung: Reagierende Maßnahmen zur Fehlerbehebung, wenn bereits Probleme bestehen. Zum Beispiel das Reparieren einer Datenbank nach CHECKDB-Fehlern (nur im Notfall, da meist Datenverlust), manuelles Wiederherstellen von Backups nach einem Ausfall oder das gezielte Neuaufbauen eines Indexes, der massive Fragmentierung aufweist und akute Performanceprobleme verursacht.
  • Prüfende Wartung: Maßnahmen zur Überwachung und Validierung des Systemzustands. Hierzu zählen Integritäts-Checks (DBCC CHECKDB, DBCC CHECKFILEGROUP, DBCC CHECKCATALOG), Überprüfen von Backup-Integrität (RESTORE VERIFYONLY, Prüfsummen) und allgemeine Health-Checks (z. B. Überwachen von Speicher-/CPU-Auslastung, Logs, TempDB).
  • Bereinigende Wartung: Aufräumarbeiten zur Säuberung des Systems. Darunter fallen das Löschen alter Backup-Dateien, das Bereinigen der Verlaufstabellen in msdb (Backup-Historie, Wartungsplan-Logs, Agent-Job-Historie) sowie das Entfernen nicht mehr benötigter Dateien (z. B. alte Audit- oder Protokolldateien). Auch TempDB-Bereinigung (sinnvolle Initialisierung nach Neustart, angemessene Größe/Dateianzahl) und gelegentliche Neuorganisation stark fragmentierter Heap-Tabellen können dazugehören.

Ein guter Wartungsplan kombiniert diese Arten: präventive Schritte, regelmäßige Prüfungen und falls nötig korrektive Eingriffe – stets begleitet von bereinigenden Maßnahmen, damit das System sauber bleibt.

Abhängigkeiten und Rahmenbedingungen

Wartungspläne müssen zur jeweiligen Datenbankumgebung passen. Zentrale Abhängigkeiten und Rahmenbedingungen sind:

  • Recovery-Modelle: SQL Server-Datenbanken können im Simple-, Full- oder Bulk-Logged-Recovery laufen. Das Recovery-Modell beeinflusst unmittelbar die Wartungsstrategie:
  • Im Full-Modell müssen Log-Backups regelmäßig erfolgen, um das Transaktionslog zu verkleinern und eine lückenlose Point-in-Time-Wiederherstellung (RPO = 0 bis minimaler Datenverlust) zu ermöglichen. Indexpflege und andere große Änderungen führen hier zu vielen Log-Einträgen, was ohne Log-Backups das Log anschwellen lässt.
  • Im Bulk-Logged-Modell werden bestimmte Massenoperationen minimal protokolliert (geringerer Log-Impact), allerdings auf Kosten einer möglichen Lücke im Point-in-Time-Recovery für diese Zeitspanne. Wartungsaufgaben wie Index-Rebuilds können hier teilweise weniger Log verbrauchen, jedoch erfordert auch dieses Modell regelmäßige Log-Backups. Zudem sind Bulk-Logged-Phasen kritisch für Log Shipping/Always On, da z. B. ein minimal protokollierter Index-Rebuild im Log-Backup komplette Extents enthalten kann.
  • Im Simple-Modell erledigt SQL Server selbst die Log-Verwaltung (automatische Trunkierung) – Log-Backups sind nicht möglich. Das vereinfacht zwar die Wartung (kein Log-Backup-Zeitplan nötig), riskiert aber größere Datenverluste im Disaster-Fall (RPO = seit letztem Full/Diff-Backup). Viele Wartungsjobs (Indexreorganisation, CheckDB etc.) funktionieren auch im Simple-Mode, aber man muss mit potenziell größeren Full/Differential-Backups planen, da Änderungen nicht durch Log-Backups ausgegliedert werden.
  • Transaktionslog & LSN-Ketten: Bei allen nicht-simple Modellen muss die LSN-Kette (Log Sequence Numbers) intakt bleiben. Ein Vollbackup im Full-Modell beeinträchtigt die Log-Kette nicht (aber ein nicht-copy-only Vollbackup kann Differenzialsicherungen zurücksetzen). Daher bei Differenzial-Strategien wichtig: Vollbackups planen, ohne unerwartet mit ad-hoc Backups die Kette zu brechen (oder diese als COPY_ONLY markieren). In Log Shipping-Szenarien oder bei Always On Availability Groups muss klar sein, welche Instanz die Log-Backups durchführt, um die LSN-Kette konsistent zu halten. Wartungspläne müssen also auf Backup-Abfolgen abgestimmt sein, damit keine Lücken entstehen.
  • TempDB und Nebenwirkungen: Wartungsprozesse beanspruchen oft TempDB (z. B. Sortieroperationen bei Index-Rebuilds oder interne Snapshot-Erstellung bei DBCC CHECKDB). Eine suboptimal konfigurierte TempDB (zu wenige Dateien, falsche Autogrowth-Einstellungen, kein Instant File Initialization für das TempDB-Datenfile) kann zum Flaschenhals werden. Parallel laufende Wartungsjobs können sich in der TempDB behindern. Daher: ausreichend viele TempDB-Datenfiles (üblicher Richtwert: 1 Datei pro 4 CPU-Kerne bis max. ~8 Dateien, gleich groß vorab angelegt), sinnvolle Startgröße und Wachstumsschritte, und ggf. Verwendung von SORT_IN_TEMPDB bei Index-Rebuilds, falls das I/O-Subsystem das hergibt.
  • Parallelität und Serverlast: Während Wartungsfenstern gilt es, Parallelität gezielt einzusetzen. Manche Aktionen skalieren mit mehreren CPU-Kernen (z. B. Index-Rebuild standardmäßig), was zwar die Laufzeit verkürzt, aber hohe Lastspitzen erzeugt. Für 24/7-Systeme kann es sinnvoll sein, Wartungsjobs mit begrenztem MAXDOP (Degree of Parallelism) laufen zu lassen oder den Cost Threshold for Parallelism für Wartungsprozesse temporär hochzusetzen, um Konkurrenz mit Nutzer-Workloads zu reduzieren. Umgekehrt kann man in dedizierten Wartungsfenstern die Parallelität voll ausschöpfen, solange andere Last gering ist.
  • Wartungsfenster & SLAs: Die verfügbare Zeit für Wartung (nachts, am Wochenende, oder bei 24/7 praktisch null Downtime) bestimmt Ablauf und Frequenz der Aufgaben. Ein starres Wartungsfenster (z. B. 02:00–05:00 Uhr täglich) verlangt sorgfältige Planung der Reihenfolge und Laufzeit der Jobs, eventuell das zeitversetzte Ausführen bestimmter Aufgaben (z. B. CheckDB nur an einzelnen Wochentagen). Service Level Agreements (SLAs) für Verfügbarkeit definieren, wann Wartung durchgeführt werden darf. Bei 24/7-Betrieb müssen online-fähige Optionen (ONLINE = ON bei Rebuilds), inkrementelle Ansätze (z. B. über die Woche verteilte Teilwartungen) und minimalinvasive Methoden (Throttling von Index-Reorgs, kleine Batches) genutzt werden. Zudem beeinflussen RPO/RTO-Vorgaben den Plan: Ein kurzes RPO erfordert häufige Backups, ein kurzes RTO erfordert z. B. vorbereitete Restore-Skripte und ggf. Instant File Initialization, um schnell wiederherstellen zu können.
  • Sizing & Systemlayout: Die Effektivität mancher Wartungsaufgaben hängt von der Hardware und dem Datenlayout ab. Beispiele: Ausreichend CPU/RAM verkürzt DBCC CHECKDB spürbar (viel RAM erlaubt mehr Cache für Prüfsummen und für Sortieren von Indexes). Schneller Storage (hohe IOPS) ist kritisch für Backups, Rebuilds und CheckDB – insbesondere bei klassischen HDD-RAIDs können diese Jobs sehr lange dauern. Ein gut geplantes Storage-Layout (z. B. separate Volume für Logs, eventuell separate SSDs für TempDB, getrennte Filegroups für unterschiedliche Nutzungsarten) erleichtert Wartung: Man kann z. B. CHECKDB Snapshots auf ein anderes Volume legen oder TempDB-I/O entlasten. Ebenso sollten Autogrowth-Einstellungen an die Speicherleistung angepasst sein: zu kleine Wachstumsinkremente führen zu häufigen, teuren Erweiterungen; zu große erschweren das Speicherplatzmanagement.
  • SLA für RPO/RTO: Im Kontext von Wartung sind RPO (Recovery Point Objective) und RTO (Recovery Time Objective) Leitgrößen: Sie definieren, wie aktuell die wiederherstellbaren Daten sein müssen (RPO) und wie schnell eine Wiederherstellung erfolgen muss (RTO). Wartungspläne müssen so gestaltet sein, dass RPO/RTO eingehalten oder übertroffen werden. Z. B. bestimmt das Backup-Intervall direkt das RPO (Log-Backups alle 15 Minuten bedeuten max. 15 Minuten Datenverlust im Worst Case). Das RTO beeinflusst, wie Wartungsjobs geplant werden: Wenn die Wiederherstellung schnell gehen muss, müssen z. B. Backups komprimiert (kleinere Dateien, schneller einzuspielen) und regelmäßig getestet werden, Indexpflege sollte dafür sorgen, dass Query-Leistung im Normalbetrieb hoch bleibt (schnellere Fehlerdiagnose im Ernstfall), etc. Auch Notfallpläne (Runbooks) und die Infrastruktur (z. B. Standby-Server für Restore) sind Teil der „Wartung“ im weiteren Sinne, um die RTO einzuhalten.

Werkzeuge und Ansätze für Wartungspläne

Microsoft SQL Server bietet verschiedene Werkzeuge zur Implementierung von Wartungsplänen, und es gibt etablierte Skripte von Drittanbietern. Jede Option hat Vor- und Nachteile:

  • SQL Server Maintenance Plans (Wartungspläne): Die integrierte GUI-Lösung innerhalb von SSMS ermöglicht das Zusammenklicken gängiger Aufgaben (Backup, Reorganize Index, Update Statistics, etc.) in Ablaufplänen. Vorteile: Einfache Handhabung, kein Tiefenwissen in T-SQL nötig, Wartungspläne sind visuell und schnell erstellt. Die Ausführung erfolgt als SQL Server Agent-Jobs (Integration Services Pakete unter der Haube). Nachteile: Begrenzte Flexibilität – komplexere Logiken (z. B. „nur Reorganize wenn Frag < 30 %“) erfordern T-SQL-Schritt oder sind gar nicht möglich. Logging ist rudimentär (man muss die Report-Datei öffnen oder msdb durchsuchen). Außerdem sind Wartungspläne weniger transparent, da sie generische Prozeduren (wie sp_updatestats) verwenden, deren Standardverhalten (z. B. Sampling) nicht offensichtlich ist. Tipp: Wartungspläne eignen sich für kleine Umgebungen mit Standardanforderungen oder als Schnellstart. Für ausgereiftere Kontrolle stößt man schnell an Grenzen.
  • Manuelle SQL Agent Jobs (T-SQL): Hierbei schreibt der DBA eigene T-SQL-Skripte und richtet sie als geplante Jobs ein. Vorteile: Maximale Flexibilität – jedes Detail kann kontrolliert werden (z. B. eigener Cursor für Index-Frag-Prüfung mit individuellen Schwellenwerten, bedingte Ablaufsteuerung je nach Wochentag, usw.). Außerdem kann Logging gezielt implementiert werden (z. B. Ergebnisse in Tabellen schreiben). Nachteile: Entwicklungsaufwand und Wartbarkeit – eigene Skripte müssen getestet, dokumentiert und an neue SQL-Versionen angepasst werden. Fehlerbehandlung und Transaktionssteuerung liegen in der Verantwortung des Autors. Kurz: maßgeschneiderte Lösung, aber man braucht SQL-Know-how und Sorgfalt. In größeren Teams muss der Code gut dokumentiert sein (siehe Änderungsprotokoll im Compliance-Teil).
  • PowerShell & DBATools: PowerShell ermöglicht serverübergreifende Wartungsautomation und komplexe Orchestrierung. Das bekannte Community-Modul DBATools stellt fertige Cmdlets bereit – etwa Backup-DbaDatabase für Backups, Invoke-DbaCheckDb für CHECKDB, Invoke-DbaIndexOptimization für Indizes usw. Vorteile: Sehr mächtig und skriptbar, insbesondere wenn viele Server parallel verwaltet werden. DBATools kapselt Best Practices (z. B. Invoke-DbaIndexOptimization kann ähnlich wie Ola Hallengrens Skripte Indizes nach Fragmentierung behandeln). Logging kann oft direkt in Tabellen oder als Ausgabeobjekt erfolgen. Nachteile: Bedarf an PowerShell-Know-how und zusätzlichem Setup (DBATools installieren, Berechtigungen für Remotezugriff). Außerdem laufen PowerShell-Jobs oft außerhalb von SQL Server (z. B. als Agent-CmdExec-Schritt), was bei Berechtigungen und Fehlerintegration bedacht werden muss. Für Cloud-VMs oder Hybrid-Umgebungen bietet PowerShell allerdings Vorteile, um S3/Azure-Storage für Offsite-Backups einzubinden, etc.
  • Ola Hallengren’s Maintenance Solution (Community-Skript): Dies ist eine weit verbreitete, kostenfreie Sammlung von T-SQL-Prozeduren und SQL Agent-Jobs für Backups, Integrity Checks und Index-/Statistik-Wartung. Vorteile: Bewährte Best Practices out-of-the-box. Hochgradig konfigurierbar via Parameter (z. B. Schwellenwerte, auszuschließende DBs, Partitionierung beachten), gute Logging-Optionen (z. B. Aufzeichnung jeder Aktion in einer CommandLog-Tabelle) und kompatibel mit allen Editionen. Viele DBAs vertrauen darauf, da es von Microsoft MVPs empfohlen wird. Nachteile: Third-Party Code – muss zunächst installiert und verstanden werden. Bei Versionsupdates des Skripts ist man selbst fürs Einspielen verantwortlich. Außerdem ist bei Problemen der Support community-basiert (Foren, GitHub). Insgesamt jedoch eine empfehlenswerte Alternative zu eigenen Skripten oder Maintenance Plans, besonders in Enterprise-Umgebungen.
  • Weitere Tools & Skripte: Es gibt kommerzielle Lösungen (z. B. MinionWare für Backup/ Reindex, Redgate SQL Backup, etc.), die erweitertes Scheduling, Kompression, Encryption und Reporting bieten. Diese sind oft in speziellen Szenarien sinnvoll (z. B. sehr große Umgebungen, zentralisiertes Management). Kombinationen der obigen Ansätze sind auch üblich: z. B. Maintenance Plan für einfache Dinge (Backup), aber Ola-Skripte für Indizes; oder eigene T-SQL-Jobs für Sonderaufgaben neben DBATools. Wichtig ist, Überschneidungen zu vermeiden (nicht zwei Jobs unterschiedlicher Systeme, die dieselbe Aufgabe doppelt ausführen oder sich gegenseitig behindern). Klare Aufgabentrennung und Dokumentation sind dann ein Muss.

Zur Veranschaulichung vergleicht die folgende Tabelle die gängigen Wartungsansätze:

Ansatz

Vorteile

Nachteile

Maintenance Plan (GUI)

Einfache Einrichtung, keine Programmierung. <br> Integriert in SSMS, schnelle Resultate.

Begrenzte Flexibilität (starre Tasks, wenig Bedingungen). <br> Wenig Einblick in interne Abläufe (Blackbox).

Eigene T-SQL-Jobs

Sehr flexibel (angepasst an spezielle Anforderungen). <br> Logik und Ablauf voll kontrollierbar.

Hoher Aufwand bei Entwicklung/Pflege. <br> Erfordert T-SQL-Kenntnisse, Fehlerbehandlung eigenständig.

PowerShell/DBATools

Automatisierung über Server hinweg (Massentauglich). <br> DBATools bietet umfangreiche, getestete Funktionen.

Zusatz-Tooling nötig (PS-Modul). <br> Komplexität bei Berechtigungen/Integration in SQL Agent.

Ola Hallengren Scripts

Best Practices implementiert (zuverlässig, anpassbar). <br> Gutes Logging und breite Community-Erfahrung.

Muss als externes Skript eingebunden werden. <br> Verständnis der Parameter nötig; Support nicht durch Microsoft.

(Tabelle: Vergleich der Wartungswerkzeuge)

Fazit Grundlagen: Vor der Umsetzung eines Wartungsplans sollte man die obigen Faktoren genau analysieren. Recovery-Modell, Systemlast und SLAs definieren den Rahmen, in dem Tools und Methoden ausgewählt werden. Häufig startet man mit Maintenance Plans für schnelle Ergebnisse und migriert später zu individuelleren Skripten (z. B. Ola oder eigene), wenn die Umgebung wächst und die Ansprüche steigen. Wichtig ist, den Wartungsplan regelmäßig zu überprüfen und anzupassen, da sich Datenbanken, Workloads und Geschäftsanforderungen ändern können.

Wartungsaktionen im Detail

In diesem Kapitel werden die wichtigsten Wartungsaktionen einzeln erläutert – mit ihrem Zweck, ihrer Funktionsweise, empfohlenen Parametern und Frequenzen sowie möglichen Fallstricken. Jede Aktion ist ein Baustein für den Gesamt-Wartungsplan. Die Tabelle am Kapitelende fasst alle Aktionen zusammen (Zweck, Intervalle, Parameter, Auswirkungen und Erfolgsindikatoren).

Integritätsprüfung (Datenbankkonsistenzcheck)

Zweck und Wirkprinzip: Die Integritätsprüfung mittels DBCC CHECKDB ist eine Schlüsselmaßnahme zur Sicherung der Datenintegrität. Sie überprüft eine Datenbank auf physische und logische Konsistenzfehler. Physisch bedeutet, dass alle Seiten und Seitengruppen auf der Festplatte gelesen werden, Prüfsummen (sofern aktiviert) verifiziert und Verweisstrukturen geprüft werden. Logisch bedeutet, dass relationale Zusammenhänge im Speicher überprüft werden (z. B. Verweisintegrität, Index vs. Tabellendaten). Intern erstellt CHECKDB standardmäßig eine transaktionskonsistente Datenbanksnapshot (einen nicht-persistenten Schnappschuss) der zu prüfenden DB, um eine Momentaufnahme zu haben, während normale Transaktionen weiterlaufen können. Dadurch vermeidet man Sperren in der produktiven DB während des Checks. Sollte kein Snapshot möglich sein (z. B. aus Platzmangel), kann CHECKDB mit TABLOCK ausgeführt werden, was die Datenbank exklusiv sperrt – das ist aber nur als Notlösung in Wartungsfenstern sinnvoll.

Vorbedingungen & Durchführung: Vor dem regelmäßigen Ausführen von DBCC CHECKDB sollte ausreichend Speicherplatz vorhanden sein – sowohl im Datenbank-Volume (für den Snapshot) als auch in TempDB (für Zwischenschritte). Falls eine Datenbank sehr groß ist und tägliche vollständige Checks zu lange dauern, gibt es Strategien: z. B. DBCC CHECKDB … WITH PHYSICAL_ONLY – das beschränkt die Prüfung auf physische Seitenkonsistenz und überspringt aufwändige logische Checks wie das Scannen aller Indexinhalte. Das reduziert Laufzeit und I/O deutlich, entdeckt aber z. B. keine inkonsistenten Referenzbeziehungen. Daher kann man z. B. an Wochentagen PHYSICAL_ONLY ausführen und am Wochenende einmal einen vollen Check. Alternativ kann für sehr große DBs die Integritätsprüfung auf einen zweiten Server ausgelagert werden (Pipeline C): Dazu nimmt man ein frisches Backup, stellt es auf dem Zweitsystem wieder her und führt dort CHECKDB aus. Das entlastet die Produktion, hat aber den Nachteil, dass hardware-spezifische Fehler auf dem Primärsystem (z. B. ein defekter Controller, der 823/824-Fehler verursacht) evtl. erst später entdeckt werden.

Risiken & Umgang mit Fehlern: Während DBCC CHECKDB viel I/O verursacht, beeinflusst es die Nutzerdaten selbst nicht (nur Leseoperationen, außer man nutzt die Repair-Optionen, was nicht Teil der Routinewartung sein sollte). Die Hauptauswirkung ist Performance-Last: CPU und Plattendurchsatz können stark beansprucht werden. Daher CheckDB nach Möglichkeit im Wartungsfenster planen oder niedrig priorisiert laufen lassen. Falls CHECKDB Fehler meldet (z. B. Meldungen mit Error 824 – logischer Konsistenzfehler, oder Error 823 – E/A-Fehler, oder Error 825 – erzwungene Wiederholung einer Leseoperation), ist höchste Vorsicht geboten: Dies sind Anzeichen für Datenkorruption. Die DBA-Pflicht ist dann, unverzüglich zu reagieren – z. B. zuletzt bekannte gute Backup-Stände bereithalten, betroffene Seiten/Tabellen identifizieren (ggf. über msdb-Tabelle suspect_pages) und einen Notfallplan einleiten. Keinesfalls sollte man ignorieren oder gar mit REPAIR_ALLOW_DATA_LOSS arbeiten, ohne alle Folgen zu bedenken. Idealerweise hat man Alerts konfiguriert, die bei 823/824/825-Fehlern sofort eine Nachricht an den DBA senden (siehe Statustelemetrie & Alerts weiter unten).

Empfohlene Parameter & Automatisierung: Standardmäßig sollte DBCC CHECKDB(‚MeineDatenbank‘) WITH NO_INFOMSGS, ALL_ERRORMSGS (ohne Info-Meldungen, aber mit allen Fehlermeldungsdetails) regelmäßig laufen. PHYSICAL_ONLY kann wie erwähnt die Frequenz erhöhen (schnellere Checks öfter, z. B. täglich) und volle Checks seltener (wöchentlich/monatlich) ergänzen. In Always On-Umgebungen kann man CHECKDB bewusst auf jedem Replikat einmal laufen lassen (so Ola Hallengren’s Empfehlung), da unterschiedliche Replikate unterschiedliche Storage-Pfade haben – ein Fehler könnte nur auf dem Primärspeicher auftreten. Wichtig: Wenn man CHECKDB auf einem nicht-produktiven Restore ausführt, sollte man dennoch hin und wieder auf dem Primärsystem laufen lassen, weil nur dort z. B. kleinste Anzeichen wie 825-Warnungen im Errorlog auftauchen könnten. Automatisiert wird CHECKDB i. d. R. als Nacht-Job geplant; bei sehr vielen Datenbanken evtl. verteilt (nicht alle in derselben Nacht). Die Ergebnisse sollten geloggt werden – mindestens das Erfolgs-/Fehlerresultat je DB. Moderne Ansätze nutzen einen zentralen Health-Check-Job, der z. B. täglich prüft: „Wann war der letzte erfolgreiche CHECKDB für jede DB?“ und ggf. Alarm schlägt, wenn dieser zu lange her ist.

Datenbanksicherungen (Full, Differential, Log)

Zweck: Backups sind das Herzstück der Wartung – sie gewährleisten, dass im Fall von Hardwaredefekten, Benutzerfehlern oder anderen Desastern die Datenbank bis zu einem akzeptablen Punkt wiederhergestellt werden kann. In Kombination aus Voll-, Differenzial- und Transaktionslog-Sicherungen kann nahezu kontinuierliche Datensicherung erreicht werden. Zudem erlauben Backups auch operationelle Maßnahmen wie das Klonen von Umgebungen (via Restore auf anderen Server) oder das Offloaden von CHECKDB (s. o.).

Arten von Backups:Vollsicherung (Full Backup): Ein vollständiges Abbild der Datenbank zu einem Zeitpunkt. Es umfasst sämtliche Daten (auch den aktiven Teil des Transaktionslogs bis zum Backup-Zeitpunkt, damit die DB konsistent ist). Vollbackups bilden die Basis für Differential-Backups und markieren in Full/Bulk-Logged-Modellen den Start einer neuen Log-Kette (d. h. nach einem nicht-copy-only Full ist ein vorheriges Diff unbrauchbar). Vollbackups sind in der Regel groß und dauern am längsten, daher oft nur täglich oder wöchentlich geplant. – Differenzialsicherung: Sichert alle Extents (Datenbereiche), die seit dem letzten Vollbackup geändert wurden. Sie sind inkrementell zur letzten Vollsicherung, nicht kaskadierend. Vorteil: deutlich kleiner und schneller als Full (wenn seit dem Full nur ein Bruchteil der DB verändert wurde). Nachteil: wächst mit der Zeit seit dem letzten Full an – am Tag 6 der Woche kann ein Differential fast so groß wie das Full sein, wenn sehr viele Änderungen anfielen. Differential-Backups beschleunigen die Wiederherstellung im Vergleich zu reinen Log-Backups: Man muss nur das letzte Full + letztes Diff + ab dann Log-Backups einspielen (statt Full + sehr lange Kette vieler Logs). Empfohlen oft in Kombination: wöchentlich Full, werktäglich Differential. – Transaktionslog-Sicherung: Sichert das Transaktionslog seit der letzten Log-Backup-Operation und trunkiert es (bei Full/Bulk-Logged), damit es nicht endlos wächst. Log-Backups sind die Grundlage für Point-in-Time Recovery – indem man alle aufeinanderfolgenden Logs nach dem letzten Full/Diff einspielt, kann man die DB auf jeden beliebigen Zeitpunkt bringen. Log-Backups sind meist klein (je nach Aktivität im Intervall) und sehr schnell. Typische Intervalle: 10, 15 oder 30 Minuten in aktiven Systemen. Wichtig: Im Simple-Recovery nicht möglich, im Bulk-Logged nur sinnvoll, wenn gerade auch normale (voll protokollierte) Vorgänge liefen, da Bulk-Phasen im Log-Backup ggf. nur Extents enthalten.

Wichtige Optionen und Parameter:COPY_ONLY: Dieses Backup-Flag (bei Full oder Diff) erstellt eine Sicherung, die keine Auswirkungen auf den Backup-Chain-Zustand hat. Ein Copy-Only-Full kann z. B. gemacht werden, ohne dass danach Differential-Backups neu an das Full anknüpfen müssten. Praktisch, um ad-hoc eine Sicherung zu ziehen (z. B. vor einem größeren Release), ohne den regulären Plan zu stören. – Komprimierung: BACKUP DATABASE … WITH COMPRESSION reduziert die Backup-Dateigröße erheblich (typisch 50–80 % Einsparung, je nach Daten). Dies entlastet Speicherplatz und meist auch die Backup-Dauer, da weniger I/O anfällt (auf Kosten höherer CPU-Last während des Backups). In den meisten Fällen empfohlen, besonders wenn CPU-Reserven vorhanden sind. (Bei aktivierter TDE-Verschlüsselung ist die Kompressionsrate geringer, da die Daten auf Platte bereits zufällig verteilt sind, aber auch hier bringt es oft etwas.) – Verschlüsselung: Backups können ab SQL Server 2014 direkt per Option WITH ENCRYPTION verschlüsselt werden (erfordert ein Zertifikat oder asym. Schlüssel im Server). Das ist essenziell, wenn Backups außer Haus gegeben werden oder in Cloud-Speicher liegen – es schützt vor unbefugtem Zugriff auf die Rohdaten. Performance-Overhead ist moderat (ebenfalls CPU-lastig). Bei TDE-verschlüsselten Datenbanken sind Backups ohnehin verschlüsselt (da die DB auf Platte verschlüsselt ist und im Backup in verschlüsselter Form landet – aber Vorsicht: zum Restore benötigt man natürlich den TDE-Schlüssel). – CHECKSUM & VERIFYONLY: Die Option WITH CHECKSUM beim Backup bewirkt, dass SQL Server beim Erstellen der Sicherung Prüfsummen für die gesicherten Seiten berechnet und existierende Page Checksums verifiziert. So wird schon beim Backup festgestellt, falls eine defekte Seite gelesen wurde (Backup bricht dann ab). Diese Checksummen werden im Backup gespeichert. Mit RESTORE VERIFYONLY (idealerweise nach jedem Backup oder stichprobenartig) lässt sich die Backup-Datei auf Lesbarkeit und Konsistenz prüfen, ohne einen eigentlichen Restore durchzuführen. VERIFYONLY checkt auch die im Backup enthaltenen Prüfsummen. Es sollte automatisiert z. B. nach dem Backup-Job oder am Morgen laufen, damit man zeitnah erfährt, falls eine Sicherung korrupt ist. – Rotation und Offsite: Ein Wartungskonzept muss definieren, wie viele Backup-Versionen aufbewahrt werden (Retention). Üblich ist z. B. 2 Wochen tägliche Backups auf Disk, ältere in Archiv oder auf günstigeren Storage ausgelagert. Mindestens ein Satz Backups sollte außerhalb des Primär-Rechenzentrums aufbewahrt werden (Offsite oder Cloud), um Katastrophen (Brand, Diebstahl) abzudecken. Die 3-2-1-Regel empfiehlt: 3 Kopien, auf 2 verschiedenen Medien, 1 davon offsite. Wartungspläne sollten also auch Aufgaben zum Kopieren von Backups (z. B. auf ein Netzlaufwerk, Tape, Cloud-Storage) und anschließendes Löschen lokal vorhalten, falls nötig.

Typische Frequenzen: Eine gängige Kombination ist Wöchentlich ein Vollbackup (z. B. Sonntagnacht), täglich eine Differenzialsicherung (an den anderen Tagen, nachts) und sehr häufige Log-Sicherungen (tagsüber alle x Minuten). In weniger kritischen Umgebungen werden auch täglich Vollbackups statt Differential gemacht (einfacher in der Wiederherstellung, aber mehr Speicherbedarf). Kleinere Datenbanken (< 50 GB) kann man problemlos täglich voll sichern. Wichtig: Backup-Fahrpläne immer mit Geschäftsanforderungen abstimmen – etwa, ob ein Datenverlust von 24 Stunden (bei nur täglichen Fulls im Simple-Modell) tolerierbar ist oder ob praktisch keinerlei Verlust (Log-Backups alle wenige Minuten im Full-Modell) nötig ist.

Auswirkungen auf System & Log: Backups beanspruchen primär IO und etwas CPU. Sie laufen jedoch schreibend außerhalb der Datenfiles (lesen aus DB, schreiben ins Backup-Ziel, z. B. Disk oder Tape). Daher belasten sie das Storage-System, können aber via Backup-Throttling (nicht nativ, aber man könnte z. B. per MAXTRANSFERSIZE/BUFFERCOUNT Tuning vornehmen) und durch Ausführen in Nebenzeiten mitigiert werden. Im Full/Bulk-Modell stoppen Log-Backups den Log-Zuwachs nicht, aber truncaten ihn – bei Fehlern im Log-Backup (z. B. Ziel voll) kann das Transaktionslog wachsen bis zum Ausfall, daher unbedingt Monitoring hier (Alert, wenn kein Log-Backup seit X Minuten). Differential- und Vollbackups beeinflussen die aktive DB kaum außer Throughput – sie setzen nur bei Start einen kurzen Freeze der DB (Checkpoint) um Konsistenz sicherzustellen, was aber meist wenige Sekunden dauert. Moderne Backups kann man mit der Option COPY_ONLY gezielt einsetzen, um Zwischensicherungen zu machen, ohne den normalen Turnus zu stören (z. B. vor einem Release ein Copy-Only-Full).

Erfolgskriterien & Tests: Ein Backup hat seinen Zweck erst erfüllt, wenn es erfolgreich zurückgesichert werden kann. Daher gehört zur Wartung immer die Überprüfung: Ist das Backup vollständig gelaufen (Agent-Job grün)? Wurden keine Warnungen (z. B. CHECKSUM-Fehler) geloggt? Lässt es sich mittels RESTORE VERIFYONLY validieren? Und letztlich: Test-Restore in eine Test-DB oder auf einem separaten Server. Viele Organisationen planen z. B. monatlich einen Restore-Test der wichtigsten DBs, messen dabei die Restore-Dauer (wichtig für RTO!) und protokollieren den Erfolg. Diese Tests sollten Teil des Wartungsplans sein, inkl. Bereinigung hinterher (die Test-DB wieder entfernen, Logs löschen).

Indexpflege (Rebuild vs. Reorganize)

Zweck: Die Indexpflege soll sicherstellen, dass relationale Indexstrukturen effizient bleiben. Durch viele Datenänderungen entstehen Fragmentierungen: Die physische Reihenfolge der Indexseiten weicht von der logischen ab, Seiten sind nur teils gefüllt, es gibt mehr Seitenumbrüche (Page Splits). Das führt zu mehr I/O beim Lesen und teils zu Platzverschwendung. Indexpflege versucht, die Seiten wieder zusammenhängender und dichter zu machen, um Lesezugriffe zu beschleunigen und Platz zurückzugewinnen. Zudem aktualisiert ein Index-Neuaufbau auch die Index-Statistiken, was der Abfrageoptimierung zugutekommt.

Rebuild vs. Reorganize: Es gibt zwei Ansätze: – Index Rebuild (Neuaufbau): Entspricht ALTER INDEX … REBUILD. Hier wird der gesamte Index (für jede Partition, falls partitioniert) neu aufgebaut, als ob man ihn frisch erstellt – die Daten werden neu sortiert, kompakt geschrieben, und alte Strukturen ersetzt. Ergebnis: ein defragmentierter Index mit zusammenhängenden Extents und optional neu gesetztem Fill-Factor. Vorteile: Beseitigt Fragmentierung vollständig, kann auch beschädigte Indexseiten ersetzen, und aktualisiert die Statistik mit einem vollständigen Scan implizit. Nachteile: Ist ein großer, atomarer Vorgang – benötigt je nach Indexgröße viel Zeit, erzeugt viele Schreib-I/Os und im Full-Recovery auch eine große Logmenge (jede geänderte Seite wird protokolliert). Standardmäßig sperrt ein Rebuild die Tabelle, außer man nutzt ONLINE = ON (Enterprise Edition erforderlich bis SQL 2016, ab SQL 2019 teilweise auch Standard für Nonclustered-Index-Rebuilds erlaubt). Online-Rebuild minimiert Sperren auf Schreibvorgänge, aber lesende Abfragen können weiterlaufen. Online-Rebuilds sind allerdings etwas langsamer und verbrauchen mehr Ressourcen (zusätzlicher Platzbedarf für interne Row-Versioning/Snapshot). SORT_IN_TEMPDB kann verwendet werden, um Sortieroperationen aus dem Userdatenfile in TempDB auszulagern – sinnvoll, wenn TempDB auf schnellerem oder separatem Storage liegt, um die Haupt-DB I/O zu entlasten. – Index Reorganize (Neuordnung): Entspricht ALTER INDEX … REORGANIZE. Dies ist ein inkrementeller Prozess, der die Blattebenen des Indexes sequentiell optimiert: Seiten werden in die richtige Reihenfolge gebracht, leere Seiten entfernt, teilweise gefüllte Seiten konsolidiert (bei Reorganize passiert dies durch sogenanntes „Leaff level page compaction“). Reorganize läuft immer online und in kleinen Schritten (es verarbeitet eine beschränkte Anzahl an Seiten pro Transaktion), was zu geringeren Sperren führt. Vorteile: Kann bei moderater Fragmentierung schneller sein und stört den Betrieb kaum – es lässt sich auch pausieren (beendet einfach nach aktuellem Seitenpaket, da es keine Gesamttransaktion braucht). Nachteile: Beseitigt Fragmentierung nur teilweise (sortiert Seiten, aber kombiniert sie nicht neu global wie Rebuild) und ist ineffizient bei hoher Fragmentierung – es kann deutlich länger dauern als ein Rebuild, wenn der Index stark zerklüftet ist. Zudem werden Index-Statistiken nicht automatisch neu berechnet (die Statistik bleibt, als wäre der Index unverändert, nur die physische Reihenfolge änderte sich). Daher muss man nach Reorganize ggf. UPDATE STATISTICS separat durchführen (siehe unten). Reorganize verbraucht weniger Log pro Vorgang, aber da es in vielen kleinen Transaktionen arbeitet, summiert sich das Log ebenfalls, wobei es insgesamt oft etwas log-sparsamer ist als ein Rebuild eines ähnlich fragmentierten Indexes.

Schwellenwerte und Strategie: Üblicherweise werden Fragmentierungs-Schwellen definiert, um zu entscheiden, ob Rebuild, Reorg oder nichts zu tun ist. Ein oft zitiertes Schema (auch Standard in Microsoft-Dokumentation und Ola Hallengrens Skript) ist: – Bei Fragmentierung < 5 %: Kein Handlungsbedarf. Diese geringe Fragmentierung beeinflusst die Performance kaum, insbesondere bei kleinen Tabellen, und das Bearbeiten wäre Ressourcenverschwendung. – Bei Fragmentierung ~5–30 %: Reorganize anwenden. In diesem Bereich lohnt sich Entfragmentierung, aber ein aufwändiger Rebuild ist noch nicht notwendig. Reorganize kann hier moderate Unordnung beheben, ohne die ganze Tabelle neu zu schreiben. – Bei Fragmentierung > 30 %: Rebuild anwenden. Ab hier ist der Index stark fragmentiert; ein Rebuild stellt den Idealzustand wieder her und ist meist effizienter als eine extrem lange Reorganize.

Wichtig ist auch, sehr kleine Indizes (wenige Seiten) auszufiltern: Bei Tabellen/Indices unter ca. 1.000 Seiten bringen weder Reorg noch Rebuild viel, da z. B. 80 % „Fragmentierung“ bei 10 Seiten nicht relevant für Performance ist. Solche bleiben oft absichtlich unberührt.

Parameter und Einflussgrößen:FILLFACTOR: Dieser Indexparameter bestimmt, wie voll eine Index-Seite bei Erstellung gefüllt wird (Standard 100 % = komplett voll). Setzt man z. B. FILLFACTOR = 90, lässt der Rebuild pro Seite 10 % Luft – das kann zukünftige Page Splits (bei Einfügen neuer Zeilen in Sortier-Reihenfolge) reduzieren, weil etwas Platz da ist. Der Fillfactor wird beim Rebuild angewendet; Reorganize respektiert existierende Fillfactor-Einstellungen, ändert sie aber nicht. Empfehlung: Fillfactor nur setzen, wenn eine Tabelle viele Split-Indikatoren (hohe avg_page_space_used oder viele Page-Split-Waits) hat – z. B. indizierte GUID-Spalten, die zufällig eingefügt werden. Sonst lässt man 100 % (d. h. keine künstlichen Lücken). – MAXDOP: Per ALTER INDEX … REBUILD WITH (MAXDOP = n) kann die Parallelität eines Rebuilds begrenzt werden. Standard nimmt das max degree of parallelism der Serverkonfiguration. In Wartungsplänen kann es sinnvoll sein, Rebuild-Jobs mit niedrigerem MAXDOP laufen zu lassen, falls gleichzeitig andere Aufgaben laufen oder um CPU für Notfälle frei zu halten. Alternativ lässt man Rebuilds parallel (um Gesamtzeit zu minimieren) und stellt sicher, dass sie im Wartungsfenster allein laufen. – ONLINE = ON: Wie erwähnt, ermöglicht dies (in entsprechend lizenzierten Editionen) das parallele Lesen/Schreiben während des Rebuilds. Bei geschäftskritischen 24/7-Systemen praktisch Pflicht, da sonst selbst ein kurzer Offline-Rebuild Transaktionen blockieren würde. Aber Achtung: bestimmte Objekte wie Clustered Indexes mit BLOB-Spalten oder Indizes auf Spatial/Geometrie-Datentypen konnten lange nicht online rebuilt werden (mittlerweile vieles verbessert, aber es gibt Ausnahmen). Das Wartungsskript muss ggf. solche Indizes erkennen und separat behandeln. – SORT_IN_TEMPDB = ON: Verlegt die temporären Sortierläufe beim Rebuild in die TempDB. Vorteil, wenn TempDB auf schnellem Medium und genügend Platz, da die Hauptdatenbank weniger I/O-Last sieht und am Ende ggf. weniger Fragmentierung der Datei hat. Nachteil: TempDB braucht genug Raum und es erhöht dort die I/O (was concurrent andere Wartung stören könnte). Diese Option setzt man in Absprache mit dem Storage-Layout.

Log- und Performance-Impact: Index Rebuilds im Full-Recovery erzeugen eine große Transaktion, die komplett protokolliert wird. Das Transaktionslog kann dabei massiv wachsen, wenn z. B. ein 100 GB Index neu aufgebaut wird, gehen 100 GB Änderung (plus Overhead) ins Log. Abhilfe: während solcher Aktionen besonders häufig Log-Backups durchführen (um das aktive VLF zu leeren – aber während einer Transaktion wird natürlich nichts freigegeben bis zum Commit!). Bulk-Logged Recovery könnte hier Teile minimal loggen, aber Index-Rebuild zählt meist nicht als minimal loggable Operation (außer evtl. Partition-Switch-Szenarien). Reorganize loggt schrittweise, was das Risiko großer, unhandlicher Logbackups reduziert. Allerdings: in AlwaysOn-Umgebungen werden diese Log-Einträge alle zu den Replica-Servern gestreamt – eine große Rebuild-Transaktion kann also das AG-Netzwerk belasten oder bei synchroner Replikation die gesamte Latenz hochschrauben (die sekundären müssen ja bestätigen, bevor commit). Hier bietet es sich an, sehr große Indexe ggf. aufzuteilen (Partitionen einzeln rebuilden z. B.) oder solche Aktionen in den Wartungsfenster mit Async-Mode (falls erlaubt) durchzuführen.

Risiken & Nebenwirkungen:Statistiken-Effekt: Nach einem Rebuild sind Statistiken aktuell (basierend auf komplettem Neuaufbau). Nach einer Reorganize hingegen bleiben Statistiken veraltet; daher empfehlen viele, im Wartungsplan nach Reorganize-Operationen ein Update der Stats (siehe nächsten Abschnitt) durchzuführen. Allerdings niemals vor der Indexpflege die Stats upzudaten – das wäre doppelt gemoppelt, da Rebuilds sie überschreiben würden. – Differential Backup Größe: Ein oft übersehener Nebeneffekt: Wenn man Differenzialsicherungen nutzt und nach dem letzten Full umfangreiche Rebuilds laufen, markieren diese nahezu jede Indexseite als „geändert“. Ein folgendes Differential-Backup wird dann sehr groß (nahe der Fullgröße). Daher empfiehlt es sich, wie im Pipeline-Vorschlag (A) erwähnt, nach der Indexpflege ein Full Backup zu machen. Alternativ, falls man Full-Backup erst später macht (Pipeline B), muss man den Nachteil größerer Diffs in Kauf nehmen. – TempDB-Auslastung: Bei Online-Rebuilds und Sort in TempDB kann TempDB stark wachsen. Hierauf überwachen und idealerweise vorab genügend Platz bereitstellen. Nach dem Wartungslauf kann man prüfen, ob TempDB eine ungewöhnliche Zunahme hatte, aber generell sollte man Autogrowth dort so einstellen, dass Rebuilds ohne viele kleine Wachstumsschritte auskommen (z. B. größere fixe Wachstumssteps). – Blockierungen: Offline Rebuilds setzen exclusive Locks; Reorganize kann bei jeder Seite kurz sperren. In ruhigen Zeiten ist das unkritisch, aber falls doch Nutzer parallel aktiv sind, könnten sie behindert werden. Im Zweifel immer die Online-Option verwenden oder Reorgs in sehr kleinen Batches manuell steuern. – Replikation & Indexed Views: In replizierten DBs oder bei indizierten Views gelten teilweise Besonderheiten: z. B. beim Rebuild von indexierten Views muss WITH NOEXPAND angegeben werden. Bei Transaktionsreplikation sollte Indexpflege auf Publisher-Seite normal möglich sein, repliziert aber natürlich nicht (Replikate pflegen ihre Indizes separat).

Erfolgskriterien: Man sollte nach Indexpflege-Läufen KPIs betrachten wie „Wie viele stark fragmentierte Indizes bleiben?“, „Wie lange dauerte es?“, „Wie hat sich die Abfrage-Performance geändert?“. Ein guter Wartungsplan sorgt dafür, dass dauerhaft kein großer Index mit z. B. > 80 % Fragmentierung verbleibt. Außerdem sollte die Seitensplit-Rate im Betrieb sinken, wenn Fillfactor richtig eingestellt und Indexe reorganisiert wurden. Monitoring kann hier ansetzen: z. B. Perfmon Counter „Page Splits/sec“ vor und nach Wartung vergleichen. Auch die Größe der Datenbank kann minimal schrumpfen (durch Auflösen leerer Seiten), aber Raumgewinn ist selten primäres Ziel – das ist nicht mit SHRINK zu verwechseln (siehe später).

Statistiken aktualisieren

Zweck: Statistiken sind essenziell für den Abfrageoptimierer, um gute Ausführungspläne zu erstellen. Sie enthalten Histogramme über die Datenverteilung in Index- oder Spaltenwerten. Veraltete Statistiken (z. B. ein Histogramm, das keine Kenntnis über die letzten 1 Mio. eingefügten Zeilen hat) führen zu falschen Abschätzungen (Cardinality Estimates) und damit ggf. zu ineffizienten Plänen. Das Aktualisieren der Statistiken als Wartungsaufgabe stellt sicher, dass der Optimizer mit aktuellem Wissen arbeitet, besonders bei stark gewachsenen oder geänderten Datenbeständen.

Automatische Aktualisierung vs. manuell: SQL Server hat von Haus aus AUTO_UPDATE_STATISTICS: Wenn ca. 20 % + 500 der Zeilen eines Tabellenindexes geändert wurden, wird beim nächsten Abfrageoptimieren jene Statistik automatisch im Hintergrund aktualisiert (Standard-Verhalten). Bei sehr großen Tabellen kann 20 % jedoch Millionen von Zeilen bedeuten – hier greift Auto-Update spät. Zudem passiert das Update i. d. R. mit einem Sample (nicht Fullscan), um es schnell zu halten. In vielen Fällen reicht das, aber in Data-Warehouse-ähnlichen oder kritischen OLTP-Szenarien möchte man lieber proaktiv und mit höherer Güte Stats aktualisieren. Daher ergänzen Wartungspläne oft manuelle Updates: – Fullscan vs. Sampling: UPDATE STATISTICS lässt sich mit WITH FULLSCAN ausführen, was das komplette Durchlesen der Tabelle bedeutet – liefert das genaueste Histogramm, ist aber für sehr große Tabellen teuer (viel IO). Standard wäre eine SQL-eigene Heuristik oder ein bestimmter Sample-Prozentsatz. Im Wartungsfenster kann Fullscan sinnvoll sein, insbesondere für Schlüsseltabellen, um optimale Pläne sicherzustellen. – Column Stats und Index Stats: Achtung, ein UPDATE STATISTICS TableName aktualisiert alle Statistiken der Tabelle (Index-Stats und separat erstellte Spaltenstatistiken). Man kann auch gezielt einzelne Stats aktualisieren. Tools wie sp_updatestats durchlaufen automatisch alle Stats aller Tabellen, überspringen aber solche, die laut SQL nicht nennenswert geändert wurden. sp_updatestats ist schnell, aber verwendet by default Sampling – gut für ein schnelles Standard-Update, aber suboptimal, wenn man absolute Genauigkeit braucht. – Rebuild-Effekt: Wie erwähnt, macht ein Index-Rebuild die Statistik dieses Indexes neu mit Fullscan. Daher müssen Index-Statistiken nach Rebuild nicht extra aktualisiert werden. Es wäre doppelte Arbeit. Hingegen nach einem Reorganize bleibt die Statistik alt. Einige Indexpflege-Skripte (wie Ola’s) bieten daher optional an, nach Reorganize ein UPDATE STATISTICS mit zu erledigen (Parameter @UpdateStatistics). Alternativ kann man auch separat nach Abschluss aller Reorgs einen Stats-Job fahren. Empfehlung: Stats-Update am Ende der Pipeline nur für die Tabellen, die nicht durch Rebuilds abgedeckt waren – so spart man Zeit und Ressourcen. – Ausschlusskriterien: Manche sehr große, selten genutzte Tabellen muss man ggf. nicht bei jedem Lauf updaten, insbesondere wenn Auto-Stats ausgereicht hat. Hier kann man selektiv verfahren. Neuere SQL-Versionen (ab 2016) haben auch Verbesserungen im Auto-Update-Verhalten (z. B. eine verringerte Schwelle für sehr große Tabellen, sog. „Multi-Threaded Stats Update“ und inkrementelle Statistiken bei Partitionierung). Dies kann man in Überlegungen einbeziehen, ändert aber das grundsätzliche Vorgehen im Wartungsplan kaum.

Frequenz: Statistiken sollten mindestens so oft wie Indexpflege aktualisiert werden, denn fragmentierungsbedingte Performanceprobleme und Stats-Probleme gehen Hand in Hand. Oft wird ein kombinierter Job geplant, der Indizes pflegt und dann Stats updatet. In sehr anspruchsvollen OLTP-Systemen aktualisiert man Stats sogar täglich (auch ohne Reindex), um stets frische Pläne zu haben. Im Warehouse-Umfeld, wo nächtlich große Batch-Loads passieren, ist ein Stats-Update nach dem Load ratsam, bevor Analysten ihre Abfragen starten. Hier kann man auch differenzieren: z. B. umfangreiche Stat-Updates (Fullscan) nur am Wochenende, wochentags nur sp_updatestats als leichte Auffrischung.

Auswirkungen: Stats-Updates verursachen Lese-I/O (um Stichproben oder alle Zeilen zu lesen) und verbrauchen CPU beim Berechnen der Verteilung. Sie können zu kurzen Sperren auf der Statistik bzw. Tabelle führen (Update Stats nimmt ein Schema-Modified Lock für die Dauer, sodass parallel evtl. Lesevorgänge kurz warten). Meist sind die Sperren aber sehr kurz, außer Fullscan auf Riesentabelle – das kann dauern. Hier dann unbedingt in Wartungszeit legen. Das Transaktionslog wird wenig belastet, da nur Statistik-Blob aktualisiert wird; es ist aber eine DML-Transaktion (Update interner Tabellen), also minimal protokolliert (nur Änderungen an Metadaten, nicht alle Zeilen). Nebenwirkungen: Nach dem Stat-Update verwirft SQL automatisch alle Ausführungspläne, die diese Stats verwendeten (ähnlich wie bei Recompile). Das ist gewollt, aber es bedeutet, dass nach Wartung die ersten Abfragen die Pläne neu berechnen – ein kurzfristiger CPU-Mehrbedarf zu Beginn der Geschäftszeit, der aber meist unproblematisch ist.

Monitoring: KPIs wie „Statistiken Alter“ gibt es so nicht, aber man merkt es indirekt: Wenn Abfragepläne plötzlich von Loops auf Hash Join wechseln oder die geschätzten vs. tatsächlichen Zeilen stark abweichen, sind Stats möglicherweise veraltet. Daher können Monitoring-Tools melden, falls Auto-Update-Statistiken sehr häufig triggert (Zeichen, dass man Intervalle verkürzen sollte) oder man trackt manuell den letzten Update-Zeitpunkt von wichtigen Statistikobjekten (STATS_DATE() Funktion). In der Praxis verlässt man sich meist auf den Wartungsplan und reagiert, wenn trotzdem Performance-Anomalien auftreten – dann kann man ad-hoc ein manuelles Update Stats für die betroffene Tabelle fahren.

Konsistenzprüfungen (Katalog, Dateigruppen)

Neben DBCC CHECKDB gibt es weitere spezifische Konsistenzchecks: – DBCC CHECKCATALOG: prüft die Konsistenz der SQL Server Systemtabellen (Katalog) innerhalb einer Datenbank. CHECKDB führt intern auch CHECKCATALOG aus, daher ist ein separates Ausführen selten nötig – es sei denn, man möchte gezielt nur Katalog prüfen (der sehr selten beschädigt ist). In hochkritischen Umgebungen könnte man CHECKCATALOG z. B. täglich und CHECKDB wöchentlich laufen lassen, weil ersteres schneller ist. Standardmäßig reicht aber das in CHECKDB enthaltene. – DBCC CHECKFILEGROUP: ermöglicht, Konsistenz auf einzelne Dateigruppen beschränkt zu prüfen. Das macht Sinn, wenn eine riesige Datenbank in Teile (Filegroups) getrennt ist, z. B. nach Jahrgängen. Man könnte an verschiedenen Tagen verschiedene Filegroups checken, um die Last zu verteilen. Allerdings stellt CHECKDB standardmäßig alle Filegroups einer DB in einem Rutsch fertig. Wenn man aber ein wirklich enges Fenster hat, kann man stückeln: z. B. Mo Filegroup1, Di FG2 usw., und am Ende der Woche CHECKCATALOG um übergreifende Katalogintegrität zu sichern. Dieser Ansatz ist nur in extrem großen Umgebungen nötig und bringt Komplexität mit sich (Skripting wer wann dran ist). Für die meisten Szenarien ist ein vollständiger CHECKDB in einem Aufwasch (ggf. auf zweitem System) die robustere Lösung.

Bereinigungen und Verlaufspflege

Im Laufe der Zeit sammeln sich in einer SQL Server Instanz viele Nebenprodukte der Wartung an: Backup-Dateien, Verlaufsdaten, Protokolle. Diese regelmäßig zu bereinigen ist wichtig, damit sie nicht selbst zur Ursache von Problemen werden (z. B. Volllaufen von Platten oder Performance-Verlust durch riesige MSDB-Tabellen).

Wichtige Bereinigungsaufgaben: – Backup-Dateien löschen: Der Storage-Bedarf von Datenbanksicherungen ist erheblich. Man sollte automatisiert alte Dateien (z. B. älter als 14 oder 30 Tage, je nach Retentionsrichtlinie) entfernen. Dies kann durch Maintenance Plan Task „Maintenance Cleanup“ geschehen oder via T-SQL (xp_delete_file in master, wobei man Pfad, Extension und Alter angibt). Hierbei ist Vorsicht geboten: sicherstellen, dass das Script wirklich nur den Backup-Pfad erwischt und nicht z. B. .bak irgendwo anders löscht. Idealerweise konfiguriert man dedizierte Backup-Verzeichnisse je Server/DB. Moderne Ansätze archivieren Backups erst (z. B. Kopie in Cloud oder Band), löschen sie dann lokal. Auch diese Schritte sollte man scripten (z. B. via PowerShell Dateioperationen). – MSDB-Backup-Historie bereinigen: Die MSDB-Systemdatenbank protokolliert jedes Backup (Tabelle backupset etc.) und jede Restore-Operation, genauso Wartungsplan-Ausführungen. Diese Tabellen wachsen mit der Zeit und können Abfragen (z. B. in SSMS Backup-Dialog) verlangsamen. Mit sp_delete_backuphistory @older_than = ‚Datum‘ lässt sich die Backup-History vor einem Stichtag entfernen. Ähnlich gibt es sp_purge_jobhistory um SQL Agent-Jobhistorie zu kürzen. Ein Wartungsplan sollte bspw. monatlich oder wöchentlich alles älter 6 Monate entfernen, je nach Compliance-Vorgabe. Wichtig: Backup-History sollte mindestens so lange wie Aufbewahrungsfrist der Backups behalten werden, damit z. B. Restore- und Audit-Abfragen noch möglich sind. – Datenbank-Mail und Agent-Log Cleanup: Wenn man Database Mail für Alerts nutzt, sollte man das Mail-Log gelegentlich bereinigen (sysmail_delete_mailitems_sp/…_log_sp prozeduren). Auch der SQL Server Errorlog sollte rotiert werden (späte SQL Versionen tun dies automatisch bei 7 Logs Standard, aber man kann per sp_cycle_errorlog in Wartung z. B. wöchentlich den Errorlog neu starten, damit Dateien nicht riesig werden). – Alte Restore-Validierungen entfernen: Falls man automatisiert Test-Restores auf dem selben Server durchführt (andere DB-Namen), sollte das Skript am Ende diese Testdatenbanken wieder löschen, um Platz und Verwirrung zu vermeiden. Auch dabei entstehende Protokoll-/Datenfiles (oft auf Temp-Verzeichnissen) sind zu entfernen. Ebenso kann es sinnvoll sein, Wartungsreports (z. B. Textdateien, die Maintenance Plans ablegen) nach einer Zeit zu löschen oder zu archivieren, damit das Dateisystem nicht überquillt. – Agent-Job-Ausführungsverlauf begrenzen:* SQL Agent speichert standardmäßig 1.000 Einträge pro Job (konfigurierbar). In Umgebungen mit sehr häufigen Jobs (z. B. minütliche Log-Backups) können das Unmengen werden. Man kann global in den SQL Agent Properties einstellen, z. B. max 100 Einträge/Job oder Aufbewahrung 4 Wochen. Diese Einstellung ist Teil der „Wartung“ in dem Sinne, dass man sie einmal sinnvoll vornimmt.

Die Bereinigungsjobs sollte man zeitlich so legen, dass sie nach den betreffenden Aktionen laufen: z. B. Backup-Datei-Löschung nach dem Erstellen neuer Backups, aber nicht gleichzeitig wie ein laufendes Backup (könnte sonst versehentlich die gerade entstehende Datei erwischen, je nach Script-Logik). Oft macht man Cleanup als letzten Schritt der nächtlichen Pipeline. Ausnahme: Falls man CheckDB auf Restore-Kopien durchführt, löscht man die Kopien (Datenbanken oder Dateien) nach erfolgreichem Check ebenfalls möglichst bald.

TempDB-Optimierung

TempDB ist eine Systemdatenbank, die für temporäre Objekte, Sortiervorgänge, Tabellenvariablen, RowVersioning etc. genutzt wird – quasi ein gemeinsamer „Schmierzettel“ für SQL Server. Gerade Wartungsaufgaben wie Index-Rebuilds (mit Sort in TempDB) oder CheckDB (macht ggf. Snapshots, nutzt TempDB für Zwischenergebnisse) belasten TempDB stark. Daher ist eine optimale Konfiguration der TempDB Teil des Wartungsplans:

  • Dateianzahl und Größe: Microsoft empfiehlt seit SQL 2016 mehrere gleich große Datendateien für TempDB (typisch 1 pro CPU-Kern bis max. 8). Das reduziert Contention auf Verwaltungseiten (PFS, SGAM). Wenn man bislang nur 1 TempDB-Datei hatte, kann man als Wartungsmaßnahme zusätzliche Dateien hinzufügen. Alle TempDB.mdf/ndf sollten gleiche Anfangsgröße und Autogrowth haben, damit Last gleichmäßig verteilt. Die Startgröße sollte so bemessen sein, dass im täglichen Betrieb kaum Autogrowth benötigt wird. Beispiel: Wenn man weiß, Wartung xy verbraucht bis zu 10 GB TempDB, könnte man 4 Files à 3 GB fest einstellen (12 GB total).
  • Autogrowth-Einstellungen: Falls Wachstum doch nötig, fixe MB-Schritte statt Prozent verwenden (z. B. 500 MB pro Schritt), um Kontrolle zu haben. Nichts ist schlimmer als 10 % Wachstum auf 100 GB – das würde 10 GB Schlag auf Schlag bedeuten und ggf. lange dauern. Lieber moderate, aber feste Schritte. Instant File Initialization (IFI): Für Datendateien (gilt nicht fürs Transaktionslog) sollte auf Windows Ebene das Recht „Perform Volume Maintenance Tasks“ für den SQL Server Dienstaccount gesetzt sein – dann gehen Wachstum und Anlegen von Dateien schneller (Dateibereich wird nicht mit Nullen gefüllt). Das ist quasi Pflicht, um im Wartungsfall (z. B. Restore, Rebuild mit Wachstum) Zeit zu sparen. Für TempDB insbesondere: beim Neustart werden die Files immer neu angelegt – IFI spart hier merklich Zeit.
  • Überwachung: Teil der Wartung ist auch, TempDB „gesund“ zu halten. Monitoren Sie z. B. tempdb_space_used regelmäßig. Kommt TempDB an Kapazitätsgrenzen, kann das ganze SQL-System stoppen. Daher evtl. Alert: Wenn TempDB > 80 % gefüllt, Mail ans DBA-Team. Im Wartungsfenster nach großen Jobs kann man schauen, ob TempDB stark gewachsen ist – und falls ja, entscheiden, ob man diese Größe beibehält (evtl. „neues Normal“) oder ob man TempDB wieder schrumpft. Auto-Shrink ist hier nicht die Lösung; besser kontrolliert per DBCC SHRINKFILE zu einem sinnvollen Wert verkleinern (z. B. wenn einmalig ein riesiger Sort ein Ausreißer war).
  • Trace Flags (Info): In früheren Zeiten musste man TempDB-Problemen mit Traceflags entgegenwirken (z. B. 1117/1118 um Mixed Extents abzuschaffen, was ab SQL 2016 Standardverhalten wurde). Aktuell relevante Flags könnten sein: T1118 (Seiten ausschließlich Uniform Extents – heute Default), T1117 (alle Files wachsen gleichmäßig – heute Default), T3226 (unterdrückt erfolgreiche Backup-Eintrage im Log, indirekt relevant um Errorlog klein zu halten). T834 (Large Page Allocations für Heap/Buffer, kann bei genügend RAM helfen). Generell gilt: Traceflags sollte man nur einsetzen, wenn konkrete Notwendigkeit besteht, und sie gut dokumentieren. Eine pauschale Empfehlung gibt es nicht, da neuere SQL-Versionen viele Problemstellen gelöst haben.

Zusammengefasst: Der Wartungsplan sollte nach Erstinstallation einmal sicherstellen, dass TempDB optimal konfiguriert ist – dies ist dann selten wieder anzufassen, außer bei großen Änderungen (mehr CPUs, Workload-Wechsel). Kontinuierlich sollte aber der Verbrauch beobachtet werden, um ggfs. proaktive Maßnahmen zu ergreifen (z. B. mehr TempDB-Platz bereitstellen, bevor etwas voll läuft).

Protokollverwaltung & Dateilayout

Daten- und Logdateien der Datenbanken verdienen Beachtung im Wartungskonzept: – Autogrowth sinnvoll einstellen: Standardmäßig erstellt SQL Server neue DBs mit 1 MB Autogrowth (Daten) und 10 % (Log) – beides ist unpraktisch. Zu viele kleine Autogrowth-Schritte fragmentieren Dateien auf dem Volume und verursachen ständige Pausen (bei jedem Wachstum wird IO und evtl. Locks benötigt). Zu große Sprünge (10 % von 100 GB = 10 GB) können zu langen Stopps führen. Deshalb: für jede Datenbank je nach Größe sinnvolle fixe Wachstumsinkremente definieren. Beispiel: eine 50 GB DB -> Growth 500 MB; eine 500 GB DB -> Growth 5 GB. Gleiches fürs Log: besser feste MB (z. B. 512 MB), damit die entstehenden VLFs (Virtual Log Files) in vernünftiger Anzahl angelegt werden (SQL teilt einen Wachstumsschub in 4–16 VLFs, je nach Größe). Weniger, große VLFs sind i. d. R. besser als tausende winzige. Es gibt bekannte Richtwerte: VLF-Anzahl > 1000 gilt als übermäßig, hier sollte man das Log neu erstellen mit größerem Chunk. – Dateigruppen & Files: In großen Datenbanken nutzt man oft mehrere Dateigruppen (Filegroups) um z. B. historische Daten separat zu halten oder spezielle Indizes auszulagern. Aus Wartungssicht kann man Filegroups offline nehmen (falls ReadOnly) und braucht sie nicht zu sichern (Backup mit READ_WRITE_FILEGROUPS-Option für Partial Backups). Die Wartungspläne sollten solche Besonderheiten respektieren: z. B. INDEX REBUILD nur auf FG = PRIMARY oder wie konfiguriert. Tools wie Ola’s Skript bieten Parameter, nur bestimmte Filegroups zu bearbeiten. Für Parallelisierung kann man bei vielen Datenfiles in einer Filegroup auch mehrere Threads in Wartung nutzen, aber meist übernimmt SQL intern Load-Balancing bei gleichgroßen Files (proportional fill). – Kein regelmäßiges SHRINK: Das Verkleinern von Daten- oder Logdateien (DBCC SHRINKFILE/…DATABASE) ist keine normale Wartungsaufgabe. Zwar mag es verlockend sein, nach Datenlöschungen Platz freizugeben, jedoch verursacht Shrink erhebliche Fragmentierung der Daten – die Seiten werden wahllos verschoben um Lücken am File-Ende freizuräumen. Danach sind Indexe typischerweise komplett zerstückelt. Außerdem kostet Shrink viel IO und CPU. Resultat: Kurzfristig etwas Plattenplatz gewonnen, aber Performance eingebüßt und die nächste Operation füllt den Platz meist wieder, sodass Kreislauf entsteht. Darum: Shrink vermeiden!. Ausnahmen gibt es selten: z. B. nach einem einmaligen Massendaten-Archivierungslauf wurden 70 % der DB frei und man weiß sicher, dass diese nicht wieder gebraucht werden. Dann kann man in Erwägung ziehen, die Datenfile zu verkleinern – am besten nicht auf einmal, sondern in Etappen, und anschließend einen vollständigen Reindex durchführen, um Fragmentierung zu bereinigen. Für Logs ähnlich: Wenn ein Log einmal aufgrund eines Ausfalls extrem anwuchs (z. B. 100 GB, normal 1 GB), kann man nach Wiederaufnahme der Log-Backups das Logfile einmal verkleinern auf den Normalmaß. Auch hier: langsam und kontrolliert vorgehen, und gleich danach wieder auf sinnvolle Größe vergrößern, damit Autogrowth-Ereignisse gering bleiben. – Dateilayout & Performance: Eine Wartungsüberlegung ist auch, ob das Dateilayout optimiert werden sollte: z. B. viele kleine Dateien auf gleichem Volume bringen wenig, während das Verteilen auf mehrere Volumes Performance bringen kann. Auch das Trennen von Lese-/Schreibmustern ist ein Punkt: Logs (sequenzielle Schreibmuster) getrennt von Daten (random IO) – üblich und sinnvoll. TempDB getrennt – auch sinnvoll. Innerhalb Daten kann man z. B. eine stark genutzte Tabelle in eigene Filegroup auf schnellem Storage legen (sofern lizenziert: Partitionierung). Solche Maßnahmen stehen zwar eher bei der Systemarchitektur am Anfang, können aber auch später im Rahmen von Wartungsprojekten (z. B. Performance-Tuning-Initiative) passieren. Der Wartungsplan sollte solche Änderungen mittragen (Backups aller Filegroups beachten, Index-Skripte anpassen, etc.).

Statustelemetrie & Benachrichtigungen

Ein oft unterschätzter Teil der Wartung ist das Monitoring der Wartung selbst und das Einrichten von automatischen Alarmen. Im Idealfall bemerkt das System Probleme und meldet diese proaktiv an den DBA, bevor Nutzer es merken. Wichtige Elemente:

  • Datenbank-Mail einrichten: Dies ist die Grundlage für E-Mail-Benachrichtigungen aus SQL Server. Es sollte ein SMTP-Konto und Profil konfiguriert sein, das vom SQL Agent genutzt werden darf. Test-E-Mails sicherstellen.
  • Operator (DBA-Team) anlegen: In msdb einen Operator anlegen (z. B. „DBA_Operator“ mit E-Mail der On-Call-Gruppe). So können Jobs und Alerts zentral an diesen Operator melden. In Wartungsjobs kann man am Ende bei Erfolg/Misserfolg Mails an den Operator schicken lassen (SQL Agent Job Properties: Notifications).
  • SQL Agent Alerts für Fehler: Über sp_add_alert lassen sich alarmierende Ereignisse definieren. Empfohlen ist, Alerts für Fehler mit Schweregrad 17–25 einzurichten – diese decken von kritischen Ressourcenschwächen bis schweren DB-Korruptionen alles ab. Insbesondere Severity 19–25 sind die „fatal errors“ (z. B. 823/824 already in severity 24). Man kann pro Schweregrad einen Alert definieren oder gezielt pro Fehlernummer: Die Fehler 823, 824, 825 (siehe Integritätsprüfung) sollten unbedingt einen sofortigen Alert (E-Mail oder sogar Pager/SMS) auslösen, da sie auf IO-Probleme hinweisen, die zu Korruption führen oder diese bereits bedeuten. Andere nützliche Alerts: Error 829 (degraded IO), 832 (Torn Page), 833 (IO-Überschreitung). Auch Datenbankzustand kann man überwachen: z. B. via WMI-Alert auf „DATABASE MIRRORING STATE CHANGE“ (für AG-Failover-Benachrichtigung) oder auf „LOB — log backup overdue“ (dafür gibt es keinen direkten Event, hier besser ein Job, siehe unten).
  • Warnung bei ausbleibenden Backups: Es gibt keinen eingebauten Alert „seit X Minuten kein Log-Backup“. Man kann aber mit einem regelmäßigen Agent-Job diese Bedingung prüfen, etwa alle 10 Minuten: IF DATEDIFF(minute, MAX(last_log_backup_time), GETDATE()) > Schwellwert THEN RAISERROR(…) um einen Fehler auszulösen, oder gleich per sp_send_dbmail eine Mail verschicken. Solche benutzerdefinierten Prüf-Jobs sind Gold wert, um etwa mitzubekommen, wenn der Backup-Job mal hängt oder jemand versehentlich das Recovery Model auf Simple setzte.
  • Health-Checks: Über die reaktiven Alerts hinaus empfiehlt es sich, tägliche Prüfberichte zu automatisieren. Ein morgendlicher „DB Health Report“ per E-Mail (ggf. als HTML-Tabelle) kann KPIs zeigen: letzte Backupzeiten, letzter CheckDB, Fragmentierungslevel, Speicher-/CPU-Auslastung etc. (siehe Kapitel Monitoring). Dieser wird idealerweise von einem dedizierten Überwachungsjob generiert. So hat man jederzeit Schwarz auf Weiß, dass die Wartung erfolgreich war oder wo nachjustiert werden muss.

Zusammenspiel und Wartung: Die Einrichtung dieser Telemetrie gehört zu den ersten Schritten, wenn man eine Instanz produktiv nimmt. In den Wartungsplan aufgenommen werden sollte, diese Mechanismen regelmäßig zu testen (z. B. einmal pro Quartal: Test-Alert auslösen, kommt Mail durch? Operator aktuell?) und Änderungen zu dokumentieren. Nichts ist schlimmer, als ein Alert-System, das still defekt ist und man bemerkt es erst beim versäumten Notfall.

Die folgende Tabelle fasst die Wartungsaktionen zusammen, mit Zweck, empfohlener Frequenz, wichtigen Parametern, typischer Ressourcenbelastung, Risiken und Erfolgskennzahlen:

Aktion

Zweck

Empfohlene Frequenz

Wichtige Parameter/Optionen

IO-/CPU-Impact

Log-Impact

Risiken/Nebenwirkungen

Erfolgskriterien (KPI)

Monitoring/Alerts

Integritätsprüfung <br> (DBCC CHECKDB)

Prüft Datenbank auf physische & logische Konsistenz, frühzeitiges Erkennen von Korruption.

Vollständiger Check je nach Größe wöchentlich, bei kleineren DBs täglich; dazwischen ggf. PHYSICAL_ONLY Checks.

WITH NO_INFOMSGS, ALL_ERRORMSGS; <br> Option: PHYSICAL_ONLY (schneller, nur physisch); <br> Auslagerung auf Read-Only Secondary oder Restore-Kopie.

Sehr hohe IO-Last (liest gesamte DB); <br> hohe CPU bei Prüfsummenprüfung.

Minimaler Log-Verbrauch (nur geringe Transaktion für Snapshot).

Hohe Laufzeit bei großen DBs; <br> evtl. TempDB-Belastung; <br> bei Fehlerfund Alarmstufe rot – potenzieller Datenverlust.

Letzter erfolgreicher CHECKDB < 7 Tage; <br> suspect_pages Tabelle leer (0 Einträge).

Alert bei Fehler 823/824/825; <br> Alarm, wenn CHECKDB länger nicht lief; <br> Job-Failure E-Mail an DBA.

Vollsicherung <br> (Full Backup)

Komplettes Backup der DB für restore, bildet Basis der Backup-Kette.

Täglich (bei <=100GB) oder wöchentlich (große DBs), typ. nachts.

WITH COMPRESSION, CHECKSUM; <br> evtl. ENCRYPTION = AES256; <br> auf getrenntes Volume schreiben; <br> COPY_ONLY für außerplanmäßige Backups.

Hohe Read-IO Last (seq. Scan aller Daten); <br> moderate CPU (Komprimierung).

Log: normaler Checkpoint zu Start, ansonsten kein Einfluss (im Full Recovery weiter laufende Log-Kette bleibt erhalten).

Backup kann lange dauern (Backupfenster einplanen); <br> benötigt genügend Speicherplatz; <br> potenziell Performance-Impact auf laufende DB (I/O Wettbewerb).

Dauer des Backups; <br> Backup-Größe (Soll: ~Datenbankgröße); <br> Vollständigkeit (kein Abbruch).

Alert bei Backup-Job-Fehler; <br> Alarm wenn kein frisches Full > SLA (z.B. > 7 Tage); <br> Backup Verification Job.

Differential Backup

Backup nur der seit dem letzten Full veränderten Extents, beschleunigt Restore kombiniert mit Full.

Täglich/mehrmals wöchentlich zwischen Fulls (z. B. jede Nacht außer Sonntag).

WITH COMPRESSION, CHECKSUM; <br> erfordert existierendes Full; <br> idealerweise nicht zu lange Kette (Full max. 1 Woche alt).

Mäßige IO Last (nur geänderte Extents); <br> schneller als Full.

Log: kein direkter Effekt (wie Full).

Größe wächst mit Abstand zum Full (Beobachten, ggf. Full-Zyklus verkürzen); <br> diff unwirksam, falls zwischenzeitlich Full (ohne copy_only) gemacht wurde.

Differenzial-Größe (Soll: << Full-Größe); <br> Zeit seit letztem Full.

Alert wenn Full älter als geplant; <br> Monitoring der Diff-Größen als Trend (ungewöhnlicher Anstieg?).

Transaktionslog-Backup

Sichert Transaktionslog für Point-in-Time Recovery, verhindert Log-Überlauf.

Sehr häufig – je nach RPO: 15 Min, 30 Min, max. 1 Stunde; <br> im Bulk-Logged Modus auch nach Bulk-Ops sofort.

BACKUP LOG … TO DISK = …; <br> WITH COMPRESSION, CHECKSUM; <br> Einrichtung als wiederkehrender Agent-Job (häufiger Schedule).

Geringe IO (nur Log-Blöcke seit letztem Backup); <br> sehr schnell, kaum CPU.

Trunkiert das Log (bei Full/Bulk); <br> im Simple RM nicht anwendbar.

Wenn ausbleibend: Log wächst endlos -> Gefahr von vollem Datenträger; <br> zu selten: höherer Datenverlust im Fehlerfall.

Zeit seit letztem Log-Backup (Soll: < RPO); <br> Log-Dateigröße stabil (kein ungeplantes Wachstum).

Alert wenn X Minuten kein Log-Backup (Job ausgefallen?); <br> Überwachung Logfüllstand (% genutzt).

Index Rebuild

Behebt Fragmentierung vollständig durch Neuaufbau; verbessert Leseperformance, aktualisiert Statistiken.

Wöchentlich bis monatlich je nach Fragmentierungsgrad; <br> gezielt für stark fragmentierte Indexe (>30%).

ALTER INDEX … REBUILD [ONLINE] [SORT_IN_TEMPDB] [MAXDOP=n] [FILLFACTOR=x]; <br> parallel oder nachts ausführen.

Sehr hohe IO (liest und schreibt gesamten Index neu); <br> hohe CPU bei Sortierung (parallel nutzbar).

Voll protokolliert (Full RM) -> großer Logeintrag; <br> eine lange Transaktion.

Sperrt Tabelle (Offline) oder reduziert Performance (Online) während Laufzeit; <br> hohe Log-Auslastung kann Replication/AG stressen; <br> diff. Backups danach groß.

Fragmentierung nach Rebuild ~0%; <br> verbesserte Scan- und Suchzeiten; <br> weniger Page-Splits nach FILLFACTOR-Anpassung.

Alert falls Index > X% fragmentiert bleibt (Report); <br> Monitor Logdisk während Rebuild (Platzwarnung).

Index Reorganize

Defragmentiert Index-Seiten in kleinen Schritten (Leaf-Level), online.

Wöchentlich (bei mittlerer Fragmentierung 5–30%); <br> ggf. häufiger für stark volatile Tabellen.

ALTER INDEX … REORGANIZE; <br> ggf. kombiniert mit LOB_COMPACTION = ON (Standard) um LOB-Seiten aufzuräumen.

Moderat hohe IO, aber verteilt (viele kleine Transaktionen); <br> CPU gering bis moderat.

Niedriger Log pro Transaktion, aber viele kleine Commits gesamt.

Wirkt bei hoher Fragmentierung unzureichend; <br> lässt Stats unverändert (veraltete Stats!); <br> kann lange laufen, wenn viele kleine Schritte.

Fragmentierung deutlich reduziert (aber evtl. nicht 0%); <br> keine langen Tabellen-Locks (online durchgeführt).

KPI: % Indexe >30% frag. vor/nachher; <br> Laufzeit im erwarteten Rahmen. <br> Monitor: evtl. Zahl der Transaktionen während Reorg hoch.

Statistiken aktualisieren

Aktualisiert Verteilungsstatistiken für Optimizer, bessere Query-Performance.

Wöchentlich (mit Indexwartung) oder täglich bei viel DML; <br> mind. nach größeren Datenimporten.

UPDATE STATISTICS Table (Index/Col) [WITH FULLSCAN]; <br> oder EXEC sp_updatestats (schneller, Sample-basiert); <br> Auto-Update-Stats am besten enabled lassen (für Zwischenzeit).

IO abhängig von Sample (Fullscan = liest gesamte Tabelle); <br> CPU moderat (Histogrammberechnung).

Wenig Log (nur Statistik-Blob update protokolliert).

Kann Recompile-Sturm auslösen (alle Pläne invalidiert) – meist gewollt/kurzzeitig; <br> bei riesigen Tabellen Fullscan zeitaufwändig.

Aktualitätsindikator: STATS_DATE für wichtige Indexe aktuell (< X Tage); <br> stabile Abfragepläne (weniger extreme Abweichungen Ist vs. Estimate).

Monitoring schwierig (indirekt über Performance); <br> Alert, wenn z. B. Auto-Update-Stats sehr häufig triggert (Hinweis auf notwendiges manuelles Update).

Backup/Cleanup <br> (Datei- & Verlaufs-Bereinigung)

Löscht alte Backup-Dateien und veraltete Verlaufsdaten aus msdb, um Speicher und Performance zu erhalten.

Täglich (Dateien löschen, Agent-Log), wöchentlich/monatlich (msdb History purgen) nach Backups.

EXEC xp_delete_file(…) für Dateien; <br> sp_delete_backuphistory(@Datum); <br> sp_purge_jobhistory; <br> Einstellen Agent-History Limits.

IO: Datei-Löschvorgänge (gering); <br> msdb Operationen (Index auf Verlauftabellen, meist ok).

Log: minimal (Löschtransaktionen in msdb).

Falsche Filter könnten zu viel löschen (Aufbewahrungsfrist beachten!); <br> msdb Locking bei massenhaft History delete (ggf. in Batches löschen).

Backup-Share nie > X% voll; <br> msdb Backupset-Eintrage überschaubar (<100k Einträge); <br> Agent History aktuell.

Alert wenn Speicherplatz für Backups knapp wird; <br> ggf. Alarm wenn Cleanup-Job fehlschlägt (z.B. Datei in Use).

TempDB Wartung

Optimiert TempDB für Performance: ausreichend Dateien, korrektes Wachstum, Bereinigung.

Überprüfung nach Bedarf (z. B. bei Neustart oder jährlich); <br> Monitoring kontinuierlich.

Dateianz. = min(Anzahl vCPU, max 8); <br> gleiche Größen & Growth (IFI aktivieren); <br> Traceflags (1117,1118) falls <2016.

Entfällt (Konfiguration); <br> Laufende TempDB-Nutzung überwachen.

Entfällt

Unterkonfigurierte TempDB führt zu Latenz (PFS Latch, etc.); <br> zu kleine Dateien -> viele Autogrowths (VLF/Frag in TempDB).

TempDB weist keine Engpässe auf (Latch Waits gering, < 5% der Gesamtwartezeit); <br> selten Autogrowth-Ereignisse im Log.

Performance-Alerts (Latch-Waits, TempDB voll >80%); <br> Alert bei TempDB-Autogrowth (um reagieren zu können).

Datei-Management & Log <br> (Autogrowth, kein Shrink)

Hält Daten- und Logdateien auf optimalem Level, verhindert zu viele VLFs, vermeidet Fragmentierung durch Shrink.

Kontinuierlich (Policies), vierteljährlich Review der Einstellungen.

Autogrowth in sinnvollen Schritten (statt 1MB/10% Default); <br> initial ausreichend Größe vergeben; <br> kein AutoShrink.

Weniger Autogrowth = weniger IO-Ereignisse zur Laufzeit.

Weniger Log-Autogrowth = stabilere VLF-Struktur; <br> geplante Größe = planbarer Log-Speicher.

Zu kleine Logfiles -> häufiges Wachsen -> viele VLFs -> langsamer Restore/Recovery. <br> Shrink => massive Index-Fragmentierung.

VLF-Anzahl < 1000; <br> Keine regelmäßigen Shrinks im Log; <br> DB File frei% angemessen (nicht >30% dauerhaft ungenutzt).

Alert wenn Autogrowth > X mal pro Tag auftritt; <br> Hinweis in Report bei VLF > Schwelle (z. B. >1000).

Alerts & DB-Mail

Automatische Benachrichtigung bei kritischen Ereignissen (Errors, fehlende Backups), damit sofortiges Eingreifen möglich.

Einmal einrichten; <br> täglich Verfügbarkeit prüfen (Mail-Session ok).

sp_add_alert für Error 823/824/825, Sev 19-25; <br> Operator mit E-Mail; <br> sp_add_notification (Alert->Operator Mapping); <br> WMI Alerts für AG Failover etc.

Kaum Impact (Event Notifications).

Kein Log-Eintrag, außer wenn Alerts Logwrites triggern.

Risiko: False Positives können zu Alarmmüdigkeit führen; <br> falls Mailserver ausfällt, keine Alerts sichtbar.

Jährlicher Test der Alerts (sicherstellen, dass E-Mails ankommen); <br> Metrik: Reaktionszeit auf Alerts (Ziel: < 15 Min).

Heartbeat-Alert (Testmail täglich an Operator); <br> ggf. SNMP/Monitoring-System Kopplung für kritische Fehler.

(Tabelle: Wichtige Wartungsaktionen – Parameter & Wirkung)

Ausführungsreihenfolgen (Wartungs-Pipelines)

Die Reihenfolge, in der Wartungsjobs ablaufen, beeinflusst Effizienz und Zuverlässigkeit erheblich. Im Folgenden werden mehrere Wartungs-Pipelines – also typische Abfolgen von Wartungsaktionen – vorgestellt, jeweils mit Zeitplan, Anwendungsfall sowie Pro und Contra.

Pipeline A: Klassischer täglicher Ablauf

Beschreibung: Pipeline A ist ein bewährter Standardablauf für tägliche Wartung in Produktionsdatenbanken. Sie eignet sich für Einzel-Instanzen und kleinere Always On-Setups, bei denen die Wartung problemlos nachts auf dem Primärserver laufen kann. Wesentliche Merkmale: Integritätschecks und Optimierungen laufen vor dem Full-Backup, sodass das Backup den „aufgeräumten“ Stand sichert. Log-Backups laufen parallel kontinuierlich.

Ablauf & Zeitplan: (Beispiel: tägliches Wartungsfenster 01:00–04:00 Uhr)

Zeit (Start)

Dauer (ca.)

Aufgabe

Parallelität

Abhängigkeit

Hinweis

00:00 Uhr

kontinuierlich (tagsüber)

Transaktionslog-Backups (alle 15 Min)

seriell (je DB)

Läuft ständig, gering belastend.

01:00 Uhr

60 Min

Integritätsprüfung (CHECKDB)

je DB sequentiell; mehrere DBs nacheinander (falls Zeit reicht parallel auf getrennten Servern)

Log-Backups laufen weiter

Evtl. auf Sekundärserver ausgelagert, falls DB groß.

02:00 Uhr

90 Min

Indexpflege (Rebuild/Reorganize)

parallel pro DB (limitierte MAXDOP)

Nach erfolgreichem CHECKDB

Verwendet Fragmentierungsschwellen; Online-Rebuild wenn 24/7 nötig.

03:30 Uhr

15 Min

Statistiken aktualisieren

sequentiell (pro DB)

Nach Indexpflege

Nur Tabellen mit Reorg (nicht Rebuild) updaten.

03:45 Uhr

30 Min

Voll-Backup aller Datenbanken

kann parallel auf DB-Ebene (bei getrennten Platten)

Nach Index/Stats (Daten unverändert seitdem außer Reorg)

Nutzung von Komprimierung für Speed; Checksummen an.

04:15 Uhr

10 Min

Cleanup (Backup-History, Dateien)

seriell

Nach Backup (Backup-Datei final)

Löscht z. B. .bak/.trn > 14 Tage, trunc. msdb-Historie.

04:30 Uhr

läuft nach

Verify/Test Restore (optional auf Sekundär)

Nach Backup fertig, läuft außerhalb des Prod-Fensters

Restore Verifyonly auf Backupfile oder vollständiger Test-Restore auf zweiter Instanz.

(Tabelle: Zeitplan Pipeline A – täglicher Ablauf)

Geeignete Einsatzszenarien: Pipeline A passt für viele Standard-Workloads, bei denen ein nächtliches Wartungsfenster von einigen Stunden verfügbar ist. Typischerweise: – Einzelserver oder synchrones Duo (AG/Cluster) mit moderatem Datenvolumen (bis einige hundert GB), wo alle Wartungsschritte täglich ausgeführt werden können. – Environments, in denen daily full backups und frequent log backups machbar sind, und eine tägliche CheckDB auf dem Primärsystem das Tagesgeschäft nicht beeinträchtigt (ggf. weil tagsüber genügend Leerlauf besteht oder nachts genug Zeit). – Auch in VM- oder Cloud-VM-Deployments nutzbar, solange I/O-Throughput für den nächtlichen Batch ausreicht. Diese Pipeline ist einfach zu implementieren und zu überwachen.

Vorteile der Pipeline A:Umfassend und Sicher: Alle wichtigen Wartungsschritte erfolgen täglich, was ein hohes Maß an Sicherheit bietet (täglicher Integritätscheck, tägliche defragmentierte Zustände). – Backup enthält optimierten Stand: Durch Indexpflege vor dem Full-Backup sind die Backups inhaltlich „sauber“ (im Sinne von fragmentationsbereinigt) und Differenzialsicherungen bleiben klein, da kurz nach Rebuild ein Full gemacht wird. – Problemerkennung zeitnah: CheckDB vor Backup bedeutet, falls Korruption entdeckt wird, macht man evtl. kein überschreibendes Backup, sondern kann zuerst analysieren. (Würde man erst sichern und dann Check laufen, hätte man evtl. ein Backup einer bereits beschädigten DB.) – Einfache Logik: Abhängigkeiten sind klar: es gibt ein definiertes Fenster, in dem Sequenz abläuft. Wenig komplexe Koordination nötig, da alles auf dem gleichen Server abläuft.

Nachteile / mögliche Probleme:Langes Wartungsfenster nötig: Alle Aktionen nacheinander können Stunden dauern. Bei sehr großen DBs (> 1 TB) ist das ggf. nicht in jeder Nacht machbar. CheckDB z. B. könnte 5 Stunden dauern – dann passt Pipeline A evtl. nicht mehr komplett in eine Nacht. – Hohe Last-Spitzen: Wenn Index-Rebuilds, Stats und Backup unmittelbar nacheinander laufen, ist das Storage-System massiv gefordert (viel Lesen/Schreiben am Stück). Das kann die Hardware an Grenzen bringen oder gar zu Überlappungen ins Morgen-Geschäft führen, falls Überziehung. – Keine Entzerrung: Tägliche Ausführung heißt auch täglich potenzielle Störung (wenn auch nachts). Manche Systeme könnten effizienter laufen, wenn nicht jeden Tag z. B. alle Indizes rebuilt werden, obwohl kaum geändert (unnötige Schreiblast). – AG-Umgebung Potential ungenutzt: In einer AlwaysOn AG mit Secondaries könnte man Backups oder CheckDBs auslagern. Pipeline A nutzt aber hauptsächlich den Primär. Das ist einfach, aber verschenkt Möglichkeiten Last zu verteilen.

Besondere Hinweise: – Reihenfolge-Falle: Sicherstellen, dass die Full-Sicherung wirklich nach der Indexwartung erfolgt. Würde man zuerst das Backup machen (siehe Pipeline B), dann Indizes neu aufbauen, würde das nächste Differential sehr groß. Bei Pipeline A ist alles konsistent. – Maxdop und Parallelität: Im Plan ist vermerkt „parallel pro DB“ – besser nicht innerhalb derselben DB gleichzeitig Rebuild und Backup fahren, das würde sich stören. Aber man kann z. B. Indizes von DB1 rebuilden, während parallel DB2 schon gebackt wird, wenn getrennte Ressourcen vorhanden und Tests dies zulassen. – CheckDB isoliert halten: Wenn möglich, CheckDB auf einem anderen Server (mit restored Backup) laufen lassen, um Prod-IO zu entlasten. Aber Pipeline A zeigt den Fall „gleich auf Primär“ – hier ist unbedingt auf ausreichend Fesplatten-IO zu achten. Ggf. MAXDOP für CheckDB limitieren, falls es sonst die Nutzer-Queries behindert (CheckDB versucht nämlich intern parallele Ausführung je nach Tabellenzahl). – Log-Backup Overlap: Während CheckDB oder Rebuild läuft, gehen weiter Log-Backups – das ist gut, aber bedenken: ein riesiger Rebuild-Log-Eintrag wird evtl. erst beim Commit komplett ins Log geschrieben. Der Log-Backup danach könnte ungewöhnlich groß werden oder länger dauern. Diese Kette muss robust sein und Diskplatz für solche Peaks vorhanden sein.

Fazit Pipeline A: Der klassische Ablauf ist leicht verständlich und gut für verlässliche Tagesrhythmen. Er garantiert, dass zumindest einmal täglich alles Wichtige erledigt ist. Für viele kleine bis mittlere SQL-Server ist dies der empfohlene Default.

Pipeline B: Backup-zuerst-Strategie

Beschreibung: Pipeline B kehrt die Reihenfolge von Pipeline A teilweise um: Hier wird zuerst ein Backup erstellt, bevor zeitaufwändige Optimierungen starten. Das Ziel ist, das Backup-Fenster zu isolieren und möglichst früh eine sichere Kopie zu haben. Die Idee: Falls nachfolgend etwas schiefläuft (z. B. ein Reindex-Prozess bringt den Server zum Absturz), hat man zumindest ein frisches Backup vom Status davor.

Ablauf & Zeitplan: (Beispiel: gleiches Fenster 01:00–04:00)

Zeit (Start)

Dauer

Aufgabe

Anmerkungen

01:00 Uhr

~30 Min

Voll-Backup zuerst

Schnell abgeschlossen, DB noch fragmentiert (vom Vortag).

01:30 Uhr

60–90 Min

Integritätsprüfung

CHECKDB anschließend (könnte theoretisch vor Backup laufen, aber hier mal danach).

02:30 Uhr

90 Min

Indexpflege

Rebuild/Reorg; viele Änderungen nach Backup.

04:00 Uhr

15 Min

Statistiken

Stats-Update falls nötig.

(optional)

+X

Differential-Backup am Morgen

Könnte gegen 05:00 eine Diff-Sicherung ziehen, um alle Reorg-Änderungen einzufangen.

Szenarien: Pipeline B wird genutzt, wenn Backup-Zeitpunkt kritisch ist: z. B. man will unbedingt um 01:30 ein Backup offsite kopieren, egal ob die Indexpflege fertig ist. Auch wenn das Wartungsfenster sehr knapp bemessen ist, sichert man vielleicht lieber zuerst und lässt Wartungsjobs, die nicht fertig werden, zur Not abbrechen oder am nächsten Tag fortsetzen. In Systemen, wo Backup-Größe wichtiger ist als maximal defragmentierte Daten im Backup (z. B. wenn Reindex eh fast alles ändert, könnte man überlegen Backup erst zu machen, bevor Reindex anschwillt – aber eigentlich macht es Backup eher kleiner, wenn man vor Reindex sichert, da das Reindex-Delta dann in nachfolgenden Differentials/Logs landet).

Vorteile:Frühe Datensicherung: Das Backup-first-Prinzip minimiert das Risiko, ungesicherte Änderungen zu haben. Um 01:30 hat man bereits ein vollständiges Backup vom Tagesendstand. Falls Indexpflege das System belastet oder scheitert, ist zumindest die Datensicherung im Kasten. – Kürzeres Backup-Fenster separat: Das Full Backup wird gezogen, während DB noch in „Tagesform“ ist (vielleicht fragmentiert, aber das stört die Sicherung an sich nicht). Es ist schneller abgeschlossen (kein Overhead durch laufende Rebuilds parallel). – Flexibilität bei Wartungsrest: Wenn Indexpflege ausfällt (z. B. Job disabled für einen Tag wegen hoher Last im Geschäft), hat man trotzdem ein aktuelles Backup – RPO bleibt erfüllt.

Nachteile:Differential Backups wachsen: Größter Nachteil: Alle nach dem Full-Backup durchgeführten Rebuilds und Reorgs ändern sehr viele Seiten. Solange bis zum nächsten Full werden Differential-Backups (oder das nächste Full selbst, wenn man doch täglich Full macht) deutlich größer sein. Beispiel: Full um 01:00, dann um 03:00 Rebuild – die nächsten Diffs (bis zum nächsten Full) enthalten fast die gesamte DB. Das kann Backup-Speicher belasten und im Restore-Fall unnötig aufblähen. – Längere Log-Kette bis Full: Wenn man nur wöchentlich Full macht, erzeugt Pipeline B eine längere Kette: Full (So) -> Woche lang Diff/Logs -> Reindex am Fr nach Diff -> nächstes Full erst So. Sollte man zwischendrin Recovery brauchen, muss man Full + diff Fr + alle Log bis Crash einspielen. Hier wäre Pipeline A mit Full nach Reindex = Full Fr Nacht, dann Logs -> Crash, etwas weniger Kettenglieder. Allerdings ist das nicht kriegsentscheidend, solange alle Teile da sind. – Integritätscheck nach Backup: Findet CheckDB Fehler, hat man gerade ein Backup einer vielleicht schon korrupten DB erstellt. Das ist das umgekehrte Problem von Pipeline A. Pipeline B könnte man aber adjustieren: man könnte CheckDB vor dem Backup laufen lassen (Mitternacht), dann Backup, dann Reindex. Dann hätte man wiederum Checkdb->Backup->Reindex. Das hätte Vorteile von beiden, aber erfordert das Backup etwas zu verschieben. Hier nehmen wir aber striktes Backup first an. – Daten im Backup unoptimiert: Das Backup enthält die DB vor Indexpflege, also fragmentierter. Das hat eigentlich nur geringe Relevanz (nach Restore müsste man halt Indexpflege nachholen für Performance), aber an sich sind Daten vollständig. Manche DBAs bevorzugen Backups nach Reindex, um im Desaster-Fall gleich optimalen Zustand zu haben.

Hinweise: Pipeline B zeigt, dass man je nach Priorität (Backup vs. Maintenance) umsortieren kann. Wenn man diesen Weg wählt, kann ein Kompromiss sein: – Reindex seltener (z. B. wöchentlich), aber Backup daily. Dann hat man nur einmal pro Woche das Problem größerer Diffs. – Alternativ nach Reindex eine zusätzliche Diff oder sogar ein zweites Full ziehen: Z.B. Full um 01:00, Reindex um 02:00–04:00, nochmal Diff um 05:00. Damit hätte man ein „inkrementelles Full“. Das ist aber Overkill, außer man hat wirklich Grund. – Wichtig: LSN-Kette beachten – wenn man zwischen Full und dem wöchentlichen Full plötzlich aus Not doch ein Full zieht (ohne copy_only), setzt man die Kette neu. Im Worst-Case machen solche Ad-hoc-Backups den Plan durcheinander. Daher diszipliniert bleiben: definieren wann Fulls sind.

Fazit Pipeline B: geeignet für Situationen, wo Datensicherung strikt vor Optimierung kommen soll, z. B. bei sehr sensiblen Daten, wo man keinerlei Risiko eingehen will, erst nach Wartungsjobs zu sichern. Es ist ein Trade-off zwischen Sicherungsstrategie und nachfolgender Maintenancelast. Für sehr große DBs, wo Rebuilds nur wöchentlich gemacht werden, aber daily Fulls nötig sind, ist Pipeline B oft Realität: man sichert täglich, aber die Indizes pflegt man vielleicht am Wochenende. In diesem Sinne ist Pipeline B eine Variante, keine absolute Empfehlung – viele Umgebungen fahren aber implizit so (Backup nightly, Maint jobs weekly).

Pipeline C: Integritätscheck auf zweiter Instanz

Beschreibung: Pipeline C entlastet die Primärumgebung, indem die Integritätsprüfung (CHECKDB) auf eine separate Instanz ausgelagert wird. Diese Pipeline eignet sich für große oder 24/7-Systeme, bei denen CheckDB auf dem Primärserver zu lange dauern oder die Performance beeinträchtigen würde. Die Idee: Jede Nacht (oder wöchentlich) wird ein Backup der Produktionsdatenbank auf einen zweiten Server (oder zweite Instanz) wiederhergestellt, und dort läuft dann DBCC CHECKDB. Alle anderen Wartungsjobs können währenddessen auf dem Primärsystem laufen, ohne die schwere Last von CheckDB.

Ablauf & Zeitplan: (Beispiel: 2 Server: Primär = PROD, Sekundär = MAINT)

Zeit

Aufgabe auf Primär

Aufgabe auf Sekundär (Maint-Server)

00:00 Uhr

(fortlaufend: Log-Backups wie üblich)

– (wartet auf Backup)

01:00 Uhr

Full-Backup der Prod-DB

01:30 Uhr

Restore der Full-Backup in Test-DB (mit NORECOVERY + UNDO, dann RECOVERY)

02:30 Uhr

Indexpflege, Stats etc. auf Prod

DBCC CHECKDB auf der wiederhergestellten DB

04:00 Uhr

Diff-Backup (optional, falls Full nur wöchentlich)

04:00 Uhr

Cleanup (Prod: History, Dateien)

Drop Test-DB, Cleanup Maint-Server (alte Restores löschen)

(Während Sekundär checkt, kann Primär weiter Maint Jobs machen.)

Vorteile:Minimale Belastung auf Prod: Der Primärserver muss das Backup erstellen (nur lesend) – das ist in der Regel leichter zu verkraften als ein volles CheckDB. Die ressourcenintensive Konsistenzprüfung läuft komplett auf dem Zweitserver. Prod-Nutzer merken davon nichts. – CheckDB parallel zu Indexpflege: Beide können gleichzeitig stattfinden, da auf unterschiedlichen Servern. Das verkürzt das gesamte Wartungsfenster erheblich. Prod-Index-Rebuilds 02:30–04:00 und Sekundär-CheckDB 02:30–04:00 stören sich nicht. – Zusätzliche Verifikation: Der Restore-Vorgang selbst ist schon ein Integritätscheck (Backup lässt sich zurückspielen = grundlegende Konsistenz ok). Kombiniert mit dem nachfolgenden CHECKDB hat man doppelte Sicherheit. Außerdem testet man so täglich seine Backups (sollte der Restore scheitern, erfährt man es sofort). – Entkopplung vom Prod-Storage: Falls Prod-Storage latent Fehler hat, man aber den Backup auf anderem Storage (Tape/Cloud) hält und auf anderer Hardware restored, könnte CheckDB dort Fehler aufdecken, die Prod-CheckDB vielleicht gar nicht gesehen hätte? (Eher unwahrscheinlich, aber zumindest reduziert man Prod-Storage-Stress).

Nachteile:Verzögerte Erkenntnis über Prod-I/O-Probleme: Paul Randal (SQLSkills) betont: Nur weil Secondary-CheckDB sauber ist, heißt das nicht, dass Prod nicht evtl. ein Problem hat (z. B. defekte Disk-Sektor, der bislang nur Prod betrifft). Wenn Prod-Storage ein Problem hat, würde aber früher oder später auch das Backup davon betroffen sein. Dennoch: Falls z. B. um 10:00 Uhr ein Korruptionsfehler in Prod auftaucht, würde man es erst merken, wenn in der Nacht der Backup+Restore+Check läuft, sofern kein Prod-CheckDB aktiv. Daher ist Monitoring der Errorlogs/Alerts umso wichtiger (Error 823/824 im Prod-Log sollte sofort Alarm schlagen). – Mehr Hardware/Storage nötig: Man braucht genügend Platz auf dem Sekundärserver, um die DB zwischenzulagern und zu prüfen. Und die Hardware dort muss leistungsfähig genug sein, sonst dauert es ewig oder man bekommt womöglich nicht denselben Durchsatz an Checksummen-Berechnung (kann aber längere Laufzeit dort oft verschmerzen). – Lizenzierung: Der zweite Server benötigt eine SQL-Lizenz, außer es ist eine dedizierte nicht-produktive Umgebung, die lizenziert entsprechend abgedeckt ist (Lizenztechnisch ist ein separater CheckDB-Server oft durch Dev/Test-Lizenzen zu regeln, aber muss bedacht werden). – Komplexität des Prozesses: Das Skript, das Backups rüberkopiert, wiederherstellt, CheckDB ausführt, ggf. Fehler meldet und aufräumt, ist deutlich komplexer als ein simpler CheckDB-Job auf Prod. Hier muss Logging und Fehlerhandhabung gut gebaut sein (z. B. wenn Restore 5 Std statt 1 Std dauert, darf CheckDB nicht zu früh starten etc.). Tools wie DBATools können diesen Prozess erleichtern (Cmdlets für Copy/Restore/Check).

Einsatzszenario: Diese Pipeline ist ideal für sehr große Datenbanken (einige TB), wo CheckDB auf Prod eventuell > 8 Stunden bräuchte, was nicht täglich geht. Auch bei AG mit asynchronen Replikas: Man könnte anstelle einer extra Instanz auch einen asynchronen Secondary nutzen, um dort per Snapshot (nur in readonly secondaries per CHECKDB WITH TABLOCK oder indem man DB in read-write Kopie kurz nimmt – unschön) die Checks zu machen. Allerdings Microsoft empfiehlt Check auf allen Replikas, was overhead wäre. Realistischer ist aber: Prod-Check selten, stattdessen Offload zum anderen Standby.

Pro-Tipp: Oft macht man diesen Check z. B. nur wöchentlich offloaded, und an restlichen Tagen gar kein CheckDB oder nur physical_only auf Prod. So spart man jede Menge Ressourcen, hat aber wöchentlich vollen Check.

Fazit Pipeline C: Sie ermöglicht Wartung für große Systeme, die anders nicht täglich konsistent prüfbar wären. Wichtig ist aber, trotz Offload, Prod im Auge zu behalten (via Alerts) und die Offload-Prozesse gut im Griff zu haben (Monitoring, dass diese erfolgreich laufen). So hat man die Balance aus Datensicherheit und Performance.

Pipeline D: Always On (HA-Umgebungen)

Beschreibung: Pipeline D ist auf Umgebungen mit Always On Availability Groups (AG) oder ähnlicher HA/DR-Technologie (Log Shipping, Mirroring) zugeschnitten. Hier stellt sich die Frage, welche Wartungsjobs auf dem Primär-Replica vs. auf Sekundär-Replicas laufen sollen. Ziele: Produktionslast verteilen und dennoch konsistente Abläufe sicherstellen.

Grundprinzip: – Backups können in einer AG-Konfiguration auf sekundäre Replikate ausgelagert werden (Backup Preference „Prefer Secondary“ usw.), insbesondere Read-Only-Secondaries können Full und Log-Backups übernehmen, um die Primärdatenbank zu entlasten. – Indexpflege (Rebuild/Reorg) muss auf dem Primär passieren, da Secondaries nur lesend sind; Änderungen am Index propagieren über das Transaktionslog zu den Secondaries. – Integritätschecks können wie Pipeline C entweder auf Secondaries (die read-only Kopien) erfolgen oder auf dem Primär oder beides (Primär+Sekundär). – Job Schedules oft identisch auf allen Replikaten angelegt, aber via Bedingungen (sys.fn_hadr_is_primary_replica() in T-SQL) prüfen die Jobs, ob sie auf der richtigen Rolle laufen sollen.

Beispiel-Zeitplan: (AG mit 1 Primär, 1 Sync Secondary, 1 Async Secondary offsite)

Primär-Replica (Sync) – ausführen: Indexpflege, Stats, evtl. CheckDB:

  • Täglich 02:00 – Index Reorg/Rebuild (Primär)
  • Täglich 03:00 – Update Statistics (Primär)
  • Wöchentlich So 01:00 – Full Backup (falls Backups lieber doch am Primär z.B. wegen Offsite LSN)
  • Täglich – Short log-backup job? (hier nein, Secondary übernimmt)
  • Wöchentlich – CheckDB (Primär) z.B. Di 02:00

Bevorzugtes Sekundär-Replica (Async) – ausführen: Backups, CheckDB:

  • Täglich 02:00 – Full Backup (wenn Backup Preference=Secondary, dann hier Full, sonst CopyOnly)
  • Halbstündlich – Log Backups (Sekundär)
  • Wöchentlich Mi 01:00 – Differential Backup (wenn genutzt, sonst nur Full+Logs)
  • Wöchentlich Mi 02:00 – DBCC CHECKDB (read-only secondary erlaubt kein CheckDB außer Snapshot/TABLOCK, daher hier evtl. Restore Kopie nutzen analog Pipeline C, oder im Fall Async die DB fürs CheckDB kurz aufheben was aber nicht geht da AG-blocking…) => realistischer, CheckDB auf Async offline Kopie.

(Hinweis: In AG kann man kein vollständiges CheckDB auf reiner Secondary Replica machen, außer per Database Snapshot. Besser: Backup vom Secondary nehmen, auf einer separaten non-AG Instanz restoren und checken.)

Pro:Backup Offloading: Entlastet Primär, besonders bei Sync-Commit AG: anstatt dass Primär I/O für Backup verbrät, macht Secondary das. Gefahr dabei: bis SQL 2016 können Full Backups auf Secondary nur copy_only sein; neuere SQL (2017+) erlauben auch normal Full auf Secondary, jedoch Differential Backups auf Secondary sind weiterhin nicht unterstützt. Daher Standard: Full/Log auf Secondary mit copy_only Full wenn Diff im Einsatz, oder gemischte Strategie. – Keine Unterbrechung der Logkette: Mit richtigem Setup (Backup Preference und Konfiguration) wird die LSN-Kette fortlaufend gehalten auch wenn Secondary sichert. Man muss nur vermeiden, dass zwei Server unabhängig Logs sichern (das würde LSN-Kette splitten). Daher oft: nur ein Replica nimmt Logs (z.B. das Sync Secondary), es schickt diese Info auch ans Primary (AG synchronisiert LSN Fortschritt). – Index-Reorg/Rebuild auf Primär repliziert nur die Ergebnisse (Änderungen) – Secondaries wenden die Log-Einträge an, was etwas Last dort verursacht, aber insgesamt bekommt man fragmentierungsfreien Zustand auf allen Knoten, ohne jeden Knoten separat pflegen zu müssen. – AG-spezifische Wartung: Man kann Sekundär nutzen z. B. für Query Store Daten Aufräumen oder Stats-Updates falls read-intent, aber das geht meist nur read-only. – Im Failover-Fall sind identische Jobs auf allen Replikas sinnvoll (mit Role-Check), damit nach Failover die Backups etc. nahtlos auf neuer Primär weiterlaufen.

Con:Komplexität: Die Koordination wer sichert wann erfordert genaue Kenntnis. Wenn Backup-Preference „Secondary“ und kein Secondary verfügbar (z. B. offline für Wartung), springt Primary ein? Im AG-Verhalten ja, es kann, wenn so eingestellt. Trotzdem muss man Monitoring bauen, dass Backups wirklich laufen, egal auf welchem Knoten. – LSN-Ketten und CopyOnly: Wenn Full auf Secondary (copy_only) gemacht wird, muss weiterhin Primary Fulls für Diff-Basis machen – umständlich. Manche Organisationen lösen das mit nur Log on Secondary und Full immer Primary, oder neu in SQL 2017+: Allowed direct full on secondary? (Nein, es bleibt copy_only). Daher gemischte Ansätze: – Option 1: Alle Backups auf Primary (einfach, aber keine Offload). – Option 2: Full CopyOnly und Logs auf Secondary – dann hat man regelmäßige Fulls (zur Sicherheit), aber diffs entfallen (kann man nicht nutzen, weil Fulls copy_only). – Option 3: Wöchentlich Full auf Primary (für Diff-Basis), täglich Diff auf Primary, Logs auf Secondary (Prim geht Idle), aber Diff auf Primary heißt doch wieder Primär belasten. Oder – Option 4 (von Ola empfohlen): Full+Diff auf Primary, Logs auf Secondary (so entlastet man nur Logs). Dieser Kompromiss funktioniert gut für ab 2012 wo logs on secondary gehen. – Also trade-offs.

  • Synchronisation Overhead: Bei synchroner AG repliziert der Primär sofort alle Rebuild-Änderungen – das kann das transaktionale Workload verlangsamen während Wartung, weil Log Send Queue hochgeht und Wait auf ACK. Evtl. sekundär während Reindex auf Async schalten (geht aber nicht ohne Hiccups).
  • CheckDB Dilemma: Wie oben: ideal auf Secondaries, aber read-only DB checken heißt DBCC CHECKDB nutzt intern DB-Snapshot, der aber auf Secondary vermutlich geht (ein Snapshot auf Secondary read-only DB? Müsste möglich sein, da Snapshots auch von online DBs gehen). In Dokus heißt es: man kann auf Secondary (readable) DBCC CHECKDB ausführen, SQL erstellt einen hidden snapshot von der snapshot? Das wäre inception, aber ich glaube doch, es gehtnicht auf reinen Secondary, man muss entweder WaitForPartner… Oder einfach Backup/Restore Weg.
  • Paul Randal sagt, CheckDB auf Mirror (ähnlich Secondary) bringt nix über Primär aussagen. Besser auf jedem Replika nacheinander. Aber das ist heavy.

Geeignete Szenarien: – Hohe Verfügbarkeit mit Lastverteilung: z. B. ein Reporting Secondary (async) kann nutzen, um dort Backups laufen zu lassen, damit Primär entlastet und Reports unaffected, etc. – Große Unternehmensdatenbanken, bei denen 24/7-Betrieb wichtig ist – hier nutzt man die Secondaries um wenigstens Backups auszulagern, und ggf. Read-only Aktivitäten (auch Wartungsanalysen) dort laufen zu lassen.

Fazit Pipeline D: In AG-Setups sollte man Wartung so gestalten, dass man die Backup Preference berücksichtigt und keine Lücken oder Doppelungen entstehen. Primär auf primärer Replica: Indexpflege, Stats; auf bevorzugter Secondary: Backups. Integritätsprüfungen evtl. auf einem weniger kritischen Secondary oder per offloaded Restore. Das Minimiert den Einfluss auf den aktiven Knoten und nutzt die teure HA-Infrastruktur auch sinnvoll aus im Alltag. Wichtig: Darauf achten, dass die Backup- und Maintenanceskripte robust gegenüber Failover sind (d.h. Jobs existieren auf allen Knoten mit entsprechender Logik).

Pipeline E: Wöchentlicher Wartungszyklus (begrenztes Fenster)

Beschreibung: Pipeline E verteilt verschiedene Wartungsaufgaben gezielt auf die Wochentage, um begrenzte tägliche Wartungsfenster einzuhalten. Statt alles täglich zu tun, werden z. B. ressourcenintensive Tasks nur an bestimmten Tagen durchgeführt. Dies ist typisch in Umgebungen mit großen DBs oder knapper Wartungszeit, wo man z. B. nur am Wochenende längere Aufgaben fahren kann.

Beispiel-Wochenplan: (Bezugnehmend auf Vorgaben in der Aufgabenstellung)

Tag

Wartung (Nacht)

Hinweise

Montag

Differential-Backup; <br> Transaktionslog-Backups (kontinuierlich)

(Voll-Backup liegt vom Sonntag vor)

Dienstag

Differential-Backup; <br> Transaktionslog-Backups; <br> Integritätsprüfung (CHECKDB)

CheckDB z.B. 2x/Woche: Di & Fr.

Mittwoch

Differential-Backup; <br> Log-Backups; <br> Indexpflege (Reorg/Rebuild)

Indexwartung 2x/Woche: Mi & Sa.

Donnerstag

Differential-Backup; <br> Log-Backups

(Keine schweren Tasks am Do)

Freitag

Differential-Backup; <br> Log-Backups; <br> Integritätsprüfung (CHECKDB)

Zweiter CHECKDB-Termin der Woche.

Samstag

Differential-Backup; <br> Log-Backups; <br> Indexpflege (Reorg/Rebuild); <br> Stats Update (falls nötig)

Zweite Indexwartung (ggf. umfangreicher).

Sonntag

Voll-Backup (alle DB); <br> Transaktionslog-Backups; <br> (optional: Indexpflege, falls am Sonntag Tag Stillstand)

Sonntags Vollbackup, Reset Diff-Kette; ggf. zusätzliche Maint, weil längeres Fenster.

(Tabelle: Pipeline E Wochenplan – Wartungsaufgaben verteilt)

Einsatzszenario:Große Datenbanken, beschränktes tägliches Zeitfenster: z. B. man hat nur 2 Stunden pro Nacht, aber CheckDB alleine braucht 4 Stunden – daher CheckDB nur an 2 Tagen, verteilt. Indizes: sehr viele, Rebuild aller dauert 8 Stunden – also auf 2 Nächte aufgeteilt (evtl. mittwochs erste Hälfte der Tabellen, samstags zweite Hälfte). – Cluster/Limitierte Fenster: Environments, wo man wochentags kaum Downtime bekommt, aber am Wochenende länger. Hier macht man minimalinvasive Routine unter der Woche (nur Diff & Log, vielleicht Light Stats), und am Wochenende „Big Bang“ Wartung (Full, Rebuilds, CheckDB). – Performance vor Konsistenz im Alltag: Das heißt, man priorisiert, dass werktags das System ungestört ist, dafür nimmt man in Kauf, dass z. B. CheckDB nur wöchentlich passiert (kleines Risiko, Korruption evtl. später zu bemerken, aber das muss man steuern mit aggressivem Monitoring).

Pro:Kurze tägliche Unterbrechung: Der Großteil der Nächte (Mo,Do) hat nur rasche Diff & Log Backups, das stört kaum. Volle Last nur an ausgewählten Terminen. – Gezielte Ressourcennutzung: Schwere Arbeiten laufen, wenn Nutzerlast gering oder am Wochenende planbar. So kann man auf teure Hardware-Upgrades evtl. verzichten, weil man Spitzen zeitlich verlagert. – Planbarkeit: Jeder Tag hat festen Plan, Admins wissen: Mi/Sa könnte morgens Response etwas langsamer sein, weil Reorg lief (Cache-Bedarf etc.), Di/Fr CheckDB, also mehr IO in diesen Nächten.

Contra:Längere Intervalle zwischen Wartungen: Wenn CheckDB nur wöchentlich, bleibt eine etwaige Korruption evtl. 6 Tage unbemerkt – wenn in der Zwischenzeit alle Backups rotiert wurden, schlecht. Daher Rotationspläne an diese Frequenz anpassen (Backup länger aufbewahren). – Uneinheitlicher Zustand: Nach dem Mittwoch-Indexrebuild sind Indizes frisch, aber bis Samstag können wieder viele fragmentieren – 3 Tage evtl. etwas suboptimal. Unter der Woche ggf. Performance nicht ideal zum Ende hin. Das muss aber abgewogen werden mit Impact vs. Nutzen. – Komplexere Umsetzung: Jobs müssen nach Wochentag verzweigen oder unterschiedlich schedulen. Und man braucht Dokumentation: z. B. „Warum war gestern kein CheckDB? Ach, weil wir nur Di/Fr laufen lassen.“ Jeder im Team muss den Plan kennen. – Wochenendabhängigkeit: Was, wenn an einem Samstag Wartung ausfällt (z. B. wegen Release-Deployment)? Dann rückt Index Maint evtl. 1 Woche aus – was tun? Müsste evtl. nachgeholt, was wieder Plan durcheinander bringt. Also man hängt stark vom spezifischen Plan ab und muss bei Ausfällen neu justieren.

Empfehlungen: – Solch eine Pipeline immer mit Prioritäten versehen: Essentiell sind weiterhin Log & Full Backups – die dürfen nie ausfallen. CheckDB und Index Maint kann man notfalls mal schieben, aber dann ASAP nachholen. – Kommunikation: Das Business sollte wissen, falls z. B. samstags bis 10 Uhr morgens die DB noch Indizes baut (manche Systeme haben Samstags-Nutzer). – Monitoring anpassen: Einen Check, der warnt „CheckDB >7 Tage nicht gelaufen“ muss hier ggf. auf 8 Tage setzen, weil wöchentlich völlig ok ist. Oder man überwacht, ob es länger als das Zweifache der geplanten Periodizität ausbleibt.

Fazit Pipeline E: Ideal für große, anspruchsvolle Umgebungen ohne tägliches großes Fenster. Man erreicht Balance zwischen Datenpflege und Verfügbarkeit. Man muss jedoch streng darauf achten, dass nichts „vergessen“ wird (z. B. falls mal am geplanten Tag ein Job ausfällt, sonst hat man Lücken von 2+ Wochen). Mit guter Automatisierung (Jobs, die nur an bestimmten Wochentagen laufen, oder Checks innerhalb eines Jobs), lässt sich das zuverlässig umsetzen.

Beispielkonfigurationen

Jede SQL-Server-Umgebung ist anders. Im Folgenden werden drei Beispiel-Szenarien beschrieben – klein, mittel und groß/HA – und dafür passende Wartungspläne skizziert. Dazu gehören Wochenkalender, spezifische Parametervorschläge und Code-Snippets, die in diesen Umgebungen typisch sind.

Szenario 1: Kleine Instanz (1–5 Datenbanken, < 200 GB gesamt)

Charakteristik: Einzelner SQL Server (Standalone oder VM) mit wenigen Datenbanken, z. B. für eine Abteilung. Datenvolumen überschaubar (jede DB vielleicht 20–50 GB). Wartungsfenster jede Nacht 1–2 Stunden gut möglich, da Applikationen nachts offline. RPO/RTO Anforderungen moderat (z. B. 24h RPO ok, RTO 4h).

Wartungsplan: Man kann problemlos Pipeline A (täglich alles) fahren, inkl. täglichem Vollbackup. Folgender Wochenkalender zeigt den Plan:

Tag

Uhrzeit (Start)

Wartungsaktivitäten

Anmerkungen

Täglich (Mo–So)

00:00 – 23:59

Transaktionslog-Backup (alle 30 Min)

Lauf per SQL Agent, Intervall 30 Min, alle DBs.

Täglich

01:00

Vollsicherung aller Datenbanken (Full Backup)

Full täglich, da DB klein; Aufbewahrung 7 Tage lokal.

Täglich

01:30

Integritätsprüfung (CHECKDB) jede DB

DBs <50 GB => jede Nacht machbar.

Täglich

02:00

Indexpflege (Rebuild/Reorg) je DB

Schwellen: Rebuild >30% Frag, Reorg 5–30%. <br> Online=OFF (Exklusivzeit verfügbar).

Täglich

03:00

Statistiken aktualisieren

sp_updatestats für alle DBs (schnell).

Täglich

03:15

Cleanup (History + alte Backups löschen)

Löschung .bak/.trn > 7 Tage; sp_delete_backuphistory(7 Tage).

Samstag

02:00

(zusätzlich: Wartungssystem neu starten optional)

Kleines Fenster, um Serverpatches o.Ä. einzuspielen, falls relevant.

(Tabelle: Wochenplan für kleine Instanz)

Parameter-Empfehlungen:Backup-Skripte: Komprimierung an, CHECKSUM an. Beispielscript unten. – Index-Jobs: Könnten direkt mit Rebuild ALL benutzt werden, aber besser: checks durchführen (Beispiel unten). – Statistiken: Hier reicht sp_updatestats, das schnell durchläuft. – TempDB: i.d.R. 1–2 Dateien ausreichend (z.B. 4 GB initial, Wachstum 512 MB). – Benachrichtigungen: Einfache E-Mail an Admin bei Job Fehlschlag reicht hier meist, plus wöchentlicher Bericht.

Code-Snippets für Szenario 1:

Vollsicherung (T-SQL):

USE [master];
DECLARE @datenbank sysname = N’MeineDatenbank‘;
DECLARE @pfad nvarchar(255) = N’D:\Backups\MeineDatenbank_Full_%DATUM%.bak‘; — %DATUM% als Platzhalter zu ersetzen z.B. per dyn. SQL Datum
BACKUP DATABASE @datenbank
TO DISK = @pfad
WITH INIT,
      COMPRESSION,
      CHECKSUM,
      FORMAT,
      NAME = @datenbank + N’_FullBackup‘,
      STATS = 10;

Hinweis: Im Pfad steht ein Platzhalter; in einem echten Script könnte man das aktuelle Datum einfügen, z. B. mit CONVERT(varchar, GETDATE(), 112) für YYYYMMDD. FORMAT erstellt ein neues Medien-Set (gut beim ersten Backup in eine Datei). In einer Schleife über alle DBs würde man dynamisch @datenbank wechseln (Ausschluss msdb, tempdb etc. per WHERE).

Differential-Backup (ähnlich):

BACKUP DATABASE @datenbank
TO DISK = @pfad — z.B. ‚D:\Backups\MeineDatenbank_Diff_%DATUM%.bak‘
WITH DIFFERENTIAL,
      COMPRESSION,
      CHECKSUM,
      NAME = @datenbank + N’_DiffBackup‘,
      STATS = 5;

Transaktionslog-Backup (T-SQL):

BACKUP LOG @datenbank
TO DISK = N’D:\Backups\MeineDatenbank_%DATUM%_%ZEIT%.trn‘
WITH COMPRESSION,
      CHECKSUM,
      NOFORMAT,
      NAME = @datenbank + N’_LogBackup‘;

Anmerkung: NOFORMAT hier, damit mehrere Log-Backups auf eine Medienfamilie geschrieben werden könnten – oft erstellt man aber je Backup eine eigene .trn-Datei mit Zeitstempel (wie angedeutet). Wichtig ist, diese regelmäßig zu löschen, siehe Cleanup.

DBCC CHECKDB Skript:

SET NOCOUNT ON;
DECLARE @db sysname;
DECLARE cur CURSOR FOR
    SELECT name FROM sys.databases
    WHERE database_id > 4 AND state_desc = ‚ONLINE‘;  — alle User-Datenbanken
OPEN cur;
FETCH NEXT FROM cur INTO @db;
WHILE @@FETCH_STATUS = 0
BEGIN
    BEGIN TRY
        EXEC(N’DBCC CHECKDB(‚ + QUOTENAME(@db) + N‘) WITH NO_INFOMSGS, ALL_ERRORMSGS;‘);
        PRINT ‚CHECKDB OK für ‚ + @db;
    END TRY
    BEGIN CATCH
        PRINT ‚FEHLER in CHECKDB für ‚ + @db + ‚: ‚ + ERROR_MESSAGE();
        — Optional: Fehler in Tabelle loggen oder Mail schicken
    END CATCH;
    FETCH NEXT FROM cur INTO @db;
END
CLOSE cur;
DEALLOCATE cur;

Hinweis: Dieser Cursor geht alle Online-User-Datenbanken durch und führt CHECKDB aus. In einer kleinen Instanz ist das praktikabel. Bei größerer Zahl DB lieber parallel aufteilen oder Datenbanken gezielt nennen, die relevant sind.

Index-Wartungsskript (T-SQL-Beispiel für eine DB):

USE [MeineDatenbank];
DECLARE @FragThresholdRebuild float = 30.0, @FragThresholdReorg float = 5.0;
DECLARE @indexId int, @objId int, @frag float, @sql nvarchar(400);
DECLARE curIdx CURSOR FOR
SELECT ps.object_id, ps.index_id, ps.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, ‚SAMPLED‘) ps
JOIN sys.indexes ix ON ps.object_id = ix.object_id AND ps.index_id = ix.index_id
WHERE ix.type_desc IN (‚CLUSTERED‘, ‚NONCLUSTERED‘)  — nur Indexe (keine Heaps)
  AND ps.page_count > 1000; — nur größere Indexe
OPEN curIdx;
FETCH NEXT FROM curIdx INTO @objId, @indexId, @frag;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @sql = NULL;
    IF @frag >= @FragThresholdRebuild
        SET @sql = N’ALTER INDEX ‚ + QUOTENAME((SELECT name FROM sys.indexes WHERE object_id=@objId AND index_id=@indexId)) +
                  N‘ ON ‚ + QUOTENAME(OBJECT_SCHEMA_NAME(@objId)) + N‘.‘ + QUOTENAME(OBJECT_NAME(@objId)) +
                  N‘ REBUILD WITH (ONLINE = OFF);‘;  — offline hier, da kleines Fenster, ggf. ON falls nötig
    ELSE IF @frag >= @FragThresholdReorg
        SET @sql = N’ALTER INDEX ‚ + QUOTENAME((SELECT name FROM sys.indexes WHERE object_id=@objId AND index_id=@indexId)) +
                  N‘ ON ‚ + QUOTENAME(OBJECT_SCHEMA_NAME(@objId)) + N‘.‘ + QUOTENAME(OBJECT_NAME(@objId)) +
                  N‘ REORGANIZE;‘;
    IF @sql IS NOT NULL
    BEGIN
        PRINT ‚Executing: ‚ + @sql;
        EXEC sp_executesql @sql;
    END
    FETCH NEXT FROM curIdx INTO @objId, @indexId, @frag;
END
CLOSE curIdx;
DEALLOCATE curIdx;

Erläuterung: Dieses Skript sammelt Fragmentierung via sys.dm_db_index_physical_stats mit Sampling (ausreichend für moderate DB) und führt abhängig vom Schwellenwert einen Rebuild oder Reorg aus. Kleine Indizes <1000 Seiten überspringt es. Für jeden Index baut es das ALTER SQL dynamisch zusammen. In einer echten Lösung würde man das besser per JOIN lösen statt subselect im String, aber Verständlichkeit geht hier vor. ONLINE = OFF gesetzt, da wir annehmen im kleinen Szenario exklusive Zeit nachts.

Statistik-Update (T-SQL einfach):

USE [MeineDatenbank];
EXEC sp_updatestats;
— sp_updatestats wählt intelligent aus, welche Stats nennenswert geändert sind und verwendet default Sampeling

Oder für vollständigen Scan:

— Alle Statistiken mit FULLSCAN (etwas zeitintensiver)
DECLARE @tbl sysname;
DECLARE curTbl CURSOR FOR SELECT QUOTENAME(s.name)+‘.’+QUOTENAME(t.name)
                          FROM sys.tables t JOIN sys.schemas s ON t.schema_id=s.schema_id;
OPEN curTbl;
FETCH NEXT FROM curTbl INTO @tbl;
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC(‚UPDATE STATISTICS ‚ + @tbl + ‚ WITH FULLSCAN;‘);
    FETCH NEXT FROM curTbl INTO @tbl;
END
CLOSE curTbl; DEALLOCATE curTbl;

Cleanup (Backup und Verlauf, T-SQL):

— Backup-Dateien älter 7 Tage löschen (nur .bak in Pfad D:\Backups)
EXEC master.dbo.xp_delete_file 0, N’D:\Backups\‘, N’bak‘, DATEADD(day, -7, GETDATE());
EXEC master.dbo.xp_delete_file 0, N’D:\Backups\‘, N’trn‘, DATEADD(day, -7, GETDATE());  — Logfiles
— Verlauf in MSDB bereinigen
EXEC msdb.dbo.sp_delete_backuphistory @oldest_date = DATEADD(day, -30, GETDATE());
EXEC msdb.dbo.sp_purge_jobhistory @oldest_date = DATEADD(day, -30, GETDATE());

Hinweis: xp_delete_file ist undocumented, aber Maintenance Plans nutzen es. Parameter 0 = Dateityp (0 für Backup, 1 für Reports etc.), dann Pfad, Extension, Datum. Man muss es zweimal für .bak und .trn aufrufen. Sicherstellen, dass Pfad exakt stimmt und keine wichtigen Dateien dort mit gleicher Ext liegen. Die SPs in msdb löschen History älter 30 Tage.

SQL Agent Alerts & Operator (T-SQL Beispiel):

USE [msdb];
— Operator anlegen
EXEC sp_add_operator @name=N’DBA_Operator‘, @email_address=N’dba-team@meinefirma.com‘, @enabled=1;
— Alert für schwerwiegende Fehler (Severity 19-25)
EXEC sp_add_alert @name=N’Severity 19-25 Fehler‘,
     @message_id=0, @severity=19, @enabled=1,
     @delay_between_responses=0,
     @include_event_description_in=1,
     @notification_message=N’SQL Server Schwerer Fehler auf Instanz XYZ‘,
     @job_id=0;
EXEC sp_add_notification @alert_name=N’Severity 19-25 Fehler‘, @operator_name=N’DBA_Operator‘, @notification_method = 1;
— (Anmerkung: Für jede Severity 19 bis 25 müsste ein separater Alert angelegt werden, da sp_add_alert severity genau so interpretiert.)
— Beispiel spezifischer Alert für Error 823:
EXEC sp_add_alert @name=N’Error 823 (IO Error)‘,
     @message_id=823, @severity=0, @enabled=1,
     @notification_message=N’ERROR 823: Speicher-IO-Fehler in Datenbank, sofort prüfen!‘,
     @include_event_description_in=1;
EXEC sp_add_notification @alert_name=N’Error 823 (IO Error)‘, @operator_name=N’DBA_Operator‘, @notification_method=1;

Erläuterung: Zuerst wird ein Operator (Empfänger) definiert. Dann ein Alert für alle Fehler Sev 19 (und höher; sp_add_alert mit severity=19 fängt leider nur 19 ab, man müsste 20 etc. extra definieren – hier exemplarisch). Der Notification links den Alert mit Operator. Dann noch ein spezieller Alert auf Msg 823 als Beispiel.

Diese Codes sind anpassbar. In einer kleinen Instanz will man vielleicht nicht zu viele Mails – aber gerade die kritischen (Datenbank down, Backup fail) sollten abgedeckt sein.

Szenario 2: Mittlere Instanz (6–50 DBs, bis 2 TB)

Charakteristik: Ein SQL-Server mit dutzenden Datenbanken, insgesamt einige Terabyte. Möglicherweise mehrere Applikationen teilen sich die Instanz (z. B. CRM, ERP). Wartungsfenster nachts vorhanden, aber nicht für alle DBs gleichzeitig (viele Jobs müssen nacheinander laufen, um IO zu managen). RPO streng (Log-Backups häufig), RTO moderat (Stunden). Evtl. Weekly Full, Daily Diff wegen Menge.

Wartungsstrategie: Hier empfiehlt sich Pipeline E (wochenweiser Plan) oder eine Kombination: z. B. kleine DBs weiterhin täglich voll sichern; große DBs wöchentlich full + daily diff. CheckDB auf die Woche verteilt (nicht jede DB jede Nacht, sondern rotierend). Indexpflege ebenfalls zeitlich gestaffelt: z. B. manche DBs Mo/Do, andere Di/Fr, um Last zu verteilen.

Wochenkalender (Beispiel):

Tag

Aktivitäten (Start ~22:00, Ende ~06:00)

Details

Montag

Full-Backup DB-Gruppe A; <br> Diff-Backup DB B,C,D; <br> Indexpflege für mittlere DBs (B,C)

50% der DBs kriegen Full (A), Rest Diff; Rebuilds auf B,C.

Dienstag

Full-Backup DB-Gruppe B; <br> Diff A,C,D; <br> Indexpflege D (große DB über 2 Nächte)

Voll auf B, Indexpflege startet auf größter DB D (Teil1).

Mittwoch

Full-Backup DB-Gruppe C; <br> Diff A,B,D; <br> Indexpflege D (Teil2) + Stats Update für D

Jetzt Voll auf C, zweiter Teil Indexpflege D fertig, Stats D.

Donnerstag

Full-Backup DB-Gruppe D (große DB); <br> Diff A,B,C; <br> CHECKDB auf A,B (kleinere DBs)

Große D bekommt wöchentlich Full; CheckDB rotiert 2 DBs.

Freitag

Diff-Backups aller DB (leicht, da Sa Full geplant); <br> CHECKDB auf C,D (große zum WE)

Freitags keine Full (So kommt), daher alle diff. CheckDB auf restlichen DBs.

Samstag

Full-Backup aller DB (Wochensicherung); <br> Indexpflege auf allen falls benötigt (Fokus kleine Restfragmente); <br> Cleanup groß (History 90d, Reorg MSDB)

Lange Nacht: alle Full parallel (gestaffelt); evtl. Reindex Reste. Offsite Kopien starten.

Sonntag

Nur Log-Backups stündlich (kein Batch) – Nutzung für Releases/Updates evtl.

Wartungsfenster für App-Teams; DB-Admin minimal aktiv (nur Logs).

(Plan unterteilt DBs in Gruppen A-D nach Größe/Priorität.)

Erläuterungen: – Log-Backups laufen kontinuierlich (alle 15 Min oder je nach RPO). – Gruppen A-D: z. B. – A = kleine DBs (täglich Full ok), – B = mittlere (2-3 pro Nacht wechselnd), – C = größere, – D = sehr große. – So rotiert Full über Mo-Do, so dass jede große DB 1x/Woche Full hat (plus alle Samstag). – Diff werden an Nicht-Full-Tagen gezogen. – Indexpflege: Große DB D auf zwei Nächte aufteilen (z.B. halbe Indizes Di, halbe Mi). – Stats große DB D nach Abschluss Indexpflege (Mi). – CheckDB: kleinere DBs (A,B) Do, große (C,D) Fr – so hat man auch 1x/Woche jede durch.

Dieses Konstrukt ist natürlich anpassbar; das Beispiel zeigt, wie man Aufgaben verteilt.

Parametereinstellungen: – Backups: Wenn 2 TB+ an Daten, Backup auf Netzwerk-Share oder Stripe auf mehrere Files um Speed zu erhöhen. Kompression unbedingt. Vielleicht differenzierte Aufbewahrung: Letztes Full der Woche länger behalten (GFS-Prinzip). – CheckDB: Evtl. mit PHYSICAL_ONLY an Werktagen und full am Freitag, falls es sonst zu heavy. – Index: Online=ON, MAXDOP=4 (um nicht alle 16 Kerne zu saturieren, weil noch andere DB Maint parallel). – Stats: Mischung aus sp_updatestats (wenn Zeit knapp) und gezielten FULLSCAN am Wochenende. – TempDB: 8 Files, je 10 GB, Growth 1000 MB, IFI on.

Skript-Anpassungen: – Loops über viele DBs parallel: Evtl. mittels Powershell (DBATools Backup-DbaDatabase -SqlInstance Prod -Database @(‚A‘,’B‘) -Type Full -Throttle) etc. – Verwendung von Agent-Job-Subplans: z. B. Create Agent Job „FullBackup Monday“ which backups set A, „FullBackup Tuesday“ for set B, etc., scheduled accordingly. – Indexpflege: evtl. Ola Hallengren IndexOptimize mit Filter by DB or by time: kann Parameter @Databases und @Indexes etc. restriktiv aufteilen. Oder eigene T-SQL wie oben, aber eingeteilt.

Spezifische Snippets:

Beispiel Powershell DBATools – Backup alle DBs:

# Vollbackup aller DBs auf Netzwerkshare mit Zeitstempel im Namen
$instance = ‚SQLPROD\INST1‘
$date = Get-Date -Format yyyyMMdd_HHmm
Backup-DbaDatabase -SqlInstance $instance -Database ‚*‘ -Type Full `
    -CompressBackup -Checksum `
    -FilePath „\\NAS\SQLBackups\$($instance)_FULL_$date.bak“ `
    -CopyOnly:$false -NumberOfFiles 4 -Throttle 30 `
    -BufferCount 50 -MediaSetName „WeeklyFull_$date“

Dieses PS-Kommando sichert alle DBs auf einmal, verteilt auf 4 Files (Parallelisierung I/O), begrenzt Schreib-IO (-Throttle 30 MB/s pro Thread) und setzt mehr Buffer für Performance. In großen Umgebungen könnte man aber einzelne DBs sequentiell sichern, um Spitzen zu vermeiden.

Ola Hallengren IndexOptimize Beispiel (T-SQL Execute):

— Index- und Statistikwartung mit Ola Hallengren Script, z.B. nur für DB=D und limitierte Dauer
EXECUTE dbo.IndexOptimize
@Databases = ‚DatenbankD‘,
@FragmentationLow = NULL,  — skip kleine Reorg
@FragmentationMedium = ‚INDEX_REORGANIZE, INDEX_STATISTICS_UPDATE‘,
@FragmentationHigh = ‚INDEX_REBUILD_ONLINE, INDEX_STATISTICS_UPDATE‘,
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@UpdateStatistics = ‚Index‘,  — nur Index-Statistiken aktualisieren (nicht Spaltenstats)
@MaxDuration = 3600;  — max 1h laufen lassen, ggf. Fortsetzung nächster Nacht

Hier würde Olas Prozedur für die angegebene DB D alle Indizes prüfen und je nach Fragmentierung reorganize/rebuild und Stats updaten. Mit MaxDuration kann man steuern, dass es z.B. nach 1h abbricht und morgen fortsetzt. Das eignet sich, um große Aufgaben aufzuteilen.

CheckDB auf Secondaries auslassen: Wenn AG vorhanden und man will primär entlasten, könnte man:

IF (SELECT PRIMARY_ROLE = 1 FROM sys.dm_hadr_availability_replica_states WHERE is_local = 1 AND role = 1) = 1
BEGIN
   — Auf Primärserver:
   EXEC OlaHallengren.dbo.DatabaseIntegrityCheck @Databases=’USER_DATABASES‘, @PhysicalOnly=’Y‘, @LogToTable=’Y‘;
END;

Und auf Secondary evtl. eine andere Job-Variante.

Monitoring: In mittleren Umgebungen empfiehlt sich Einsatz eines Monitoring-Tools oder selbst gebauter Reports: – tgl. Report: Liste aller DBs mit Zeitpunkten letzter Full/Diff/Log Backup, letzte CheckDB, % Fragmentierung Top5 Index, etc. – Ampellogik: z. B. Excel/PowerBI ingest der KPIs, rot markieren wo > Schwelle.

Szenario 3: Große Umgebung / Always On (>\~ 2 TB, HA/DR vorhanden)

Charakteristik: Mehrere Instanzen in Hochverfügbarkeitskonfiguration (Always On AG über 2+ Replikas, evtl. zusätzlich DR-Standort mit Async). Datenbanken sehr groß (mehrere TB), 24/7 Betrieb mit minimalen Wartungsfenstern. RPO streng (log backups 5-15min), RTO streng (Failover möglichst transparent, im Desaster < 1h restore).

Wartungsstrategie: Hier muss man alle Register ziehen: – Backups auf Sekundär-Server auslagern (Backup Preference = Secondary). Evtl. beim DR-Standort (um im Desaster die Backups schon offsite zu haben). – Transaktionslog-Backups sehr häufig (alle 5 Min), damit das Send Queue auch klein bleibt. – Indexpflege häppchenweise: Resumable Online Index Rebuild (SQL 2019+ Feature) könnte hier eingesetzt werden, um einen großen Index über mehrere Nächte stückweise neu aufzubauen ohne von vorn anfangen zu müssen. Oder Partition-Switching/ Rolling Window Maintainance für Partitioned Tables statt full Rebuilds. – CheckDB offloaded: wie Pipeline C, per Restore auf separater QA-Instanz (denn Sekundär might be busy). – Überwachung streng: Jedes Wartungsjob-Ergebnis muss automatisch gemeldet (Ticketsystem etc.), weil bei so großen Systemen kein Raum für stillschweigende Fehlschläge ist.

Wochenkalender (in groben Zügen):

Maßnahme

Zeit/Intervall

Details

Log-Backup (Primär)

alle 5 Min (24/7)

Evtl. vom Sync-Secondary ausgeführt (AG-Backup-Preference).

Full-Backup (Sekundär)

So 02:00 (wöchentlich)

Copy_Only Full auf DR-Async Node, direkt auf Offsite Storage (z.B. Azure Blob/Tape).

Diff-Backup (Sekundär)

tägl. 02:00 außer So

Auf Sync Secondary, um Prod nicht zu belasten (bei AG 2019+ weiterhin copy_only not needed für diff? Nicht möglich diff auf sec, also ggf. diff auf primary doch?).

Index Rebuild (Primär)

Täglich kleine Portion, kontinuierlich

Verwendung von Resumable Index Rebuild: z.B. jede Nacht 00:00-01:00 Index XYZ rebuild weiterführen bis fertig; Nächste Nacht anderer Index. Parallel Reorg für kleinere Indexe.

Update Stats (Primär)

Kontinuierlich, auto + Wochentags je eine DB

Rundenbasiert: Mo Stats auf DB1, Di auf DB2… oder on-the-fly wenn Performance drop beobachtet.

CHECKDB (Restore auf Extra)

Wöchentlich je DB (rollierend)

Jeden Tag eine der großen DB auf extra Server restaurieren und checken, so dass jede alle X Tage geprüft ist (X ~ 7-14).

Cleanup / Audits

monatlich

DB Mail Test, Operator review, restore drill test etc. geplant am Monatsanfang.

Besonderheiten: – In AG-Umgebung wird Code in Jobs oft mit Abfragen versehen:

IF sys.fn_hadr_is_primary_replica(‚MeineDB‘) = 1
BEGIN
   — führe IndexMaint aus
END;

Damit laufen wichtige Jobs nur auf Primär. Backups analog mit Prefer Secondary Einstellung. – Backup-Zeit verkürzen: Multi-Threading (Backup to multiple files), Storage Snapshot Backups (Integration mit SAN-VSS Snapshots) sind hier zu erwägen. Letzteres: man macht z.B. SAN Snapshot als „Full Backup“ surrogate, aber noch immer Log-Backups für Transaktionen. Diese Snapshots könnten schnell sein und Offloading erfolg via SAN replication. Allerdings Komplexität. – Rebuild vs. Reorg: Bei 24/7 muss alles online sein. Resumable Index Rebuild (ab SQL 2017/2019) erlaubt Pause/Resume, und wird empfohlen für sehr große Indizes, um Wartungsfenster zu sprengen. – Partitionierung nutzen: Wenn historisch, kann man Partitionen einzeln pflegen (z.B. immer nur neueste partition neu bauen). – Offsite & Sicherheit: Backups evtl. direkt auf WORM Storage (immutable), wegen Ransomware. In so großen Umgebungen fließt Wartung und Security zusammen (Thema Compliance).

Code-Elemente: – Resumable Rebuild usage:

ALTER INDEX [IX_BigIndex] ON [dbo].[BigTable] REBUILD WITH (ONLINE = ON, RESUMABLE = ON, MAX_DURATION = 60);
— This starts a rebuild which auto-pauses after 60 minutes.
— Next night:
ALTER INDEX [IX_BigIndex] ON [dbo].[BigTable] RESUME;
— Or, if time up:
ALTER INDEX [IX_BigIndex] ON [dbo].[BigTable] PAUSE;

(Manage via job controlling dynamic which indexes are resumed or paused.)

  • A lot might be orchestrated via agent jobs and flags in tables to know what to do next.

Monitoring & Automation Tools: In solchen Umgebungen nutzt man oft professionelle Monitoring Suites (SentryOne, RedGate SQL Monitor, Dynatrace etc.) plus custom scripts. DBATools can help to gather cluster-wide info (like Get-DbaDbFile, Get-DbaLastBackup etc. for reporting).

Zusammenfassend: In großen/HA Umgebungen geht Wartung stark in Richtung kontinuierlicher Prozess statt einmal täglich. Man macht so viel wie möglich so oft wie möglich in kleinen Inkrementen, verteilt über alle Ressourcen (Primär/Secondary). Skripting wird komplexer, aber es ist nötig, um die Anforderungen einzuhalten.

Überwachung, KPIs & Berichte

Wartung ist nur effektiv, wenn ihr Erfolg messbar und überprüfbar ist. Daher müssen Kennzahlen (KPIs) definiert und regelmäßig ausgewertet werden. Wichtige KPIs im SQL-Server-Wartungskontext und deren Schwellenwerte sind:

Kennzahl

Zielwert (grün)

Warnung (gelb)

Alarm (rot)

Messpunkt

Korrekturmaßnahme

Zeit seit letztem Full-Backup

< 1 Tag (Prod) <br> < 7 Tage (Dev)

> 1 Tag (Prod) <br> > 7 Tage (Dev)

> 2 Tage (Prod) <br> > 14 Tage (Dev)

msdb.dbo.backupset (max backup_finish_date für type=’D‘)

Sofort Full-Backup nachholen; Backup-Plan prüfen.

Zeit seit letztem Log-Backup

< 30 Min (Prod kritisch) <br> < 12h (Dev)

> 30 Min (Prod)

> 60 Min (Prod)

msdb.dbo.backupset (type=’L‘) oder PerfMon Log Shrinks

Log-Backup Job prüfen/starten; ggf. Log Settings/Space prüfen.

Letzter erfolgreicher CHECKDB

< 7 Tage (Prod) <br> < 30 Tage (Dev)

> 7 Tage

> 14 Tage

Jobs History / eigenes Tracking Table

CHECKDB asap durchführen; Wartungsplan anpassen (häufiger).

Index-Fragmentierung (größter Index)

< 20 %

> 30 %

> 50 %

sys.dm_db_index_physical_stats (max avg_fragmentation_in_percent)

Gezielten Index Rebuild/ Reorg durchführen; Autonom. Job anstoßen.

Anzahl Autogrowth-Ereignisse (pro DB pro Woche)

0–5 (Daten), 0–10 (Log)

> 5 (Daten) <br> > 10 (Log)

> 20 (Daten oder Log)

SQL Server Default Trace <br> (Event 92) oder Extended Events

Datei-Größen erhöhen; Autogrowth-Schritte anpassen; Kapazität erweitern.

Transaktionslog-Nutzung (% bei Peak)

< 50 %

> 70 %

> 90 %

PerfMon Counter SQL Database(Log% Used)

Log-Backup-Intervall verkürzen; Log-Datei vergrößern.

Seitenfehler (suspect_pages)

0

1 (nur repaired)

>= 1 (unreparierte)

msdb.dbo.suspect_pages (Status 1=unrestored error)

Sofort Ursachenanalyse, ggf. DB im Einzelbenutzermodus prüfen, Restore erwägen.

Backup-Dauer (Full Backup Zeit)

ungefähr konstant (+/- 10%)

Steigt > 20% ggü. Durchschnitt

Steigt > 50%

Messen Start/Ende aus Job History / msdb

Prüfen: Engpass? (Netz, Disk) Defragmentierung, Kompression, Snapshots.

Test-Restore (Durchführungsintervall)

< 1 Monat (wichtigste DB) <br> < 3 Monate (alle DB)

> 3 Monate

> 6 Monate

Manuell protokolliert / DBA-Dokumentation

Restore-Test einplanen; ggf. Prozess automatisieren (Skript).

(Tabelle: Wichtige KPIs & Grenzwerte für Wartung)

Erläuterung zu den KPIs: – Die Backup-Aktualität (Full/Log) stellt sicher, dass RPO eingehalten wird. Ein Alarm hier bedeutet akute Gefährdung der Wiederherstellbarkeit. – CHECKDB-Alter: Ist ein Indikator, ob möglicherweise unentdeckte Korruption vorliegt. Gelb heißt: CheckDB-Job evtl. ausgefallen oder vergessen. Rot heißt: dringend nachholen. – Fragmentierung: Wenn einzelne große Indexe dauerhaft hoch fragmentiert sind, wurde Wartung übersprungen oder ist unzureichend. Evtl. muss man Maintenance intensiver fahren oder Partitionierung einführen. – Autogrowth: Viele Autogrowths deuten auf zu knappe Sizing-Strategie hin – diese KPI hilft proaktiv Plattenplatzprobleme und Performanceverlust (durch ständiges Wachsen) zu verhindern. – Log-Nutzung: Zeigt an, ob das Log nahe voll läuft. Könnte auf ausstehende Backups oder ungeplanten Log-Wachstum hinweisen. – Suspect Pages: Schon 1 Eintrag (rot) heißt, es gab einen echten Lese-/Schreibfehler. Bei „repaired = 1“ (gelb) heißt, per DBCC repariert oder mit Reparatur wiederhergestellt, aber immer noch Warnzeichen. – Backup-Dauer: Wenn Full-Backup plötzlich viel länger dauert, könnte das ein IO Problem oder Datenaufwuchs sein. Frühwarnung, um Backup-Zeitfenster neu zu bewerten. – Test-Restore: Diese KPI ist eher organisatorisch – man sollte tracken, wann zuletzt ein erfolgreicher Restore geübt wurde. Bei großen Organisationen oft vernachlässigt.

Berichte und Dashboards: Man kann diese KPIs z. B. in einem Excel oder BI-Dashboard zusammenführen, mit Ampelfarben wie oben. Typischer Tagesreport (Beispiel):

Datenbank

Last Full

Last Log (min)

Last CheckDB

Max Frag %

Log Used %

Status

DB1

0.5 Tage

10 min

3 Tage

12 %

40 %

🟢 OK

DB2

8 Tage

20 min

15 Tage

35 %

75 %

🟠 Warn (CheckDB)

DB3

1 Tage

55 min

7 Tage

5 %

95 %

🔴 Alarm (Log)

(Ampelfarben: Grün=OK, Orange=Warnung, Rot=Alarm.)

Solche Berichte können automatisiert per T-SQL (Abfragen gegen msdb und System-DMs, Ausgabe in HTML via DB Mail) oder mittels PowerShell (DBATools, dann Mail) generiert werden. Wichtig ist die Trendbeobachtung: z. B. Autogrowth-Events Woche über Woche, Backup-Dauer steigend, Fragmentierung nach Maint bleibt gleich (vllt. Maint ineffektiv).

Alerting-Logik: Neben den starren Alerts (Error 823 etc.) lohnt es, die KPIs proaktiv zu überwachen: – Implementieren eines Agent-Jobs „Überwachungs-Checks“ der täglich läuft und prüft: Wenn DATEDIFF(hh, last_full_backup, GETDATE()) > 30 dann RAISERROR (dieser RAISERROR kann Severity 16 haben und von einem Alert aufgefangen werden). Oder direkt sp_send_dbmail im Script bei Verstoß. – Ähnlich: Query msdb für jede DB wo kein log backup seit > X oder backupset fehler etc. – Tools: Policy Based Management (PBM) könnte solche Policies definieren (z.B. Condition „Last Backup < 24h“) und ein zentraler Management Server evaluiert das regelmäßig. PBM kann dann Alerts triggern. Allerdings nutzen das wenige aktiv für Backup, es ist aber möglich. – Viele Monitoring-Lösungen haben eingebaute Alarme für diese Dinge, aber wenn nicht vorhanden, lieber selber etwas Stricken als blind vertrauen.

Praxis-Tipp: Richten Sie eine Wartungs-Checkliste (siehe nächstes Kapitel) und einen regelmäßigen Review-Termin ein, um die Kennzahlen durchzugehen. Einmal im Monat könnte das DBA-Team die Trends analysieren: Haben sich Backupzeiten verlängert? Wächst DB schneller als angenommen? Gab es Alerts? Daraus folgen dann Anpassungen im Plan.

Besondere Szenarien & Stolpersteine

In der Praxis stößt die Standard-Wartung auf spezielle Situationen. Hier einige besondere Szenarien und wie man ihnen begegnet:

Hochverfügbarkeitslösungen (Always On AG, Log Shipping, Replikation)

Always On Availability Groups: – In AGs gilt es Backup Preferences zu beachten (siehe Pipeline D). Wenn Backup auf Secondaries, dann Kette im Blick (full copy_only = keine Diff möglich). Falls man gemischte Strategie fährt (Full/Diff auf Primär, Logs auf Sec), sicherstellen, dass im Failover-Fall die Backups weitergehen (Jobs auf beiden, mit Role Check). – Seeding/Wiederabgleich: Wartung kann Einfluss haben – z. B. ein großer Index Rebuild erzeugt viel Log, was bei asynchroner AG eine große Send Queue verursacht (erhöht potenziellen Datenverlust bei Failover, da Async). Bei synchroner AG kann es die Transaktionslatenz hoch treiben, evtl. Zeitouts bei Anwendungen. Lösung: Große Wartungsaktionen evtl. zu Wartungszwecken auf Async stellen (wenn möglich) oder throttlen (Resumable Rebuild oder kleinere Batches). – Verhalten von CHECKDB: Microsoft Best Practice (per Ola und Randal) sagt: Führ CheckDB auf allen Replikaten aus, denn Primär- und Sekundärkopie liegen evtl. auf unterschiedlichem Storage – ein korrupter Page auf Primär könnte dem Sekundär entgangen sein. Realistisch macht das kaum jemand täglich, aber man könnte z.B. Primär wöchentlich, Secondary monatlich checken, so hat man etwas Abdeckung. Primary zeigt Hardwarefehler schneller (823/824 im Errorlog). – Automatisierung bei AG-Failover: Wenn Failover passiert, kann es sein, dass z.B. der Log-Backup-Job auf dem neuen Primär erst beim nächsten Intervall greift, während auf altem Primär (jetzt Secondary) vllt. noch einer lief und fehlschlug. Hier am besten so scripten: Job läuft auf beiden, prüft per fn_hadr_is_primary_replica, nur macht Aktion wenn Primary. So springt’s automatisch. – Log Shipping: Weniger komplex: dort nimmt immer Primary Full+Log, Secondary nur read-only copy apply. Wichtig: In LS-Umgebung keine zusätzlichen Log-Backups abseits des Shipping Plans machen – das würde die Kette unterbrechen. Also muss der Wartungsplan Log-Backups dem Shipping überlassen. Full Backups kann man copy_only machen damit Shipping nicht durcheinanderkommt (LS basiert nicht auf full/diff, aber ein nicht-copy-only Full würde das restore LSN auf Secondary beeinflussen, aber LS erkennt das i.d.R.). – Replikation (Transactional Replication): Hier sind Wartungshürden: – Index Rebuild auf Publisher generiert viel Log, was der Log Reader Agent verarbeiten muss – kann Replikation verzögern. Ggf. außerhalb Hauptlast tun. – Replikation & Wartungsvorgänge: DBCC CHECKDB hat kein Einfluss auf Repl. – Schema Changes: Reorganize/Rebuild beeinflussen Schema nicht, safe. Aber Shrinks oder weglöschen von Artikeln natürlich kritisch. – Man sollte drauf achten, dass Distribution DB ebenfalls gewartet wird – dort z.B. Verlaufs-Bereinigung (Distribution Cleanup) regelmäßig laufen lassen, sonst bläht die sich auf. – Snapshot Repl: während Snapshots Indexpflege egal. – Bei Replikation ist speziell: DBCC DBREINDEX (veraltet) war mal Problem, aber mit ALTER INDEX kein Thema.

TDE / Verschlüsselung

Transparent Data Encryption (TDE): Verschlüsselt die DB-Dateien. Auswirkungen: – Backup-Größe & Komprimierung: Vor SQL 2016 waren TDE-verschlüsselte Daten kaum komprimierbar (da random). Ab SQL 2016 kann Backup-Komprimierung auch auf verschlüsselte DBs angewendet werden, bringt ca. 30-50% je nach Daten. Also Komprimierung auch bei TDE ON nutzen, es lohnt sich eingeschränkt. – CPU-Last: TDE hat bereits CPU-Overhead beim Lesen/Schreiben (Verschlüsselung/Entschlüsselung on the fly). Wartungsjobs, die viel IO machen (Backup, CheckDB, Index Rebuild), belasten CPU also noch stärker. Planen Sie ca. 3-10% mehr CPU-Bedarf ein. Manche messen >30% mehr CPU bei Backup mit TDE vs ohne. – Schlüssel-Management: Aus Wartungssicht wichtig: Sichern Sie den TDE-Zertifikat/Asym Key und rotation Keys (z. B. Schlüsselwechsel) sicher extern. Sonst sind Backups unbrauchbar, wenn Master DB weg ist. – TempDB: Bei TDE ist auch TempDB verschlüsselt, sobald eine DB TDE verwendet (Server-weite Implikation). Das kann TempDB IO etwas langsamer machen. Throttlen Sie evtl. Wartung die TempDB stark nutzt, oder planen mehr Spindeln / schnellere SSD. – Aufräum-Tasks: TDE cipher changes (Reencrypt) nicht so relevant hier. Aber falls man TDE neu aktiviert (Key-Rotation), generiert das viel IO (TDE Scanner) – am besten vom Wartungsfenster getrennt halten.

Partitionierte Tabellen, sehr große Indizes, FILESTREAM

Partitionierte Tabellen: – Vorteil: Man kann Wartung feingranular nach Partition machen. ALTER INDEX … REBUILD PARTITION = n (Enterprise) erlaubt es, nur einzelne Partition neu aufzubauen. So kann man z.B. Rolling Window: immer nur die aktuelle Partition (die viele Änderungen hat) nightly rebuilden, ältere bleiben unberührt oder selten (da read-only). – Partition Switch: Eine gängige Archivtaktik: Partition out alte Daten in andere Table/Filegroup und dann diese Filegroup read_only machen. Das erleichtert Wartung (die read-only Teile müssen nicht mehr gesichert oder reindexed). – Bei Stats muss man auf incremental stats (Ab SQL 2014) schauen: Statistiken können pro Partition gepflegt werden. Ola’s Script hat Option @UpdateStatistics = ‚INDEX‘ und @OnlyModifiedStatistics = ‚Y‘ etc., um nur nötige Stats zu aktualisieren. – Sehr große Indizes: Jenseits >100 Mio. Zeilen / > mehrere GB per Index. Hier erwägen: – Online & Resumable Rebuild (wie oben). – Reorganize statt rebuild, falls kein Wartungsfenster: Reorg kann pausiert werden (stop Job) und am nächsten Lauf macht er wieder von vorne, leider kennt er keinen Resume, aber minimal stört er. – Im Extremfall: gar nicht pflegen, sondern rely on index usage (es gibt Ansätze, riesige Indexe werden so selten voll gelesen, dass Fragmentierung wurscht ist – aber meist nicht). – Evtl. Heaps mit großer Unordnung: Schlimm, wenn Forwarded Records. Da hilft nur ALTER TABLE … REBUILD (gibt’s in 2019+ glaub ich, sonst create clustered index). – FILESTREAM/FILETABLE: – In CheckDB werden Filestream-Daten auch geprüft (ob die Verknüpfungen passen, ob Dateien vorhanden). Das kann dauern, wenn Millionen Dateien. – Indexpflege hat auf Filestream keine Wirkung (sind ja auf Dateisystem). – Backup enthält Filestream-Daten, das kann riesige Backups bedeuten. Diff Backup ist sinnvoll, weil Filestream bits tracken extents changed. – Wartung: Regelmäßig Filestream Garbage Collector prüfen (er räumt deleted files? Das passiert automatisch). – Wenn viele kleine Files: NTFS Fragmentierung? Not directly DB maintenance, eher OS defrag. – FILETABLE: ähnliches, plus vielleicht Windows Search indexing interfering? Das sollte man checken.

TempDB-Sättigung & Parallelität

TempDB-Sättigung: – Engpässe zeigen sich durch Waits wie PAGELATCH_UP/EX on tempdb, or frequent spills (Workfile I/O). – Wartung kann tun: Mehr Dateien, verteilen, oder Queries modifizieren: e.g. Index Rebuild ohne sort_in_tempdb wenn TempDB knapp, dann sort in user DB (traut dem dort mehr Platz zu). – Monitoring: PerfCounter Tempdb Data files size vs space used. – Notfall: Wenn TempDB vollläuft während Maint, notfalls Job abbrechen und ggf. DB neustart, falls es TempDB free space resets (besser: proactively size big). – Parallelität (MAXDOP): – Maint Jobs oft standard parallel. Aber wenn gleichzeitig mehrere DB Maint laufen, kann alle CPU-Kerne auslasten -> Nebenwirkungen auf each other. – Lösen: sp_configure ‚max degree parallelism‘ runtersetzen während Maint? Besser pro-Befehl mit MAXDOP hint. – Oder „Resource Governor“ use separate resource pool for Maint jobs with cap on CPU. – Cost Threshold: Usually global, but one can lower it to allow smaller queries parallel. But for maintenance specifically, one might not want a tiny index to go parallel overhead (if any). – Some DBAs set MAXDOP = 1 for index reorg (since it’s single-thread anyway by design, no effect) and MAXDOP = [half cores] for rebuild to not freeze everything. – Also consider BUFFERCOUNT and MAXTRANSFERSIZE for backup to optimize throughput but not hog memory fully.

Cloud-Storage/Netzwerk

Viele SQL Server laufen inzwischen auf VMs oder speichern Backups in Cloud-Speicher: – Netzlaufwerke für Backup: Immer Durchsatz testen. Wenn man z.B. Azure VM hat und Backup nach Azure Blob (via URL/BLOB Storage) schreibt, beachten: Standard Backups via URL können langsamer sein. Eventuell mit Stripping (parallel multiple URLs) oder use Azure Backup tooling. – Egress-Kosten: Wenn Offsite = Cloud, jede GB raus kann kosten. Daher Backup-Größe minimieren (Komprimierung, Diff). Oder consider storing only incremental changes (some 3rd party continuous backup solutions). – IOPS begrenzen: Cloud disks oft mit IOPS limits. Wartungsjobs (reindex, checkdb) können die IOPS Max erreichen und dann throttle alle IO, darunter auch normale ops => performance drop. – Lösung: Weniger parallel, degrade tasks or use bigger disk (with higher IOPS quota). – Managed SQL (PaaS like Azure SQL DB): Da hat man keinen SQL Agent (bzw. sehr eingeschränkt). Wartung in PaaS: Microsoft auto-manages many: backups automated, checkDB Microsoft side, index maybe via auto tuning? – Falls man trotzdem Index optimieren will, Azure SQL DB uses auto-index manage optionally or you schedule via Elastic Jobs or Azure Automation. – In PaaS, tasks like file management and shrink mostly not in control. – Hier Kontext aber vermutlich On-Prem/VM main, aber Erwähnung: Cloud-PaaS entlastet Admin von vielem, doch man sollte wissen, was dort passiert. – Azure SQL: auto-statistics on, fragmentation one might use external solution or trust cloud to handle (it doesn’t auto defrag indexes as of now, except maybe Auto tuning index creation/deletion, not defrag). – Geo-Replication: If using, similar to AG (but at service level).

Shrink vermeiden (und Ausnahmefälle)

Warum ist SHRINK so schlecht? – Data File Shrink (DBCC SHRINKDATABASE/FILE) bewegt Seiten von file-end nach vorne, leaving them out-of-order -> völlig fragmentierte Indexstrukturen hinterher. Zudem große CPU/IO Last und das Freed Space wird oft schnell wieder gebraucht, also vergeudete Mühe. – Log Shrink: Frees VLFs at end if possible. Hier Fragmentierung egal (VLF fragmentation internal, nicht so relevant?), aber das Problem: nächstes Wachstum wieder overhead, und während Shrinks exklusive Lock auf Log maybe (can’t log something while shrink? Actually log can be shrunk while use but it will hold if active part at end). – Außerdem: kontinuierliches Shrinken (AutoShrink ON) führt zu ständiger Pendelei der Dateigröße -> katastrophale Performance. – Empfehlung: AutoShrink immer OFF (Standard). – Einzige sinnvolle Anwendungsfälle: 1. Massendaten gelöscht oder archiviert und sicher nie wieder benötigt -> um Platz ans OS zurückzugeben darf man einmalig shrinken. Aber auch dann oft besser: neu DB erstellen und nur relevante Daten reintransferieren (wenn Extremschrumpfung). 2. Log nach Ausnahmeereignis (riesige Transaktion, jetzt leer, aber Datei 100x größer als nötig) -> einmalig shrink, danach sofort DBCC LOGINFO check VLF count, evtl. optimieren (durch einmaliges Full+Log backup or set initial size properly). 3. TempDB falls exorbitant gewachsen nach monster query -> kann man DB restart (fastest way to shrink, resets tempdb) oder manuell shrink, aber lieber neu starten in off-peak. – Nach jedem Shrink: – For Data: am besten Reindex aller Tables, damit Fragmentierung weg. Also was man an Platz gewann, investiert man wieder an Zeit und Log. – For Log: nach shrink, set initial size to good value to avoid immediate regrowth.

  • Sonderfall: Filestream container shrinken geht nicht, man muss Dateien löschen if needed at FS level, but not relevant.

So in Wartungsdoku: „Shrink nie in Routine, nur als Ausnahme mit Zustimmung und Plan.“

Wartungsfenster vs. 24/7 Betrieb

Wartungsfenster: Fester Zeitblock, in dem man exklusive oder bevorzugte Rechte hat. Kann man offensiv nutzen (offline Index Rebuild, lange Backups). 24/7: Kein downtime, alle Wartung muss online und möglichst transparent sein.

Strategien für 24/7: – Online Index Operations: (Enterprise feature) immer nutzen: ONLINE = ON bei rebuild, oder stattdessen reorganize falls Edition Standard (da es online per design). – Throttling/Batches: – Index Reorg kann man BatchWise machen via MAXDOP? (Nein, Reorg ist single thread, aber man kann via SET LOCK_TIMEOUT or by chunking e.g. reorganize index pagecount=… not directly but by splitting index? Hard). – Rebuild kann man using Resumable (to break into chunks). – Ola’s script has @WaitAtLowPriority and @MaxDuration. – Or custom: Rebuild only a subset of indexes each night, not all. – Stats: use sampling instead of fullscan to reduce impact. – CheckDB: Offload if possible, if not, maybe break into filegroups or tables with CHECKTABLE in rotation (one night tables A-M, next N-Z, etc., but recommended only if necessary). – Consider new features like Accelerated Database Recovery (ADR) (SQL 2019) which changes how long running transactions impact log truncation (makes log reuse easier even if long maint trans? Actually ADR helps faster rollback of long transactions, but not sure if relevant). – Partitioning to isolate hot data (like daily, do check on recent part). – User Impact Minimierung: – Use low priority locks for schema modifications if possible (Rebuild uses SCH-M locks at end to swap index, which can block briefly writes. With WAIT_AT_LOW_PRIORITY one can specify what to do if lock not granted, e.g. abort after X min). – Monitor at runtime: if maintenance block user queries heavily (lots of blocking), decide to pause or stop and continue later. – Possibly do some tasks in small transaction loops: e.g. if one must delete archivable rows, do in batches of 1000 per transaction, commit, yield, so normal operations can interleave.

  • Communication: For 24/7, coordinate with business if any heavy task must run, maybe degrade non-critical app features temporarily or user comms.
  • Continuous vs scheduled: Some 24/7 shops do a bit of maintenance continuously instead of one big chunk:
  • e.g. run a job that every hour picks one heavily fragmented small index and rebuild online quickly (just spreading work out).
  • Or update stats on one table every 30 minutes on rotation.
  • Hardware/Software assist:
  • Use replication or always on to offload (discussed).
  • Possibly use features like Buffer Pool Extension (to SSD) to reduce maintenance IO impact ( seldom used).
  • Up memory to allow checkdb mostly from cache if possible.

Härtung, Sicherheit & Compliance

Wartungsaufgaben berühren auch Fragen der Sicherheit und Compliance. Einige wichtige Punkte, um den Wartungsbetrieb abzusichern:

  • Prinzip der minimalen Rechte: Wartungsskripte/-Jobs sollen nur mit den nötigsten Berechtigungen laufen. Beispielsweise: Für Backups braucht ein Konto BACKUP DATABASE und Schreibrechte aufs Backupziel, aber nicht zwingend sysadmin. In der Praxis laufen viele Maint-Jobs unter sa oder einem DBA-Account mit sysadmin, was einfach ist aber sicherheitstechnisch ein Risiko (falls Jobscript kompromittiert würde). Besser:
  • Erstellen Sie einen speziellen Wartungs-Login (Windows oder SQL) mit begrenzten Rechten: z. B. Mitglied der festen Rolle db_backupoperator auf den DBs für Backups, db_ddladmin falls Index Rebuilds erforderlich (oder besser: nutzen signierte Stored Procs mit elevate).
  • Nutzen Sie Agent-Proxys: Im SQL Agent kann man Credentials definieren und Jobschritte (CmdExec, PowerShell) unter diesen weniger privilegierten Windows-Accounts laufen lassen, statt unter dem Agent Service Account (der oft hohe Rechte hat).
  • Pflegen Sie diese Accounts gut (Passwortwechsel, keine Interactive Logon).
  • Remove unnecessary permissions: z.B. Wartungskonto braucht kein DROP DATABASE. Falls eigene Procs die brauchen, isolieren.
  • Geschützte Anmeldedaten: Backup-Skripte, die auf Netzlaufwerke sichern, erfordern oft Netzfreigabe-Zugang. Statt im Klartext im Script ein Netz-UNC mit User/PW anzugeben (sehr unsicher), nutzen:
  • Ein Windows-Domänenkonto für SQL Agent Service mit passenden Rechten auf Share oder ein Agent Proxy mit hinterlegtem Credential für den Share-Zugriff.
  • DBATools & Powershell: Credentials im Windows Credential Manager speichern und im Script referenzieren, statt im Code.
  • Database Mail Profile: Versenden von Mails authentifiziert – auch hier nur notwendige Berechtigungen (SMTP-User) verwenden, kein globales Admin-Postfach.
  • Backup-Verschlüsselung & Offsite-Lagerung: Schon erwähnt: immer erwägen, Backups zu verschlüsseln (TDE oder Backup Encryption). Darüber hinaus: Offsite-Kopien sollten gegen Manipulation geschützt sein – z.B. Cloud Storage mit Immutability (WORM) für Backups aktivieren, sodass niemand (auch kein Virus/Ransomware) diese löschen oder verändern kann für eine gewisse Zeit. Die 3-2-1 Regel implementieren:
  • 3 Kopien: Primär, lokale Kopie, offsite Kopie.
  • 2 verschiedene Medien: z. B. Disk + Cloud, oder Disk + Tape.
  • 1 offsite: anderes Rechenzentrum oder Cloud.
  • Zugriffsschutz auf Wartungsartifakte: Wartungspläne/Jobs selbst sollten vor unbefugtem Zugriff geschützt sein. Z.B. nicht jeder Entwickler sollte den Wartungsjob ändern können. Nur DBAs (Rollen SQLAgentOperatorRole in msdb begrenzen).
  • Protokollieren, wer wann Änderungen vornimmt: in vielen Firmen sind DBAs verpflichtet, Changes via Change-Management-System abzustimmen. Dokumentieren Sie Wartungsjobs dort genauso wie Schema-Änderungen.
  • Verwenden Sie ggf. DDL-Trigger auf CREATE/ALTER JOB um Änderungen an Jobs in eine Audit-Tabelle zu schreiben.
  • Test-Wiederherstellungen & Runbooks: Compliance (z. B. ISO27001) fordert oft, regelmäßige Desaster-Übungen durchzuführen. Dazu gehört: Simulieren eines DB-Verlusts, Wiederherstellung aus Backup testen und Dauer messen. Halten Sie ein Runbook bereit, in dem steht, wer im Notfall welche Schritte durchführt, wo Backups liegen, wie lang einzelne Schritte dauern. Nach Wartung sollte dieses Runbook aktualisiert werden (z. B. wenn neuer Storage -> Restore dauert jetzt nur noch halb so lang).
  • Dokumentation & Versionierung: Alle Wartungsskripte (T-SQL, PS, Ola-Config) sollten versioniert sein (z. B. in Git). Änderungen daran gehen per Pull-Request durchs Team. So hat man Historie, was wann geändert wurde (z. B. „Index Reorg Schwelle von 10% auf 5% gesenkt am 2025-09-01 wegen XY“). Das ist wichtig, falls Wartung auf einmal länger dauert: man sieht, oh, wir rebuilden jetzt mehr Indizes seit Änderung.
  • Führen Sie ein Änderungsprotokoll für Wartungsplan:

Datum

Änderung/Bemerkung

Verantwortlich

Version

Rückfallplan

01.09.2025

Indexpflege Schwellen angepasst (Reorg ab 5% statt 10%).

A. Admin

1.3

Bei Performanceproblemen zurück auf 10%.

15.10.2025

Backup-Speicher auf neuen NAS migriert. Pfade geändert.

B. Bauer

1.4

Alte Pfade 30 Tage beibehalten als Kopie.

20.12.2025

Wartungsjobs auf getrennten Service-Account umgestellt.

C. Cheng

2.0

Zurück auf SQLAgent Account falls Auth fehlschlägt.

(Tabelle: Änderungsprotokoll Beispiel)

  • Audits aktivieren: Für streng regulierte Umgebungen (Finance/Healthcare) kann man SQL Audit oder Extended Events auf bestimmte Aktionen setzen: z. B. wer hat ein BACKUP DATABASE Befehl abgesetzt (um unautorisierte Backups mitzuschneiden), wer hat Maintenance Plan geändert (s. o.).
  • Least Privilege für DB Mail: Das Mail-Konto selbst sollte keine sensiblen Infos enthalten, besser generisches technisches Mailkonto.

Zusammengefasst: Der Wartungsplan sollte nicht nur technisch, sondern auch organisatorisch „gehärtet“ sein. Ein kompromittierter Wartungsjob (z. B. durch infizierten Admin-Rechner) könnte ggf. böswillig Schaden anrichten, daher sind o.g. Maßnahmen präventiv wichtig. Außerdem müssen Wartungsabläufe so dokumentiert sein, dass im Urlaubsfall ein Vertreter schnell versteht, was zu tun ist.

Fazit

Die Planung und Umsetzung von Wartungsplänen für Microsoft SQL Server erfordert Sorgfalt, regelmäßige Anpassung und ein gutes Verständnis sowohl der technischen Abläufe als auch der Geschäftsanforderungen. Wir fassen die wichtigsten Entscheidungen und Empfehlungen zusammen:

  • Wartungspipeline wählen: Abhängig von Datenbankgröße und Betriebsanforderungen entscheidet man sich für einen geeigneten Ablauf (z. B. tägliche Rundum-Wartung vs. wöchentliche verteilte Tasks). In vielen Fällen ist der klassische Ansatz (Pipeline A) ein guter Startpunkt: tägliche Backups, regelmäßige CheckDBs und Indexpflege. Für sehr große Umgebungen empfiehlt sich eine verteilte Strategie (Pipeline E) oder Offloading (Pipeline C) – so bleibt die Produktion leistungsfähig.
  • Backup-Strategie festlegen: Voll- und Log-Backups bilden das Rückgrat. Empfehlung: Im Full Recovery Model mindestens tägliches Full oder Differential + frequente Log-Backups. Die Parameter Komprimierung und Prüfsummen immer aktivieren. Offsite- und Test-Restore-Konzept nicht vergessen (Backups sind nur so gut wie ihre Wiederherstellung).
  • Index- und Statistikpflege ausbalancieren: Nutzen Sie das Rebuild/Reorg-Konzept mit sinnvollen Schwellen (z. B. 5/30%). Rebuild nach Möglichkeit online, Reorg für geringere Impact. Stellen Sie sicher, dass Statistiken im Anschluss konsistent sind (nach Reorg updaten, nach Rebuild nicht nötig). Vermeiden Sie Doppelarbeit (kein Stats-Update aller Tabellen nach einem kompletten Reindex).
  • Automatisieren und überwachen: Setzen Sie auf SQL Agent Jobs, Powershell-Skripte oder bewährte Lösungen (Ola Hallengren) zur Automatisierung. Richten Sie Alerts ein, damit Fehler nicht unbemerkt bleiben (Backup-Fail, Korruptionsfehler, ausbleibende Log-Backups). Führen Sie KPI-Dashboards ein, um den Zustand stets im Blick zu haben (Backup-Aktualität, Fragmentierung, etc.).
  • Ressourcen schonen: Passen Sie Wartungsaktivitäten an die Hardware und Betriebszeiten an. Nutzen Sie Wartungsfenster voll aus, aber respektieren Sie 24/7-Umgebungen mit online-Optionen und Throttling. Größere Systeme profitieren von aufgeteilten Tasks über die Woche und Features wie Resumable Index Rebuilds.
  • Sicherheit einbeziehen: Schützen Sie Wartungsabläufe durch Minimierung der Rechte und Verschlüsselung. Integrieren Sie Backups in das Sicherheitskonzept (Zugriffsschutz, Offsite, regelmäßige Restore-Übungen). Dokumentieren Sie Änderungen an Wartungsjobs, um Compliance und Nachvollziehbarkeit sicherzustellen.

Abschließend sei betont: Ein Wartungsplan ist kein statisches Konstrukt. Überwachen Sie die Wirkung Ihrer Wartung – z. B. ob die Performance nachlässt vor dem nächsten Wartungstermin oder ob Wartungsjobs regelmäßig länger dauern als geplant – und passen Sie den Plan iterativ an. Der folgende priorisierte To-do-Plan kann als Leitfaden dienen, um einen soliden Wartungsplan aufzubauen und weiterzuentwickeln:

30-Tage Plan (Sofortmaßnahmen)

  1. Backup-Basics implementieren: Stellen Sie sicher, dass alle Datenbanken (auch System-DBs, falls relevant) in einem konsistenten Backup-Plan sind. Richten Sie tägliche Voll- (oder Voll+Differential-) Backups und regelmäßige Log-Backups ein. Aktivieren Sie Backup-Komprimierung und Prüfsummen. Legen Sie Backup-Aufbewahrungsfristen fest und löschen Sie alte Files.
  2. Integrity Check aktivieren: Planen Sie DBCC CHECKDB mindestens wöchentlich für alle produktiven DBs. Für große DBs, wo nötig, erst mal PHYSICAL_ONLY, aber führen Sie es aus und überprüfen Sie, ob Fehler vorliegen (und lösen Sie diese, falls ja).
  3. Index- und Statistik-Grundpflege: Implementieren Sie ein Skript oder Maintenance Plan Task, das regelmäßig Indexfragmentierung analysiert und Rebuild/Reorg gemäß Schwellen vornimmt. Sorgen Sie dafür, dass danach Statistiken aktuell sind (z. B. durch sp_updatestats). Führen Sie dies initial testweise durch und validieren Sie die Dauer.
  4. Alerts & Operator: Konfigurieren Sie Database Mail, legen Sie einen Operator für DB-Alerts an, und erstellen Sie grundlegende Alerts (Severity 19-25, 823/824/825). Testen Sie, dass im Fehlerfall E-Mails ankommen (z. B. Test-Alert manuell RAISERROR).
  5. Dokumentation/Plan absegnen: Schreiben Sie den entworfenen Wartungsplan (Welche Jobs, wann laufen sie, was tun sie) nieder und lassen Sie ihn ggf. vom Change Advisory Board oder Vorgesetzten freigeben. So ist auch für Vertretung klar, was eingerichtet wurde.

60-Tage Plan (Optimierung und Erweiterung)

  1. Performance Tuning der Wartung: Analysieren Sie die letzten Wochen: Laufen manche Wartungsjobs zu lange oder verursachen hohe Last? Passen Sie Parameter an (z. B. MAXDOP runter für Indexrebuild, Wartung aufteilen in mehrere Nächte, etc.). Implementieren Sie fortgeschrittene Features wie Resumable Index Rebuilds für sehr große Tabellen oder Partition Maintenance, falls angebracht.
  2. Offsite/DR-Backups: Etablieren Sie einen Prozess, der Backups an einen sicheren Ort repliziert (Cloud Storage, Tape, zweites Rechenzentrum). Testen Sie die Wiederherstellung aus dieser Quelle. Stellen Sie sicher, dass Schlüssel (für TDE oder Backup Encryption) extern gesichert sind.
  3. Erweitertes Monitoring: Bauen Sie Ihr KPI-Dashboard auf. Nutzen Sie SQL und/oder ein Monitoring-Tool, um täglichen Bericht zu generieren (Backups, CheckDB, Fragmentierung, etc.). Richten Sie Warnschwellen ein, sodass proaktive Benachrichtigungen erfolgen (z. B. Mail, wenn kein Fullbackup in 2 Tagen).
  4. Sicherheit härten: Überprüfen Sie die Rechte der Wartungs-Jobs. Wenn möglich, ändern Sie die Job-Run-Accounts auf weniger privilegierte Nutzer oder Proxy und testen Sie gründlich. Stellen Sie sicher, dass Wartungsskripte keine Passwörter im Klartext enthalten. Aktivieren Sie ggf. Auditing für Wartungsänderungen.

90-Tage Plan (Feinschliff und Routine)

  1. Regelbetrieb & Review: Führen Sie eine erste Wiederholungs-Schulung/Übergabe durch: alle DBA-Teammitglieder kennen nun den Wartungsplan und wissen im Notfall einzugreifen. Erstellen Sie eine Checkliste (siehe unten) für tägliche oder wöchentliche Routinekontrollen.
  2. Testen von Notfällen: Simulieren Sie mindestens einmal ein Recovery: z. B. Restore einer wichtigen DB auf einen anderen Server, um die Ablaufkette und Dauer zu prüfen. Dokumentieren Sie Abweichungen vom erwarteten RTO. Ebenso simulieren Sie einen defekten Index oder eine Korruption, um zu sehen, ob Alerts anschlagen und das Team weiß, was zu tun ist.
  3. Periodische Plan-Überprüfung festlegen: Setzen Sie ein wiederkehrendes Meeting (vielleicht vierteljährlich), um den Wartungsplan zu überprüfen: Passt er noch zur Daten- und Systemlage? Müssen Parameter angepasst (z. B. Intervalle verkürzt, neue DB aufgenommen, alte entfernt) werden? Halten Sie diese Änderungen im Änderungsprotokoll fest.

Zum Abschluss noch eine praktische Checkliste zur Inbetriebnahme eines neuen oder überarbeiteten Wartungsplans:

  • [ ] Backup-Jobs aktiviert und getestet: Alle vorgesehenen Backup-Jobs laufen planmäßig (Überprüfung: msdb-Einträge vorhanden, Dateien am Ziel erstellt). Test-Restore von mindestens einer Backup-Datei erfolgreich.
  • [ ] CHECKDB zuletzt erfolgreich: Ein voller DBCC CHECKDB wurde für jede produktive Datenbank nach Plan ausgeführt, und es liegen keine unerledigten Fehler vor (sonst: Fehlersuche/Restore sofort nötig).
  • [ ] Indexwartung vollständig durchgelaufen: Nach Implementierung einmal manuellen Lauf anstoßen und sicherstellen, dass alle Indizes die gewünschten Fragmentationswerte unterschreiten. Prüfen, ob Jobs innerhalb des Zeitfensters fertig werden.
  • [ ] Benachrichtigungslauf getestet: Lösen Sie testweise einen Alarm aus (z. B. mit einem kurzen RAISERROR oder indem Sie einen Job absichtlich fehlschlagen lassen) und vergewissern Sie sich, dass eine E-Mail/SMS beim Operator ankommt.
  • [ ] Sicherungen extern gesichert: Überprüfen Sie, dass Backups auch extern verfügbar sind (z. B. auf Offsite-Share, Cloud-Bucket). Test-Datei vom Offsite-Medium zurückholen und Lesbarkeit prüfen (z. B. RESTORE VERIFYONLY).
  • [ ] Wartungsdokumentation verteilt: Alle relevanten Kollegen haben Zugriff auf die Dokumentation: Wartungsplan-Beschreibung, Notfall-Runbook, Änderungsprotokoll. Verantwortlichkeiten sind geklärt (Wer reagiert auf Alarm nachts? Wer pflegt die Scripts bei Bedarf?).
  • [ ] Performance Base Line vorhanden: Dokumentieren Sie den aktuellen Zustand (z. B. durchschnittliche Backupdauer, Query-Performance vor/nach Reindex). So können Sie bei zukünftigen Änderungen beurteilen, ob Wartung hilft oder neue Probleme schafft.
  • [ ] Auto-Features geprüft: Vergewissern Sie sich, dass keine automatische Funktion dem Plan entgegenläuft: z. B. AUTO_SHRINK ist Off, AUTO_CLOSE Off (für stabile Statistiken), eventuell AUTO_UPDATE_STATISTICS_ASYNC auf ON setzen, falls sinnvoll (verhindert Stat-Update Wartezeiten für Benutzer).
  • [ ] Notfallkontakte definiert: Für den Fall von schweren Problemen (z. B. nächtlicher CheckDB findet Korruption) ist klar, wer informiert wird und wer Entscheidung trifft (z. B. Failover, sofortiger Restore). Alerts haben korrekte Kontaktdaten (kein leeres Mailpostfach).
  • [ ] Genehmigungen/Compliance erfüllt: Falls für Ihren Betrieb eine offizielle Abnahme nötig ist (Audit, IT-Security), holen Sie diese ein. Beispielsweise Abnahme, dass Backup-Verschlüsselung korrekt ist, oder dass die Retention Policy gesetzeskonform (DSGVO etc.) umgesetzt ist.

Mit dieser Checkliste und den oben beschriebenen Maßnahmen sollte der Wartungsplan nicht nur technisch funktionieren, sondern auch den organisatorischen Anforderungen genügen. Denken Sie daran: Wartung ist ein fortlaufender Prozess. Bleiben Sie flexibel und reagieren Sie auf neue Herausforderungen – sei es wachsende Datenmengen, neue Systemversionen oder geänderte SLA-Vorgaben. Mit einem gut durchdachten Wartungsplan und regelmäßiger Überwachung legen Sie den Grundstein für einen zuverlässigen, performanten SQL-Server-Betrieb auf lange Sicht.

 

Weitere Beiträge zum Thema SQL Server

 

Azure SQL für IT-Entscheider

1. Management Summary Azure SQL bezeichnet eine Familie von Microsofts Cloud-Datenbankdiensten, die SQL Server-Technologie in Azure als Service bereitstellen. Dazu gehören Azure SQL Database (ein einzeldatenbankbasierter PaaS-Dienst für moderne Anwendungen), Azure SQL...

mehr lesen

Azure SQL für Entwickler

Management Summary Azure SQL (PaaS) bietet Softwareentwicklern eine fully-managed SQL-Plattform in der Cloud – mit integrierter Hochverfügbarkeit, automatischen Backups und einfacher Skalierbarkeit. Im Vergleich zu einer selbstverwalteten SQL Server-Instanz entfallen...

mehr lesen

NUMA – Grundlagen und Anwendung in SQL Server 2022

Grundlagen von NUMA (Non-Uniform Memory Access) Was ist NUMA?  NUMA (Nicht-uniformer Speicherzugriff) ist eine Architektur für Mehrprozessorsysteme, bei der jeder Prozessor über einen eigenen lokalen Arbeitsspeicher verfügt. Alle Prozessoren teilen sich zwar...

mehr lesen

Tutorial: SQL Server-Indizes für Entwickler

Einführung: Dieser Fachartikel richtet sich an Entwickler mit Grundkenntnissen in Microsoft SQL Server und bietet eine umfassende Einführung in das Thema Indizes. Wir beleuchten, was Indizes sind und warum sie für die Performance einer Datenbank entscheidend sind....

mehr lesen

Virtualisierung von SQL Server, Best Practices

Management Summary Virtualisierung von Microsoft SQL Server ermöglicht es Unternehmen, Datenbank-Workloads effizienter bereitzustellen und zu verwalten. Durch Konsolidierung mehrerer SQL-Server-Instanzen auf weniger Hardware steigern Organisationen die Auslastung und...

mehr lesen

SQL Performance-Analyse (hypothetisches Beispiel)

Management Summary Die Performance-Analyse einer Microsoft SQL-Server-Instanz (Version 2019) hat CPU- und I/O-Engpässe als Hauptprobleme identifiziert. In Spitzenzeiten lag die CPU-Auslastung dauerhaft über 90 %, und die Speicher-I/O-Latenz der Datenbanken überschritt...

mehr lesen

Weitere Beiträge zum Thema

Azure SQL für IT-Entscheider

1. Management Summary Azure SQL bezeichnet eine Familie von Microsofts Cloud-Datenbankdiensten, die SQL Server-Technologie in Azure als Service bereitstellen. Dazu gehören Azure SQL Database (ein einzeldatenbankbasierter PaaS-Dienst für moderne Anwendungen), Azure SQL...

mehr lesen

Azure SQL für Entwickler

Management Summary Azure SQL (PaaS) bietet Softwareentwicklern eine fully-managed SQL-Plattform in der Cloud – mit integrierter Hochverfügbarkeit, automatischen Backups und einfacher Skalierbarkeit. Im Vergleich zu einer selbstverwalteten SQL Server-Instanz entfallen...

mehr lesen

SQL Server Monitoring / Überwachung

Das Monitoring von SQL Server ist entscheidend, um die Leistung und Stabilität Ihrer Datenbank zu gewährleisten. Durch kontinuierliche Überwachung können potenzielle Probleme frühzeitig erkannt und behoben werden, bevor sie sich negativ auf Ihre Anwendungen auswirken....

mehr lesen

Microsoft SQL Server Lizenzierung

Die Lizenzierung von SQL Server kann komplex und kostspielig sein. Eine optimierte Lizenzierungsstrategie kann jedoch erhebliche Kosteneinsparungen und eine effizientere Nutzung der Ressourcen ermöglichen. Als erfahrener Berater werde ich die wichtigsten Schritte und...

mehr lesen

Microsoft SQL Server Kostenoptimierung

Die Verwaltung und Optimierung der Kosten einer SQL Server-Umgebung ist entscheidend für die Effizienz und Rentabilität eines Unternehmens. Als erfahrener Berater weiß ich, dass eine gut durchdachte Strategie zur Kostenoptimierung verschiedene Aspekte der SQL...

mehr lesen

SQL Server Analysis Services (SSAS)

SQL Server Analysis Services (SSAS) ist ein leistungsstarkes analytisches Datenbankmodul, das für Entscheidungsunterstützung und Geschäftsanalysen verwendet wird. Als erfahrener Berater weiß ich, dass SSAS eine Schlüsselrolle bei der Bereitstellung von...

mehr lesen

Microsoft SQL Server Sicherheit

Die Sicherheit von Microsoft SQL Server ist von entscheidender Bedeutung, um die Integrität, Vertraulichkeit und Verfügbarkeit Ihrer Daten zu gewährleisten. Als erfahrener Berater weiß ich, dass eine umfassende Sicherheitsstrategie verschiedene Ebenen und Methoden...

mehr lesen

Hochverfügbarkeit für Microsoft SQL Server

Die Gewährleistung der Hochverfügbarkeit (HA) von Microsoft SQL Server ist entscheidend für die Geschäftskontinuität und die Minimierung von Ausfallzeiten. Als erfahrener Berater weiß ich, dass eine gut durchdachte HA-Strategie verschiedene Technologien und Best...

mehr lesen

Indexoptimierung Microsoft SQL Server

Die Indexoptimierung ist ein zentraler Bestandteil der Leistungssteigerung eines SQL Servers. Als erfahrener Berater weiß ich, dass eine gut durchdachte Indexstrategie entscheidend für die Effizienz und Geschwindigkeit von Datenbankabfragen ist. In diesem Beitrag...

mehr lesen

Optimierung Microsoft SQL Server

Die Optimierung eines SQL Servers ist ein komplexer Prozess, der verschiedene Aspekte der Datenbankleistung berücksichtigt. Ich beschreibe hier die wichtigsten Schritte und Methoden zur Optimierung eines SQL Servers.: Die Optimierung eines SQL Servers ist...

mehr lesen