Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

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

Forberedelse

Enhver opdatering af en database server vil sandsynligvis være forbundet med omkonfiguration af databasen: ændringer i kravene til grænser for systemressourcer og rettelse af konfigurationer, som nødvendigvis skal renses for forældede direktiver.

Før opdateringen vil vi helt sikkert konsultere den officielle dokumentation:

Og vi vil sammen lave en handlingsplan:

  1. Korrigere konfigurationsfilerne ved at fjerne forældede direktiver.
  2. Kontrollere kompatibiliteten med værktøjer.
  3. Opdatere slave-databaserne ved at installere pakken percona-server-server.
  4. Opdatere masteren ved at installere den samme pakke.

Lad os gennemgå hvert punkt i planen og se, hvad der kan gå galt.

VIGTIGT! Opdateringsproceduren for MySQL-klynger baseret på Galera har sine egne nuancer, som ikke er beskrevet i artiklen. Det anbefales ikke at bruge denne vejledning i sådanne tilfælde.

Del 1: Kontrol af konfigurationer

I MySQL 8 er query_cachefjernet. Det blev faktisk anerkendt som forældet allerede i version 5.7, men nu er det helt fjernet. Derfor er det nødvendigt at fjerne de relaterede direktiver. Og til forespørgselscaching kan man nu bruge eksterne værktøjer — for eksempel, ProxySQL.

Derudover fandt vi forældede direktiver i konfigurationen vedrørende innodb_file_format. Hvis der i MySQL 5.7 var mulighed for at vælge InnoDB-formatet, så fungerer 8. version allerede kun med Barracuda-formatet..

Vores konklusion er at fjerne følgende direktiver:

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

Til kontrol bruger vi Docker-billedet af Percona Server. Serverens konfiguration placeres i mappen mysql_config_test, og vi opretter mapper til data og logs ved siden af. Eksempel på konfigurationstest for 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-centos

Konklusion: Enten i Docker-logfilerne eller i mappen med logfiler — afhængigt af dine konfigurationer — vil der vises en fil, der beskriver de problematiske direktiver.

Her er hvad vi havde:

2020-04-03T12:44:19.670831Z 0 [Warning] [MY-011068] [Server] Syntaksen 'expire-logs-days' er forældet og vil blive fjernet i en fremtidig version. Brug venligst binlog_expire_logs_seconds i stedet.
2020-04-03T12:44:19.671678Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' er i øjeblikket et alias for tegnsættet UTF8MB3, men vil være et alias for UTF8MB4 i en fremtidig version. Overvej venligst at bruge UTF8MB4 for at være entydig.
2020-04-03T12:44:19.671682Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' er en sammenligning af det forældede tegnsæt UTF8MB3. Overvej venligst at bruge UTF8MB4 med en passende sammenligning i stedet.

Dermed var vi nødt til også at forstå kodningerne og erstatte den forældede direktiv expire-logs-days.

Del 2: Kontrol af fungerende installationer

I dokumentationen til opgraderingen er der 2 værktøjer til at kontrollere databasen for kompatibilitet. Deres brug hjælper administratoren med at tjekke kompatibiliteten af den eksisterende datamodel.

Lad os begynde med det klassiske værktøj mysqlcheck. Det er ganske enkelt at starte:

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

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

Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

Derudover er der i moderne versioner af MySQL et værktøj 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 klienten, SQL-kodeditoren og MySQL-administrationsværktøjer. For at kontrollere serveren før opgraderingen kan du udføre følgende kommando gennem den:

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

Og her er hvilke bemærkninger vi fik:

Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

Generelt, intet kritisk — kun advarsler om kodninger. (se nedenfor)Den samlede udførelsesresultat:

Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

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

Bemærkningen om advarslerne ovenfor indikerer problemer med kodningerne. Det er faktisk sådan, at UTF-8 i MySQL indtil for nylig ikke var 'ægte' UTF-8,da den kun opbevarede 3 bytes i stedet for 4. I MySQL 8 har de endelig besluttet at rette dette:aliaset utf8 vil snart føre til kodningen utf8mb4, og gamle kolonner i tabellerne vil blive utf8mb3.I fremtiden vil kodningen utf8mb3. blive fjernet, men ikke i denne version. Derfor besluttede vi at rette kodningerne allerede i den kørende installation af DBMS'en, efter opgraderingen.

Del 3: Opgradering af servere

Hvad kan gå galt, når der findes en så flot plan?.. Velvidende at der altid kan komme nuancer, gennemførte vi det første eksperiment på dev-klusteret MySQL.

Som nævnt tidligere, den officielle dokumentation belyser spørgsmålet om opdatering af MySQL-servere med replikaer. Det korte af det lange er, at man først bør opdatere alle replikaer (slave), da MySQL 8 kan replikeres fra en master med version 5.7. En vis kompleksitet opstår, fordi vi bruger tilstanden master master, hvor den fjerne master er i tilstand read-only. Det vil sige, at den faktiske trafik går til et datacenter, mens det andet fungerer som backup.

Topologien ser således ud:

Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

Opdateringen skal starte med replikaerne mysql replica dc 2, mysql master dc 2 og mysql replica dc 1, og afsluttes med serveren mysql master dc 1. For at øge pålideligheden stoppede vi de virtuelle maskiner, lavede snapshots, og lige før opdateringen stoppede vi replikationen med kommandoen STOP SLAVE. Ellers ser opdateringen således ud:

  1. Vi genstarter hver replika og tilføjer 3 indstillinger til konfigurationerne: skip-networking, skip-slave-start, skip-log-bin. Problemet er, at opdateringen af databasen genererer binære logs ved opdatering af systemtabeller. Disse direktiver sikrer, at der ikke ændres applikationsdata i databasen, og at opdateringsoplysningerne om systemtabellerne ikke ender i de binære logs. Dette vil forhindre problemer, når replikationen genoptages.
  2. Vi installerer pakken percona-server-server. Det er vigtigt at bemærke, at i versionen MySQL 8 ikke skal kommandoen mysqlupgrade køres efter opdateringen af serveren.
  3. Efter en vellykket opstart genstarter vi serveren igen – nu uden de parametre, der blev tilføjet i første punkt.
  4. Vi sikrer os, at replikationen fungerer korrekt: vi kontrollerer SHOW SLAVE STATUS og ser, at tabellerne med tællerne i applikationsdatabasen opdateres.

Det hele ser ret enkelt ud: dev-opdateringen gik godt. Okay, vi kan roligt planlægge den natlige opdatering for produktionen.

Der var ingen sorg – vi opdaterede prod

Dog gik overførslen af den vellykkede erfaring fra dev til produktion ikke uden overraskelser.

Heldigvis begynder selve opdateringsprocessen med replikaerne, så da vi stødte på problemer, stoppede vi arbejdet og gendannede replikaen fra snapshotet. Problemanalysen blev udskudt til næste morgen. I loggene fandt vi følgende optegnelser:

2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] tabel: t1 har 19 kolonner, men InnoDB-ordbogen har 20 kolonner
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Fejl ved reparation af SE-data for db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Mislykkedes med at udfylde DD-tabeller.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Annullerer

Undersøgelse af arkiver fra forskellige e-mail-nyhedsbreve i Google førte til forståelsen af, at dette problem opstår på grund af en fejl i MySQL. Det er dog mere sandsynligt, at det er en fejl i værktøjerne mysqlcheck og mysqlsh.

Det viser sig, at MySQL har ændret måden data præsenteres for decimalfelter (int, tinyint mv.), så inde i mysql-serveren bruges en anden metode til opbevaring. Hvis din database oprindeligt var i version 5.5 eller 5.1, og du så opdaterede til 5.7, kan det være nødvendigt at udføre OPTIMIZE for nogle tabeller. Så opdaterer MySQL datafilerne og konverterer dem til det aktuelle opbevaringsformat.

Dette kan også kontrolleres med værktøjet mysqlfrm:

mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
 'field_length': 8,
  'field_type': 246, # felttypen
  'field_type_name': 'decimal',
  'flags': 3,
  'flags_extra': 67,
  'interval_nr': 0,
 'name': 'you_decimal_column',
...

Hvis field_type er lig med 0, så anvendes den gamle type i tabellen — dette skal rettes OPTIMIZE. Men hvis værdien er 246 — så har du allerede den nye type. Du kan finde flere oplysninger om typerne i koden.

Desuden overvejes der i denne fejl en anden mulig årsag, som vi undgik, - nemlig fraværet af InnoDB-tabeller i systemtabellenINNODB_SYS_TABLESPACES , hvis disse tabeller blev oprettet i version 5.1. For at undgå problemer ved opgradering kan du bruge.

den vedlagte SQL-script Hvorfor opstod disse problemer ikke hos os på dev? Databasen kopieres jævnligt fra produktionen — således.

bliver tabellerne genskabt OPTIMIZEDesværre kan man ikke bare tage en stor, fungerende database og udføre en generel

. Her hjælper percona-toolkit: til online OPTIMIZE-operationen er værktøjet pt-online-schema-change fremragende.

  1. Den opdaterede plan blev således:
  2. Udfør optimering af alle tabeller.

Udfør opdatering af databaser.

For at tjekke det og samtidig finde ud af opdateringstiden, slukkede vi en af replikkerne, og vi 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

Opdatering af tabeller foretages uden langvarige låsninger, da værktøjet opretter en ny midlertidig tabel, hvori det kopierer data fra hovedtabellen. I det øjeblik, hvor begge tabeller er identiske, låses den oprindelige tabel og erstattes af den nye. I vores tilfælde viste testkørslen, at opdatering af alle tabeller ville tage omkring et døgn, men at dataoverførslen medførte for stor belastning på diskene.

For at undgå dette tilføjede vi på production et argument til kommandoen --sleep med værdien 10 — denne parameter regulerer længden af ventetid efter overførslen af en datasæt til den nye tabel. På den måde kan man reducere belastningen, hvis det faktisk kørende program er tidssensitivt.

Efter optimeringen blev opdateringen udført med succes.

… men ikke helt!

Allerede en halv time efter opdateringen kom kunden med et problem. Databasen fungerede meget mærkeligt: periodisk blev forbindelser afbrudt. Sådan så det ud i overvågningen:

Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

På skærmbilledet kan man se en savtakket graf, der er relateret til, at nogle af MySQL-serverens tråde periodisk faldt med en fejl. I programmet opstod der fejl:

[PDOException] SQLSTATE[HY000] [2002] Forbindelse nægtet

En hurtig gennemgang af loggene afslørede, at dæmonen mysqld ikke kunne få de nødvendige ressourcer fra operativsystemet. Da vi undersøgte fejlene, opdagede vi i systemet "forladte" 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 stammer fra opdateringen 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 mest enkle operation, kan føre til uventede problemer. Og selv en velovervejet plan garanterer ikke altid det forventede resultat. Nu indgår der i enhver opdateringsplan også en obligatorisk oprydning af unødvendige filer, der kunne være opstået som følge af de seneste handlinger.

Og med dette ikke særligt professionelle grafiske værk vil jeg gerne sige en stor tak til Percona for deres fremragende produkter!

Opgradering af MySQL (Percona Server) fra 5.7 til 8.0

P.S.

Læs også på vores blog:

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster