Layer 8Ehrlicher Tech-Support

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. 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. 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. 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. 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. 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.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler

SWLästig

Der Termin verschiebt sich um eine Stunde

Nach der Zeitumstellung steht die Besprechung plötzlich um zehn statt um neun. Schuld ist nicht der Kalender, sondern eine Uhrzeit ohne Zeitzone.

SWLästigAccess denied for user

MySQL: Access denied for user

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.

SWLästigconnection refused

PostgreSQL: Connection refused auf Port 5432

Die App erreicht die Datenbank nicht — Connection refused? Meist lauscht PostgreSQL nur auf localhost oder die Client-Freigabe in pg_hba.conf fehlt.