MySQL-Update (Percona Server) von 5.7 auf 8.0

MySQL-Update (Percona Server) von 5.7 auf 8.0

Die Technologie entwickelt sich ständig weiter, und die Gründe, auf die aktuellen Versionen von MySQL umzusteigen, werden immer drängender. Kürzlich war es an der Zeit, in einem unserer Projekte die bewährten Percona Server 5.7-Cluster auf die Version 8 zu aktualisieren. Dies geschah auf der Plattform Ubuntu Linux 16.04. Wie wir diese Operation mit minimalen Ausfallzeiten durchgeführt haben und auf welche Probleme wir beim Upgrade gestoßen sind – lesen Sie in diesem Artikel.

Vorbereitung

Jedes Upgrade eines Datenbankservers erfordert höchstwahrscheinlich eine Neuanpassung der Datenbank: Änderungen der Anforderungen an die Limits von Systemressourcen und das Bereinigen der Konfigurationsdateien, die von veralteten Direktiven befreit werden müssen.

Vor dem Upgrade werden wir unbedingt die offizielle Dokumentation konsultieren:

Und einen Aktionsplan erstellen:

  1. Konfigurationsdateien anpassen, veraltete Direktiven entfernen.
  2. Kompatibilität mit Tools überprüfen.
  3. Slave-Datenbanken aktualisieren, indem das Paket percona-server-server.
  4. installiert wird.

Master aktualisieren, indem dasselbe Paket installiert wird.

WICHTIG! Wir werden jeden Punkt des Plans durchgehen und sehen, was möglicherweise schiefgehen kann.

Teil 1: Überprüfung der Konfigurationen

In der MySQL-Version 8 wurde query_cacheentfernt. Dieser wurde bereits in Version 5.7 als veraltet eingestuft, aber nun wurde er komplettentfernt. Daher müssen die entsprechenden Direktiven entfernt werden. Zur Abfrageoptimierung können jetzt externe Tools verwendet werden – zum Beispiel ProxySQL.

Auch im Konfigurationsfile fanden sich veraltete Direktiven über innodb_file_format.Während in MySQL 5.7 die Auswahl des InnoDB-Formats möglich war, arbeitet Version 8 nun nur noch mit dem Barracuda-Format..

Unser Fazit ist das Entfernen der folgenden Direktiven:

  • query_cache_type, query_cache_limit und query_cache_size;
  • innodb_file_format. und innodb_file_format_max.

Zur Überprüfung verwenden wir das Docker-Image von Percona Server. Die Serverkonfiguration platzieren wir im Verzeichnis mysql_config_test,und daneben erstellen wir die Verzeichnisse für Daten und Logs. Beispiel für den Test der Konfiguration von percona-server:

mkdir -p {mysql_config_test,mysql_data,mysql_logs}
cp -r /etc/mysql/conf.d/* mysql_config_test/
docker run --name some-percona -v $(pwd)/mysql_config_test:/etc/my.cnf.d/ -v $(pwd)/mysql_data/:/var/lib/mysql/ -v $(pwd)/mysql_logs/:/var/log/mysql/ -e MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD} -d percona:8-centos

Zusammenfassend wird entweder in den Docker-Protokollen oder im Verzeichnis mit den Protokollen, abhängig von Ihren Konfigurationen, eine Datei erscheinen, in der die problematischen Direktiven beschrieben sind.

Das hatten wir:

2020-04-03T12:44:19.670831Z 0 [Warnung] [MY-011068] [Server] Die Syntax 'expire-logs-days' ist veraltet und wird in einer zukünftigen Version entfernt. Bitte verwenden Sie stattdessen binlog_expire_logs_seconds.
2020-04-03T12:44:19.671678Z 0 [Warnung] [MY-013242] [Server] --character-set-server: 'utf8' ist derzeit ein Alias für den Zeichensatz UTF8MB3, wird aber in einer zukünftigen Version ein Alias für UTF8MB4 sein. Bitte ziehen Sie in Betracht, UTF8MB4 zu verwenden, um Eindeutigkeit zu gewährleisten.
2020-04-03T12:44:19.671682Z 0 [Warnung] [MY-013244] [Server] --collation-server: 'utf8_general_ci' ist eine Kollation des veralteten Zeichensatzes UTF8MB3. Bitte verwenden Sie stattdessen UTF8MB4 mit einer geeigneten Kollation.

Daher mussten wir uns auch mit den Kodierungen auseinandersetzen und die veraltete Direktive ersetzen. expire-logs-days.

Teil 2: Überprüfung der funktionierenden Installationen

In der Upgrade-Dokumentation gibt es 2 Dienstprogramme zur Überprüfung der Datenbank auf Kompatibilität. Ihre Nutzung hilft dem Administrator, die Kompatibilität der bestehenden Datenstruktur zu überprüfen.

Wir beginnen mit dem klassischen Dienstprogramm mysqlcheck. Es reicht aus, einfach auszuführen:

mysqlcheck -u root -p --all-databases --check-upgrade

Wenn keine Probleme festgestellt werden, beendet sich das Dienstprogramm mit dem Code 0:

MySQL-Update (Percona Server) von 5.7 auf 8.0

Darüber hinaus steht in den modernen Versionen von MySQL das Dienstprogramm zur Verfügung. mysql-shell (im Fall von Percona ist dies ein Paket percona-mysql-shell). Es ist ein Ersatz für den klassischen MySQL-Client und vereint die Funktionen eines Clients, eines SQL-Code-Editors und Verwaltungstools für MySQL. Um den Server vor dem Upgrade zu überprüfen, kann man über diesen Befehl Folgendes ausführen:

mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=/etc/mysql/my.cnf

Und hier sind die Anmerkungen, die wir erhalten haben:

MySQL-Update (Percona Server) von 5.7 auf 8.0

Im Großen und Ganzen nichts Kritisches — nur Warnungen zu den Zeichencodierungen (siehe unten). Das Gesamtergebnis der Ausführung:

MySQL-Update (Percona Server) von 5.7 auf 8.0

Wir sind zu dem Schluss gekommen, dass das Upgrade problemlos verlaufen sollte.

Anmerkungen zu den oben genannten Warnungen deuten auf Probleme mit den Zeichencodierungen hin. Das Problem ist, dass UTF-8 in MySQL bis vor kurzem kein 'echtes' UTF-8 war, da es nur 3 Bytes anstelle von 4 gespeichert hat. In MySQL 8 wurde dies endlich behoben: Alias utf8 wird bald auf die Kodierung utf8mb4verweisen, während alte Spalten in den Tabellen zu utf8mb3werden. In Zukunft wird die Kodierung utf8mb3 entfernt, jedoch nicht in dieser Version. Daher haben wir beschlossen, die Zeichencodierungen bereits bei der laufenden Installation des DBMS nach deren Upgrade zu korrigieren.

Teil 3: Upgrade der Server

Was könnte schiefgehen, wenn wir einen so eleganten Plan haben? Während wir uns bewusst sind, dass immer etwas schiefgehen kann, haben wir unser erstes Experiment auf dem dev-Cluster von MySQL durchgeführt.

Wie bereits erwähnt, behandelt die offizielle Dokumentation das Thema der Aktualisierung von MySQL-Servern mit Replikaten. Der Kernpunkt ist, dass zuerst alle Replikate (Slaves) aktualisiert werden sollten, da MySQL 8 in der Lage ist, von einem Master der Version 5.7 zu replizieren. Eine gewisse Komplexität ergibt sich daraus, dass wir den Modus verwenden, Master Master, wobei der entfernte Master im Read-OnlyModus läuft. Das bedeutet, dass der tatsächliche Produktionsverkehr in einem Rechenzentrum eingeht, während das zweite als Backup dient.

Die Topologie sieht folgendermaßen aus:

MySQL-Update (Percona Server) von 5.7 auf 8.0

Das Update sollte mit den Replikaten mysql replica dc 2, mysql master dc 2 und mysql replica dc 1, und enden mit dem Server mysql master dc 1. Zur höheren Sicherheit haben wir die virtuellen Maschinen gestoppt, Snapshots erstellt und kurz vor dem Update die Replikation mit dem Befehl STOP SLAVEgestoppt. Ansonsten gestaltet sich das Update wie folgt:

  1. Jede Replik wird neu gestartet, wobei wir in die Konfigurationen 3 Optionen hinzufügen: skip-networking, skip-slave-start, skip-log-bin. Das Update der Datenbank generiert binäre Protokolle, während die Systemtabellen aktualisiert werden. Diese Direktiven stellen sicher, dass es keine Änderungen an den Anwendungsdaten in der Datenbank gibt und dass keine Informationen über das Update der Systemtabellen in die binären Protokolle gelangen. Dadurch werden Probleme beim Wiederaufnehmen der Replikation vermieden.
  2. Paket installieren percona-server-server. Es ist wichtig zu beachten, dass in MySQL 8 nicht der Befehl mysqlupgrade nach dem Server-Update ausgeführt werden muss.
  3. Nach dem erfolgreichen Start den Server erneut neu starten — diesmal ohne die Parameter, die im ersten Punkt hinzugefügt wurden.
  4. Sicherstellen, dass die Replikation erfolgreich läuft: überprüfen SHOW SLAVE STATUS und sehen, dass die Tabellen mit den Zählern in der Anwendung aktualisiert werden.

Das alles scheint recht einfach zu sein: Das Update der dev-Umgebung war erfolgreich. Gut, man kann nun das nächtliche Update für die Produktion planen.

Es gab keine Probleme — wir haben prod aktualisiert

Aber die Übertragung der erfolgreichen dev-Erfahrungen auf die Produktion ging nicht ohne Überraschungen vonstatten.

Glücklicherweise beginnt der Aktualisierungsprozess mit Replikaten. Daher haben wir die Arbeiten bei Schwierigkeiten gestoppt und die Replikation aus einem Snapshot wiederhergestellt. Die Untersuchung der Probleme haben wir auf den nächsten Morgen verschoben. Folgende Einträge fanden sich in den Logs:

2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] Tabelle: t1 hat 19 Spalten, aber das InnoDB-Wörterbuch hat 20 Spalten
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Fehler beim Reparieren der SE-Daten für db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] DD-Tabellen konnten nicht populiert werden.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Abbruch

Die Untersuchung von Archiven verschiedener Mailinglisten bei Google führte zu der Erkenntnis, dass ein solches Problem aufgrund von eines MySQL-Bugs. Wahrscheinlich handelt es sich jedoch sogar um einen Bug der Dienstprogramme mysqlcheck und mysqlsh.

Es stellte sich heraus, dass MySQL die Art der Datenpräsentation für Dezimalfelder (int, tinyint usw.) geändert hat, weshalb im mysql-server eine andere Art der Speicherung verwendet wird. Wenn Ihre Datenbank ursprünglich in Version 5.5 oder 5.1 war und Sie dann auf 5.7 aktualisiert haben, kann es sein, dass Sie für einige Tabellen OPTIMIZE eine Aktualisierung durchführen müssen. Dann wird MySQL die Datendateien aktualisieren und in das aktuelle Speicherformat konvertieren.

Das kann auch mit dem Dienstprogramm mysqlfrm:

mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
 'field_length': 8,
  'field_type': 246, # Feldformat
  'field_type_name': 'decimal',
  'flags': 3,
  'flags_extra': 67,
  'interval_nr': 0,
 'name': 'you_deciaml_column',
...

Wenn field_type wenn es 0 ist, wird in der Tabelle der alte Typ verwendet – es sind Anpassungen nötig. OPTIMIZE. Wenn jedoch der Wert 246 gesetzt ist, dann haben Sie bereits den neuen Typ. Weitere Informationen zu den Typen finden Sie in Code.

Darüber hinaus wird in diesem Fehlerbericht eine zweite mögliche Ursache erörtert, die uns entgangen ist – das Fehlen von InnoDB-Tabellen in der Systemtabelle INNODB_SYS_TABLESPACES, falls die Tabellen in der Version 5.1 erstellt wurden. Um Probleme bei einer Aktualisierung zu vermeiden, können Sie das beigefügte SQL-Skript.

Warum hatten wir solche Probleme nicht in der Entwicklungsumgebung? Die Datenbank wird dort regelmäßig von der Produktionsumgebung kopiert – so werden die Tabellen neu erstellt..

Leider ist es bei einer produktiv laufenden großen Datenbank nicht möglich, einfach einen umfassenden OPTIMIZE. Hier kann das Percona-Toolkit hilfreich sein: für operationale ONLINE OPTIMIERUNGEN eignet sich das Tool pt-online-schema-change hervorragend.

Der aktualisierte Plan sieht folgendermaßen aus:

  1. Alle Tabellen optimieren.
  2. Datenbanken aktualisieren.

Um dies zu überprüfen und zugleich die Aktualisierungszeit zu ermitteln, haben wir eine der Repliken abgeschaltet und für alle Tabellen den folgenden Befehl ausgeführt:

pt-online-schema-change --critical-load Threads_running=150 --alter "ENGINE=InnoDB" --execute --chunk-size 100 --quiet --alter-foreign-keys-method auto h=127.0.0.1,u=root,p=${MYSQL_PASSWORD},D=db1,t=t1

Die Aktualisierung der Tabellen erfolgt ohne lange Sperrzeiten, da das Tool eine neue temporäre Tabelle erstellt, in die die Daten aus der Haupttabelle kopiert werden. In dem Moment, in dem beide Tabellen identisch sind, wird die ursprüngliche Tabelle gesperrt und durch die neue ersetzt. In unserem Fall hat der Testlauf gezeigt, dass für die Aktualisierung aller Tabellen etwa einen Tag benötigt wird, jedoch die Datenübertragung eine zu hohe Belastung für die Festplatten verursachte.

Um dies zu vermeiden, haben wir im Produktionsbetrieb dem Befehl das Argument hinzugefügt --sleep mit dem Wert 10 – dieser Parameter regelt die Wartezeit nach dem Transfer einer Datenmenge in die neue Tabelle. So kann die Belastung gesenkt werden, wenn die tatsächlich laufende Anwendung auf die Antwortzeit angewiesen ist.

Nach der Optimierung wurde das Update erfolgreich abgeschlossen.

… aber nicht ganz!

Bereits eine halbe Stunde nach dem Update kam der Kunde mit einem Problem. Die Datenbank verhielt sich sehr seltsam: Es kam regelmäßig zu Verbindungsabbrüchen. So sah das Monitoring aus:

MySQL-Update (Percona Server) von 5.7 auf 8.0

Auf dem Screenshot ist ein gezackter Graph zu sehen, der zeigt, dass einige MySQL-Server-Threads periodisch mit einem Fehler abgestürzt sind. In der Anwendung traten folgende Fehler auf:

[PDOException] SQLSTATE[HY000] [2002] Verbindung verweigert

Ein kurzer Blick in die Logs zeigte, dass der mysqld-Daemon die erforderlichen Ressourcen vom Betriebssystem nicht erhalten konnte. Bei der Fehlersuche entdeckten wir im System „verwaiste“ AppArmor-Policy-Dateien:

# dpkg -S /etc/apparmor.d/cache/usr.sbin.mysqld
dpkg-query: no path found matching pattern /etc/apparmor.d/cache/usr.sbin.mysqld
# dpkg -S /etc/apparmor.d/local/usr.sbin.mysqld
dpkg-query: no path found matching pattern /etc/apparmor.d/local/usr.sbin.mysqld
# dpkg -S /etc/apparmor.d/usr.sbin.mysqld
mysql-server-5.7: /etc/apparmor.d/usr.sbin.mysqld
# dpkg -l mysql-server-5.7
rc  mysql-server-5.7 5.7.23-0ubuntu0.16.04.1      amd64

Diese Dateien entstanden beim Update auf MySQL 5.7 vor ein paar Jahren und gehören zu einem entfernten Paket. Das Löschen der Dateien und der Neustart des AppArmor-Dienstes lösten das Problem:

systemctl stop apparmor
rm /etc/apparmor.d/cache/usr.sbin.mysqld
rm /etc/apparmor.d/local/usr.sbin.mysqld
rm /etc/apparmor.d/usr.sbin.mysqld
systemctl start apparmor

Zusammenfassung

Jede, auch die einfachste Operation, kann unerwartete Probleme verursachen. Selbst ein durchdachter Plan garantiert nicht immer das erwartete Ergebnis. Jetzt gehört zur Planung von Updates unserer Teams auch die obligatorische Bereinigung überflüssiger Dateien, die als Folge letzter Aktionen entstanden sein könnten.

Mit dieser nicht sehr professionellen Grafik möchte ich der Firma Percona ein großes Dankeschön für ihre hervorragenden Produkte aussprechen!

MySQL-Update (Percona Server) von 5.7 auf 8.0

P.S.

Lesen Sie auch in unserem Blog:

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster