Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

Fremskridtene står ikke stille, så grundene til at opgradere til de nyeste versioner af MySQL bliver stadig mere overbevisende. For ikke længe siden, i et af vores projekter, var det tid til at opdatere de hyggelige Percona Server 5.7-klynger til version 8. Alt dette skete på Ubuntu Linux 16.04-platformen. Hvordan man udfører en sådan operation med minimal nedetid, og hvilke problemer vi stødte på under opdateringen - læs i denne artikel.

Træning

Enhver opdatering af databaseserveren er højst sandsynligt forbundet med databaseomkonfiguration: ændringer i krav til begrænsninger på systemressourcer og rettelse af databasekonfigurationer, der skal ryddes for forældede direktiver.

Før vi opdaterer, vil vi helt sikkert henvise til den officielle dokumentation:

Og lad os lave en handlingsplan:

  1. Korrekt konfigurationsfiler ved at fjerne forældede direktiver.
  2. Tjek kompatibilitet med hjælpeprogrammer.
  3. Opdater slavedatabaser ved at installere pakken percona-server-server.
  4. Opdater masteren med den samme pakke.

Lad os se på hvert punkt i planen og se, hvad der kunne gå galt.

VIGTIGT! Proceduren for opdatering af en MySQL-klynge baseret på Galera har sine egne finesser, som ikke er beskrevet i artiklen. Du bør ikke bruge denne instruktion i dette tilfælde.

Del 1: Kontrol af konfigurationer

MySQL blev fjernet i version 8 query_cache. Det var han faktisk erklæret forældet tilbage i version 5.7, men nu helt slettet. Det er derfor nødvendigt at fjerne de tilhørende direktiver. Og til at cache anmodninger kan du nu bruge eksterne værktøjer - f.eks. ProxySQL.

Også i konfigurationen var der forældede direktiver om innodb_file_format. Hvis det i MySQL 5.7 var muligt at vælge InnoDB-formatet, så virker den 8. version allerede kun med Barracuda-format.

Vores resultat er fjernelse af følgende direktiver:

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

For at kontrollere, vil vi bruge Docker-billedet af Percona Server. Vi placerer serverkonfigurationen i mappen mysql_config_test, og ved siden af ​​vil vi oprette mapper til data og logfiler. Percona-server konfigurationstest eksempel:

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

Nederste linje: enten i Docker-logfilerne eller i mappen med logfilerne - afhængigt af dine konfigurationer - vil en fil dukke op, hvori de problematiske direktiver vil blive beskrevet.

Her er hvad vi havde:

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.

Derfor skulle vi stadig finde ud af kodningerne og erstatte det forældede direktiv expire-logs-days.

Del 2: Kontrol af fungerende installationer

Opdateringsdokumentationen indeholder 2 hjælpeprogrammer til at kontrollere databasen for kompatibilitet. Deres brug hjælper administratoren med at kontrollere kompatibiliteten af ​​den eksisterende datastruktur.

Lad os starte med det klassiske mysqlcheck-værktøj. Kør blot:

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

Hvis der ikke findes nogen problemer, afsluttes værktøjet med kode 0:

Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

Derudover er et hjælpeprogram tilgængeligt i moderne versioner af MySQL mysql-shell (i tilfælde af Percona er dette pakken percona-mysql-shell). Det er en erstatning for den klassiske mysql-klient og kombinerer funktionerne fra en klient, en SQL-kodeeditor og MySQL-administrationsværktøjer. For at kontrollere serveren før opdatering, kan du køre følgende kommandoer gennem den:

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

Her er de kommentarer, vi har modtaget:

Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

Generelt ikke noget kritisk - kun advarsler om kodninger (se nedenunder). Samlet udførelsesresultat:

Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

Vi besluttede, at opdateringen skulle forløbe uden problemer.

En note om advarslerne ovenfor, der indikerer problemer med kodninger. Faktum er, at UTF-8 i MySQL indtil for nylig var ikke "ægte" UTF-8, da den kun lagrede 3 bytes i stedet for 4. I MySQL 8 er dette endelig besluttede at ordne det: alias utf8 vil snart føre til kodning utf8mb4, og de gamle kolonner i tabellerne bliver til utf8mb3. Yderligere kodning utf8mb3 vil blive fjernet, men ikke i denne udgivelse. Derfor besluttede vi at rette kodningerne allerede på den kørende DBMS-installation, efter at have opdateret den.

Del 3: Serveropdateringer

Hvad kunne gå galt, når der er sådan en smart plan?.. For at forstå, at nuancer altid sker, udførte vi det første eksperiment på en MySQL-udviklerklynge.

Som allerede nævnt, officiel dokumentation dækker spørgsmålet om opdatering af MySQL-servere med replikaer. Den nederste linje er, at du først skal opdatere alle replikaer (slaver), da MySQL 8 kan replikere fra en masterversion 5.7. Nogle vanskeligheder ligger i, at vi bruger tilstanden mester <-> mester, når den eksterne master er i tilstanden read-only. Det vil sige, at kamptrafikken går til det ene datacenter, og det andet er en backup.

Topologien ser sådan ud:

Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

Opdateringen skal starte med replikaer mysql replika dc 2, mysql master dc 2 и mysql replica dc 1, og slutter med mysql master dc 1-serveren. For at være mere pålidelig stoppede vi de virtuelle maskiner, tog snapshots af dem og stoppede umiddelbart før opdateringen replikering med kommandoen STOP SLAVE. Resten af ​​opdateringen ser sådan ud:

  1. Vi genstarter hver replika ved at tilføje 3 muligheder til konfigurationerne: skip-networking, skip-slave-start, skip-log-bin. Faktum er, at opdatering af databasen genererer binære logfiler med opdateringer til systemtabeller. Disse direktiver garanterer, at der ikke vil være ændringer i applikationsdata i databasen, og information om opdatering af systemtabeller vil ikke blive inkluderet i de binære logfiler. Dette vil undgå problemer, når du genoptager replikering.
  2. Installation af pakken percona-server-server. Det er vigtigt at bemærke, at i MySQL version 8 nej du skal køre kommandoen mysqlupgrade efter serveropdatering.
  3. Efter en vellykket start genstarter vi serveren igen - uden de parametre, der blev tilføjet i første afsnit.
  4. Sørg for, at replikeringen fungerer korrekt: tjek SHOW SLAVE STATUS og se, at tabellerne med tællere i applikationsdatabasen er opdateret.

Det hele ser ret simpelt ud: udvikleropdateringen var vellykket. Ok, du kan roligt planlægge en natlig opdatering til produktion.

Der var ingen tristhed - vi opdaterede prod

Overførslen af ​​succesfuld dev-erfaring til produktion var dog ikke uden overraskelser.

Heldigvis begynder selve opdateringsprocessen med replikaer, så da vi stødte på vanskeligheder, stoppede vi arbejdet og gendannede replikaen fra snapshotet. Undersøgelsen af ​​problemerne blev udsat til næste morgen. Logfilerne indeholdt følgende poster:

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

At undersøge arkiverne af forskellige mailinglister på Google førte til forståelsen af, at dette problem opstår pga. MySQL fejl. Selvom dette mere sandsynligt er en utility-fejl mysqlcheck и mysqlsh.

Det viser sig, at MySQL har ændret den måde, de repræsenterer data på for decimalfelter (int, tinyint, osv.), så mysql-server bruger en anden måde at gemme dem på. Hvis din database oprindeligt var i version 5.5 eller 5.1, og så opdaterede du til 5.7, så skal du muligvis gøre OPTIMIZE for nogle borde. Derefter vil MySQL opdatere datafilerne og overføre dem til det aktuelle lagerformat.

Du kan også tjekke dette med værktøjet 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',
...

Hvis field_type Hvis du har det lig med 0, så bruges den gamle type i tabellen - du skal udføre OPTIMIZE. Men hvis værdien er 246, har du allerede en ny type. Mere information om typerne kan findes i kode.

Desuden i denne fejl Vi overvejer den anden mulige årsag, som omgik os: fraværet af InnoDB-tabeller i systemtabellen INNODB_SYS_TABLESPACES, hvis de, tabeller, blev oprettet i version 5.1. For at undgå problemer ved opdatering, kan du bruge vedhæftet SQL-script.

Hvorfor havde vi ikke sådanne problemer på dev? Databasen bliver med jævne mellemrum kopieret dertil fra produktionen - således, tabeller genskabes.

Desværre, på en virkelig fungerende stor database, vil du ikke være i stand til bare at tage og udføre en universal OPTIMIZE. percona-toolkit vil hjælpe her: pt-online-schema-change-værktøjet er fremragende til online OPTIMIZE-operationen.

Den opdaterede plan så således ud:

  1. Optimer alle tabeller.
  2. Opdater databaserne.

For at tjekke det og samtidig finde ud af opdateringstiden, deaktiverede vi en af ​​replikaerne og kørte følgende kommando for alle tabeller:

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

Tabeller opdateres uden lange låse på grund af det faktum, at hjælpeprogrammet opretter en ny midlertidig tabel, som den kopierer data fra hovedtabellen til. I det øjeblik, hvor begge borde er identiske, låses det originale bord og erstattes med det nye. I vores tilfælde viste en testkørsel, at det ville tage omkring en dag at opdatere alle tabeller, men kopiering af data forårsagede for meget belastning på diskene.

For at undgå dette tilføjede vi i produktionen argumentet til kommandoen --sleep med en værdi på 10 - denne parameter justerer ventelængden efter overførsel af en batch af data til en ny tabel. På denne måde kan du reducere belastningen, hvis den faktiske kørende applikation er krævende på responstid.

Efter at have udført optimeringen, lykkedes opdateringen.

... men ikke helt!

Inden for en halv time efter opdateringen kom klienten med et problem. Databasen fungerede meget mærkeligt: ​​med jævne mellemrum startede de forbindelsen nulstilles. Sådan så det ud i overvågningen:

Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

Skærmbilledet viser en savtandsgraf på grund af det faktum, at nogle af MySQL-servertrådene periodisk styrtede ned med en fejl. Der opstod fejl i applikationen:

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

En hurtig inspektion af logfilerne afslørede, at mysqld-dæmonen ikke kunne hente de nødvendige ressourcer fra operativsystemet. Mens vi sorterede fejl, opdagede vi i systemet "forældreløse" apparmor-politikfiler:

# 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

Disse filer blev oprettet ved opgradering til MySQL 5.7 for et par år siden og tilhører en fjernet pakke. Sletning af filerne og genstart af apparmor-tjenesten løste problemet:

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

Afslutningsvis

Enhver, selv den enkleste operation, kan føre til uventede problemer. Og selv at have en gennemtænkt plan garanterer ikke altid det forventede resultat. Nu inkluderer alle opdateringsplaner, som vores team har, også den obligatoriske rensning af unødvendige filer, der kunne være dukket op som et resultat af nylige handlinger.

Og med denne ikke særlig professionelle grafiske kreativitet, vil jeg gerne sige en kæmpe tak til Percona for deres fremragende produkter!

Opdatering af MySQL (Percona Server) fra 5.7 til 8.0

PS

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar