MySQL: Unknown or incorrect time zone bei „Europe/Berlin“
Benannte Zeitzonen funktionieren nur, wenn die Zeitzonentabellen in der mysql-Datenbank gefüllt sind. Frisch installiert sind sie leer.
Aufwand:
ca. 20 Min.
Voraussetzung:
Datenbankzugang mit Schreibrechten auf die mysql-Datenbank, Zoneinfo-Daten des Betriebssystems
Gilt für:
MySQL 8.0
Das Symptom
Die Anwendung setzt beim Verbindungsaufbau SET time_zone = 'Europe/Berlin' und
bekommt zurück: ERROR 1298 (HY000): Unknown or incorrect time zone. Auf dem
Entwicklerrechner lief dieselbe Zeile jahrelang, auf dem neuen Server oder im
frischen Container nicht mehr.
Mit SET time_zone = '+02:00' geht es dagegen anstandslos — was den Verdacht
zunächst auf die Anwendung lenkt. Zwei Wochen später, in der Nacht der Zeitumstellung,
liegen dann alle Termine um eine Stunde daneben, weil der feste Versatz die
Sommerzeit nicht kennt.
Die „Layer 8“-Wahrheit
MySQL kennt Zeitzonennamen nicht von Haus aus. Es liest sie aus mehreren Tabellen in
der mysql-Systemdatenbank, und diese Tabellen sind nach der Installation leer. Der
Server bringt also die Fähigkeit mit, benannte Zonen zu verstehen, aber nicht das
Wissen darüber, welche es gibt und welche Regeln für sie gelten. Dieses Wissen liegt
beim Betriebssystem, in der Zoneinfo-Datenbank, und muss mit mysql_tzinfo_to_sql
einmal hinüberkopiert werden. Das ist kein Fehler, sondern ein bewusst
ausgelassener Schritt — der in keinem Installationsassistenten auftaucht.
Der numerische Versatz als Notlösung ist dabei die schlechtere Hälfte des Problems.
+02:00 wird immer angenommen und ist immer falsch, sobald die Sommerzeit
wechselt. Eine benannte Zone weiß, dass Deutschland zweimal im Jahr springt; ein
fester Versatz weiß gar nichts. Wer nach dem Fehler 1298 auf +01:00 ausweicht,
tauscht eine laute Fehlermeldung gegen einen stillen Fehler, der sich zweimal
jährlich meldet und dann niemand mehr mit dieser Entscheidung in Verbindung bringt.
Und selbst geladene Tabellen sind keine Dauerlösung. Zeitzonenregeln ändern sich,
weil Parlamente das beschließen. Das Betriebssystem bekommt die neuen Regeln über
seine Paketverwaltung, die Kopie in der mysql-Datenbank nicht. Das Handbuch weist
ausdrücklich darauf hin, dass ein Neuladen der Zeitzonentabellen nötig werden kann,
um den Server aktuell zu halten. Wer das einmal beim Aufsetzen macht und dann nie
wieder, hat eine Datenbank, die den Sommerzeitregeln des Aufsetzungsjahres treu
bleibt.
Die echte, verifizierte Lösung
1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:
1.
Nachsehen, ob die Zeitzonentabellen befüllt sind
Erst den Befund sichern, statt gleich zu laden. Die Zählung auf der Namenstabelle beantwortet die Frage in einer Zeile. Steht dort 0, ist die Ursache gefunden und alle weiteren Vermutungen über Konfigurationsdateien erübrigen sich.
SELECT COUNT(*) FROM mysql.time_zone_name;
2.
Die Tabellen aus der Zoneinfo-Datenbank des Systems laden
MySQL bringt ein eigenes Programm dafür mit, das die Zoneinfo-Dateien des Betriebssystems in SQL-Anweisungen übersetzt. Deren Ausgabe wird in die mysql-Datenbank eingespielt. Unter Linux liegen die Dateien üblicherweise unter /usr/share/zoneinfo. Wer nur eine einzelne Zone braucht, kann dem Programm auch eine einzelne Datei und den gewünschten Namen übergeben.
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
3.
Den Server neu starten
MySQL hält Zeitzonendaten im Speicher vor. Nach dem Einspielen sollte der Serverprozess neu gestartet werden, damit er nicht weiter mit dem alten Stand arbeitet. Genau diesen Hinweis gibt auch das Handbuch für den Fall, dass die Tabellen aktualisiert wurden.
4.
Prüfen, ob die benannte Zone jetzt angenommen wird
Derselbe Befehl, der vorher mit Fehler 1298 gescheitert ist, muss nun ohne Rückmeldung durchlaufen. Die Vorgabe des Systemwertes time_zone ist laut Handbuch SYSTEM, was bedeutet, dass die Zeitzone des Servers der des Betriebssystems entspricht — für reproduzierbares Verhalten ist eine ausdrücklich gesetzte Zone die bessere Wahl.
SET time_zone = 'Europe/Berlin';
SELECT @@global.time_zone, @@session.time_zone, NOW();
5.
Die Tabellen bei Regeländerungen nachziehen
Zeitzonenregeln sind Politik, keine Physik. Ändert ein Land seine Sommerzeitregelung, wird die Zoneinfo-Datenbank des Betriebssystems aktualisiert — die Kopie in der mysql-Datenbank aber nicht. Das Handbuch formuliert es so: Treten solche Änderungen auf, werden Anwendungen, die die alten Regeln verwenden, ungültig, und es kann nötig sein, die Zeitzonentabellen neu zu laden, um die Informationen im Server aktuell zu halten. Praktisch heißt das: Der Ladebefehl gehört in dieselbe Routine, die auch die Systempakete aktualisiert.
Häufige Fragen (FAQ)
?Warum meldet MySQL bei SET time_zone eine unbekannte oder falsche Zeitzone?
Weil die Zeitzonentabellen leer sind. Benannte Zeitzonen wie Europe/Helsinki, US/Eastern oder UTC lassen sich laut Handbuch nur verwenden, wenn die Zeitzonen-Informationstabellen in der mysql-Datenbank angelegt und befüllt wurden. Andernfalls kommt genau die Meldung ERROR 1298 (HY000): Unknown or incorrect time zone zurück. Numerische Angaben wie +02:00 funktionieren dagegen auch ohne die Tabellen — was die Fehlersuche gern in die falsche Richtung schickt, weil scheinbar ja etwas geht.
?Wie prüfe ich, ob die Tabellen wirklich leer sind?
Mit einer Zählung auf mysql.time_zone_name. Das Handbuch führt genau diese Abfrage als Prüfung an; kommt dort 0 zurück, stehen keine benannten Zeitzonen zur Verfügung. Das ist der Normalzustand nach einer frischen Installation und nach vielen Container-Abbildern: Die Tabellen sind vorhanden, aber niemand hat sie gefüllt. Sie sind kein Teil der Serverinstallation im engeren Sinn, sondern werden aus der Zoneinfo-Datenbank des Betriebssystems nachgeladen.
?Betrifft die Zeitzone alle Datums- und Zeitspalten gleichermaßen?
Nein, und dieser Unterschied ist die eigentliche Falle. Werte in TIMESTAMP-Spalten werden laut Handbuch beim Speichern von der Zeitzone der Sitzung nach UTC umgerechnet und beim Lesen von UTC wieder in die Zeitzone der Sitzung zurück. DATETIME-Werte werden nicht umgerechnet; sie liegen so in der Datenbank, wie sie hineingeschrieben wurden. Zwei Spalten, dieselbe Uhrzeit hineingeschrieben, zwei verschiedene Antworten aus einer anderen Sitzung — und beides ist genau das dokumentierte Verhalten.
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.