Läuft lokal, stirbt auf dem Server? Unter Unix unterscheidet MySQL bei Tabellennamen die Schreibweise, unter Windows und macOS nicht.
Aufwand:
ca. 30 Min.
Voraussetzung:
Datenbankzugang mit Leserechten, Zugriff auf beide Umgebungen
Gilt für:
MySQL 8.0
Das Symptom
Die Anwendung läuft auf dem Entwicklerrechner tadellos. Dieselbe Fassung auf dem
Server meldet, eine Tabelle existiere nicht — obwohl sie in der Datenbank sichtbar
danebensteht und ein Datenbankwerkzeug sie anstandslos öffnet. Betroffen sind oft
nur einzelne Abfragen, nämlich genau die, in denen jemand die Tabelle irgendwann
mit einem Großbuchstaben geschrieben hat.
Die „Layer 8“-Wahrheit
MySQL ist an dieser Stelle keine abgeschlossene Welt, sondern reicht die Eigenheiten
des Betriebssystems durch. Eine Datenbank ist ein Verzeichnis, eine Tabelle
mindestens eine Datei darin. Damit erbt die Datenbank die Frage, ob Users und
users dasselbe sind, direkt vom Dateisystem — und die Antwort fällt unter Windows
anders aus als unter Linux. macOS liegt dazwischen: Unix-artig, aber mit einem
Dateisystem, das die Schreibweise ebenfalls durchgehen lässt.
Das ist nicht dasselbe wie ein Build, der im CI an einem falsch geschriebenen
Dateinamen scheitert, auch wenn es sich genauso anfühlt. Dort geht es um Dateien im
Projektverzeichnis; hier um Namen innerhalb der Datenbank, die ihre Empfindlichkeit
lediglich vom Dateisystem geerbt haben. Gemeinsam ist beiden nur die Erkenntnis,
dass Nachsicht kein Verhalten ist, auf das man bauen kann.
Der eigentliche Ärger beginnt beim Reparieren. Der naheliegende Reflex — die
Einstellung in die Optionsdatei schreiben und neu starten — geht ins Leere: Sie ist
nur beim Initialisieren des Servers zu haben, danach ist eine Änderung untersagt.
Bleiben zwei ehrliche Wege. Entweder man einigt sich auf eine Schreibweise, benennt
um und hält sie durch. Oder man sorgt dafür, dass die Datenbank auf dem eigenen
Rechner unter denselben Bedingungen läuft wie die auf dem Server. Beides ist
langweilig. Beides ist besser als ein Programm, dessen Funktionieren davon abhängt,
auf welchem Betriebssystem es zufällig gestartet wurde.
Die echte, verifizierte Lösung
1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:
1.
Die tatsächliche Schreibweise nachsehen
Erst feststellen, wie die Tabelle wirklich heißt, statt sich auf die Erinnerung oder auf ein Datenbankwerkzeug zu verlassen, das Namen hübsch macht. Die Ausgabe Zeichen für Zeichen mit dem Namen in der Abfrage vergleichen:
SHOW TABLES;
2.
Die Einstellung auf beiden Rechnern vergleichen
Denselben Befehl auf dem Entwicklerrechner und auf dem Server absetzen und die Werte nebeneinanderlegen. Genau hier wird der Unterschied sichtbar, den man sonst nur ahnt:
SHOW VARIABLES LIKE 'lower_case_table_names';
3.
Die Vorgabewerte einordnen
Das MySQL-8.0-Handbuch nennt drei verschiedene Voreinstellungen: unter Unix 0, unter Windows 1, unter macOS 2. Bei 0 werden Namen so gespeichert, wie sie angelegt wurden, und Vergleiche sind schreibweisenempfindlich. Bei 1 speichert MySQL alle Tabellennamen kleingeschrieben und vergleicht ohne Rücksicht auf die Schreibweise. Bei 2 bleibt die Schreibweise erhalten, der Vergleich ist aber unempfindlich. Drei Rechner, drei Verhaltensweisen — und niemand hat je etwas eingestellt.
4.
Nicht am laufenden Server schrauben
Der Griff zur Optionsdatei ist der naheliegende und der falsche. Die Einstellung lässt sich laut Handbuch nur beim Initialisieren des Servers festlegen; eine spätere Änderung ist untersagt. Wer sie trotzdem einträgt, hat danach keinen umgestellten, sondern einen streikenden Server. Falls die Umstellung wirklich sein muss: neue Instanz mit der gewünschten Einstellung initialisieren, Abzug einspielen, alte Instanz abschalten.
5.
Die Namen im Schema angleichen
Der belastbare Weg führt über eine einzige, konsequent durchgehaltene Schreibweise — üblicherweise durchgehend klein. Vorhandene Tabellen lassen sich gezielt umbenennen; danach muss der Code dieselbe Schreibweise verwenden:
RENAME TABLE Users TO users;
6.
Die Abweichung früh sichtbar machen
Damit der Unterschied nicht erst beim nächsten Aufspielen auffällt, sollte die Entwicklungsumgebung dieselbe Plattform benutzen wie der Server — in der Praxis heißt das: die Datenbank lokal im selben Container-Abbild betreiben wie in der Produktion. Dann meldet sich der Fehler auf dem eigenen Rechner statt zwei Wochen später vor Publikum.
Häufige Fragen (FAQ)
?Warum läuft dieselbe Abfrage lokal und stirbt auf dem Linux-Server?
Weil MySQL Datenbanken als Verzeichnisse und Tabellen als Dateien darin ablegt. Damit entscheidet das Dateisystem des Betriebssystems mit, ob die Schreibweise zählt. Das Handbuch sagt es unverblümt: Solche Namen sind unter Windows nicht schreibweisenempfindlich, in den meisten Unix-Varianten dagegen schon. macOS ist zwar Unix-artig, benutzt aber ein Standarddateisystem, das die Schreibweise ebenfalls nicht unterscheidet. Der Entwicklerrechner ist also nachsichtig, der Server nicht — und beide haben recht.
?Kann ich lower_case_table_names einfach in die Konfiguration schreiben und neu starten?
Nein, und das ist der Punkt, an dem die meisten eine Stunde verlieren. Das MySQL-8.0-Handbuch stellt fest, dass diese Einstellung nur bei der Initialisierung des Servers gesetzt werden kann und eine Änderung nach der Initialisierung untersagt ist. Ein nachträglicher Eintrag in die Optionsdatei stellt einen bestehenden Server also nicht um. Wer den Wert wirklich ändern will, initialisiert eine neue Instanz mit der gewünschten Einstellung und spielt die Daten dort ein — ein Umzug, keine Konfigurationsänderung.
?Betrifft das auch Spalten, Indizes und Aliase?
Nein, und diese Unterscheidung erspart viel unnötige Sucherei. Laut Handbuch sind Partitions-, Unterpartitions-, Spalten-, Index-, Routinen-, Ereignis- und Ressourcengruppennamen auf keiner Plattform schreibweisenempfindlich, Spaltenaliase ebenso wenig. Betroffen sind Datenbank-, Tabellen- und Triggernamen — also genau das, was auf dem Datenträger als Verzeichnis oder Datei landet. Wer eine Spalte falsch schreibt, bekommt überall denselben Fehler; wer eine Tabelle falsch schreibt, nur auf einem Teil der Rechner.
Belege
Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.
Der Login wird abgewiesen, obwohl das Passwort stimmt? Bei MySQL zählt auch, von welchem Host aus man kommt — der Benutzer ist an eine Herkunft gebunden.