
Der Fortschritt steht nicht still, daher werden die Gründe für ein Upgrade auf die aktuellen Versionen von MySQL immer gewichtiger. Vor nicht allzu langer Zeit war es an der Zeit, unsere komfortablen Percona Server 5.7 Cluster auf die Version 8 zu aktualisieren. Dies geschah auf der Plattform Ubuntu Linux 16.04. Wie eine derartige Operation mit minimalen Ausfallzeiten durchgeführt werden kann und mit welchen Problemen wir beim Upgrade konfrontiert wurden, lesen Sie in diesem Artikel.
Vorbereitung
Jedes Upgrade eines Datenbankservers ist wahrscheinlich mit einer Neukonfiguration der Datenbank verbunden: Änderungen der Anforderungen an die Systemressourcengrenzen und Anpassungen der Konfigurationsdateien, die von veralteten Direktiven bereinigt werden müssen.
Bevor wir mit dem Upgrade beginnen, werden wir auf die offizielle Dokumentation zurückgreifen:
- ;
- ;
- ;
- .
Und wir werden einen Aktionsplan erstellen:
- Die Konfigurationsdateien korrigieren, indem wir veraltete Direktiven entfernen.
- Die Kompatibilität mit Tools überprüfen.
- Die Slave-Datenbanken aktualisieren, indem das Paket
percona-server-server. - aktualisiert wird, indem dasselbe Paket installiert wird.
Lassen Sie uns jeden Punkt des Plans durchgehen und sehen, was dabei schiefgehen kann.
WICHTIG! Das Upgrade-Verfahren für einen MySQL-Cluster auf Basis von Galera hat seine Besonderheiten, die in diesem Artikel nicht beschrieben sind. Diese Anleitung sollte in einem solchen Fall nicht verwendet werden.
Teil 1: Prüfung der Konfigurationen
In der 8. Version von MySQL wurde query_cacheentfernt. Er wurde eigentlich bereits in Version 5.7 deklariert, aber nun auch . Dementsprechend müssen die dazugehörigen Direktiven entfernt werden. Für die Abfrage-Caching können nun externe Werkzeuge genutzt werden – beispielsweise, .
In der Konfiguration haben wir zudem veraltete Direktiven über innodb_file_format. Während in MySQL 5.7 eine Wahl des InnoDB-Formats möglich war, arbeitet die 8. Version nun .
Unser Ergebnis – Entfernen der folgenden Direktiven:
-
query_cache_type,query_cache_limitundquery_cache_size; -
innodb_file_formatundinnodb_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 Verzeichnisse für Daten und Protokolle. Beispiel für die Konfigurationstest 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-centosFazit: Entweder in den Docker-Logs oder im Verzeichnis mit den Logs – je nach Ihrer Konfiguration – wird 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 eindeutig zu sein.
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 befassen und die veraltete Direktive ersetzen expire-logs-days.
Teil 2: Überprüfung der funktionierenden Installationen
In der Aktualisierungsdokumentation gibt es 2 Tools 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 Tool mysqlcheck. Es reicht aus, Folgendes auszuführen:
mysqlcheck -u root -p --all-databases --check-upgradeWenn keine Probleme gefunden werden, beendet das Tool mit dem Code 0:

Zudem steht in modernen Versionen von MySQL das Tool (im Fall von Percona ist es das Paket percona-mysql-shell). Es ist ein Ersatz für den klassischen mysql-Client und vereint Funktionen eines Clients, SQL-Code-Editors und Administrationswerkzeuge für MySQL. Zur Überprüfung des Servers vor dem Update kann über dieses Tool der folgende Befehl ausgeführt werden:
mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=\/etc\/mysql\/my.cnfUnd das sind die Anmerkungen, die wir erhalten haben:

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

Wir sind zu dem Schluss gekommen, dass das Update ohne Probleme verlaufen sollte.
Die oben genannten Warnungen weisen auf Probleme mit den Kodierungen hin. Der Punkt ist, dass UTF-8 in MySQL bis vor kurzem da es nur 3 Bytes anstelle von 4 gespeichert hat. In MySQL 8 wurde das endlich Der Alias utf8 wird bald auf den Zeichensatz utf8mb4, und alte Spalten in den Tabellen werden zu utf8mb3.Zukünftig wird der Zeichensatz utf8mb3. entfernt, jedoch nicht in dieser Version. Daher haben wir beschlossen, die Kodierungen bereits in der laufenden Installation der Datenbank nach ihrem Update zu korrigieren.
Teil 3: Aktualisierung der Server
Was könnte schiefgehen, wenn man einen so großartigen Plan hat? Wir sind uns bewusst, dass immer Nuancen auftreten können, und deshalb haben wir das erste Experiment auf dem Dev-Cluster von MySQL durchgeführt.
Wie bereits erwähnt, die Frage des Upgrades von MySQL-Servern mit Replikaten. Das Wesentliche ist, dass zunächst alle Replikate (Slave) aktualisiert werden sollten, da MySQL 8 in der Lage ist, mit einem Master der Version 5.7 zu replizieren. Eine gewisse Komplexität besteht darin, dass wir den Modus verwenden Master <-> Master, in dem der entfernte Master im Modus read-onlyarbeitet. Das bedeutet, dass der echte Traffic tatsächlich in ein Rechenzentrum läuft, während das zweite als Backup dient.
Die Topologie sieht wie folgt aus:

Das Upgrade sollte mit den Replikaten beginnen mysql replica dc 2, mysql master dc 2 und mysql replica dc 1, und enden mit dem Server mysql master dc 1. Zur weiteren Sicherheit haben wir die virtuellen Maschinen gestoppt, Snapshots erstellt und kurz vor dem Upgrade die Replikation mit dem Befehl STOP SLAVEgestoppt. Ansonsten sieht das Upgrade so aus:
- Wir starten jede Replik neu und fügen in den Konfigurationen 3 Optionen hinzu:
skip-networking,skip-slave-start,skip-log-bin. Das liegt daran, dass das Upgrade der Datenbank binäre Logs mit den aktualisierten Systemtabellen erzeugt. Diese Direktiven gewährleisten, dass es keine Änderungen an den Anwendungsdaten in der Datenbank gibt und dass Informationen über das Update der Systemtabellen nicht in die binären Logs gelangen. Das wird helfen, Probleme beim Wiederaufnehmen der Replikation zu vermeiden. - Wir installieren das Paket
percona-server-server. Es ist wichtig zu beachten, dass in MySQL 8 nicht es notwendig ist, den Befehlmysqlupgradenach dem Server-Upgrade auszuführen. - Nach dem erfolgreichen Start starten wir den Server erneut — bereits ohne die in Punkt eins hinzugefügten Parameter.
- Wir stellen sicher, dass die Replikation erfolgreich funktioniert: Wir überprüfen
SHOW SLAVE STATUSund sehen, dass die Tabellen mit den Zählern in der Anwendungsdatenbank aktualisiert werden.
Das alles klingt ziemlich einfach: Das Upgrade von Dev war erfolgreich. Okay, man kann das nächtliche Upgrade für die Produktion nun ruhig planen.
Es gab keinen Grund zur Traurigkeit — wir haben das Prod-Upgraden
Jedoch verlief der Transfer der erfolgreichen Dev-Erfahrungen auf die Produktion nicht ohne Überraschungen.
Glücklicherweise beginnt der Upgradeprozess mit den Replikaten, deshalb haben wir, als wir auf Schwierigkeiten stießen, die Arbeiten eingestellt und die Replik aus dem Snapshot wiederhergestellt. Die Problemuntersuchung haben wir auf den nächsten Morgen verschoben. In den Logs fanden sich folgende Einträge:
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 Beheben der SE-Daten für db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Fehler beim Auffüllen der DD-Tabellen.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Abgebrochen Die Untersuchung von Archiven verschiedener Mailinglisten in Google ergab, dass dieses Problem aufgrund von . Obwohl es eher ein Bug der Tools mysqlcheck und mysqlsh.
ist. Es stellt sich heraus, dass MySQL die Art und Weise geändert hat, wie Daten für Dezimalfelder (int, tinyint usw.) dargestellt werden, weshalb innerhalb von mysql-server eine andere Art der Speicherung verwendet wird. Wenn Ihre Datenbank ursprünglich in der Version 5.5 oder 5.1 war und Sie dann auf 5.7 aktualisiert haben, ist es möglich, dass Sie eine Wenn in der Partition nur noch ein Stück übrig ist, kann man nicht mit einem normalen Befehl zusammenführen, man muss für einige Tabellen durchführen müssen. Dann wird MySQL die Dateien mit den Daten aktualisieren und sie in das aktuelle Speicherformat konvertieren.
Außerdem kann dies mit dem Tool 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': 'your_decimal_column',
... Wenn field_type ist gleich 0, wird in der Tabelle der alte Typ verwendet — es muss eine Wenn in der Partition nur noch ein Stück übrig ist, kann man nicht mit einem normalen Befehl zusammenführen, man mussdurchgeführt werden. Wenn der Wert jedoch 246 ist — haben Sie bereits einen neuen Typ. Weitere Informationen zu den Typen finden Sie in .
Darüber hinaus eine zweite mögliche Ursache betrachtet, die uns entgangen ist — das Fehlen von InnoDB-Tabellen in der Systemtabelle INNODB_SYS_TABLESPACES, wenn diese Tabellen in Version 5.1 erstellt wurden. Um Probleme bei der Aktualisierung zu vermeiden, können Sie das .
Warum hatten wir solche Probleme nicht in der Entwicklungsumgebung? Die Datenbank wird regelmäßig von der Produktion kopiert — so werden die Tabellen neu erstellt.
Leider kann man bei einer tatsächlich in Betrieb befindlichen großen Datenbank nicht einfach eine umfassende Wenn in der Partition nur noch ein Stück übrig ist, kann man nicht mit einem normalen Befehl zusammenführen, man muss. Hier hilft das percona-toolkit: für die Online-OPTIMIERUNG eignet sich das Tool pt-online-schema-change hervorragend.
Der aktualisierte Plan sieht so aus:
- Alle Tabellen optimieren.
- Datenbanken aktualisieren.
Um dies zu überprüfen und gleichzeitig die Aktualisierungszeit zu ermitteln, haben wir eine der Replikate 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=t1Die Aktualisierung der Tabellen erfolgt ohne längere Sperren, 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 zeigte der Testlauf, dass für die Aktualisierung aller Tabellen etwa einen Tag benötigt wird, aber das Kopieren der Daten verursachte eine zu hohe Belastung der Festplatten.
Um dies zu vermeiden, haben wir auf der Produktionsumgebung der Befehl hinzugefügt --sleep mit dem Wert 10 — dieser Parameter regelt die Wartezeit nach dem Transfer einer Datenmenge in die neue Tabelle. So kann die Last verringert werden, wenn die tatsächlich laufende Anwendung empfindlich auf die Antwortzeit reagiert.
Nach der Durchführung der Optimierung war die Aktualisierung erfolgreich.
… aber nicht ganz!
Bereits eine halbe Stunde nach der Aktualisierung kam der Kunde mit einem Problem. Die Datenbank verhielt sich sehr merkwürdig: gelegentlich traten Verbindungsabbrücheauf. So sah das im Monitoring aus:

Auf dem Screenshot ist das gezackte Diagramm zu sehen, das damit zusammenhängt, dass einige MySQL-Server-Threads gelegentlich mit einem Fehler abgestürzt sind. Im Anwendung traten folgende Fehler auf:
[PDOException] SQLSTATE[HY000] [2002] Verbindung abgelehntEine schnelle Durchsicht der Logs ergab, dass der Dienst mysqld nicht die erforderlichen Ressourcen vom Betriebssystem erhalten konnte. Bei der Analyse der Fehler entdeckten wir im System „verwaiste“ AppArmor-Konfigurationsdateien:
# 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 amd64Diese Dateien sind vor zwei Jahren beim Upgrade auf MySQL 5.7 entstanden und gehören zu einem entfernten Paket. Das Entfernen 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 apparmorAbschließend
Jede, sogar die einfachste Operation kann zu unerwarteten Problemen führen. Und selbst ein durchdachter Plan garantiert nicht immer das erwartete Ergebnis. Jetzt gehört zur Aktualisierungsplanung unseres Teams auch die zwingende Reinigung überflüssiger Dateien, die als Ergebnis letzter Aktionen entstanden sein könnten.
Und für dieses nicht sehr professionelle grafische Werk möchte ich der Firma Percona für ihre großartigen Produkte herzlich danken!

P.S.
Lesen Sie auch in unserem Blog:
- «»;
- «»;
- «»;
- «»;
- «».
Quelle: habr.com
