
De technologie staat niet stil, waardoor de redenen om te upgraden naar de nieuwste versies van MySQL steeds belangrijker worden. Onlangs was het tijd om in een van onze projecten de vertrouwde clusters van Percona Server 5.7 naar versie 8 te upgraden. Dit alles gebeurde op het Ubuntu Linux 16.04-platform. Hoe we deze operatie met minimale downtime hebben uitgevoerd en met welke problemen we tijdens de upgrade zijn geconfronteerd, leest u in dit artikel.
Voorbereiding
Elke upgrade van een databaseserver houdt waarschijnlijk verband met het opnieuw configureren van de database: wijzigingen in de eisen aan de limieten van systeembronnen en het corrigeren van configuraties die ontdaan moeten worden van verouderde richtlijnen.
Voor de upgrade zullen we zeker de officiële documentatie raadplegen:
- ;
- ;
- ;
- .
En we stellen een actieplan op:
- Corrigeer de configuratiebestanden door verouderde richtlijnen te verwijderen.
- Controleer de compatibiliteit met hulpmiddelen.
- Upgrade de slave-databases door het pakket
percona-server-server. - te installeren. Upgrade de master door hetzelfde pakket te installeren.
Laten we elk punt van het plan bespreken en kijken wat er mis kan gaan.
BELANGRIJK! De procedure voor het upgraden van een MySQL-cluster op basis van Galera heeft zijn eigen nuances die in dit artikel niet worden beschreven. Gebruik deze instructie in dat geval niet.
Deel 1: Controle van configuraties
In versie 8 van MySQL is query_cacheverwijderd. Het was eigenlijk al sinds versie 5.7, maar is nu volledig Daarom moeten de bijbehorende richtlijnen worden verwijderd. Voor het cachen van queries kunnen nu externe tools worden gebruikt — bijvoorbeeld, .
Ook in de configuratie zijn verouderde richtlijnen over innodb_file_format. Terwijl in MySQL 5.7 de mogelijkheid bestond om het InnoDB-formaat te kiezen, werkt versie 8 al .
Onze conclusie is de verwijdering van de volgende richtlijnen:
-
query_cache_type,query_cache_limitenquery_cache_size; -
innodb_file_formateninnodb_file_format_max.
Voor de controle gebruiken we de Docker-image van Percona Server. We plaatsen de serverconfiguratie in de map mysql_config_test, en we maken naast elkaar mappen voor gegevens en logs. Voorbeeld van de configuratietest 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-centosConclusie: ofwel in de Docker-logs, ofwel in de directory met logs — afhankelijk van uw configuraties — verschijnt er een bestand waarin de probleemdirectieven zijn beschreven.
Dit is wat wij hebben gevonden:
2020-04-03T12:44:19.670831Z 0 [Waarschuwing] [MY-011068] [Server] De syntaxis 'expire-logs-days' is verouderd en zal in een toekomstige release worden verwijderd. Gebruik alstublieft in plaats daarvan binlog_expire_logs_seconds.
2020-04-03T12:44:19.671678Z 0 [Waarschuwing] [MY-013242] [Server] --character-set-server: 'utf8' is momenteel een alias voor de tekenreeks UTF8MB3, maar zal in een toekomstige release een alias zijn voor UTF8MB4. Overweeg alstublieft het gebruik van UTF8MB4 om onduidelijkheid te voorkomen.
2020-04-03T12:44:19.671682Z 0 [Waarschuwing] [MY-013244] [Server] --collation-server: 'utf8_general_ci' is een sortering van de verouderde tekenreeks UTF8MB3. Overweeg alstublieft het gebruik van UTF8MB4 met een geschikte sortering. Daarom moesten we ook de coderingen bekijken en de verouderde richtlijn vervangen. expire-logs-days.
Deel 2: Controle van werkende installaties
In de documentatie voor de update zijn er 2 hulpprogramma's beschikbaar voor het controleren van de database op compatibiliteit. Het gebruik ervan helpt de beheerder om de compatibiliteit van de bestaande data-structuur te controleren.
Laten we beginnen met het klassieke hulpprogramma mysqlcheck. Het is voldoende om het gewoon uit te voeren:
mysqlcheck -u root -p --all-databases --check-upgradeAls er geen problemen worden gevonden, sluit het hulpprogramma af met code 0:

Daarnaast is er in moderne versies van MySQL het hulpprogramma (in het geval van Percona is dit pakket percona-mysql-shell). Het is een vervanging voor de klassieke mysql-client en combineert de functies van een client, een SQL-code-editor en beheertools voor MySQL. Voor de controle van de server vóór de update kan de volgende opdracht via dit hulpprogramma worden uitgevoerd:
mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=\/etc\/mysql\/my.cnfEn dit zijn de opmerkingen die we hebben ontvangen:

Over het algemeen niets kritiek — alleen waarschuwingen over coderingen. (zie hieronder)Algemene uitvoeringsresultaat:

We hebben besloten dat de update zonder problemen zou moeten verlopen.
Opmerking over de bovenstaande waarschuwingen, die problemen met coderingen aangeven. Het probleem is dat UTF-8 in MySQL tot voor kort omdat het slechts 3 bytes in plaats van 4 opsloeg. In MySQL 8 hebben ze dit eindelijk de alias utf8 zal binnenkort verwijzen naar de codering utf8mb4,en de oude kolommen in tabellen worden utf8mb3.De codering zal op termijn worden verwijderd, maar niet in deze release. Daarom hebben we besloten om de coderingen al op de werkende installatie van de DBMS aan te passen, na de update. utf8mb3. Deel 3: Update van servers
Deel 3: Serverupdates
Wat kan er misgaan met zo'n fantastisch plan?.. Volledig begrip hebbende dat nuance altijd voorkomt, hebben wij ons eerste experiment uitgevoerd op de dev-cluster van MySQL.
Zoals eerder vermeld, behandelt de vraag van het upgraden van MySQL-servers met replica's. Het komt erop neer dat we eerst alle replica's (slave) moeten upgraden, omdat MySQL 8 kan repliceren van een master van versie 5.7. Een zekere complexiteit ontstaat doordat we de modus gebruiken master master, waarin de externe master zich in de modus bevindt read-only. Dit betekent dat het daadwerkelijke live verkeer naar één datacenter gaat, terwijl het andere als reserve dient.
De topologie ziet er als volgt uit:

