MySQL-Backup auf neuerem Server — Kompatibilitätsprobleme lösen

MySQL-Versionskompatibilität bei Migrationen prüfen

Du hast einen sauberen mysqldump gemacht, spielst ihn auf dem neuen Server ein — und der Import bricht mit kryptischen Fehlermeldungen ab. Willkommen im Minenfeld der MySQL-Versionskompatibilität. Über die Jahre hat sich an der MySQL-Syntax einiges geändert, und ein Dump, der auf MySQL 4.x oder 5.0 erstellt wurde, läuft auf MySQL 8.0 nicht ohne Anpassungen durch.

Hier sind die häufigsten Kompatibilitätsprobleme und ihre Lösungen — sortiert nach Häufigkeit.

1. TYPE=MyISAM vs. ENGINE=MyISAM

Das ist der absolute Klassiker, wenn du Dumps aus der MySQL-4.x-Ära importierst.

Fehlermeldung

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
near 'TYPE=MyISAM' at line 25

Ursache

In MySQL 4.x und frühen 5.0-Versionen wurde die Storage Engine mit TYPE= angegeben. Ab MySQL 5.0 wurde ENGINE= eingeführt, TYPE= funktionierte aber noch als Alias. Ab MySQL 5.5 ist TYPE= komplett entfernt.

Lösung

Einfaches Suchen-und-Ersetzen in der Dump-Datei:

# Mit sed ersetzen
sed -i 's/TYPE=MyISAM/ENGINE=MyISAM/g' dump.sql
sed -i 's/TYPE=InnoDB/ENGINE=InnoDB/g' dump.sql

# Oder gleich alle TYPE=-Vorkommen
sed -i 's/TYPE=/ENGINE=/g' dump.sql

Falls du die Gelegenheit nutzen willst, um gleich auf InnoDB zu wechseln (empfohlen für die meisten Anwendungsfälle):

sed -i 's/ENGINE=MyISAM/ENGINE=InnoDB/g' dump.sql

2. Zeichensatz-Änderungen (CHARSET)

Fehlermeldung

ERROR 1115 (42000): Unknown character set: 'utf8mb3'
-- oder --
ERROR 1273 (HY000): Unknown collation: 'utf8mb4_0900_ai_ci'

Ursache

MySQL 8.0 hat den Standard-Zeichensatz von latin1 auf utf8mb4 geändert und eine neue Standard-Collation utf8mb4_0900_ai_ci eingeführt. Ältere MySQL-Versionen kennen diese Collation nicht. Umgekehrt verwenden manche MySQL-8.0-Dumps utf8mb3 als expliziten Alias für das alte utf8, was ältere Versionen nicht verstehen.

Lösung

# Unbekannte Collation in älteren MySQL-Versionen ersetzen
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' dump.sql

# utf8mb3 durch utf8 ersetzen (für Import in ältere Versionen)
sed -i 's/utf8mb3/utf8/g' dump.sql

# Zeichensatz beim Import explizit setzen
mysql -u user -p --default-character-set=utf8mb4 datenbank < dump.sql

Mehr zu Zeichensatz-Problemen findest du im Artikel MySQL-Zeichensatz und Umlaute.

3. sql_mode STRICT (MySQL 5.7+)

Fehlermeldung

ERROR 1364 (HY000): Field 'email' doesn't have a default value
ERROR 1292 (22007): Incorrect date value: '0000-00-00' for column 'created_at'

Ursache

Ab MySQL 5.7 ist STRICT_TRANS_TABLES standardmäßig aktiviert. Das bedeutet:

  • Fehlende Pflichtfelder ohne Default-Wert erzeugen einen Fehler statt einer Warnung
  • Das Datum 0000-00-00 wird nicht mehr akzeptiert
  • Leere Strings in numerische Spalten einzufügen schlägt fehl

Alte Dumps enthalten oft genau solche Daten, weil MySQL 5.5 und früher das alles stillschweigend akzeptiert hat.

Lösung

