Upgrade von MySQL (Percona Server) von 5.7 auf 8.0



Der Fortschritt steht nicht still, daher werden die Gründe für das Upgrade auf die neuesten Versionen von MySQL immer wichtiger. Vor nicht allzu langer Zeit war es in einem unserer Projekte an der Zeit, gemütliche Percona Server 5.7-Cluster auf Version 8 zu aktualisieren. All dies geschah auf der Ubuntu Linux 16.04-Plattform. Lesen Sie diesen Artikel, um einen ähnlichen Vorgang mit minimalen Ausfallzeiten durchzuführen und auf welche Probleme beim Upgrade gestoßen ist.

Ausbildung


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

Vor dem Update werden wir uns definitiv der offiziellen Dokumentation zuwenden:


Und machen Sie einen Aktionsplan:

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

Wir werden jeden Punkt im Plan analysieren und sehen, was schief gehen kann.

WICHTIG! Das Galera-basierte MySQL-Cluster-Upgrade-Verfahren verfügt über eigene Feinheiten, die im Artikel nicht beschrieben werden. Sie sollten diese Anweisung in diesem Fall nicht verwenden.

Teil 1: Überprüfen von Konfigurationen


In Version 8 wurde MySQL entfernt query_cache. Tatsächlich wurde es in Version 5.7 für veraltet erklärt , aber jetzt ist es vollständig gelöscht . Dementsprechend müssen die entsprechenden Richtlinien entfernt werden. Zum Zwischenspeichern von Abfragen können Sie jetzt externe Tools verwenden, z. B. ProxySQL .

Auch veraltete Pro-Direktiven wurden in der Konfiguration gefunden innodb_file_format. Wenn in MySQL 5.7 das InnoDB-Format ausgewählt werden konnte, funktioniert die 8. Version bereits nur mit dem Barracuda-Format .

Unser Ergebnis ist die Streichung der folgenden Richtlinien:

  • query_cache_type, query_cache_limitUnd query_cache_size;
  • innodb_file_formatund innodb_file_format_max.

Zur Überprüfung verwenden wir das Docker-Image von Percona Server. Wir werden die Serverkonfiguration in das Verzeichnis stellen mysql_config_testund als Nächstes die Verzeichnisse für Daten und Protokolle erstellen. 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

Ergebnis: Entweder in den Docker-Protokollen oder im Verzeichnis mit den Protokollen - abhängig von Ihren Konfigurationen - wird eine Datei angezeigt, in der die Problemanweisungen 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 uns immer noch mit Codierungen befassen und die veraltete Richtlinie ersetzen expire-logs-days.

Teil 2: Überprüfen laufender Installationen


In der Update-Dokumentation finden Sie zwei Dienstprogramme zum Überprüfen 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. Einfach ausführen:

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

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



Darüber hinaus ist das Dienstprogramm mysql-shell in modernen Versionen von MySQL verfügbar (im Fall von Percona ist dies ein Paket percona-mysql-shell). Es ist ein Ersatz für den klassischen MySQL-Client und kombiniert die Funktionen des Clients, des SQL-Editors und der 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

Und hier sind die Kommentare, die wir erhalten haben:



Im Allgemeinen nichts Kritisches - nur Warnungen vor Codierungen (siehe unten) . Das Gesamtergebnis der Implementierung:



Wir haben beschlossen, dass das Update ohne Probleme verlaufen soll.

Ein Hinweis zu den obigen Warnungen, der auf Codierungsprobleme hinweist. Tatsache ist, dass UTF-8 in MySQL bis vor kurzem kein „echtes“ UTF-8 war , da es nur 3 statt 4 Bytes speicherte. In MySQL 8 beschlossen sie schließlich , es zu beheben : Der Alias utf8wird bald zur Codierung führen utf8mb4, und die alten Die Spalten in den Tabellen werden utf8mb3. In Zukunft wird die Codierung utf8mb3gelöscht, jedoch nicht in dieser Version. Aus diesem Grund haben wir uns entschlossen, die Codierungen, die bereits in einer funktionierenden Installation des DBMS vorhanden sind, nach der Aktualisierung zu korrigieren.

Teil 3: Server-Updates


Was kann schief gehen, wenn es einen so schicken Plan gibt? Da wir uns bewusst sind, dass die Nuancen immer auftreten, haben wir das erste Experiment mit dem MySQL-Entwicklungscluster durchgeführt.

Wie bereits erwähnt, wird in der offiziellen Dokumentation das Problem der Aktualisierung von MySQL-Servern mit Replikaten hervorgehoben. Unter dem Strich lohnt es sich zunächst, alle Replikate (Slaves) zu aktualisieren, da MySQL 8 vom Assistenten der Version 5.7 replizieren kann. Einige Schwierigkeiten liegen in der Tatsache, dass wir den Master <-> Master- Modus verwenden, wenn sich der Remote-Master im schreibgeschützten Modus befindet . Das heißt, der Kampfverkehr gelangt in ein Rechenzentrum, und das zweite ist die Sicherung.

Die Topologie lautet wie folgt: Das



Upgrade sollte mit MySQL-Replikat-DC 2- Replikaten beginnen, mysql master dc 2 und mysql replica dc 1, und am Ende mit dem mysql master dc 1. Server. Für eine bessere Zuverlässigkeit haben wir die virtuellen Maschinen gestoppt, sie als Snapshots erstellt und die Replikation mit dem Befehl kurz vor dem Update gestoppt STOP SLAVE. Der Rest des Updates sieht folgendermaßen aus:

  1. Jeder Replik Neustart Hinzufügen der Konfigurationsoption 3: skip-networking, skip-slave-start, skip-log-bin. Tatsache ist, dass beim Aktualisieren der Datenbank binäre Protokolle mit aktualisierten Systemtabellen generiert werden. Diese Anweisungen garantieren, dass keine Änderungen an den Anwendungsdaten in der Datenbank vorgenommen werden und Informationen zum Aktualisieren der Systemtabellen nicht in die Binärprotokolle gelangen. Dadurch werden Probleme beim Fortsetzen der Replikation vermieden.
  2. Installieren Sie das Paket percona-server-server. Es ist wichtig zu beachten, dass Sie in MySQL 8 den Befehl nach dem Aktualisieren des Servers nicht ausführen müssen mysqlupgrade.
  3. Starten Sie den Server nach einem erfolgreichen Start erneut - bereits ohne die im ersten Absatz hinzugefügten Parameter.
  4. Wir stellen sicher, dass die Replikation erfolgreich funktioniert: Wir überprüfen, SHOW SLAVE STATUSob die Tabellen mit Zählern in der Anwendungsdatenbank aktualisiert werden.

Das alles sieht ganz einfach aus: Das Entwickler-Update war erfolgreich. Ok, Sie können sicher ein Upgrade über Nacht für die Produktion planen.

Es gab keine Traurigkeit - wir haben das Produkt aktualisiert


Die erfolgreiche Entwicklung der Entwicklererfahrung auf die Produktion war jedoch nicht ohne Überraschungen.

Glücklicherweise beginnt der Aktualisierungsprozess selbst mit Replikaten. Nachdem wir auf Schwierigkeiten gestoßen sind, haben wir die Arbeit eingestellt und das Replikat aus dem Snapshot wiederhergestellt. Die Problemstudie wurde am nächsten Morgen verschoben. Die folgenden Einträge wurden in den Protokollen angezeigt:

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

Eine Untersuchung der Archive verschiedener Mailinglisten bei Google ergab, dass ein solches Problem aufgrund eines MySQL-Fehlers auftritt . Obwohl es eher ein Utility-Bug ist mysqlcheckund mysqlsh.

Es stellt sich heraus, dass MySQL die Darstellung von Daten für Dezimalfelder (int, tinyint usw.) geändert hat, sodass eine andere Möglichkeit zum Speichern in MySQL-Servern verwendet wird. Wenn Ihre Datenbank ursprünglich in Version 5.5 oder 5.1 war und Sie dann auf 5.7 aktualisiert haben, müssen Sie möglicherweise OPTIMIZEeinige Tabellen erstellen . 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_typeSie 0 haben, wird der alte Typ in der Tabelle verwendet - dies muss durchgeführt werden OPTIMIZE. Wenn der Wert jedoch 246 ist, haben Sie bereits einen neuen Typ. Weitere Informationen zu den Typen finden Sie im Code .

Darüber hinaus berücksichtigt dieser Fehler den zweiten möglichen Grund, der uns umgangen hat - das Fehlen von InnoDB-Tabellen in der Systemtabelle INNODB_SYS_TABLESPACES, wenn diese Tabellen in Version 5.1 erstellt wurden. Um Probleme während des Upgrades zu vermeiden, können Sie das angehängte SQL-Skript verwenden .

Warum hatten wir solche Probleme bei dev nicht? Die Basis wird dort regelmäßig aus der Produktion kopiert - somit werden die Tabellen neu erstellt .

Leider funktioniert es in einer wirklich funktionierenden großen Datenbank nicht nur, die allgegenwärtige Datenbank zu übernehmen und auszuführen OPTIMIZE. Das Percona-Toolkit hilft hier: Das Dienstprogramm pt-online-schema-change eignet sich hervorragend für den Online-OPTIMIZE-Vorgang.

Der aktualisierte Plan lautete wie folgt:

  1. Optimieren Sie alle Tabellen.
  2. Führen Sie ein Datenbank-Upgrade durch.

Um dies zu überprüfen und gleichzeitig die Aktualisierungszeit herauszufinden, haben wir eines der Replikate deaktiviert 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 Tabellen werden ohne lange Sperren aktualisiert, da das Dienstprogramm 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 eine neue ersetzt. In unserem Fall ergab ein Testlauf, dass das Aktualisieren aller Tabellen etwa einen Tag dauern würde, das Kopieren der Daten jedoch zu viel Belastung der Festplatten verursachte.

Um dies zu vermeiden, haben wir bei der Produktion dem Befehl ein Argument --sleepmit dem Wert 10 hinzugefügt. Dieser Parameter steuert die Wartezeit nach der Übertragung eines Datenpakets in eine neue Tabelle. Auf diese Weise können Sie die Last reduzieren, wenn eine wirklich ausgeführte Anwendung eine Antwortzeit benötigt.

Nach Durchführung der Optimierung war das Update erfolgreich.

... aber nicht ganz!


Eine halbe Stunde nach dem Update hatte der Client ein Problem. Die Basis funktionierte sehr seltsam: In regelmäßigen Abständen begannen Verbindungsabbrüche . So sah es bei der Überwachung aus:



Das Sägezahndiagramm ist im Screenshot sichtbar, da ein Teil der Threads des MySQL-Servers regelmäßig mit einem Fehler herunterfiel. In der Anwendung sind Fehler aufgetreten:

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

Eine schnelle Überprüfung der Protokolle ergab, dass der mysqld-Daemon die erforderlichen Ressourcen nicht vom Betriebssystem erhalten konnte. Beim Umgang mit Fehlern haben wir in den Apparmor-Richtliniendateien des Systems Folgendes gefunden :

# 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 während des Upgrades auf MySQL 5.7 vor einigen Jahren erstellt und gehören zum Remote-Paket. Das Löschen von Dateien und das Neustarten 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, auch der einfachste Vorgang, kann zu unerwarteten Problemen führen. Und selbst ein gut durchdachter Plan garantiert nicht immer das erwartete Ergebnis. In allen Update-Plänen umfasst unser Team jetzt auch die obligatorische Bereinigung zusätzlicher Dateien, die aufgrund der jüngsten Aktionen auftreten können.

Und mit dieser nicht so professionellen Grafik möchte ich Percona für ihre großartigen Produkte danken!



PS


Lesen Sie auch in unserem Blog:


All Articles