De upgrade moet beginnen met de replica's mysql replica dc 2, mysql master dc 2 en mysql replica dc 1, en eindigen met de mysql master dc 1 server. Voor extra betrouwbaarheid hebben we de virtuele machines gestopt, snapshots gemaakt, en direct voorafgaand aan de upgrade de replicatie gestopt met het commando STOP SLAVE. Het overige van de upgrade ziet er als volgt uit:
- We herstarten elke replica en voegen 3 opties toe aan de configuraties:
skip-networking,skip-slave-start,skip-log-bin. Het probleem is dat de database-upgrade binaire logs genereert met updates van systeemtabellen. Deze richtlijnen garanderen dat er geen veranderingen in de applicatiedata plaatsvinden in de database en dat de informatie over de updates van de systeemtabellen niet in de binaire logs terechtkomt. Dit voorkomt problemen bij het hervatten van de replicatie. - We installeren het pakket
percona-server-server. Het is belangrijk op te merken dat in MySQL 8 niet het vereist is de commandoregelmysqlupgradeuit te voeren na de serverupgrade. - Na een succesvolle startup herstarten we de server nogmaals — nu zonder de parameters die in het eerste punt zijn toegevoegd.
- We controleren of de replicatie succesvol werkt: we controleren
SHOW SLAVE STATUSen kijken of de tabellen met tellers in de applicatiedatabase worden bijgewerkt.
Dit lijkt vrij eenvoudig: de dev-update is succesvol verlopen. Oké, we kunnen ontspannen de nachtelijke update voor de productie plannen.
Er was geen verdriet — we hebben prod geüpgraded
Echter, het overbrengen van de succesvolle ervaring van dev naar productie ging niet zonder verrassingen.
Gelukkig begint het upgradeproces zelf met de replica's, dus toen we tegen problemen aanliepen, hebben we het werk stopgezet en de replica uit de snapshot hersteld. Het onderzoeken van de problemen hebben we naar de volgende ochtend verschoven. In de logs stonden de volgende vermeldingen:
2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] tabel: t1 heeft 19 kolommen, maar het InnoDB woordenboek heeft 20 kolommen
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Fout bij het herstellen van SE-gegevens voor db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Mislukt om DD-tabellen te vullen.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Afgebroken Onderzoek van archieven van verschillende e-mailnieuwsbrieven in Google leidde tot het inzicht dat dit probleem voortkomt uit . Het is zelfs meer een bug van de tools mysqlcheck en mysqlsh.
Het blijkt dat MySQL de manier waarop gegevens worden weergegeven voor decimale velden (int, tinyint, enz.) heeft veranderd, daarom wordt in de mysql-server een andere opslagmethode gebruikt. Als uw database oorspronkelijk was in versie 5.5 of 5.1 en u vervolgens hebt geüpdatet naar 5.7, dan moet u mogelijk OPTIMIZE voor sommige tabellen uitvoeren. Dan zal MySQL de gegevensbestanden bijwerken naar het actuele opslagformaat.
Dit kan ook worden gecontroleerd met de tool mysqlfrm:
mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
'field_length': 8,
'field_type': 246, # veldformaat
'field_type_name': 'decimal',
'flags': 3,
'flags_extra': 67,
'interval_nr': 0,
'name': 'you_deciaml_column',
... Als field_type is gelijk aan 0, dan wordt in de tabel het oude type gebruikt — dit moet worden uitgevoerd OPTIMIZE. Maar als de waarde 246 is — dan heeft u al het nieuwe type. Voor meer details over de types kunt u terecht bij .
Bovendien wordt in een tweede mogelijke oorzaak besproken die ons is ontgaan — het ontbreken van InnoDB-tabellen in de systeemtabel INNODB_SYS_TABLESPACES, als deze tabellen zijn gemaakt in versie 5.1. Om problemen bij de update te voorkomen, kunt u gebruikmaken van .
Waarom hebben we niet zulke problemen gehad op dev? De database wordt daar regelmatig gekopieerd vanuit productie — zo worden de tabellen opnieuw aangemaakt.
Helaas kan dit niet eenvoudigweg worden uitgevoerd op een werkelijk functionerende grote database. OPTIMIZEHier kan percona-toolkit bij helpen: voor de online OPTIMIZE operatie is de tool pt-online-schema-change zeer geschikt.
Het bijgewerkte plan is als volgt:
- Voer optimalisatie uit voor alle tabellen.
- Voer database-updates uit.
Om dit te controleren en om de update-tijd te achterhalen, hebben we een van de replicas uitgeschakeld en voor alle tabellen de volgende opdracht uitgevoerd:
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=t1Het bijwerken van tabellen gebeurt zonder langdurige blokkeringen, omdat het hulpprogramma een nieuwe tijdelijke tabel aanmaakt waarin gegevens uit de hoofdtafel worden gekopieerd. Op het moment dat beide tabellen identiek zijn, wordt de oorspronkelijke tabel geblokkeerd en vervangen door de nieuwe. In ons geval toonde een test dat het ongeveer een dag zou duren om alle tabellen bij te werken, maar daarbij veroorzaakte het kopiëren van gegevens een te hoge belasting op de schijven.
Om dit te voorkomen, hebben we in production een argument toegevoegd aan het commando --sleep met een waarde van 10 — deze parameter regelt de wachttijd na het overzetten van een gegevensbatch naar de nieuwe tabel. Dit kan de belasting verlagen als de daadwerkelijk uitgevoerde applicatie gevoelig is voor responstijden.
Na de optimalisatie is de update succesvol verlopen.
… maar niet helemaal!
Al na een halfuur na de update kwam de klant met een probleem. De database werkte zeer vreemd: af en toe werden er verbindingen verbroken. Dit is hoe het eruitzag in de monitoring:

In de screenshot is een zaagtandgrafiek te zien, gerelateerd aan het feit dat een deel van de MySQL-serverthreads af en toe met een fout uitviel. In de applicatie verschenen fouten:
[PDOException] SQLSTATE[HY000] [2002] Verbinding geweigerdBij een oppervlakkige inspectie van de logs bleek dat de mysqld-daemon de benodigde resources van het besturingssysteem niet kon verkrijgen. Bij het achterhalen van de fouten ontdekten we in het systeem "verwaarloosde" apparmor-beleidsbestanden:
# 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 amd64Deze bestanden zijn ontstaan tijdens de upgrade naar MySQL 5.7 een paar jaar geleden en behoren tot een verwijderde package. Het verwijderen van de bestanden en het herstarten van de apparmor-service loste het probleem op:
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 apparmorTer conclusie
Elke, zelfs de eenvoudigste operatie, kan leiden tot onverwachte problemen. En zelfs de aanwezigheid van een doordacht plan garandeert niet altijd het verwachte resultaat. Nu omvat elk updateplan van ons team ook het verplichte opruimen van overbodige bestanden die mogelijk als gevolg van eerdere acties zijn ontstaan.
Met deze niet al te professionele grafische creatie wil ik enorm bedanken aan Percona voor hun uitstekende producten!

P.S.
Lees ook op onze blog:
- «»;
- «»;
- «»;
- «»;
- «».
Bron: habr.com
