
Fremgangen står ikke stille, så årsakene til å oppdatere til de nyeste versjonene av MySQL blir stadig mer presserende. Nylig kom tiden for å oppdatere våre komfortable Percona Server 5.7-klynger til versjon 8. Dette skjedde på plattformen Ubuntu Linux 16.04. Hvordan gjennomføre en slik operasjon med minimal nedetid og hvilke problemer vi møtte under oppdateringen — les mer i denne artikkelen.
Forberedelse
Enhver oppdatering av databasemotoren er sannsynligvis knyttet til en omkonfigurering av databasen: endringer i krav til systemressursgrenser og korrigering av konfigurasjonsfiler som må renses for utdaterte direktiver.
Før oppdateringen vil vi nødvendigvis konsultere den offisielle dokumentasjonen:
- ;
- ;
- ;
- .
Og vi vil lage en handlingsplan:
- Fikse konfigurasjonsfilene ved å fjerne utdaterte direktiver.
- Sjekke kompatibilitet med verktøy.
- Oppdatere slave-databaser ved å installere pakken
percona-server-server. - Oppdatere masteren ved å installere den samme pakken.
La oss gå gjennom hvert punkt i planen og se hva som kan gå galt.
VIKTIG! Oppdateringsprosedyren for MySQL-klynger basert på Galera har sine spesialiteter som ikke er beskrevet i denne artikkelen. Ikke bruk denne instruksjonen i så fall.
Del 1: Sjekking av konfigurasjoner
I versjon 8 av MySQL fjernet de query_cache. Generelt ble det allerede i versjon 5.7, men nå er det . Dermed må relaterte direktiver fjernes. For spørringsbuffer kan nå eksterne verktøy brukes — for eksempel, .
Også i konfigurasjonen fant vi utdaterte direktiver om innodb_file_format. Hvis MySQL 5.7 hadde muligheten til å velge InnoDB-formatet, så fungerer versjon 8 allerede .
Vår konklusjon — fjerning av følgende direktiver:
-
query_cache_type,query_cache_limitogquery_cache_size; -
innodb_file_formatoginnodb_file_format_max.
For å sjekke vil vi bruke Docker-bildet Percona Server. Serverkonfigurasjonen plasseres i katalogen mysql_config_test, og vi oppretter kataloger for data og logger ved siden av. Eksempel på konfigurasjonstest 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-centosKonklusjon: enten i Docker-loggene eller i katalogen med logger - avhengig av konfigurasjonen din - vil det dukke opp en fil som beskriver problematiske direktiver.
Slik så dette ut hos oss:
2020-04-03T12:44:19.670831Z 0 [Warning] [MY-011068] [Server] Syntaksen 'expire-logs-days' er foreldet og vil bli fjernet i en fremtidig utgivelse. Vennligst bruk binlog_expire_logs_seconds i stedet.
2020-04-03T12:44:19.671678Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' er for tiden et alias for karaktersettene UTF8MB3, men vil bli et alias for UTF8MB4 i en fremtidig utgivelse. Vennligst vurder å bruke UTF8MB4 for å være utvetydig.
2020-04-03T12:44:19.671682Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' er en kollasjon av det foreldede karaktersettet UTF8MB3. Vennligst vurder å bruke UTF8MB4 med en passende kollasjon i stedet. Dermed måtte vi også forstå kodene og erstatte den foreldede direktiven expire-logs-days.
Del 2: Sjekk av fungerende installasjoner
I dokumentasjonen for oppgradering er det 2 verktøy for å sjekke databasens kompatibilitet. Deres bruk hjelper administratoren med å sjekke kompatibiliteten til den eksisterende datakonstruksjonen.
La oss starte med det klassiske verktøyet mysqlcheck. Du trenger bare å kjøre:
mysqlcheck -u root -p --all-databases --check-upgradeHvis det ikke oppdages problemer, vil verktøyet avslutte med kode 0:

I tillegg er det i moderne versjoner av MySQL tilgjengelig et verktøy (i tilfelle Percona er det pakken percona-mysql-shell). Det er en erstatning for den klassiske mysql-klienten og kombinerer funksjonene til en klient, SQL-kode-editor og MySQL-administrasjonsverktøy. For å sjekke serveren før oppgradering kan du kjøre følgende kommando gjennom det:
mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=\/etc\/mysql\/my.cnfOg her er hvilke merknader vi fikk:

Generelt, ingenting kritisk - bare advarsler om koderingene (se nedenfor). Den samlede resultatet er:

Vi har besluttet at oppgraderingen bør gå uten problemer.
Merknaden om advarslene ovenfor indikerer problemer med koderingene. Faktisk, UTF-8 i MySQL var til nylig , da det lagret bare 3 byte i stedet for 4. I MySQL 8 ble dette endelig : aliaset utf8 vil snart referere til kodingen utf8mb4, og gamle kolonner i tabellene vil bli utf8mb3. I fremtiden vil kodingen utf8mb3 bli fjernet, men ikke i denne utgivelsen. Derfor bestemte vi oss for å rette kodene allerede på den fungerende installasjonen av DBMS, etter oppgraderingen.
Del 3: Oppgradering av servere
Hva kan gå galt når det finnes en så flott plan? Med full forståelse for at detaljer alltid kan oppstå, gjennomførte vi vårt første eksperiment på MySQL dev-klusteret.
Som allerede nevnt, belyser spørsmålet om oppgradering av MySQL-servere med replikaer. Hovedpoenget er at man først bør oppgradere alle replikaer (slave), ettersom MySQL 8 kan replikere fra en master av versjon 5.7. Noe av utfordringen er at vi bruker modusen master master, der den fjerne masteren er i read-onlymodus. Det vil si at all faktisk produksjonstrafikk går til ett datasenter, mens det andre er backup.
Topologien ser slik ut:

Oppgraderingen bør starte med replikaene mysql replica dc 2, mysql master dc 2 og mysql replica dc 1, og avsluttes med serveren mysql master dc 1. For å øke påliteligheten stoppet vi de virtuelle maskinene, lagret snapshots, og stoppet replikasjonen rett før oppgraderingen med kommandoen STOP SLAVE. Ellers ser oppgraderingen slik ut:
- Hver replika startes på nytt, med 3 alternativer lagt til i konfigurasjonene:
skip-networking,skip-slave-start,skip-log-bin. Det skyldes at oppgraderingen av databasen genererer binærlogg med oppdatering av systemtabeller. Disse direktivene sikrer at det ikke skjer endringer i applikasjonsdata i databasen, og at informasjon om oppdateringen av systemtabeller ikke havner i binærloggen. Dette vil forhindre problemer ved gjenopptakelse av replikasjonen. - Vi installerer pakken
percona-server-server. Det er viktig å merke seg at i MySQL 8 ikke må kommandoenmysqlupgradekjøres etter oppgraderingen av serveren. - Etter en vellykket oppstart, restart serveren en gang til — allerede uten parameterne som ble lagt til i første punkt.
- Vi sjekker at replikasjonen fungerer som den skal: vi kontrollerer
SHOW SLAVE STATUSog ser at tabeller med tellere i applikasjonsdatabasen oppdateres.
Alt dette ser ganske enkelt ut: oppgraderingen av dev gikk bra. Ok, vi kan trygt planlegge nattoppgraderingen for produksjon.
Ingen sorg — vi oppgraderte prod.
Imidlertid gikk overføringen av vellykkede erfaringer fra dev til produksjon ikke uten overraskelser.
Heldigvis begynner selve oppgraderingsprosessen med replikaene, så når vi støtte på problemer, stoppet vi arbeidet og gjenopprettet replikaen fra snapshotet. Undersøkelsen av problemene ble flyttet til neste morgen. Loggene viste følgende oppføringer:
2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] tabellen: t1 har 19 kolonner, men InnoDB-ordlisten har 20 kolonner
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Feil under fiksing av SE-data for db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Klarte ikke å fylle ut DD-tabeller.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Avbryter Forskning på arkivene til forskjellige e-postutsendelser i Google har ført til forståelsen av at et slikt problem oppstår på grunn av . Selv om dette er mer en feil i verktøyene mysqlcheck og mysqlsh.
Det viser seg at MySQL har endret måten dataene representeres for desimale felt (int, tinyint, osv.), så derfor brukes en annen lagringsmetode inne i mysql-server. Hvis databasen din opprinnelig var i versjon 5.5 eller 5.1, og deretter oppgraderte du til 5.7, kan det hende du må utføre OPTIMIZE for noen tabeller. Da vil MySQL oppdatere filene med dataene og konvertere dem til det aktuelle lagringsformatet.
Dette kan også sjekkes med verktøyet mysqlfrm:
mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
'field_length': 8,
'field_type': 246, # feltformat
'field_type_name': 'decimal',
'flags': 3,
'flags_extra': 67,
'interval_nr': 0,
'name': 'you_deciaml_column',
... Hvis field_type er lik 0, betyr det at tabellen bruker den gamle typen - du må utføre OPTIMIZE. Men hvis verdien er 246 - har du allerede den nye typen. Du kan finne mer informasjon om typene i .
Videre diskuteres det i en annen mulig årsak som vi unngikk - det er fraværet av InnoDB-tabeller i systemtabellen INNODB_SYS_TABLESPACES, hvis disse tabellene ble opprettet i versjon 5.1. For å unngå problemer under oppgraderingen, kan du bruke .
Hvorfor oppsto ikke slike problemer hos oss på dev? Databasen kopieres der periodisk fra produksjon - dermed blir tabellene gjenopprettet.
Dessverre vil det ikke være mulig å bare ta og utføre en omfattende OPTIMIZE. Her vil percona-toolkit hjelpe: for online OPTIMIZE-operasjonen passer verktøyet pt-online-schema-change perfekt.
Den oppdaterte planen ble slik:
- Utføre optimalisering av alle tabeller.
- Utføre oppdatering av databasene.
For å sjekke den og samtidig finne ut tiden for oppdateringen, deaktiverte vi en av replikaene, og for alle tabeller kjørte vi følgende kommando:
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=t1Oppdatering av tabeller skjer uten langvarige blokkeringer fordi verktøyet oppretter en ny midlertidig tabell, der det kopierer data fra hovedtabellen. Når begge tabellene er identiske, blir den opprinnelige tabellen blokkert og byttet ut med den nye. I vårt tilfelle viste testkjøringen at det vil ta omtrent ett døgn å oppdatere alle tabellene, men samtidig førte datakopieringen til for stor belastning på diskene.
For å unngå dette la vi til et argument til kommandoen på production --sleep med verdi 10 — denne parameteren regulerer lengden på ventetiden etter overføringen av en datablokk til den nye tabellen. Slik kan man redusere belastningen hvis det kjørende programmet er tidkrevende.
Etter optimaliseringen ble oppdateringen utført med suksess.
… men ikke helt!
Allerede en halvtime etter oppdateringen kom kunden med et problem. Databasen oppførte seg veldig rart: til tider startet tilkoblingsfeilene. Slik så det ut i overvåkingen:

I skjermbildet ser vi et sagformet diagram, relatert til at noen MySQL-servertråder periodisk falt med feil. Det dukket opp feil i applikasjonen:
[PDOException] SQLSTATE[HY000] [2002] Tilkobling nektetEn rask gjennomgang av loggene avdekket at mysqld-tjenesten ikke kunne få nødvendige ressurser fra operativsystemet. Mens vi undersøkte feilene, oppdaget vi i systemet " hjemløse " apparmor policy-filer:
# 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 amd64Disse filene ble laget ved oppdateringen til MySQL 5.7 for et par år siden og tilhører en avinstallert pakke. Fjerning av filene og omstart av 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 apparmorAvslutningsvis
Hver, selv den enkleste operasjonen, kan føre til uventede problemer. Og selv om det finnes en gjennomtenkt plan, garanterer det ikke alltid det forventede resultatet. Nå er det obligatorisk for vårt team å inkludere opprydding av overflødige filer, som kan ha dukket opp som følge av de siste handlingene, i alle oppdateringsplaner.
Og med denne ikke så profesjonelle grafiske kunsten vil jeg gjerne takke Percona for deres flotte produkter!

P.S.
Also read in our blog:
- «»;
- «»;
- «»;
- «»;
- «».
Kilde: habr.com
