Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

Der Fortschritt steht nicht still, daher werden die Gründe für ein Upgrade auf die neuesten Versionen von MySQL immer überzeugender. Vor nicht allzu langer Zeit war es in einem unserer Projekte an der Zeit, die gemütlichen Percona Server 5.7-Cluster auf Version 8 zu aktualisieren. All dies geschah auf der Ubuntu Linux 16.04-Plattform. Wie Sie einen solchen Vorgang mit minimaler Ausfallzeit durchführen und welche Probleme beim Update aufgetreten sind, lesen Sie in diesem Artikel.

Training

Jede Aktualisierung des Datenbankservers ist höchstwahrscheinlich mit einer Neukonfiguration der Datenbank verbunden: Änderungen der Anforderungen hinsichtlich der Begrenzung von Systemressourcen und Korrektur von Datenbankkonfigurationen, die von veralteten Anweisungen befreit werden müssen.

Vor der Aktualisierung verweisen wir auf jeden Fall auf die offizielle Dokumentation:

Und lassen Sie uns einen Aktionsplan erstellen:

  1. Korrigieren Sie Konfigurationsdateien, indem Sie veraltete Anweisungen entfernen.
  2. Überprüfen Sie die Kompatibilität mit Dienstprogrammen.
  3. Aktualisieren Sie Slave-Datenbanken, indem Sie das Paket installieren percona-server-server.
  4. Aktualisieren Sie den Master mit demselben Paket.

Schauen wir uns jeden Punkt des Plans an und sehen, was schief gehen könnte.

WICHTIG! Das Verfahren zum Aktualisieren eines MySQL-Clusters auf Basis von Galera weist seine eigenen Feinheiten auf, die im Artikel nicht beschrieben werden. In diesem Fall sollten Sie diese Anleitung nicht verwenden.

Teil 1: Konfigurationen überprüfen

MySQL wurde in Version 8 entfernt query_cache. Tatsächlich war er es für veraltet erklärt zurück in Version 5.7, aber jetzt komplett gelöscht. Dementsprechend ist es notwendig, die zugehörigen Anweisungen zu entfernen. Und um Anfragen zwischenzuspeichern, können Sie jetzt externe Tools verwenden – zum Beispiel ProxySQL.

Auch in der Konfiguration gab es veraltete Anweisungen dazu innodb_file_format. Wenn in MySQL 5.7 das InnoDB-Format ausgewählt werden konnte, funktioniert die 8. Version bereits nur mit Barracuda-Format.

Unser Ergebnis ist die Entfernung der folgenden Richtlinien:

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

Zur Überprüfung verwenden wir das Docker-Image von Percona Server. Wir werden die Serverkonfiguration im Verzeichnis ablegen mysql_config_test, und daneben erstellen wir Verzeichnisse für Daten und Protokolle. Beispiel für einen Percona-Server-Konfigurationstest:

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

Fazit: Entweder in den Docker-Protokollen oder im Verzeichnis mit den Protokollen – abhängig von Ihren Konfigurationen – erscheint eine Datei, in der die problematischen Anweisungen beschrieben werden.

Folgendes hatten wir:

2020-04-03T12:44:19.670831Z 0 [Warning] [MY-011068] [Server] The syntax 'expire-logs-days' is deprecated and will be removed in a future release. Please use binlog_expire_logs_seconds instead.
2020-04-03T12:44:19.671678Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.
2020-04-03T12:44:19.671682Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead.

Daher mussten wir noch die Codierungen herausfinden und die veraltete Direktive ersetzen expire-logs-days.

Teil 2: Überprüfung funktionierender Installationen

Die Update-Dokumentation enthält 2 Dienstprogramme zur Überprüfung der Datenbank auf Kompatibilität. Ihre Verwendung hilft dem Administrator, die Kompatibilität der vorhandenen Datenstruktur zu überprüfen.

Beginnen wir mit dem klassischen Dienstprogramm mysqlcheck. Führen Sie einfach Folgendes aus:

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

Wenn keine Probleme gefunden werden, wird das Dienstprogramm mit Code 0 beendet:

Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

