In vielen Cloud-Migrationen steht die Datenbank als eine Zeile im Plan: Umzug auf einen verwalteten Dienst. Das ist meist richtig, und es verdeckt, dass mit dem Umzug fast immer ein Versionssprung erzwungen wird, weil ältere Versionen dort gar nicht mehr angeboten werden.
Damit werden aus einem Vorhaben zwei: ein Ortswechsel und ein Versionssprung. Der Ortswechsel ist Handwerk. Der Versionssprung bringt Verhaltensänderungen mit, die keine Fehlermeldung erzeugen, sondern andere Ergebnisse.
Dieser Artikel beschreibt die vier Klassen von Brüchen zwischen MySQL 5.7 und 8.0, wie man sie vor dem Umzug findet, und was der verwaltete Dienst zusätzlich anders macht.
Warum der Sprung erzwungen wird
MySQL 5.7 hat den erweiterten Support im Oktober 2023 verlassen. Verwaltete Dienste bieten solche Versionen eine Weile über eine kostenpflichtige Verlängerung an und stellen sie danach ein.
Praktisch heißt das: Ein Umzug auf einen verwalteten Dienst mit 5.7 ist entweder gar nicht möglich oder eine Zwischenlösung mit Aufpreis und Enddatum. Wer den Umzug plant, plant deshalb den Versionssprung mit, und die ehrliche Frage ist nur, ob beides zusammen oder nacheinander passiert.
Meine Empfehlung ist nacheinander, und zwar in dieser Reihenfolge: erst die Version anheben, im eigenen Rechenzentrum, dann umziehen. Der Grund ist derselbe wie überall in dieser Serie: Wenn nach dem Umzug ein Ergebnis anders ist, soll es nur eine mögliche Ursache geben.
Wo der Terminplan das nicht hergibt, weil das Rechenzentrum zu einem festen Datum geräumt wird, geht auch beides zusammen. Dann gehört der Abschnitt über den Rückweg am Ende dieses Artikels zur Pflichtlektüre.
Die vier Klassen von Brüchen
Was zwischen 5.7 und 8.0 kaputtgeht, fällt in vier Gruppen. Die ersten beiden melden sich, die letzten beiden nicht.
Erstens: reservierte Wörter. MySQL 8.0 hat eine Reihe neuer reservierter Wörter, und wenn eine Spalte so heißt, sind alle Abfragen darauf ungültig, sofern sie nicht in Anführungszeichen stehen. Die häufigsten Treffer in deutschen Projekten sind rank, groups, system, rows und lead. Das ist die freundlichste der vier Klassen, weil sie einen harten Fehler erzeugt.
Zweitens: der SQL-Modus. ONLY_FULL_GROUP_BY ist ab 8.0 in der Voreinstellung aktiv und war es in vielen 5.7-Installationen nicht. Jede Abfrage, die Spalten auswählt, die weder gruppiert noch aggregiert sind, wird abgewiesen. In gewachsenem Code sind das viele, und sie sind alle über Jahre unauffällig gelaufen.
-- Laeuft in 5.7 mit lockerem Modus, wird in 8.0 abgewiesen:
-- name ist weder gruppiert noch aggregiert. Welcher Name kam vorher
-- zurueck? Ein beliebiger. Genau deshalb ist die Abweisung richtig.
SELECT kunde_id, name, SUM(betrag)
FROM bestellung
GROUP BY kunde_id;Drittens: Kollationen und Sortierung. Die Voreinstellung wechselt von utf8mb4_general_ci auf utf8mb4_0900_ai_ci. Das ist keine Kleinigkeit: Die neue Kollation sortiert anders, vergleicht Umlaute anders und hält manche Zeichen für gleich, die vorher verschieden waren. Eine Abfrage mit WHERE name = 'Müller' kann danach mehr oder weniger Zeilen liefern als vorher.
Viertens: die Reihenfolge ohne ORDER BY. Der Optimierer in 8.0 entscheidet an vielen Stellen anders, und Abfragen ohne ausdrückliche Sortierung liefern deshalb regelmäßig eine andere. Das ist formal kein Bruch, weil ohne ORDER BY nie eine Reihenfolge zugesagt war. In einer Anwendung, die seit zehn Jahren dieselbe Reihenfolge sieht, ist es trotzdem einer.
Die dritte und die vierte Klasse sind die teuren. Sie erzeugen keinen Fehler, sondern ein anderes Ergebnis, und das fällt in einem Bericht auf, nicht im Betrieb.
Wie Sie die Brüche vorher finden
Für die ersten beiden Klassen gibt es Werkzeuge, für die anderen beiden braucht es einen Vergleich.
Reservierte Wörter und Schemaprobleme findet das Prüfwerkzeug, das MySQL mitbringt. Es läuft gegen die alte Datenbank und nennt, was in 8.0 nicht mehr geht:
# Mit den Client-Werkzeugen aus 8.0 gegen den 5.7-Server
mysqlcheck --check-upgrade --all-databases -u pruefer -p
# Und die Kollationen im Bestand, sortiert nach Haeufigkeit
mysql -e "SELECT table_collation, COUNT(*) FROM information_schema.tables
WHERE table_schema = 'anwendung' GROUP BY table_collation;"Den SQL-Modus prüft man am besten, indem man ihn vorzeitig einschaltet. Das geht auf der alten Version, für eine einzelne Sitzung, und erzeugt genau die Fehler, die später kommen würden:
SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,
NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO';
-- Danach die Testsuite laufen lassen. Was jetzt scheitert, scheitert
-- spaeter in Produktion.Das ist der nützlichste einzelne Schritt der ganzen Vorbereitung, weil er die zweite Klasse vollständig auf der alten Version abräumt.
Für Kollation und Reihenfolge hilft kein Werkzeug, sondern ein Vergleich: dieselben Abfragen auf beiden Versionen, Ergebnisse gegenübergestellt. In der Praxis reicht eine Auswahl, und die Auswahl steht schon irgendwo, nämlich im Protokoll der langsamen Abfragen und in der Liste der Berichte.
Das ist derselbe Gedanke wie bei einem Golden Master im Code: Man vergleicht Ausgaben statt Annahmen.
Was der verwaltete Dienst zusätzlich anders macht
Zum Versionssprung kommen Eigenschaften des Dienstes selbst, und drei davon überraschen regelmäßig.
Es gibt keinen Wurzelzugang zur Maschine. Alles, was bisher über Dateien im Dateisystem lief, entfällt: Import über LOAD DATA INFILE mit lokalen Pfaden, eigene Einträge in der Konfigurationsdatei, das Lesen von Protokolldateien über die Konsole. Das ist selten ein Problem, es ist aber regelmäßig eine Überraschung mitten im Umzug.
Parameter stehen in Gruppen, nicht in einer Datei. Und einige lassen sich nicht ändern. Vor dem Umzug lohnt ein Abgleich: Welche Abweichungen von der Voreinstellung hat die eigene Installation, und sind die im Dienst überhaupt möglich?
-- Alles, was vom Standard abweicht, auf der alten Installation
SELECT variable_name, variable_value
FROM performance_schema.global_variables
WHERE variable_name IN ('sql_mode','character_set_server','collation_server',
'innodb_buffer_pool_size','max_allowed_packet','group_concat_max_len',
'transaction_isolation','innodb_flush_log_at_trx_commit');Die Sicherung ist anders und besser, wenn man sie versteht. Automatische Sicherungen und Wiederherstellung auf einen Zeitpunkt sind da und müssen nicht gebaut werden. Was fehlt, ist die Gewohnheit, sie zu prüfen: Eine Wiederherstellung erzeugt eine neue Instanz, und wie lange das für die eigene Datenmenge dauert, weiß man erst, wenn man es einmal gemacht hat. Das gehört vor den Umzug, nicht danach.
Ein Teil der Stellen, die dabei auffallen, ist älter als jede Datenbankfassung: Das eigentliche Legacy ist Ihr Datenbankschema.
Der Umzug ohne langes Wartungsfenster
Bei kleineren Datenbanken ist der Weg einfach: Export, Import, umschalten. Bis etwa zwanzig Gigabyte passt das in ein Fenster, das niemandem wehtut.
Darüber wird aus dem Export ein Problem, und dann ist Replikation der Weg. Der Ablauf hat vier Schritte und ist seit Jahren derselbe.
- Einen Abzug der alten Datenbank einspielen, mit der Position im Binärprotokoll. Das darf Stunden dauern, es stört niemanden.
- Replikation einschalten. Die neue Instanz zieht ab der notierten Position alles nach und hängt danach wenige Sekunden hinterher.
- Warten, bis der Rückstand null ist, und in dieser Zeit auf der neuen Instanz lesend testen. Das ist der eigentliche Gewinn des Verfahrens: Man kann die neue Version mit echten Daten prüfen, während die alte weiterläuft.
- Umschalten. Schreibzugriffe anhalten, Rückstand auf null warten, Verbindungszeichenfolge wechseln, Replikation beenden. Das Fenster ist eine Frage von Minuten.
Zwei Details entscheiden über den vierten Schritt. Der Anwendungsteil muss die Datenbankadresse aus der Konfiguration lesen und nicht fest verdrahtet haben, sonst braucht das Umschalten eine Auslieferung. Und es muss einen Weg geben, Schreibzugriffe kurz anzuhalten, sonst gehen die letzten Vorgänge verloren.
Der nächste erzwungene Termin steht schon fest, man muss ihn nur aufschreiben: Ein EOL-Kalender für den ganzen Stack.
Was nach dem Umzug messbar anders ist
Zwei Dinge ändern sich nach dem Sprung regelmäßig, und beide gehören gemessen statt erwartet.
Manche Abfragen werden langsamer. Der Optimierer in 8.0 ist insgesamt besser und entscheidet in Einzelfällen schlechter als vorher, besonders bei Abfragen mit vielen Verknüpfungen. Das ist kein Rückschritt, sondern eine andere Kostenschätzung, und es betrifft meist eine Handvoll Abfragen.
Deshalb gehört das Protokoll langsamer Abfragen in der ersten Woche nach dem Umzug eingeschaltet, mit einer niedrigeren Schwelle als sonst. Was dort auftaucht und vorher nicht drinstand, ist die Liste der Abfragen, die einen Blick brauchen.
Die Rechnung hat eine andere Form. Ein verwalteter Dienst kostet nach Instanzgröße, Speicherplatz und, je nach Einstellung, nach Ein- und Ausgabevorgängen. Der letzte Posten ist der, der überrascht, weil er im eigenen Rechenzentrum nicht existierte. Eine Anwendung mit vielen kleinen Abfragen kann dort mehr kosten als die Instanz selbst.
Der Rückweg
Bis zum Umschalten ist der Rückweg trivial: Die alte Datenbank läuft weiter, man ändert die Verbindungszeichenfolge zurück.
Danach ist er es nicht mehr, und das ist der Punkt, den man vorher beschreiben muss. Sobald auf der neuen Instanz geschrieben wird, liegen dort Daten, die die alte nicht hat. Zurück geht es dann nur mit einer Replikation in die Gegenrichtung, und die muss vorher eingerichtet sein, nicht im Moment der Entscheidung.
Für die meisten Projekte ist die ehrlichere Antwort eine andere: Der Rückweg ist ein Zeitfenster, keine Dauerlösung. Zwei Stunden nach dem Umschalten wird entschieden, ob es bleibt. Was in dieser Zeit auffällt, sind Verbindungsfehler und offensichtlich falsche Ergebnisse, und dafür reicht das Fenster.
Was später auffällt, etwa eine Kollation, die einen Bericht anders sortiert, wird nach vorn repariert. Das ist kein Versagen der Planung, sondern die Einsicht, dass eine Rückkehr nach zwei Tagen mehr kostet als die Korrektur.
Wie eine AWS-Migration insgesamt abläuft, steht auf einer eigenen Seite. Die Datenbank ist dort der Baustein, bei dem sich der Aufwand am wenigsten abkürzen lässt, und der einzige, bei dem ein Fehler die Daten betrifft statt nur den Betrieb.
Dieser Artikel gehört zu einer Reihe über Systeme, die es schon gibt. Der Rückblick ordnet alle Artikel der Reihe nach Anlass.