Am Anfang der Dump-Datei den sql_mode temporär lockern:

SET sql_mode = '';
SET GLOBAL sql_mode = '';

Oder beim Import direkt angeben:

mysql -u user -p --init-command="SET sql_mode=''" datenbank < dump.sql

Die nachhaltigere Lösung ist, die problematischen Daten im Dump zu korrigieren:

# 0000-00-00 Datumswerte durch NULL ersetzen
sed -i "s/'0000-00-00'/NULL/g" dump.sql
sed -i "s/'0000-00-00 00:00:00'/NULL/g" dump.sql

4. ROW_FORMAT-Probleme

Fehlermeldung

ERROR 1031 (HY000): Table storage engine for 'tabelle' doesn't have this option
ERROR 1005 (HY000): Can't create table (errno: 140 "Wrong create options")

Ursache

Dumps können explizite ROW_FORMAT-Angaben enthalten (z.B. ROW_FORMAT=FIXED, ROW_FORMAT=COMPRESSED), die auf dem Zielsystem nicht unterstützt werden. Besonders ROW_FORMAT=COMPRESSED erfordert das Barracuda-Dateiformat bei InnoDB.

Lösung

# ROW_FORMAT-Angaben entfernen
sed -i 's/ROW_FORMAT=[A-Z]*//g' dump.sql

Falls du ROW_FORMAT=COMPRESSED brauchst, muss auf dem Zielsystem Folgendes gesetzt sein:

[mysqld]
innodb_file_format = Barracuda
innodb_file_per_table = 1

5. Reservierte Wörter als Spalten- oder Tabellennamen

Fehlermeldung

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
near 'rank int(11)' at line 3

Ursache

MySQL erweitert mit jeder Version die Liste der reservierten Wörter. Was in MySQL 5.5 noch als Spaltenname erlaubt war, kann in MySQL 8.0 ein reserviertes Schlüsselwort sein. Bekannte Beispiele:

Wort Reserviert seit
RANK MySQL 8.0
GROUPS MySQL 8.0
FUNCTION MySQL 8.0
SYSTEM MySQL 8.0
ROW MySQL 8.0
WINDOW MySQL 8.0
LATERAL MySQL 8.0.14

Lösung

Die betroffenen Bezeichner müssen mit Backticks escaped werden:

-- Vorher (funktioniert nicht in MySQL 8.0):
CREATE TABLE rankings (rank int(11), name varchar(255));

-- Nachher:
CREATE TABLE rankings (`rank` int(11), `name` varchar(255));

Ein guter mysqldump setzt standardmäßig Backticks um alle Bezeichner. Probleme entstehen meist bei manuell erstellten SQL-Dateien oder Dumps von sehr alten Tools.

# Prüfen, ob der Dump Backticks verwendet
head -50 dump.sql | grep "CREATE TABLE"

6. Integer Display Width deprecated (MySQL 8.0)

Warnmeldung

Warning 1681: Integer display width is deprecated and will be removed in a future release.

Ursache

In MySQL 8.0.17 wurde die Angabe der Display-Breite bei Integer-Typen als deprecated markiert. Das betrifft Definitionen wie int(11), tinyint(1), bigint(20). Die Zahl in Klammern hat nie die Speichergröße beeinflusst — sie bestimmte nur die Anzeigebreite bei ZEROFILL.

Lösung

Aktuell ist das nur eine Warnung, kein Fehler. Der Import funktioniert trotzdem. Wenn du die Warnungen loswerden willst:

# Display Width aus dem Dump entfernen
sed -i 's/int([0-9]*)/int/g' dump.sql
sed -i 's/bigint([0-9]*)/bigint/g' dump.sql
sed -i 's/tinyint([0-9]*)/tinyint/g' dump.sql
sed -i 's/smallint([0-9]*)/smallint/g' dump.sql
sed -i 's/mediumint([0-9]*)/mediumint/g' dump.sql

Achtung: tinyint(1) wird von vielen ORMs (z.B. in PHP/Laravel) als Boolean interpretiert. Wenn du das entfernst, kann es zu Problemen in der Anwendung kommen. Prüfe das vorher.

7. Authentication Plugin (MySQL 8.0)

Fehlermeldung

ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded

Ursache

MySQL 8.0 verwendet standardmäßig caching_sha2_password statt mysql_native_password. Ältere Clients und PHP-Versionen unterstützen das nicht.

Lösung

Den Benutzer auf das alte Plugin umstellen:

ALTER USER 'dbuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'passwort';

Oder in der my.cnf global setzen:

[mysqld]
default_authentication_plugin = mysql_native_password

Strategie: Migration sicher testen

Bevor du einen Dump auf dem Produktivsystem einspielst, teste die Migration immer in einer sicheren Umgebung:

1. Lokale Testumgebung aufsetzen

# Docker-Container mit der Ziel-MySQL-Version starten
docker run -d --name mysql-test \
  -e MYSQL_ROOT_PASSWORD=test \
  -e MYSQL_DATABASE=testdb \
  -p 3307:3306 \
  mysql:8.0

# Dump importieren
mysql -h 127.0.0.1 -P 3307 -u root -ptest testdb < dump.sql

2. Fehler protokollieren

# Import mit Fehlerprotokoll
mysql -u root -p testdb < dump.sql 2> import_errors.log

# Fehler auswerten
cat import_errors.log | sort | uniq -c | sort -rn

3. Schrittweise korrigieren

Arbeite die Fehler systematisch ab. Erstelle ein Korrektur-Skript, das du auf den Dump anwendest:

#!/bin/bash
# fix_dump.sh — Kompatibilitäts-Fixes für MySQL 8.0

DUMP=$1

# TYPE= durch ENGINE= ersetzen
sed -i 's/TYPE=MyISAM/ENGINE=MyISAM/g' "$DUMP"
sed -i 's/TYPE=InnoDB/ENGINE=InnoDB/g' "$DUMP"

# Unbekannte Collation ersetzen
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' "$DUMP"

# Ungültige Datumswerte korrigieren
sed -i "s/'0000-00-00'/NULL/g" "$DUMP"
sed -i "s/'0000-00-00 00:00:00'/NULL/g" "$DUMP"

# ROW_FORMAT entfernen
sed -i 's/ROW_FORMAT=[A-Z]*//g' "$DUMP"

echo "Fixes angewendet auf $DUMP"

4. Daten nach Import prüfen

# Tabellen zählen
SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'testdb';

# Zeilenanzahl pro Tabelle
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = 'testdb'
ORDER BY table_rows DESC;

Kompatibilitätsmatrix

Dump-Quelle Ziel-Version Typische Probleme
MySQL 4.x MySQL 5.7/8.0 TYPE=, CHARSET, sql_mode strict
MySQL 5.0-5.5 MySQL 5.7 sql_mode strict, 0000-00-00 Daten
MySQL 5.5-5.6 MySQL 8.0 Reservierte Wörter, Display Width, Auth Plugin
MySQL 5.7 MySQL 8.0 Reservierte Wörter, Auth Plugin, Collation
MySQL 8.0 MySQL 5.7 utf8mb3-Alias, Window Functions, CTEs in Views
MySQL 8.0 MariaDB 10.x Collation, Auth Plugin, JSON-Syntax-Unterschiede

Fazit

MySQL-Versionsinkompatibilitäten sind lästig, aber beherrschbar. Die meisten Probleme lassen sich mit ein paar gezielten sed-Befehlen vor dem Import lösen. Mein Rat: Teste den Import immer zuerst in einer Wegwerf-Umgebung (Docker ist dafür ideal), protokolliere die Fehler, und arbeite sie systematisch ab. So vermeidest du böse Überraschungen auf dem Produktivsystem.

Weiterführende Anleitungen findest du im mysqldump-Tutorial und im Artikel MySQL-Zeichensatz und Umlaute richtig konfigurieren.