auto_increment-Werte bei MySQL-Migration beibehalten

Auto-Increment Werte bei der Datenbank-Migration beibehalten

Du migrierst eine Datenbank auf einen neuen Server, importierst den Dump — und plötzlich stimmen die auto_increment-Werte nicht mehr. IDs fangen bei 1 an statt bei 48.372, oder Zeilen mit dem Wert 0 in der ID-Spalte bekommen eine neue Nummer verpasst. Was ist passiert, und wie verhinderst du das? Hier erfährst du alles, was du über auto_increment bei MySQL-Migrationen wissen musst.

Das Problem: Warum auto_increment-Werte sich ändern

MySQL hat eine Eigenheit, die bei Migrationen regelmäßig für Ärger sorgt: Standardmäßig interpretiert der Server den Wert 0 in einer auto_increment-Spalte als „generiere den nächsten Wert“. Wenn deine Anwendung also tatsächlich die ID 0 verwendet — ja, das gibt es, besonders bei Magento, WooCommerce und einigen Legacy-Systemen — wird diese 0 beim Import stillschweigend durch den nächsten freien Wert ersetzt.

Zweites Problem: Der auto_increment-Zähler der Tabelle. Auch wenn alle Zeilen korrekt importiert werden, kann der Zähler auf einen falschen Startwert gesetzt werden. Das passiert, wenn der Dump den AUTO_INCREMENT-Wert im CREATE TABLE-Statement nicht enthält oder die Import-Reihenfolge durcheinanderkommt.

SQL_MODE: NO_AUTO_VALUE_ON_ZERO

Der Schlüssel zur Lösung heißt NO_AUTO_VALUE_ON_ZERO. Dieser SQL-Modus ändert das Verhalten von MySQL: Der Wert 0 wird nicht mehr als „nächsten auto_increment-Wert generieren“ interpretiert, sondern als echte 0 eingefügt.

-- SQL_MODE temporär setzen (aktuelle Session)
SET SESSION sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

-- Prüfen, welcher SQL_MODE gerade aktiv ist
SELECT @@sql_mode;

Wichtig: Nur der Wert NULL löst dann noch die auto_increment-Generierung aus. Das ist in 99% der Fälle genau das, was du willst.

Wann brauchst du NO_AUTO_VALUE_ON_ZERO?

  • Deine Anwendung speichert bewusst die ID 0 (Magento: admin-User, WooCommerce: bestimmte Default-Einträge)
  • Du migrierst eine Datenbank 1:1 und willst exakt identische Daten
  • Dein Dump enthält INSERT INTO ... VALUES (0, ...)-Statements

mysqldump richtig konfigurieren

mysqldump setzt NO_AUTO_VALUE_ON_ZERO standardmäßig am Anfang des Dumps — aber nur, wenn du bestimmte Flags nicht weglässt. Hier die sichere Variante:

mysqldump \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --hex-blob \
  --set-gtid-purged=OFF \
  --default-character-set=utf8mb4 \
  -u backup_user -p \
  meine_datenbank > migration.sql

Wenn du den erzeugten Dump öffnest, solltest du am Anfang diese Zeilen sehen:

/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

Und am Ende:

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;

Das stellt sicher, dass der Import die auto_increment-Werte korrekt übernimmt und danach den ursprünglichen SQL_MODE wiederherstellt.

Was –skip-opt kaputt macht

Vorsicht mit --skip-opt! Dieses Flag deaktiviert unter anderem --disable-keys und entfernt den SQL_MODE-Header aus dem Dump. Wenn du --skip-opt brauchst, setze den Modus manuell:

mysqldump --skip-opt --create-options --add-drop-table \
  -u root -p meine_datenbank > dump.sql

Und füge am Anfang der Dump-Datei manuell ein:

SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

auto_increment-Zähler prüfen und korrigieren

Nach dem Import solltest du prüfen, ob der auto_increment-Zähler jeder Tabelle korrekt ist:

-- Aktuellen auto_increment-Wert anzeigen
SELECT TABLE_NAME, AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'meine_datenbank'
  AND AUTO_INCREMENT IS NOT NULL
ORDER BY TABLE_NAME;

Falls ein Wert nicht stimmt, kannst du ihn manuell setzen:

ALTER TABLE users AUTO_INCREMENT = 48373;

Oder du lässt MySQL den korrekten Wert selbst berechnen — das funktioniert seit MySQL 8.0 zuverlässig:

