Shopware 6 Update: MySQL Trigger & DEFINER Probleme lösen
Beim Shopware 6 Update kann es zu frustrierenden Datenbank-Fehlern kommen, die nicht im Code, sondern auf MySQL-Ebene liegen. Besonders tückisch: MySQL-Trigger mit ungültigen DEFINER-Usern, die jede Migration blockieren. In diesem Beitrag zeige ich dir, wie du diese Probleme systematisch löst.
Typische Ausgangssituation
Bei einem Shopware 6.6.x Update laufen composer update und Symfony Recipes problemlos durch. Erst beim Datenbank-Migrationsschritt treten Fehler auf:
php bin/console database:migrate --all
# → Fehler!
Die Fehler sind oft verwirrend, weil sie nicht auf fehlerhaften Code hindeuten, sondern auf Inkonsistenzen zwischen Datenbankschema und Migration-Tracking.
Problem 1: Duplicate Column
Fehlermeldung:
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'is_eu'
Migration1718615305AddEuToCountryTable
Ursache: Die Migration will eine Spalte anlegen, die bereits existiert. Das passiert, wenn:
- Die Spalte manuell oder durch ein Plugin angelegt wurde
- Eine frühere Migration nur teilweise lief
- Das Migration-Tracking in der
migration-Tabelle nicht stimmtLösung: Migration manuell als ausgeführt markieren:
-- Prüfen ob Eintrag existiert SELECT * FROM migration WHERE class = 'Shopware\\Core\\Migration\\V6_6\\Migration1718615305AddEuToCountryTable';-- Als ausgeführt markieren UPDATE migration SET
update= NOW(6), message = 'Manually marked as executed (column already existed)' WHERE class = 'Shopware\\Core\\Migration\\V6_6\\Migration1718615305AddEuToCountryTable';Danach Migration erneut starten:
php bin/console database:migrate --all
- Das Migration-Tracking in der
- Eine frühere Migration nur teilweise lief
Problem 2: DEFINER does not exist
Fehlermeldung:
The user specified as a definer ('tcsycdxs'@'localhost') does not exist
Was ist passiert? Auf der betroffenen Tabelle (z.B. country) existieren MySQL-Trigger, die mit einem bestimmten Datenbank-User als DEFINER erstellt wurden. Dieser User existiert nicht mehr.
Wichtig zu verstehen:
- MySQL prüft den DEFINER bevor der Trigger überhaupt ausgeführt wird
- Selbst ein
IF @TRIGGER_DISABLEDim Trigger hilft nicht- Jede INSERT/UPDATE-Operation auf der Tabelle wird blockiert
- Die Shopware-Migration kann nicht weiterlaufen
- Jede INSERT/UPDATE-Operation auf der Tabelle wird blockiert
- Selbst ein
Warum ist das auf Plesk besonders problematisch?
Auf Shared-Hosting mit Plesk hast du eingeschränkte MySQL-Rechte:
- Kein CREATE USER erlaubt
- Benutzer werden automatisch mit Präfixen erstellt (z.B.
pre_username)- Der ursprüngliche DEFINER-User kann nicht nachträglich angelegt werden
SUPER-Privilegien fehlen für Trigger-ModifikationenDie Konsequenz: Der Fehler lässt sich nicht durch User-Anlage beheben. Der Trigger muss modifiziert oder entfernt werden.
- Der ursprüngliche DEFINER-User kann nicht nachträglich angelegt werden
Trigger analysieren
Zuerst die vorhandenen Trigger identifizieren:
SHOW TRIGGERS WHERE Table = 'country';
Typische Ausgabe:
Trigger | Event | Definer
country_tax_free_insert | BEFORE INSERT | tcsycdxs@localhost
country_tax_free_update | BEFORE UPDATE | tcsycdxs@localhost
Der DEFINER tcsycdxs@localhost existiert nicht mehr – das ist der Blocker.
Lösung: Trigger entfernen oder reparieren
Option A: Trigger aus Backup wiederherstellen
Wenn du Zugriff auf ein Backup oder eine Staging-Umgebung hast:
mysqldump -u USER -p --no-data --triggers DB_NAME > triggers.sql
Dann den DEFINER ersetzen oder entfernen und neu importieren.
Option B: Trigger entfernen (Notfall-Lösung)
Wenn kein Backup verfügbar ist und die Trigger nicht kritisch sind:
DROP TRIGGER IF EXISTS country_tax_free_insert;
DROP TRIGGER IF EXISTS country_tax_free_update;
Danach Migration ausführen:
php bin/console database:migrate --all
Wichtig: Prüfe vorher, ob die Trigger geschäftskritische Logik enthalten. Bei Shopware sind Trigger selten essentiell – die Business-Logik liegt in Plugins, DAL-Events und Subscribern.
Best Practices für die Zukunft
Trigger vermeiden:
- Shopware benötigt normalerweise keine Custom-Trigger
- Business-Logik gehört in Plugins, nicht in die Datenbank
- Verwende DAL-Events, Subscriber oder Scheduled Tasks
Wenn Trigger unvermeidbar:
- DEFINER immer auf den finalen DB-User setzen
- Oder DEFINER komplett weglassen (wenn möglich)
- Trigger-Definitionen versionieren und dokumentieren
Vor jedem Update:
SHOW TRIGGERSausführen und DEFINER prüfen- Backup der Trigger-Definitionen erstellen
- Bei Hosting-Wechsel: Trigger-DEFINER anpassen
- Backup der Trigger-Definitionen erstellen
- Trigger-Definitionen versionieren und dokumentieren
- Oder DEFINER komplett weglassen (wenn möglich)
- DEFINER immer auf den finalen DB-User setzen
- Verwende DAL-Events, Subscriber oder Scheduled Tasks
- Business-Logik gehört in Plugins, nicht in die Datenbank
Zusammenfassung
Shopware-Updates scheitern manchmal nicht am Code, sondern an einer inkonsistenten Datenbank:
1. Duplicate Column: Migration manuell als ausgeführt markieren 2. DEFINER-Fehler: Trigger mit gültigem User neu erstellen oder entfernen 3. Plesk/Shared-Hosting: Eingeschränkte Rechte erfordern Trigger-Entfernung
Die wichtigste Erkenntnis: MySQL-Trigger mit gelöschten DEFINER-Usern sind harte Blocker, die keine Workarounds auf Query-Ebene erlauben. Der Trigger muss modifiziert oder entfernt werden.
Brauchst du Unterstützung bei einem festgefahrenen Shopware-Update? Als Shopware-Entwickler helfe ich dir gerne, auch bei komplexen Datenbank-Problemen.
Matthias Hanske
Shopware 6 Fullstack Developer
Ich helfe E-Commerce-Unternehmen dabei, das volle Potenzial aus ihrem Shopware-Shop herauszuholen.
Brauchst du Hilfe bei deinem Shopware-Projekt?
Ich unterstütze dich gerne bei Updates, Migrationen und Entwicklung.