Darüber hinaus ist in modernen Versionen von MySQL ein Dienstprogramm verfügbar MySQL-Shell (Im Fall von Percona ist dies das 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 MySQL-Verwaltungstools. Um den Server vor dem Update zu überprüfen, können Sie die folgenden Befehle ausführen:

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

Hier sind die Kommentare, die wir erhalten haben:

Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

Im Allgemeinen nichts Kritisches – nur Warnungen zu Kodierungen (siehe unten). Gesamtergebnis der Ausführung:

Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

Wir haben entschieden, dass das Update ohne Probleme verlaufen sollte.

Ein Hinweis zu den oben genannten Warnungen, die auf Probleme mit der Kodierung hinweisen. Tatsache ist, dass UTF-8 in MySQL bis vor kurzem existierte war kein „echtes“ UTF-8, da nur 3 statt 4 Bytes gespeichert wurden. In MySQL 8 ist dies endlich der Fall beschlossen, das Problem zu beheben: alias utf8 wird bald zur Codierung führen utf8mb4, und die alten Spalten in den Tabellen werden zu utf8mb3. Weitere Kodierung utf8mb3 wird entfernt, jedoch nicht in dieser Version. Aus diesem Grund haben wir uns entschieden, die Kodierungen, die sich bereits in der laufenden DBMS-Installation befanden, nach der Aktualisierung zu korrigieren.

Teil 3: Server-Updates

Was könnte schief gehen, wenn es einen so intelligenten Plan gibt? Da wir uns völlig darüber im Klaren sind, dass es immer Nuancen gibt, führten wir das erste Experiment auf einem MySQL-Entwicklungscluster durch.

Wie bereits erwähnt, offizielle Dokumentation behandelt das Problem der Aktualisierung von MySQL-Servern mit Replikaten. Unterm Strich sollten Sie zunächst alle Replikate (Slaves) aktualisieren, da MySQL 8 von einer Master-Version 5.7 replizieren kann. Eine gewisse Schwierigkeit liegt darin, dass wir den Modus verwenden Master <-> Master, wenn sich der Remote-Master im Modus befindet read-only. Das heißt, der Kampfverkehr geht tatsächlich an ein Rechenzentrum und das zweite ist ein Backup.

Die Topologie sieht so aus:

Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

Das Update muss mit Replikaten beginnen MySQL-Replik DC 2, MySQL Master DC 2 и mysql replica dc 1und enden mit dem MySQL-Master-Server DC 1. Um die Zuverlässigkeit zu erhöhen, haben wir die virtuellen Maschinen gestoppt, Snapshots von ihnen erstellt und unmittelbar vor dem Update die Replikation mit dem Befehl gestoppt STOP SLAVE. Der Rest des Updates sieht so aus:

  1. Wir starten jedes Replikat neu, indem wir den Konfigurationen drei Optionen hinzufügen: skip-networking, skip-slave-start, skip-log-bin. Tatsache ist, dass durch die Aktualisierung der Datenbank Binärprotokolle mit Aktualisierungen der Systemtabellen generiert werden. Diese Anweisungen garantieren, dass es keine Änderungen an den Anwendungsdaten in der Datenbank gibt und dass Informationen über die Aktualisierung von Systemtabellen nicht in die Binärprotokolle aufgenommen werden. Dadurch werden Probleme bei der Wiederaufnahme der Replikation vermieden.
  2. Installieren des Pakets percona-server-server. Es ist wichtig zu beachten, dass in MySQL Version 8 nicht Sie müssen den Befehl ausführen mysqlupgrade nach Server-Update.
  3. Nach erfolgreichem Start starten wir den Server erneut – ohne die Parameter, die im ersten Absatz hinzugefügt wurden.
  4. Wir stellen sicher, dass die Replikation erfolgreich funktioniert: prüfen SHOW SLAVE STATUS und achten Sie darauf, dass die Tabellen mit Zählern in der Anwendungsdatenbank aktualisiert werden.

Es sieht alles ganz einfach aus: Das Dev-Update war erfolgreich. Ok, Sie können getrost ein nächtliches Update für die Produktion planen.

Es gab keine Traurigkeit – wir haben das Produkt aktualisiert

Der Transfer erfolgreicher Entwicklungserfahrungen in die Produktion verlief jedoch nicht ohne Überraschungen.

Glücklicherweise beginnt der Update-Prozess selbst mit Replikaten. Als wir auf Schwierigkeiten stießen, stoppten wir die Arbeit und stellten das Replikat aus dem Snapshot wieder her. Die Untersuchung der Probleme wurde auf den nächsten Morgen verschoben. Die Protokolle enthielten folgende Einträge:

2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] table: t1 has 19 columns but InnoDB dictionary has 20 columns
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Error in fixing SE data for db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Failed to Populate DD tables.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Aborting

Die Recherche in den Archiven verschiedener Mailinglisten bei Google führte zu der Erkenntnis, dass dieses Problem aufgrund von auftritt MySQL-Fehler. Obwohl es sich hierbei eher um einen Dienstprogrammfehler handelt mysqlcheck и mysqlsh.

Es stellt sich heraus, dass MySQL die Art und Weise geändert hat, wie Daten für Dezimalfelder (int, tinyint usw.) dargestellt werden, sodass mysql-server eine andere Methode zum Speichern dieser Daten verwendet. Wenn Ihre Datenbank ursprünglich in Version 5.5 oder 5.1 war und Sie dann auf 5.7 aktualisiert haben, müssen Sie dies möglicherweise tun OPTIMIZE für einige Tische. Anschließend aktualisiert MySQL die Datendateien und überträgt sie in das aktuelle Speicherformat.