ANALYZE TABLE users;

MySQLDumper: Pre- und Post-SQL-Befehle nutzen

Wenn du MySQLDumper für die Migration nutzt, kannst du Pre- und Post-SQL-Befehle konfigurieren, die vor und nach dem Import ausgeführt werden.

Pre-SQL (vor dem Import)

SET SESSION sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;

Post-SQL (nach dem Import)

SET FOREIGN_KEY_CHECKS = 1;
SET UNIQUE_CHECKS = 1;
SET SESSION sql_mode = '';

Diese Befehle trägst du in der MySQLDumper-Konfiguration unter den Restore-Einstellungen ein. FOREIGN_KEY_CHECKS = 0 verhindert zusätzlich Fehler durch Fremdschlüssel-Abhängigkeiten bei der Import-Reihenfolge.

Praxisbeispiel: Magento-Migration

Magento speichert den Admin-User mit der ID 0 in der Tabelle admin_user. Ohne NO_AUTO_VALUE_ON_ZERO passiert folgendes:

-- Original-Daten:
-- admin_user: user_id = 0 (Super-Admin)
-- admin_user: user_id = 1 (Erster Admin)

-- Nach Import OHNE NO_AUTO_VALUE_ON_ZERO:
-- admin_user: user_id = 2 (war 0, wurde auto_increment!)
-- admin_user: user_id = 1 (unverändert)

Das Ergebnis: Der Super-Admin hat eine neue ID, alle Verknüpfungen (Rollen, Berechtigungen, Logs) zeigen ins Leere. Die Migration sieht oberflächlich erfolgreich aus, aber das Backend funktioniert nicht mehr.

Sichere Magento-Migration in 3 Schritten

  1. Dump erstellen mit Standard-mysqldump (enthält NO_AUTO_VALUE_ON_ZERO automatisch)
  2. Dump prüfen: Öffne die Datei und suche nach NO_AUTO_VALUE_ON_ZERO im Header
  3. Import mit explizitem SQL_MODE:
    mysql -u root -p -e "SET GLOBAL sql_mode = 'NO_AUTO_VALUE_ON_ZERO';"
    mysql -u root -p magento_db < magento_dump.sql
    mysql -u root -p -e "SET GLOBAL sql_mode = '';"

Checkliste: auto_increment bei Migration

Prüfpunkt Aktion
Dump enthält SQL_MODE-Header? Suche nach NO_AUTO_VALUE_ON_ZERO in den ersten 20 Zeilen
IDs mit Wert 0 vorhanden? SELECT * FROM tabelle WHERE id = 0;
auto_increment-Zähler korrekt? SELECT TABLE_NAME, AUTO_INCREMENT FROM information_schema.TABLES
Fremdschlüssel konsistent? Anwendung nach Import testen, nicht nur SQL-Import-Erfolg prüfen
mysqldump-Version kompatibel? Dump- und Import-Server sollten gleiche Major-Version haben (siehe Versionskompatibilität)

Häufige Fehler

„Duplicate entry '0' for key 'PRIMARY'"

Passiert wenn NO_AUTO_VALUE_ON_ZERO aktiv ist, aber die Zieltabelle schon einen Eintrag mit ID 0 hat. Lösung: DROP TABLE vor dem Import (Standard bei mysqldump mit --add-drop-table).

„auto_increment springt nach Import auf hohen Wert"

MySQL 8.0+ persistiert den auto_increment-Zähler in der InnoDB-Tablespace-Datei. Bei MySQL 5.7 und älter wird der Zähler beim Neustart auf MAX(id) + 1 zurückgesetzt. Nach einer Migration auf MySQL 8.0 bleibt der Wert aus dem Dump erhalten — auch wenn er höher ist als der tatsächliche Maximalwert.

„IDs stimmen, aber Verknüpfungen sind kaputt"

Prüfe, ob alle Tabellen im Dump enthalten sind. Teilweise Dumps (einzelne Tabellen) führen zu Inkonsistenzen bei Fremdschlüsseln. Immer die komplette Datenbank sichern und wiederherstellen.

auto_increment-Probleme bei Migrationen sind einer der häufigsten Stolpersteine — und einer der am einfachsten zu vermeidenden. Wenn du dir angewöhnst, jeden Dump vor dem Import kurz auf den NO_AUTO_VALUE_ON_ZERO-Header zu prüfen, sparst du dir Stunden an Debugging.