Themenseite · SQL Server unter Linux und Docker

SQL Server unter Linux für Windows-Admins: Die Handgriffe, die anders sind

Ihr Prüfskript fragt mit xp_fixeddrives nach dem freien Platz. SQL Server unter Linux antwortet: Laufwerk C, 22.327 MB frei. Ein Laufwerk C gibt es auf diesem Server nicht. Die Zahl stimmt trotzdem, sie gehört zum Dateisystem unter /var/opt/mssql.

Stand 12.11.2026 · ca. 19 Minuten

Teil 2 · Windows-AdminsSQL-Abfrage 3Lab SQL Server 2017–2025
Unter WindowsUnter LinuxConfiguration Managermssql-confDienste-KonsolesystemctlC:\Program Files\…/opt/mssqlERRORLOG/var/opt/mssql/logWindows-FailoverclusterPacemakerWartungsplan-Assistentgibt es nicht

So geht es mit vielen Handgriffen, die unter Windows selbstverständlich sind. Manche funktionieren unverändert, manche liefern Windows-Antworten auf Linux-Fragen, manche gehen ins Leere, ohne Fehler zu melden. Den Configuration Manager gibt es nicht, den Wartungsplan-Assistenten auch nicht. Diese Seite geht die Bereiche durch, in denen Windows-Admins umlernen müssen, jeweils mit der Gegenüberstellung „Unter Windows · Unter Linux · Stolperstelle“. Was wir über Linux sagen, haben wir auf SQL Server 2017, 2019, 2022 und 2025 gemessen. Was wir über Windows sagen, stammt aus der Dokumentation von Microsoft.

In 60 Sekunden

  • Dateien liegen unter /var/opt/mssql, und C:\ gibt es trotzdem. SQL Server übersetzt C:\ in /. Ein Pfad wie C:\var\opt\mssql\data\x.mdf funktioniert, C:\SQLData\x.mdf scheitert. Groß- und Kleinschreibung von Dateinamen ignoriert SQL Server auch unter Linux.
  • Alles gehört dem Benutzer mssql. Ein Backupziel ohne Schreibrecht für mssql endet mit einer Windows-Fehlermeldung: Operating system error 5(Access is denied.).
  • mssql-conf ersetzt den Configuration Manager, systemctl die Dienstverwaltung. Im Container schlagen Umgebungsvariablen die Konfigurationsdatei bei jedem Start. Wer master per mssql-conf verlegt, ohne die Dateien mitzunehmen, startet mit einer leeren master.
  • Windows-Griffe liefern Windows-Antworten oder nichts. Registry-Abfragen geben NULL zurück, ohne dass T-SQL einen Fehler meldet, sys.dm_server_registry ist leer, und sys.dm_server_services ist je Version anders lückenhaft.
  • Wartungspläne gibt es gegen Linux-Instanzen nicht. Ola Hallengrens Wartungslösung lief in unserem Lab auf allen vier Versionen ohne Fehler; sp_Blitz ebenfalls, deutet aber einige Windows-Antworten falsch.
  • Hochverfügbarkeit ohne Windows-Failovercluster: Pacemaker oder gar kein Cluster-Manager, Endpunkte mit Zertifikaten.

1 · Wo liegt was?

Unter WindowsUnter LinuxStolperstelle
ProgrammC:\Program Files\Microsoft SQL Server\…/opt/mssqlEine Instanz je Host, benannte Instanzen gibt es nicht
Daten und Log neuer DatenbankenPfade aus dem Setup, oft getrennte Laufwerkebeides /var/opt/mssql/dataDaten und Log liegen zusammen, bis Sie es mit mssql-conf ändern
Standard-BackupverzeichnisPfad aus dem Setup/var/opt/mssql/dataBackups landen neben den Datenbankdateien
Errorlog…\MSSQL\Log\ERRORLOG/var/opt/mssql/log/errorlogText; das Agent-Log sqlagent.out ist UTF-16
KonfigurationConfiguration Manager, Registry, Startparameter/var/opt/mssql/mssql.confDie Datei entsteht erst, wenn Sie etwas einstellen
Speicherabbilder (Dumps)…\MSSQL\Log/var/opt/mssql/log

Symbolische Links für Daten- und Logverzeichnisse unterstützt Microsoft nicht. Eigene Verzeichnisse für Daten, Log und Backups sind dagegen üblich; sie brauchen die passenden Rechte (Abschnitt 2).

C:\ gibt es trotzdem

SQL Server läuft unter Linux auf einer Abstraktionsschicht, die ihm eine Windows-Umgebung vorspielt. Das zeigt sich an Pfaden. Wir haben auf allen vier Versionen ausprobiert, was mit Windows-Pfaden passiert:

AnweisungErgebnis
CREATE DATABASE mit Datei C:\SQLData\x.mdfFehler 5133, Betriebssystemfehler 2: das Verzeichnis gibt es nicht
CREATE DATABASE mit Datei C:\var\opt\mssql\data\x.mdffunktioniert: Die Datei liegt in /var/opt/mssql/data/, im Katalog steht weiter der Windows-Pfad
BACKUP … TO DISK = 'C:\var\opt\mssql\data\x.bak'funktioniert, die Backup-Historie zeigt den Windows-Pfad
BACKUP … TO DISK = 'C:\Temp\x.bak'2017 (läuft im Container als root): legt /Temp/x.bak an; ab 2019: Fehler 3201, Betriebssystemfehler 5
BACKUP … TO DISK = '\var\opt\mssql\data\x.bak'Fehler 3038: ungültiger Dateiname
BACKUP … TO DISK = 'x.bak' (ohne Pfad)landet im Standard-Backupverzeichnis
RESTORE … WITH MOVE … TO 'D:\MSSQL\Data\x.mdf'Fehler 5133, Betriebssystemfehler 2

C:\ steht also für /, andere Laufwerksbuchstaben haben keine Entsprechung. Das hilft, wenn ein Skript mit festem C:\-Pfad zufällig auf einen existierenden Linux-Pfad zeigt, und es verwirrt, weil Katalog und Backup-Historie danach Windows-Pfade für Dateien zeigen, die unter Linux liegen. Abfrage 3 am Ende der Seite findet solche Pfade. Unsere Empfehlung: in T-SQL immer Linux-Pfade schreiben. Beim Zurückspielen eines Windows-Backups gehören alle Dateien mit WITH MOVE auf Linux-Pfade; das ist Thema von Teil 6.

Groß- und Kleinschreibung

Linux-Dateisysteme unterscheiden Fall.mdf und fall.mdf. SQL Server tut es nicht, auch nicht unter Linux:

  • Lag Fall.mdf schon im Verzeichnis, lehnte SQL Server eine neue Datenbank mit fall.mdf ab (Fehler 5170, die Datei existiere bereits).
  • Ein Backup namens L8.BAK ließ sich mit RESTORE … FROM DISK = '…/l8.bak' lesen.

Werkzeuge außerhalb von SQL Server, etwa ein Aufräumskript in der Shell, sehen dagegen die genaue Schreibweise. Wer Dateinamen einheitlich klein schreibt, erspart sich beide Überraschungen.

2 · Wer darf was?

Unter WindowsUnter LinuxStolperstelle
DienstkontoDienstkonto oder virtuelles Konto, Rechte über NTFSBenutzer mssql ohne interaktive Anmeldung; alles unter /var/opt/mssql gehört ihmEinen Eigentümerwechsel der SQL-Server-Verzeichnisse unterstützt Microsoft nicht
Eigenes BackupverzeichnisNTFS-Recht für das DienstkontoEigentümer oder Gruppe mssql, SchreibrechtOhne Recht: Operating system error 5(Access is denied.)
Neue Dateienerben NTFS-Rechtegehören mssql, Rechte 640 bzw. 660Andere Benutzer und Werkzeuge brauchen Gruppenrechte
Zusätzliche Abschottung–SELinux (Red Hat) mit Paket mssql-server-selinuxEigene Datenpfade brauchen den passenden SELinux-Typ

Ein eigenes Backupverzeichnis richten Sie so ein:

sudo install -d -o mssql -g mssql -m 770 /srv/sqlbackup
sudo /opt/mssql/bin/mssql-conf set filelocation.defaultbackupdir /srv/sqlbackup
sudo systemctl restart mssql-server

Bemerkenswert ist die Fehlermeldung, wenn das Recht fehlt: SQL Server meldet sie im Windows-Wortlaut Operating system error 5(Access is denied.), nicht als Linux-Meldung. Wer in Linux-Protokollen nach „Permission denied“ sucht, findet sie nicht.

SELinux: Ohne das Paket mssql-server-selinux läuft SQL Server unter Red Hat ohne SELinux-Abschottung. Mit dem Paket läuft er in einer eigenen Domäne, und eigene Datenpfade müssen den Typ mssql_db_t bekommen (semanage fcontext -a -t mssql_db_t "/srv/sqldata(/.*)?", danach restorecon -R -v /srv/sqldata). Das stammt aus der Microsoft-Dokumentation; im Container konnten wir es nicht prüfen. Zu AppArmor unter Ubuntu haben wir keine Aussage von Microsoft gefunden.

Im Container läuft SQL Server ab 2019 als Benutzer mit der ID 10001. Wem dort das Datenverzeichnis gehören muss, steht in Teil 3.

3 · Dienst und Konfiguration

Unter WindowsUnter LinuxStolperstelle
Dienst steuernDienste-Konsole, Configuration Manager`systemctl start\stop\restart\status mssql-server oder T-SQL SHUTDOWN`Pausieren gibt es nicht; ein Neustart des Agent startet die Engine mit neu
EinstellungenConfiguration Managermssql-conf, schreibt /var/opt/mssql/mssql.confFast jede Änderung braucht einen Neustart
Trace Flags beim StartStartparameter -Tmssql-conf traceflag 3226 on
Port, TLSConfiguration Managermssql-conf set network.tcpport, network.tlscert, network.tlskeyZertifikatsdateien müssen mssql gehören
Speichergrenzemax server memoryzusätzlich memory.memorylimitmb für den ganzen Prozess, Standard 80 %Beide Grenzen setzen, sie meinen Verschiedenes
SQL Server AgentDienst „SQL Server Agent“mssql-conf set sqlagent.enabled trueNach der Installation ausgeschaltet
Lage von masterStartparameter -d, -lmssql-conf set filelocation.masterdatafile, …masterlogfileOhne verschobene Dateien entsteht eine neue, leere master (siehe unten)

Der SQL Server Configuration Manager kann sich mit einer Linux-Instanz nicht verbinden. So sieht der Ersatz aus:

sudo /opt/mssql/bin/mssql-conf set sqlagent.enabled true
sudo /opt/mssql/bin/mssql-conf traceflag 3226 on
sudo /opt/mssql/bin/mssql-conf set memory.memorylimitmb 12288
sudo cat /var/opt/mssql/mssql.conf
sudo systemctl restart mssql-server

mssql-conf antwortet nach jeder Änderung im englischen Original mit SQL Server needs to be restarted in order to apply this setting. In den Images von 2022 und 2025 weist es zusätzlich auf sp_reload_mssqlconf hin, mit dem sich ein Teil der Einstellungen ohne Neustart übernehmen lässt; das haben wir nicht geprüft.

master verlegen: Vorsicht

Der sichere Ablauf: Dienst stoppen, Dateien master.mdf und mastlog.ldf an den neuen Ort verschieben, Eigentümer mssql prüfen, dann erst mssql-conf setzen und starten.

Im Container: Variablen gewinnen

Im Container stellt man SQL Server mit Umgebungsvariablen wie MSSQL_AGENT_ENABLED oder MSSQL_MEMORY_LIMIT_MB ein. Laut Microsoft gelten sie bei der Einrichtung; danach soll man mssql-conf verwenden. Wir haben beides kombiniert und den Container neu gestartet:

VariableEinstellung in mssql.confnach dem Neustart (2017–2025)
MSSQL_AGENT_ENABLED=falsesqlagent.enabled = trueAgent aus
MSSQL_AGENT_ENABLED=truesqlagent.enabled = falseAgent an
MSSQL_MEMORY_LIMIT_MB=2000memory.memorylimitmb = 30002.000 MB

Die Variable gewann auf allen Versionen bei jedem Start. Für die Speichergrenze steht dieser Vorrang auch in der Dokumentation, für den Agent haben wir ihn nur im Lab gesehen. Legen Sie eine Einstellung im Container deshalb an genau einer Stelle fest: entweder als Variable in der Container-Definition oder in einer eingebundenen mssql.conf, nicht in beiden.

Zwei weitere Beobachtungen aus dem Container:

  • Im Image von SQL Server 2019 verweigert mssql-conf dem Containerbenutzer den Dienst, er muss als root laufen. Hat root die Datei einmal geschrieben, scheitern spätere Aufrufe als Containerbenutzer mit Permission denied to modify SQL Server configuration. und enden trotzdem mit Exitcode 0. Ein Skript, das nur den Exitcode prüft, hält die Änderung für erledigt.
  • systemctl gibt es im Container nicht. Neu gestartet wird der Container; wie man ihn dabei sauber herunterfährt, zeigt Teil 3.

Errorlog lesen

Unter WindowsUnter LinuxStolperstelle
Errorlog der EngineDatei ERRORLOG, sp_readerrorlogDatei /var/opt/mssql/log/errorlog, sp_readerrorlogDie Datei ist Text, obwohl die Dokumentation UTF-16 nennt
Agent-LogDatei SQLAGENT.OUTDatei /var/opt/mssql/log/sqlagent.outUTF-16 mit Byte-Order-Mark
Ereignisse des DienstesEreignisanzeigesystemctl status mssql-server; im Container docker logsjournalctl nennt Microsoft nicht
Anzahl aufbewahrter LogsSSMS, Registrynicht änderbarsiehe unten

In allen geprüften Images begann errorlog mit Klartext, sqlagent.out mit den Bytes ff fe, der Kennung für UTF-16 Little Endian. cat und grep funktionieren also für das Errorlog direkt, für das Agent-Log nach einer Umwandlung:

sudo iconv -f UTF-16LE -t UTF-8 /var/opt/mssql/log/sqlagent.out | tail -20

Die Zahl der aufbewahrten Errorlogs lässt sich in SSMS gegen Linux nicht ändern, sagt Microsoft. Das Skript, das SSMS dafür unter Windows ausführt, schreibt einen Registry-Wert. Unter Linux lief dieser Aufruf im Lab ohne Fehlermeldung durch und änderte nichts.

4 · Speicher, Volumes, Freigaben

Unter WindowsUnter LinuxStolperstelle
DateisystemNTFS, ReFSXFS oder ext4, NFS ab Version 4.2Andere Dateisysteme sind nicht unterstützt
Backup auf eine FreigabeBACKUP … TO DISK = '\\server\share\…'Freigabe als Verzeichnis einhängen (CIFS), dann Linux-PfadUNC-Pfade in T-SQL nur über mssql-conf set uncmapping
Instant File InitializationRecht „Perform volume maintenance tasks“ für das Dienstkontoohne Recht wirksam für DatendateienManche Werkzeuge melden sie als ausgeschaltet
Lock Pages in MemoryRecht „Lock pages in memory“keine dokumentierte EntsprechungAlle geprüften Images meldeten das Speichermodell CONVENTIONAL

Backups auf eine Windows-Freigabe: Unter Linux spricht SQL Server die Freigabe nicht direkt an, sondern schreibt in ein Verzeichnis, unter dem die Freigabe eingehängt ist. Microsoft zeigt das in den Anleitungen für Failover Cluster Instances und Log Shipping, eine eigene Anleitung für Backups auf Freigaben haben wir nicht gefunden. Nach dem Muster der Log-Shipping-Anleitung, mit Schreibrecht:

sudo apt-get install cifs-utils          # Red Hat: dnf install cifs-utils
sudo install -d -o mssql -g mssql -m 770 /var/opt/mssql/backup-share
# /etc/fstab, eine Zeile; Anmeldedaten in einer Datei nur für root lesbar
//fileserver/sqlbackup  /var/opt/mssql/backup-share  cifs  credentials=/root/.sqlbackup-creds,vers=3.0,uid=mssql,gid=mssql  0  0

Danach schreibt BACKUP DATABASE … TO DISK = '/var/opt/mssql/backup-share/…' auf die Freigabe. Microsoft verlangt SMB 3.0 oder neuer. Für die Anmeldung am Dateiserver mit Kerberos statt Kennwortdatei haben wir keine Anleitung von Microsoft gefunden, und den Mount selbst haben wir im Container nicht geprüft.

Instant File Initialization heißt: SQL Server legt neue Datendateien an, ohne sie vorher mit Nullen zu füllen. Unter Windows braucht das Dienstkonto dafür ein Recht. Unter Linux gibt es dieses Recht nicht, und wir haben gemessen, ob die Abkürzung trotzdem wirkt:

2017201920222025
Neue 4-GB-Datendatei0,7 s0,8 s0,8 s0,7 s
Neue 4-GB-Logdatei11,8 s11,6 s11,6 s11,5 s

Datendateien entstehen ohne Füllen, Logdateien werden wie unter Windows mit Nullen beschrieben (Trace Flag 3004 zeigte das im Errorlog). Die Spalte instant_file_initialization_enabled in sys.dm_server_services zeigt das nur auf 2019 und 2025. Auf 2017 und 2022 fehlt dort die Zeile für die Engine ganz, und Werkzeuge, die dort nachsehen, melden IFI als ausgeschaltet (Abschnitt 7).

Lock Pages in Memory: Für Linux haben wir weder eine Entsprechung noch eine Aussage von Microsoft gefunden. Die Linux-Empfehlungen von Microsoft behandeln stattdessen Transparent Huge Pages und vm.swappiness; das ist Thema von Teil 4.

5 · Anmeldung und Active Directory

SQL-Anmeldungen funktionieren wie unter Windows. Windows-Anmeldungen gegen ein Active Directory sind möglich, brauchen aber Einrichtung, die unter Windows der Domänenbeitritt erledigt:

  1. Linux-Host in die Domäne aufnehmen (zum Beispiel mit realmd und SSSD).
  2. Ein AD-Benutzerkonto für SQL Server anlegen, mit AES-Verschlüsselung für Kerberos.
  3. SPNs MSSQLSvc/<FQDN>:<Port> und MSSQLSvc/<Hostname>:<Port> für dieses Konto registrieren.
  4. Ein Keytab erzeugen (adutil unter Linux oder ktpass unter Windows), unter /var/opt/mssql/secrets ablegen, Eigentümer mssql, Rechte 400.
  5. mssql-conf set network.privilegedadaccount <Konto> und network.kerberoskeytabfile <Pfad>, Neustart.
  6. Logins wie gewohnt mit CREATE LOGIN [DOMÄNE\Benutzer] FROM WINDOWS.

Stolperstellen laut Microsoft: Clients müssen den vollständigen Hostnamen (FQDN) verwenden, nicht localhost oder die IP-Adresse. Ändert sich das Kennwort des Dienstkontos, braucht SQL Server ein neues Keytab. Domänenlokale Gruppen werden nicht unterstützt. Diese Einrichtung haben wir nicht im Lab aufgebaut.

Zwei Windows-Logins bringt jede Linux-Instanz mit: BUILTIN\Administrators und NT AUTHORITY\NETWORK SERVICE, beide sysadmin. Unter dem zweiten laufen die Schritte von Agent-Jobs; im Jobverlauf steht Executed as user: NT AUTHORITY\NETWORK SERVICE. BUILTIN\Administrators soll man laut Microsoft nicht löschen. Sicherheitsprüfungen, die Windows-Logins auflisten, finden beide.

6 · Availability Groups ohne Windows-Failovercluster

Unter WindowsUnter LinuxStolperstelle
ClusterWindows-Failovercluster (WSFC)Pacemaker (CLUSTER_TYPE = EXTERNAL) oder keiner (NONE)Ohne Pacemaker nur manueller Failover
EndpunkteKerberos oder ZertifikateZertifikateWindows-Authentifizierung für Endpunkte gibt es nicht
ListenerNetzwerkname im ADIP-Adresse als Cluster-Ressource plus DNS-EintragKurzer Ausfall beim Failover
Verteilte TransaktionenMSDTCnicht in Availability Groups

Ein Active Directory braucht eine Availability Group unter Linux nicht. Wir haben eine Availability Group mit CLUSTER_TYPE = NONE und Zertifikatsendpunkten zwischen Linux-Containern aufgebaut und acht manuelle Failover ohne Datenverlust gefahren; die Messungen stehen in unserer Reihe FCI vs. Availability Groups. Pacemaker, Fencing und automatischen Failover behandelt Teil 5 dieser Reihe.

7 · Werkzeuge und Skripte

Unter WindowsUnter LinuxStolperstelle
SSMSvoller Umfangverbindet sich wie gewohntKeine Wartungspläne, kein Data Collector, Zahl der Errorlogs nicht änderbar
Configuration Managerjaverbindet sich nichtmssql-conf (Abschnitt 3)
Azure Data Studioim Ruhestand seit 28.02.2026ebensoNachfolger: VS Code mit MSSQL-Erweiterung; Agent und klassische Verwaltung bleiben in SSMS
sqlcmd, bcpjaja, nativ
dbatoolsvoller UmfangBefehle, die nur T-SQL nutzenBefehle mit WMI oder Remoting zielen auf Windows (unsere Deutung aus dem Quellcode)

Was Ihre Skripte zurückbekommen

Viele Prüf- und Wartungsskripte fragen Windows ab: Laufwerke, Registry, Dienste. Wir haben die gängigen Griffe auf allen vier Versionen als sa ausgeführt:

liefertliefertliefertliefertliefertliefertliefertliefertliefertliefertliefertliefert/var/opt/…/var/opt/…/var/opt/…/var/opt/…teils NULLteils NULLteils NULLteils NULLLaufwerk CLaufwerk CLaufwerk CLaufwerk CNT x64NT x64NT x64NT x64nur Agent„Stopped“nur AgentKonto NULLNULLLocalSystemNULLNULLNULL128NULLNULLohne Wirkungohne Wirkungohne Wirkungohne Wirkungkeine Zeilenkeine Zeilenkeine Zeilenkeine Zeilen2017201920222025sys.dm_os_host_infoxp_dirtree '/var/opt/mssql'sp_readerrorlogxp_instance_regread 'BackupDirectory'sys.dm_os_volume_statsxp_fixeddrivesxp_msversys.dm_server_servicesxp_regread (Dienstkonto)xp_instance_regread 'NumErrorLogs'xp_instance_regwritesys.dm_server_registryliefert Linux-WerteWindows-Sicht oder lückenhaftleer oder ohne Wirkung, ohne Fehlermeldung
liefertliefertliefertliefertliefertliefertliefertliefertliefertliefertliefertliefert/var/opt/…/var/opt/…/var/opt/…/var/opt/…teils NULLteils NULLteils NULLteils NULLLaufwerk CLaufwerk CLaufwerk CLaufwerk CNT x64NT x64NT x64NT x64nur Agent„Stopped“nur AgentKonto NULLNULLLocalSystemNULLNULLNULL128NULLNULLohne Wirkungohne Wirkungohne Wirkungohne Wirkungkeine Zeilenkeine Zeilenkeine Zeilenkeine Zeilen2017201920222025sys.dm_os_host_infoxp_dirtree '/var/opt/mssql'sp_readerrorlogxp_instance_regread 'BackupDirectory'sys.dm_os_volume_statsxp_fixeddrivesxp_msversys.dm_server_servicesxp_regread (Dienstkonto)xp_instance_regread 'NumErrorLogs'xp_instance_regwritesys.dm_server_registryliefert Linux-WerteWindows-Sicht oder lückenhaftleer oder ohne Wirkung, ohne Fehlermeldung
Was gängige Windows-Griffe unter Linux zurückgeben, als sa auf SQL Server 2017 bis 2025 im Container gemessen. Die Einzelheiten stehen in der Tabelle.
GriffWas er unter Linux liefert
xp_fixeddrivesein Laufwerk C mit dem freien Platz des Dateisystems unter /var/opt/mssql
xp_dirtree 'C:\'eine Mischung aus Windows-Ordnern (binn, Windows, Program Files) und Linux-Einträgen (.dockerenv, run)
xp_dirtree '/var/opt/mssql'den Verzeichnisinhalt, wie erwartet
xp_regread (Dienstkonto)NULL mit der Meldung RegQueryValueEx() returned error 2; nur 2019 lieferte „LocalSystem“
xp_instance_regread (BackupDirectory)/var/opt/mssql/data
xp_instance_regread (andere Werte)meist NULL, ohne T-SQL-Fehler
xp_instance_regwriteläuft ohne Fehler, ändert nichts
sys.dm_server_registrykeine Zeilen
sys.dm_server_services2017 und 2022: nur der Agent; 2019: Engine als „Stopped“, obwohl sie läuft; 2025: Engine und Agent. Der Agent läuft laut DMV als „LocalSystem“
sys.dm_os_volume_statsGröße und freier Platz ja; Mountpunkt, Volumename und Dateisystemtyp NULL
xp_msverPlattform „NT x64“
xp_readerrorlog, sp_readerrorlogfunktionieren
sys.dm_os_host_infoLinux und die Distribution; der zuverlässige Weg, die Plattform zu erkennen

Die gefährlichste Zeile ist die Registry: Ein Skript, das @@ERROR prüft, merkt nicht, dass es nichts gelesen hat, und Schreibzugriffe bleiben ohne Wirkung. Ohne sysadmin-Rechte lieferten xp_fixeddrives, xp_dirtree und sys.dm_os_volume_stats leere Ergebnisse statt Fehlern. Unsere Empfehlung: Skripte, die auf beiden Plattformen laufen sollen, fragen zuerst sys.dm_os_host_info ab und verzweigen danach, so wie es die beiden folgenden Projekte tun.

Wartung ohne Wartungsplan: Ola Hallengren

Der verbreitete Ersatz für Wartungspläne ist die SQL Server Maintenance Solution von Ola Hallengren. Sie erkennt Linux über sys.dm_os_host_info und passt Pfadtrenner und Verfahren an. Wir haben den Stand vom 12.09.2026 mit Standardeinstellungen auf allen vier Versionen installiert und ausgeführt:

  • Installation ohne Fehlermeldung. Unter Linux legt sie zehn Agent-Jobs an, alle mit T-SQL-Schritten. Den Job „Output File Cleanup“, der unter Windows alte Ausgabedateien mit PowerShell löscht, legt sie unter Linux nicht an; der Installer wählt dort nur Jobs mit T-SQL-Schritten. Betriebssystembefehle und PowerShell kann der Agent unter Linux ohnehin nicht ausführen.
  • Backups, Integritätsprüfung, Indexpflege liefen ohne Fehler. Ohne @Directory sicherte sie in das Standard-Backupverzeichnis unter /var/opt/mssql/data/<Server>/<Datenbank>/FULL/; die Unterverzeichnisse legte SQL Server beim BACKUP selbst an. Alte Backups löschte sie mit @CleanupTime.
  • Die Jobs liefen auf 2022 und 2025 erfolgreich und schrieben ihre Ausgabedateien nach /var/opt/mssql/log. Auf 2017 und 2019 konnten wir sie nicht über den Agent starten (siehe Methode und Grenzen).

Was Sie unter Linux selbst ergänzen sollten: Die Ausgabedateien der Jobs räumt niemand auf, und Backups liegen ohne @Directory neben den Datenbankdateien. Geben Sie ein eigenes Backupverzeichnis an und löschen Sie alte Ausgabedateien mit einem Cron-Job oder einem T-SQL-Jobschritt.

Diagnose: sp_Blitz

sp_Blitz aus dem First Responder Kit unterstützt Linux laut Projektseite vollständig, mit Ausnahme von sp_DatabaseRestore. Mit Version 8.34 vom 02.07.2026 lief es auf allen vier Versionen ohne Fehlermeldung, ebenso sp_BlitzFirst. Einige Befunde beruhen unter Linux auf den Windows-Antworten aus der Tabelle oben:

Befund (Original)Bedeutung unter Linux
Drive C Spaceder freie Platz unter /var/opt/mssql, nicht eines Laufwerks C
Power Plan: „unknown power mode“unter Linux nicht ermittelbar; die CPU-Einstellungen behandelt Teil 4
Instant File Initialization Not Enabled (2017, 2022)trifft nicht zu, IFI wirkt (Abschnitt 4); die Engine fehlt in sys.dm_server_services
Invalid login defined with Windows Authentication: BUILTIN\AdministratorsLogin aus der Installation, kein Fehler Ihrer Konfiguration
Sysadmins: NT AUTHORITY\NETWORK SERVICEebenso; unter diesem Login laufen Agent-Jobs

Betriebssystem und Container erkennt sp_Blitz korrekt. Lesen Sie die übrigen Befunde wie gewohnt, aber prüfen Sie die Zeilen zu Laufwerken, Energiesparplan, IFI und Windows-Logins gegen diese Tabelle, bevor Sie handeln.

8 · Updates

Unter WindowsUnter LinuxStolperstelle
Kumulative UpdatesInstallationsprogramm des CUPaketmanager aus dem Repository mssql-server-<Version> (dnf/yum, apt-get, zypper)Das Repository legt die Hauptversion fest
Ohne InternetzugangCU-Datei kopierenPaketdatei herunterladen und lokal installieren
Zurück auf einen älteren StandDeinstallation des CUDowngrade des Pakets, nur innerhalb der Hauptversion
Im Container–neues Image mit neuem Tag, gleiches DatenvolumeTeil 3
sudo apt-get update && sudo apt-get install mssql-server     # Ubuntu
sudo dnf update mssql-server                                  # Red Hat

Steckbrief: Was hat diese Instanz?

Die folgende Abfrage fasst die Punkte dieser Seite für eine konkrete Instanz zusammen: Plattform und Pfade, Speichermodell, Datenbankdateien je Verzeichnis mit freiem Platz und Windows-Reste in msdb, etwa Jobschritte mit Laufwerksbuchstaben nach einer Migration. Was die Container-Grenzen und den Agent betrifft, zeigt Abfrage 2 in Teil 3; welche unter Linux fehlenden Funktionen eine Instanz nutzt, zeigt Abfrage 1 in Teil 1.

Abfrage: Steckbrief der Instanz

Abfrage 3: Steckbrief der Instanz · nur lesend · im PSG-Lab geprüft, Versionen im Kopf
/* PSG Stack · SQL Server unter Linux und Docker · Abfrage 3 „Steckbrief der Instanz“   Für Windows-Admins: Wo liegen Dateien und Backups, wie viel Platz ist dort frei,   welches Speichermodell gilt, und welche Windows-Reste stehen noch in msdb?    !!! WARNUNG — bitte vor dem Ausführen lesen !!!   - Nur lesend. Die Abfrage ändert keine Daten und keine Einstellung.   - Rechte: VIEW SERVER STATE und VIEW ANY DEFINITION für Teil 1 und 2, Lesezugriff auf msdb     für Teil 3. Fehlt ein Recht, liefert der Teil keine Zeilen oder meldet das in der Spalte     hinweis, statt falsche Nullen zu zeigen.   - MAXDOP 1: Jede Teilabfrage läuft seriell und belegt keine weiteren Kerne.   - Ab SQL Server 2017. Läuft auch unter Windows; die Hinweise sind für Linux geschrieben.     Geprüft im PSG-Lab auf 2017, 2019, 2022 und 2025 in Linux-Containern, als sa und ohne     sysadmin (12.11.2026); unter Windows nicht geprüft.   - Teil 3 durchsucht Jobschritte und die Backup-Historie der letzten 30 Tage. Bei sehr großer     Historie in msdb kann das einige Sekunden dauern.*/SET NOCOUNT ON; DECLARE @sql nvarchar(max);DECLARE @linux bit = 0;IF OBJECT_ID(N'sys.dm_os_host_info') IS NOT NULL    SELECT @linux = CASE WHEN host_platform = N'Linux' THEN 1 ELSE 0 END FROM sys.dm_os_host_info; /* 1 · Plattform, Standardpfade, Speichermodell */SET @sql = N'SELECT ' +  CASE WHEN OBJECT_ID(N'sys.dm_os_host_info') IS NULL THEN N'N''n/a'' AS plattform, N''n/a'' AS distribution, N''n/a'' AS release'       ELSE N'h.host_platform AS plattform, h.host_distribution AS distribution, h.host_release AS release' END + N',    CONVERT(nvarchar(20), SERVERPROPERTY(''ProductVersion'')) AS version,    CONVERT(nvarchar(260), SERVERPROPERTY(''InstanceDefaultDataPath'')) AS standard_datenpfad,    CONVERT(nvarchar(260), SERVERPROPERTY(''InstanceDefaultLogPath'')) AS standard_logpfad,    ISNULL(CONVERT(nvarchar(260), SERVERPROPERTY(''InstanceDefaultBackupPath'')), N''n/a (vor 2019)'') AS standard_backuppfad,    CONVERT(nvarchar(260), SERVERPROPERTY(''ErrorLogFileName'')) AS errorlog,    i.sql_memory_model_desc AS speichermodell,    CASE i.sql_memory_model_desc WHEN N''CONVENTIONAL'' THEN N''ohne gesperrte Seiten (Lock Pages in Memory nicht aktiv)''                                 WHEN N''LOCK_PAGES'' THEN N''gesperrte Seiten aktiv''                                 WHEN N''LARGE_PAGES'' THEN N''Large Pages aktiv'' END AS speichermodell_bedeutungFROM sys.dm_os_sys_info AS i' +  CASE WHEN OBJECT_ID(N'sys.dm_os_host_info') IS NULL THEN N'' ELSE N' CROSS JOIN sys.dm_os_host_info AS h' END +  N' OPTION (MAXDOP 1);';EXEC sys.sp_executesql @sql; /* 2 · Datenbankdateien je Verzeichnis mit freiem Platz   Unter Linux bleibt mountpunkt leer; Größe und freier Platz kommen trotzdem.   Ein Pfad mit C:\ ist unter Linux möglich: SQL Server legt die Datei dann unter / ab   (C:\var\opt\mssql\data\x.mdf liegt in /var/opt/mssql/data/x.mdf) und speichert den Windows-Pfad. */IF HAS_PERMS_BY_NAME(NULL, NULL, N'VIEW ANY DEFINITION') = 1    SELECT        LEFT(f.physical_name, LEN(f.physical_name) - pos.p) AS verzeichnis,        f.type_desc AS dateityp,        COUNT(*) AS dateien,        COUNT(DISTINCT f.database_id) AS datenbanken,        CONVERT(decimal(12, 1), SUM(CONVERT(bigint, f.size)) * 8 / 1048576.0) AS groesse_gb,        CONVERT(decimal(12, 1), MAX(v.total_bytes) / 1073741824.0) AS volume_gb,        CONVERT(decimal(12, 1), MIN(v.available_bytes) / 1073741824.0) AS frei_gb,        MAX(ISNULL(v.volume_mount_point, N'(leer)')) AS mountpunkt,        w.hinweis    FROM sys.master_files AS f    CROSS APPLY (SELECT CHARINDEX(N'/', REVERSE(f.physical_name)) AS s, CHARINDEX(N'\', REVERSE(f.physical_name)) AS b) AS r    CROSS APPLY (SELECT CASE WHEN r.s = 0 THEN r.b WHEN r.b = 0 THEN r.s WHEN r.s < r.b THEN r.s ELSE r.b END AS p) AS pos    CROSS APPLY (SELECT CASE WHEN @linux = 1 AND f.physical_name LIKE N'[A-Za-z]:\%'                             THEN N'Windows-Pfad unter Linux: C:\ steht für /' ELSE N'' END AS hinweis) AS w    CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id) AS v    GROUP BY LEFT(f.physical_name, LEN(f.physical_name) - pos.p), f.type_desc, w.hinweis    ORDER BY verzeichnis, dateityp    OPTION (MAXDOP 1);ELSE    SELECT N'Datenbankdateien je Verzeichnis' AS verzeichnis,           N'nicht geprüft: VIEW ANY DEFINITION fehlt (sys.master_files zeigt sonst keine Zeilen)' AS hinweis; /* 3 · Windows-Reste in msdb (nach einer Migration typisch)   Jobschritte mit Laufwerksbuchstaben oder UNC-Pfad im Befehl oder in der Ausgabedatei,   Jobschritte vom Typ CmdExec, PowerShell oder SSIS, Backups der letzten 30 Tage auf Windows-Pfade. */IF HAS_PERMS_BY_NAME(N'msdb.dbo.sysjobsteps', N'OBJECT', N'SELECT') = 1   AND HAS_PERMS_BY_NAME(N'msdb.dbo.backupmediafamily', N'OBJECT', N'SELECT') = 1BEGIN    SELECT fund, anzahl, beispiel, N'' AS hinweis    FROM (        SELECT N'Jobschritt mit Windows-Pfad' AS fund, COUNT(*) AS anzahl,               MIN(j.name + N' / ' + s.step_name) AS beispiel        FROM msdb.dbo.sysjobsteps AS s JOIN msdb.dbo.sysjobs AS j ON j.job_id = s.job_id        WHERE s.command LIKE N'%[A-Za-z]:\%' OR s.command LIKE N'%\\%'           OR s.output_file_name LIKE N'[A-Za-z]:\%' OR s.output_file_name LIKE N'\\%'        UNION ALL        SELECT N'Jobschritt CmdExec, PowerShell oder SSIS', COUNT(*),               MIN(j.name + N' / ' + s.step_name + N' (' + s.subsystem + N')')        FROM msdb.dbo.sysjobsteps AS s JOIN msdb.dbo.sysjobs AS j ON j.job_id = s.job_id        WHERE s.subsystem IN (N'CmdExec', N'PowerShell', N'SSIS')        UNION ALL        SELECT N'Backup der letzten 30 Tage auf Windows-Pfad', COUNT(*), MIN(m.physical_device_name)        FROM msdb.dbo.backupmediafamily AS m        JOIN msdb.dbo.backupset AS b ON b.media_set_id = m.media_set_id        WHERE b.backup_finish_date >= DATEADD(DAY, -30, GETDATE())          AND (m.physical_device_name LIKE N'[A-Za-z]:\%' OR m.physical_device_name LIKE N'\\%')    ) AS x    OPTION (MAXDOP 1);ENDELSE    SELECT N'Windows-Reste in msdb' AS fund, NULL AS anzahl, NULL AS beispiel,           N'nicht geprüft: Lesezugriff auf msdb (sysjobsteps, backupmediafamily) fehlt' AS hinweis;

Beispielausgabe

Aus dem Lab: SQL Server 2022 CU27 im Container, als sa, nachdem wir für Abschnitt 1 eine Datenbank und ein Backup mit C:\-Pfad angelegt hatten:

Beispielausgabe
plattform  distribution  release  version      standard_datenpfad    standard_backuppfad  speichermodell
---------  ------------  -------  -----------  --------------------  -------------------  --------------
Linux      Ubuntu        22.04    16.0.4295.3  /var/opt/mssql/data/  /var/opt/mssql/data  CONVENTIONAL

verzeichnis            dateityp  dateien  datenbanken  groesse_gb  volume_gb  frei_gb  hinweis
---------------------  --------  -------  -----------  ----------  ---------  -------  -----------------------------------------
/var/opt/mssql/data    LOG       7        7            .1          46.9       21.7
/var/opt/mssql/data    ROWS      12       7            .2          46.9       21.7
C:\var\opt\mssql\data  LOG       1        1            .0          46.9       21.7     Windows-Pfad unter Linux: C:\ steht für /
C:\var\opt\mssql\data  ROWS      1        1            .0          46.9       21.7     Windows-Pfad unter Linux: C:\ steht für /

fund                                         anzahl  beispiel
-------------------------------------------  ------  ------------------------------------
Jobschritt mit Windows-Pfad                  0       NULL
Jobschritt CmdExec, PowerShell oder SSIS     0       NULL
Backup der letzten 30 Tage auf Windows-Pfad  1       C:\var\opt\mssql\data\l8_cmaster.bak

Spalten gekürzt. So lesen Sie das: Daten, Log und Backups liegen alle unter /var/opt/mssql/data, auf einem Dateisystem mit 21,7 GB frei; das ist der Standard und selten das, was man in Produktion will (Abschnitt 1). Zwei Datenbankdateien und ein Backup tragen Windows-Pfade, obwohl sie im selben Linux-Verzeichnis liegen. Nach einer Migration finden Sie hier vor allem Jobschritte und Backup-Ziele, die noch auf Laufwerke oder Freigaben unter Windows zeigen. Ohne VIEW ANY DEFINITION meldet Teil 2 „nicht geprüft“, ohne Lesezugriff auf msdb ebenso Teil 3.

Methode und Grenzen

Gemessen am 12.11.2026 in Linux-Containern auf einer Ubuntu-VM (cgroup v2, Docker 29.8) mit den Microsoft-Images SQL Server 2017 CU31, 2019 CU32, 2022 CU27 und 2025 CU10 (Ubuntu-Varianten), Developer Edition; je Version ein frischer Container ohne Netzwerk, Instant File Initialization mit 4-GB-Dateien auf dem Container-Dateisystem (overlayfs). Ola Hallengrens Maintenance Solution im Stand vom 12.09.2026 und das First Responder Kit 8.34 haben wir unverändert mit Standardeinstellungen ausgeführt. Was wir nicht selbst gemessen haben, stammt aus Microsoft Learn (Seitenstände Juli 2025 bis Oktober 2026, gelesen am 12.11.2026) und aus dem Quellcode der genannten Projekte. Grenzen:

  • Container statt Server: Kein systemd, kein SELinux, keine Domäne, keine eingehängte Freigabe. systemctl, SELinux, Active Directory, CIFS und Pacemaker beschreiben wir nach der Dokumentation, nicht nach eigener Messung.
  • Agent auf 2017 und 2019: Der Agent dieser Versionen meldet sich per Netzwerk an (local),1433 an. Im Container ohne Netzwerk scheiterte das, und er beendete sich. Ola-Jobs auf diesen Versionen haben wir deshalb nicht über den Agent geprüft, nur die Prozeduren direkt. Das ist eine Grenze unseres Aufbaus, kein Verhalten unter Linux.
  • Keine Windows-Gegenprobe: Die Spalte „Unter Windows“ beruht auf der Dokumentation, nicht auf eigenen Messungen.
  • dbatools: Aussagen aus dem Quellcode, nicht getestet.
  • Je Fall ein Lauf; Zeiten zeigen Größenordnungen.

Weiterlesen

Sie übernehmen eine Linux-Instanz?

Drei Dinge zuerst: Lassen Sie Abfrage 3 laufen und sehen Sie nach, wo Daten, Log und Backups liegen und ob msdb noch Windows-Pfade enthält. Prüfen Sie, ob der Agent eingeschaltet ist und ob es eine Wartung gibt, denn einen Wartungsplan kann es nicht geben. Und lesen Sie /var/opt/mssql/mssql.conf sowie im Container die Umgebungsvariablen, bevor Sie etwas mit mssql-conf ändern.

Weitere Teile der Reihe