Sie können dies auch mit dem Dienstprogramm überprüfen mysqlfrm:

mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
 'field_length': 8,
  'field_type': 246, # формат поля
  'field_type_name': 'decimal',
  'flags': 3,
  'flags_extra': 67,
  'interval_nr': 0,
 'name': 'you_deciaml_column',
...

wenn field_type Wenn Sie den Wert 0 haben, wird der alte Typ in der Tabelle verwendet – Sie müssen ihn ausführen OPTIMIZE. Wenn der Wert jedoch 246 ist, haben Sie bereits einen neuen Typ. Weitere Informationen zu den Typen finden Sie in Code.

Darüber hinaus in dieser Fehler Wir erwägen den zweiten möglichen Grund, der uns entgangen ist: das Fehlen von InnoDB-Tabellen in der Systemtabelle INNODB_SYS_TABLESPACES, wenn sie, Tabellen, in Version 5.1 erstellt wurden. Um Probleme beim Aktualisieren zu vermeiden, können Sie verwenden angehängtes SQL-Skript.

Warum hatten wir bei der Entwicklung keine derartigen Probleme? Die Datenbank wird regelmäßig aus der Produktion dorthin kopiert – somit Tabellen werden neu erstellt.

Leider ist es bei einer wirklich funktionierenden großen Datenbank nicht möglich, einfach eine universelle Datenbank zu übernehmen und auszuführen OPTIMIZE. Hier hilft percona-toolkit: Das Dienstprogramm pt-online-schema-change eignet sich hervorragend für den Online-OPTIMIZE-Vorgang.

Der aktualisierte Plan sah so aus:

  1. Optimieren Sie alle Tabellen.
  2. Aktualisieren Sie die Datenbanken.

Um dies zu überprüfen und gleichzeitig die Aktualisierungszeit herauszufinden, haben wir eines der Replikate deaktiviert und den folgenden Befehl für alle Tabellen 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

Tabellen werden ohne langwierige Sperren aktualisiert, da das Dienstprogramm eine neue temporäre Tabelle erstellt, in die es Daten aus der Haupttabelle kopiert. In dem Moment, in dem beide Tabellen identisch sind, wird die ursprüngliche Tabelle gesperrt und durch die neue ersetzt. In unserem Fall zeigte ein Testlauf, dass die Aktualisierung aller Tabellen etwa einen Tag dauern würde, das Kopieren der Daten jedoch zu einer zu hohen Belastung der Festplatten führte.

Um dies zu vermeiden, haben wir in der Produktion das Argument zum Befehl hinzugefügt --sleep mit einem Wert von 10 – dieser Parameter passt die Wartezeit nach der Übertragung eines Datenstapels in eine neue Tabelle an. Auf diese Weise können Sie die Last reduzieren, wenn die tatsächlich laufende Anwendung hohe Anforderungen an die Reaktionszeit stellt.

Nach Durchführung der Optimierung war das Update erfolgreich.

... aber nicht ganz!

Innerhalb einer halben Stunde nach dem Update trat beim Client ein Problem auf. Die Datenbank funktionierte sehr seltsam: Sie startete regelmäßig Verbindung wird zurückgesetzt. So sah es im Monitoring aus:

Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

Der Screenshot zeigt ein Sägezahndiagramm, da einige der MySQL-Server-Threads regelmäßig mit einem Fehler abstürzten. In der Anwendung sind Fehler aufgetreten:

[PDOException] SQLSTATE[HY000] [2002] Connection refused

Eine schnelle Überprüfung der Protokolle ergab, dass der mysqld-Daemon nicht die erforderlichen Ressourcen vom Betriebssystem erhalten konnte. Beim Aussortieren haben wir Fehler im System entdeckt „verwaiste“ Apparmor-Richtliniendateien:

# 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 wurden beim Upgrade auf MySQL 5.7 vor ein paar Jahren erstellt und gehören zu einem entfernten Paket. Das Löschen der Dateien und ein 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

Abschließend

Jeder noch so einfache Vorgang kann zu unerwarteten Problemen führen. Und selbst ein gut durchdachter Plan garantiert nicht immer das erwartete Ergebnis. Zu den Update-Plänen unseres Teams gehört nun auch die obligatorische Bereinigung unnötiger Dateien, die aufgrund kürzlich durchgeführter Aktionen entstanden sein könnten.

Und angesichts dieser nicht sehr professionellen grafischen Kreativität möchte ich Percona ein großes Dankeschön für seine hervorragenden Produkte aussprechen!

Aktualisierung von MySQL (Percona Server) von 5.7 auf 8.0

PS

Lesen Sie auch auf unserem Blog:

Source: habr.com

Kommentar hinzufügen