MySQL (Percona Server) updaten van 5.7 naar 8.0

MySQL (Percona Server) updaten van 5.7 naar 8.0

De vooruitgang staat niet stil, dus de redenen om te upgraden naar de nieuwste versies van MySQL worden steeds dwingender. Nog niet zo lang geleden was het in een van onze projecten tijd om de gezellige Percona Server 5.7 clusters te updaten naar versie 8. Dit gebeurde allemaal op het Ubuntu Linux 16.04-platform. Hoe je zo'n operatie kunt uitvoeren met minimale downtime en welke problemen we tegenkwamen tijdens de update - lees in dit artikel.

Opleiding

Elke update van de databaseserver gaat hoogstwaarschijnlijk gepaard met herconfiguratie van de database: veranderingen in de vereisten voor limieten op systeembronnen en correctie van databaseconfiguraties die moeten worden ontdaan van verouderde richtlijnen.

Voordat we updaten, zullen we zeker de officiële documentatie raadplegen:

En laten we een actieplan opstellen:

  1. Corrigeer configuratiebestanden door verouderde richtlijnen te verwijderen.
  2. Controleer de compatibiliteit met hulpprogramma's.
  3. Update slave-databases door het pakket te installeren percona-server-server.
  4. Werk de master bij met hetzelfde pakket.

Laten we elk punt van het plan bekijken en kijken wat er mis kan gaan.

BELANGRIJK! De procedure voor het updaten van een MySQL-cluster op basis van Galera heeft zijn eigen subtiliteiten die niet in het artikel worden beschreven. In dit geval dient u deze instructie niet te gebruiken.

Deel 1: Configuraties controleren

MySQL is verwijderd in versie 8 query_cache. Eigenlijk was hij dat verouderd verklaard terug in versie 5.7, maar nu volledig verwijderd. Dienovereenkomstig is het noodzakelijk de bijbehorende richtlijnen te schrappen. En om verzoeken in de cache op te slaan, kunt u nu externe tools gebruiken, bijvoorbeeld ProxySQL.

Ook in de configuratie stonden er verouderde richtlijnen over innodb_file_format. Als het in MySQL 5.7 mogelijk was om het InnoDB-formaat te selecteren, dan werkt de 8e versie al alleen met Barracuda-formaat.

Ons resultaat is de verwijdering van de volgende richtlijnen:

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

Ter controle gebruiken we de Docker-image van Percona Server. We plaatsen de serverconfiguratie in de map mysql_config_test, en daarnaast zullen we mappen voor gegevens en logs maken. Voorbeeld van een Percona-server configuratietest:

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

Kort gezegd: in de Docker-logboeken of in de map met de logbestanden zal - afhankelijk van uw configuraties - een bestand verschijnen waarin de problematische richtlijnen worden beschreven.

Dit is wat we hadden:

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.

We moesten dus nog steeds de coderingen uitzoeken en de verouderde richtlijn vervangen expire-logs-days.

Deel 2: Controle van werkende installaties

De updatedocumentatie bevat twee hulpprogramma's waarmee u de database op compatibiliteit kunt controleren. Het gebruik ervan helpt de beheerder de compatibiliteit van de bestaande datastructuur te controleren.

Laten we beginnen met het klassieke mysqlcheck-hulpprogramma. Gewoon uitvoeren:

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

Als er geen problemen worden gevonden, wordt het hulpprogramma afgesloten met code 0:

MySQL (Percona Server) updaten van 5.7 naar 8.0

Bovendien is er een hulpprogramma beschikbaar in moderne versies van MySQL mysql-shell (in het geval van Percona is dit het 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 MySQL-beheertools. Om de server te controleren voordat u de update uitvoert, kunt u de volgende opdrachten uitvoeren:

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

Dit zijn de opmerkingen die we hebben ontvangen:

MySQL (Percona Server) updaten van 5.7 naar 8.0

Over het algemeen niets kritisch - alleen waarschuwingen over coderingen (zie hieronder). Algemeen uitvoeringsresultaat:

MySQL (Percona Server) updaten van 5.7 naar 8.0

We hebben besloten dat de update zonder problemen zou moeten verlopen.

Een opmerking over de bovenstaande waarschuwingen die problemen met coderingen aangeven. Feit is dat UTF-8 tot voor kort in MySQL zat was niet "waar" UTF-8, omdat het slechts 3 bytes opsloeg in plaats van 4. In MySQL 8 is dit eindelijk besloten om het te repareren: alias utf8 zal binnenkort leiden tot codering utf8mb4, en de oude kolommen in de tabellen worden utf8mb3. Verdere codering utf8mb3 zal worden verwijderd, maar niet in deze release. Daarom hebben we besloten om de coderingen die al aanwezig zijn op de actieve DBMS-installatie te corrigeren, nadat we deze hebben bijgewerkt.

Deel 3: Serverupdates

Wat zou er mis kunnen gaan als er zo'n slim plan is? Omdat we heel goed begrepen dat nuances altijd voorkomen, voerden we het eerste experiment uit op een MySQL-ontwikkelaarscluster.

Zoals al genoemd, officiële documentatie behandelt de kwestie van het updaten van MySQL-servers met replica's. Het komt erop neer dat u eerst alle replica's (slaves) moet updaten, aangezien MySQL 8 kan repliceren vanaf een masterversie 5.7. Enige moeilijkheid ligt in het feit dat we de modus gebruiken meester <-> meester, wanneer de externe master in de modus staat alleen-lezen. Dat wil zeggen dat het gevechtsverkeer in feite naar één datacenter gaat, en het tweede is een back-up.

De topologie ziet er als volgt uit:

MySQL (Percona Server) updaten van 5.7 naar 8.0

De update moet beginnen met replica's mysql-replica dc 2, mysqlmaster dc2 и mysql replica dc 1en eindigen met de mysql master dc 1-server. Om betrouwbaarder te zijn, hebben we de virtuele machines gestopt, momentopnamen ervan gemaakt en onmiddellijk vóór de update de replicatie gestopt met de opdracht STOP SLAVE. De rest van de update ziet er als volgt uit:

  1. We starten elke replica opnieuw door 3 opties aan de configuraties toe te voegen: skip-networking, skip-slave-start, skip-log-bin. Feit is dat het bijwerken van de database binaire logboeken genereert met updates van systeemtabellen. Deze richtlijnen garanderen dat er geen wijzigingen zullen plaatsvinden in de applicatiegegevens in de database, en dat informatie over het bijwerken van systeemtabellen niet zal worden opgenomen in de binaire logbestanden. Dit voorkomt problemen bij het hervatten van de replicatie.
  2. Het pakket installeren percona-server-server. Het is belangrijk op te merken dat in MySQL versie 8 geen je moet de opdracht uitvoeren mysqlupgrade na serverupdate.
  3. Na een succesvolle start herstarten we de server opnieuw - zonder de parameters die in de eerste paragraaf zijn toegevoegd.
  4. Wij zorgen ervoor dat de replicatie succesvol verloopt: check SHOW SLAVE STATUS en zorg ervoor dat de tabellen met tellers in de applicatiedatabase worden bijgewerkt.

Het ziet er allemaal vrij simpel uit: de dev-update was succesvol. Oké, je kunt veilig een nachtelijke update voor productie plannen.

Er was geen verdriet - we hebben de prod bijgewerkt

De overdracht van succesvolle ontwikkelervaring naar productie was echter niet zonder verrassingen.

Gelukkig begint het updateproces zelf met replica's, dus toen we problemen ondervonden, stopten we het werk en herstelden we de replica vanaf de momentopname. Het onderzoek naar de problemen werd uitgesteld tot de volgende ochtend. De logboeken bevatten de volgende vermeldingen:

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

Onderzoek in de archieven van verschillende mailinglijsten op Google leidde tot het inzicht dat dit probleem optreedt als gevolg van MySQL-bug. Hoewel dit waarschijnlijker een hulpprogrammafout is mysqlcheck и mysqlsh.

Het blijkt dat MySQL de manier heeft veranderd waarop ze gegevens voor decimale velden (int, tinyint, etc.) weergeven, dus mysql-server gebruikt een andere manier om ze op te slaan. Als uw database eerste was in versie 5.5 of 5.1, en vervolgens hebt u geüpdatet naar 5.7, dan moet u mogelijk dit doen OPTIMIZE voor sommige tafels. Vervolgens zal MySQL de gegevensbestanden bijwerken en overbrengen naar het huidige opslagformaat.

U kunt dit ook controleren met het hulpprogramma 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',
...

als field_type Als je het gelijk hebt aan 0, dan wordt het oude type in de tabel gebruikt - je moet het uitvoeren OPTIMIZE. Als de waarde echter 246 is, hebt u al een nieuw type. Meer informatie over de soorten vindt u in code.

Bovendien, in deze bug We overwegen de tweede mogelijke reden die ons is ontgaan: de afwezigheid van InnoDB-tabellen in de systeemtabel INNODB_SYS_TABLESPACES, als deze tabellen zijn gemaakt in versie 5.1. Om problemen bij het updaten te voorkomen, kunt u gebruiken bijgevoegd SQL-script.

Waarom hadden we niet zulke problemen op dev? De database wordt daar periodiek vanuit de productie gekopieerd - dus tabellen worden opnieuw gemaakt.

Helaas kun je op een echt werkende grote database niet zomaar een universele nemen en uitvoeren OPTIMIZE. percona-toolkit helpt hier: het hulpprogramma pt-online-schema-change is uitstekend voor de online OPTIMIZE-bewerking.

Het bijgewerkte plan zag er als volgt uit:

  1. Optimaliseer alle tabellen.
  2. Update de databases.

Om dit te controleren en tegelijkertijd de updatetijd te achterhalen, hebben we een van de replica's uitgeschakeld en de volgende opdracht voor alle tabellen 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=t1

Tabellen worden bijgewerkt zonder langdurige vergrendelingen, omdat het hulpprogramma een nieuwe tijdelijke tabel maakt waarin het gegevens uit de hoofdtabel kopieert. Op het moment dat beide tafels identiek zijn, wordt de originele tafel vergrendeld en vervangen door de nieuwe. In ons geval bleek uit een testrun dat het ongeveer een dag zou duren om alle tabellen bij te werken, maar het kopiëren van gegevens veroorzaakte te veel belasting op de schijven.

Om dit te voorkomen, hebben we in de productie het argument aan de opdracht toegevoegd --sleep met een waarde van 10 - deze parameter past de wachtduur aan na het overbrengen van een batch gegevens naar een nieuwe tabel. Op deze manier kunt u de belasting verminderen als de feitelijk actieve applicatie veel van de responstijd vraagt.

Na het uitvoeren van de optimalisatie was de update succesvol.

... maar niet helemaal!

Binnen een half uur na de update kwam de klant met een probleem. De database werkte heel vreemd: periodiek startten ze verbinding wordt gereset. Zo zag het eruit bij het monitoren:

MySQL (Percona Server) updaten van 5.7 naar 8.0

De schermafbeelding toont een zaagtandgrafiek vanwege het feit dat sommige MySQL-serverthreads periodiek crashten met een fout. Er zijn fouten verschenen in de applicatie:

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

Een snelle inspectie van de logbestanden bracht aan het licht dat de mysqld-daemon niet de vereiste bronnen van het besturingssysteem kon verkrijgen. Tijdens het uitzoeken van fouten ontdekten we in het systeem "wees"-apparmorbeleidsbestanden:

# 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

Deze bestanden zijn gemaakt tijdens de upgrade naar MySQL 5.7 een paar jaar geleden en behoren tot een verwijderd pakket. Het verwijderen van de bestanden en het opnieuw opstarten 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 apparmor

Concluderend

Elke, zelfs de eenvoudigste handeling, kan tot onverwachte problemen leiden. En zelfs het hebben van een goed doordacht plan garandeert niet altijd het verwachte resultaat. Nu omvatten alle updateplannen die ons team heeft ook het verplicht opschonen van onnodige bestanden die zouden kunnen zijn verschenen als gevolg van recente acties.

En met deze niet erg professionele grafische creativiteit wil ik Percona enorm bedanken voor hun uitstekende producten!

MySQL (Percona Server) updaten van 5.7 naar 8.0

PS

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie