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.
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, undC:\gibt es trotzdem. SQL Server übersetztC:\in/. Ein Pfad wieC:\var\opt\mssql\data\x.mdffunktioniert,C:\SQLData\x.mdfscheitert. Groß- und Kleinschreibung von Dateinamen ignoriert SQL Server auch unter Linux. - Alles gehört dem Benutzer
mssql. Ein Backupziel ohne Schreibrecht fürmssqlendet mit einer Windows-Fehlermeldung:Operating system error 5(Access is denied.). mssql-confersetzt den Configuration Manager,systemctldie Dienstverwaltung. Im Container schlagen Umgebungsvariablen die Konfigurationsdatei bei jedem Start. Wermasterpermssql-confverlegt, ohne die Dateien mitzunehmen, startet mit einer leerenmaster.- Windows-Griffe liefern Windows-Antworten oder nichts. Registry-Abfragen geben NULL zurück, ohne dass T-SQL einen Fehler meldet,
sys.dm_server_registryist leer, undsys.dm_server_servicesist 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 Windows | Unter Linux | Stolperstelle | |
|---|---|---|---|
| Programm | C:\Program Files\Microsoft SQL Server\… | /opt/mssql | Eine Instanz je Host, benannte Instanzen gibt es nicht |
| Daten und Log neuer Datenbanken | Pfade aus dem Setup, oft getrennte Laufwerke | beides /var/opt/mssql/data | Daten und Log liegen zusammen, bis Sie es mit mssql-conf ändern |
| Standard-Backupverzeichnis | Pfad aus dem Setup | /var/opt/mssql/data | Backups landen neben den Datenbankdateien |
| Errorlog | …\MSSQL\Log\ERRORLOG | /var/opt/mssql/log/errorlog | Text; das Agent-Log sqlagent.out ist UTF-16 |
| Konfiguration | Configuration Manager, Registry, Startparameter | /var/opt/mssql/mssql.conf | Die 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:
| Anweisung | Ergebnis |
|---|---|
CREATE DATABASE mit Datei C:\SQLData\x.mdf | Fehler 5133, Betriebssystemfehler 2: das Verzeichnis gibt es nicht |
CREATE DATABASE mit Datei C:\var\opt\mssql\data\x.mdf | funktioniert: 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.mdfschon im Verzeichnis, lehnte SQL Server eine neue Datenbank mitfall.mdfab (Fehler 5170, die Datei existiere bereits). - Ein Backup namens
L8.BAKließ sich mitRESTORE … 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 Windows | Unter Linux | Stolperstelle | |
|---|---|---|---|
| Dienstkonto | Dienstkonto oder virtuelles Konto, Rechte über NTFS | Benutzer mssql ohne interaktive Anmeldung; alles unter /var/opt/mssql gehört ihm | Einen Eigentümerwechsel der SQL-Server-Verzeichnisse unterstützt Microsoft nicht |
| Eigenes Backupverzeichnis | NTFS-Recht für das Dienstkonto | Eigentümer oder Gruppe mssql, Schreibrecht | Ohne Recht: Operating system error 5(Access is denied.) |
| Neue Dateien | erben NTFS-Rechte | gehören mssql, Rechte 640 bzw. 660 | Andere Benutzer und Werkzeuge brauchen Gruppenrechte |
| Zusätzliche Abschottung | – | SELinux (Red Hat) mit Paket mssql-server-selinux | Eigene 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-serverBemerkenswert 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 Windows | Unter Linux | Stolperstelle | ||||
|---|---|---|---|---|---|---|
| Dienst steuern | Dienste-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 |
| Einstellungen | Configuration Manager | mssql-conf, schreibt /var/opt/mssql/mssql.conf | Fast jede Änderung braucht einen Neustart | |||
| Trace Flags beim Start | Startparameter -T | mssql-conf traceflag 3226 on | ||||
| Port, TLS | Configuration Manager | mssql-conf set network.tcpport, network.tlscert, network.tlskey | Zertifikatsdateien müssen mssql gehören | |||
| Speichergrenze | max server memory | zusätzlich memory.memorylimitmb für den ganzen Prozess, Standard 80 % | Beide Grenzen setzen, sie meinen Verschiedenes | |||
| SQL Server Agent | Dienst „SQL Server Agent“ | mssql-conf set sqlagent.enabled true | Nach der Installation ausgeschaltet | |||
Lage von master | Startparameter -d, -l | mssql-conf set filelocation.masterdatafile, …masterlogfile | Ohne 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-servermssql-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:
| Variable | Einstellung in mssql.conf | nach dem Neustart (2017–2025) |
|---|---|---|
MSSQL_AGENT_ENABLED=false | sqlagent.enabled = true | Agent aus |
MSSQL_AGENT_ENABLED=true | sqlagent.enabled = false | Agent an |
MSSQL_MEMORY_LIMIT_MB=2000 | memory.memorylimitmb = 3000 | 2.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-confdem Containerbenutzer den Dienst, er muss als root laufen. Hat root die Datei einmal geschrieben, scheitern spätere Aufrufe als Containerbenutzer mitPermission 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. systemctlgibt es im Container nicht. Neu gestartet wird der Container; wie man ihn dabei sauber herunterfährt, zeigt Teil 3.
Errorlog lesen
| Unter Windows | Unter Linux | Stolperstelle | |
|---|---|---|---|
| Errorlog der Engine | Datei ERRORLOG, sp_readerrorlog | Datei /var/opt/mssql/log/errorlog, sp_readerrorlog | Die Datei ist Text, obwohl die Dokumentation UTF-16 nennt |
| Agent-Log | Datei SQLAGENT.OUT | Datei /var/opt/mssql/log/sqlagent.out | UTF-16 mit Byte-Order-Mark |
| Ereignisse des Dienstes | Ereignisanzeige | systemctl status mssql-server; im Container docker logs | journalctl nennt Microsoft nicht |
| Anzahl aufbewahrter Logs | SSMS, Registry | nicht änderbar | siehe 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 -20Die 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 Windows | Unter Linux | Stolperstelle | |
|---|---|---|---|
| Dateisystem | NTFS, ReFS | XFS oder ext4, NFS ab Version 4.2 | Andere Dateisysteme sind nicht unterstützt |
| Backup auf eine Freigabe | BACKUP … TO DISK = '\\server\share\…' | Freigabe als Verzeichnis einhängen (CIFS), dann Linux-Pfad | UNC-Pfade in T-SQL nur über mssql-conf set uncmapping |
| Instant File Initialization | Recht „Perform volume maintenance tasks“ für das Dienstkonto | ohne Recht wirksam für Datendateien | Manche Werkzeuge melden sie als ausgeschaltet |
| Lock Pages in Memory | Recht „Lock pages in memory“ | keine dokumentierte Entsprechung | Alle 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 0Danach 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:
| 2017 | 2019 | 2022 | 2025 | |
|---|---|---|---|---|
| Neue 4-GB-Datendatei | 0,7 s | 0,8 s | 0,8 s | 0,7 s |
| Neue 4-GB-Logdatei | 11,8 s | 11,6 s | 11,6 s | 11,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:
- Linux-Host in die Domäne aufnehmen (zum Beispiel mit
realmdund SSSD). - Ein AD-Benutzerkonto für SQL Server anlegen, mit AES-Verschlüsselung für Kerberos.
- SPNs
MSSQLSvc/<FQDN>:<Port>undMSSQLSvc/<Hostname>:<Port>für dieses Konto registrieren. - Ein Keytab erzeugen (
adutilunter Linux oderktpassunter Windows), unter/var/opt/mssql/secretsablegen, Eigentümermssql, Rechte 400. mssql-conf set network.privilegedadaccount <Konto>undnetwork.kerberoskeytabfile <Pfad>, Neustart.- 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 Windows | Unter Linux | Stolperstelle | |
|---|---|---|---|
| Cluster | Windows-Failovercluster (WSFC) | Pacemaker (CLUSTER_TYPE = EXTERNAL) oder keiner (NONE) | Ohne Pacemaker nur manueller Failover |
| Endpunkte | Kerberos oder Zertifikate | Zertifikate | Windows-Authentifizierung für Endpunkte gibt es nicht |
| Listener | Netzwerkname im AD | IP-Adresse als Cluster-Ressource plus DNS-Eintrag | Kurzer Ausfall beim Failover |
| Verteilte Transaktionen | MSDTC | nicht 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 Windows | Unter Linux | Stolperstelle | |
|---|---|---|---|
| SSMS | voller Umfang | verbindet sich wie gewohnt | Keine Wartungspläne, kein Data Collector, Zahl der Errorlogs nicht änderbar |
| Configuration Manager | ja | verbindet sich nicht | mssql-conf (Abschnitt 3) |
| Azure Data Studio | im Ruhestand seit 28.02.2026 | ebenso | Nachfolger: VS Code mit MSSQL-Erweiterung; Agent und klassische Verwaltung bleiben in SSMS |
sqlcmd, bcp | ja | ja, nativ | |
| dbatools | voller Umfang | Befehle, die nur T-SQL nutzen | Befehle 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:
sa auf SQL Server 2017 bis 2025 im Container gemessen. Die Einzelheiten stehen in der Tabelle.| Griff | Was er unter Linux liefert |
|---|---|
xp_fixeddrives | ein 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_regwrite | läuft ohne Fehler, ändert nichts |
sys.dm_server_registry | keine Zeilen |
sys.dm_server_services | 2017 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_stats | Größe und freier Platz ja; Mountpunkt, Volumename und Dateisystemtyp NULL |
xp_msver | Plattform „NT x64“ |
xp_readerrorlog, sp_readerrorlog | funktionieren |
sys.dm_os_host_info | Linux 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
@Directorysicherte sie in das Standard-Backupverzeichnis unter/var/opt/mssql/data/<Server>/<Datenbank>/FULL/; die Unterverzeichnisse legte SQL Server beimBACKUPselbst 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 Space | der 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\Administrators | Login aus der Installation, kein Fehler Ihrer Konfiguration |
Sysadmins: NT AUTHORITY\NETWORK SERVICE | ebenso; 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 Windows | Unter Linux | Stolperstelle | |
|---|---|---|---|
| Kumulative Updates | Installationsprogramm des CU | Paketmanager aus dem Repository mssql-server-<Version> (dnf/yum, apt-get, zypper) | Das Repository legt die Hauptversion fest |
| Ohne Internetzugang | CU-Datei kopieren | Paketdatei herunterladen und lokal installieren | |
| Zurück auf einen älteren Stand | Deinstallation des CU | Downgrade des Pakets, nur innerhalb der Hauptversion | |
| Im Container | – | neues Image mit neuem Tag, gleiches Datenvolume | Teil 3 |
sudo apt-get update && sudo apt-get install mssql-server # Ubuntu
sudo dnf update mssql-server # Red HatSteckbrief: 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
/* 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:
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.bakSpalten 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),1433an. 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
- Microsoft Learn: „Configure SQL Server settings on Linux (mssql-conf)“, „Start, stop, and restart SQL Server services on Linux“, „SQL Server on Linux: Known issues“, „SQL Server on Linux frequently asked questions“, „Get started with SQL Server on SELinux“, „Tutorial: Use adutil to configure Active Directory authentication“, „Configure log shipping on Linux“.
- Microsoft Learn: „What's happening with Azure Data Studio“.
- Ola Hallengren: SQL Server Maintenance Solution. Brent Ozar Unlimited: First Responder Kit.
- In dieser Reihe: Übersicht, Teil 1: Linux, Container oder Windows?, Teil 3: Was im Container schiefgeht.
- Bei PSG: FCI vs. Availability Groups, Backup und Restore.
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.