Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

Napredek ne miruje, zato so razlogi za nadgradnjo na najnovejše različice MySQL vedno bolj prepričljivi. Nedolgo nazaj je bil v enem od naših projektov čas, da posodobimo prijetne gruče Percona Server 5.7 na različico 8. Vse to se je zgodilo na platformi Ubuntu Linux 16.04. Kako izvesti takšno operacijo z minimalnimi izpadi in na kakšne težave smo naleteli med posodobitvijo - preberite v tem članku.

Izobraževanje

Vsaka posodobitev strežnika baze podatkov je najverjetneje povezana z rekonfiguracijo baze podatkov: spremembe v zahtevah glede omejitev sistemskih virov in popravki konfiguracij baze podatkov, ki jih je treba očistiti zastarelih direktiv.

Pred posodobitvijo se bomo zagotovo sklicevali na uradno dokumentacijo:

In pripravimo akcijski načrt:

  1. Popravite konfiguracijske datoteke z odstranitvijo zastarelih direktiv.
  2. Preverite združljivost s pripomočki.
  3. Posodobite podrejene baze podatkov z namestitvijo paketa percona-server-server.
  4. Posodobite master z istim paketom.

Poglejmo vsako točko načrta in ugotovimo, kaj bi lahko šlo narobe.

POMEMBNO! Postopek posodabljanja gruče MySQL, ki temelji na Galeri, ima svoje posebnosti, ki v članku niso opisane. V tem primeru ne smete uporabiti tega navodila.

1. del: Preverjanje konfiguracij

MySQL je bil odstranjen v različici 8 query_cache. Pravzaprav je bil razglašen za zastarelega nazaj v različici 5.7, vendar zdaj popolnoma izbrisana. V skladu s tem je treba odstraniti povezane direktive. In za predpomnilnik zahtev lahko zdaj uporabite zunanja orodja - na primer ProxySQL.

Tudi v konfiguraciji so bile zastarele direktive o innodb_file_format. Če je bilo v MySQL 5.7 mogoče izbrati format InnoDB, potem 8. različica že deluje samo s formatom Barracuda.

Naš rezultat je odstranitev naslednjih direktiv:

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

Za preverjanje bomo uporabili Dockerjevo sliko strežnika Percona. Konfiguracijo strežnika bomo postavili v imenik mysql_config_test, zraven pa bomo ustvarili imenike za podatke in dnevnike. Primer preizkusa konfiguracije strežnika Percona:

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

Bistvo: v Dockerjevih dnevnikih ali v imeniku z dnevniki - odvisno od vaših konfiguracij - se bo pojavila datoteka, v kateri bodo opisane problematične direktive.

Tole smo imeli:

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.

Tako smo še vedno morali ugotoviti kodiranja in zamenjati zastarelo direktivo expire-logs-days.

2. del: Preverjanje delujočih inštalacij

Dokumentacija o posodobitvi vsebuje 2 pripomočka za preverjanje združljivosti baze podatkov. Njihova uporaba pomaga skrbniku preveriti združljivost obstoječe strukture podatkov.

Začnimo s klasičnim pripomočkom mysqlcheck. Preprosto zaženite:

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

Če ne najde nobenih težav, bo pripomoček zapustil s kodo 0:

Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

Poleg tega je v sodobnih različicah MySQL na voljo pripomoček lupina mysql (v primeru Percone je to paket percona-mysql-shell). Je zamenjava za klasični odjemalec mysql in združuje funkcije odjemalca, urejevalnika kode SQL in skrbniških orodij MySQL. Če želite preveriti strežnik pred posodobitvijo, lahko prek njega zaženete naslednje ukaze:

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

Tukaj so komentarji, ki smo jih prejeli:

Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

Na splošno nič kritičnega - samo opozorila o kodiranjih (glej spodaj). Skupni rezultat izvedbe:

Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

Odločili smo se, da posodobitev poteka brez težav.

Opomba o zgornjih opozorilih, ki kažejo na težave s kodiranjem. Dejstvo je, da je UTF-8 v MySQL do nedavnega ni bil "pravi" UTF-8, saj je shranil samo 3 bajte namesto 4. V MySQL 8 je to končno mogoče odločil, da ga popravi: vzdevek utf8 bo kmalu vodilo do kodiranja utf8mb4, stari stolpci v tabelah pa bodo postali utf8mb3. Nadaljnje kodiranje utf8mb3 bo odstranjen, vendar ne v tej izdaji. Zato smo se odločili popraviti kodiranja že v delujoči namestitvi DBMS, potem ko smo jo posodobili.

3. del: Posodobitve strežnika

Kaj bi lahko šlo narobe, ko obstaja tako pameten načrt?.. Dobro razumemo, da se nianse vedno zgodijo, smo izvedli prvi poskus na razvijalski gruči MySQL.

Kot že omenjeno, uradna dokumentacija pokriva vprašanje posodabljanja strežnikov MySQL z replikami. Bistvo je, da morate najprej posodobiti vse replike (podrejene), saj se MySQL 8 lahko replicira iz glavne različice 5.7. Nekaj ​​težav je v tem, da uporabljamo način mojster <-> mojster, ko je oddaljeni glavni v načinu samo za branje. To pomeni, da bojni promet dejansko gre v en podatkovni center, drugi pa je rezervni.

Topologija izgleda takole:

Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

Posodobitev se mora začeti z replikami replika mysql dc 2, mysql master dc 2 и mysql replica dc 1, zaključili pa s strežnikom mysql master dc 1. Zaradi večje zanesljivosti smo virtualne stroje zaustavili, naredili njihove posnetke in tik pred posodobitvijo z ukazom ustavili replikacijo STOP SLAVE. Preostali del posodobitve izgleda takole:

  1. Vsako repliko znova zaženemo tako, da konfiguracijam dodamo 3 možnosti: skip-networking, skip-slave-start, skip-log-bin. Dejstvo je, da posodabljanje baze podatkov ustvari binarne dnevnike s posodobitvami sistemskih tabel. Te direktive zagotavljajo, da ne bo sprememb podatkov aplikacij v bazi podatkov in da informacije o posodabljanju sistemskih tabel ne bodo vključene v binarne dnevnike. S tem se boste izognili težavam pri nadaljevanju podvajanja.
  2. Namestitev paketa percona-server-server. Pomembno je omeniti, da v MySQL različici 8 ne morate zagnati ukaz mysqlupgrade po posodobitvi strežnika.
  3. Po uspešnem zagonu znova zaženemo strežnik - brez parametrov, ki smo jih dodali v prvem odstavku.
  4. Prepričamo se, da replikacija deluje uspešno: preverite SHOW SLAVE STATUS in preverite, ali so tabele s števci v bazi podatkov aplikacije posodobljene.

Vse je videti precej preprosto: posodobitev za razvijalce je bila uspešna. V redu, lahko varno načrtujete nočno posodobitev za produkcijo.

Ni bilo žalosti - posodobili smo izdelek

Vendar pa prenos uspešnih razvijalskih izkušenj v proizvodnjo ni bil brez presenečenj.

Na srečo se sam proces posodabljanja začne z replikami, zato smo ob težavah prekinili delo in obnovili repliko iz posnetka. Preiskavo težav so prestavili na naslednje jutro. Dnevniki so vsebovali naslednje vnose:

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

Raziskovanje arhivov različnih poštnih seznamov v Googlu je pripeljalo do zaključka, da se ta težava pojavlja zaradi Napaka MySQL. Čeprav je to bolj verjetno pomožna napaka mysqlcheck и mysqlsh.

Izkazalo se je, da je MySQL spremenil način predstavljanja podatkov za decimalna polja (int, tinyint itd.), zato mysql-strežnik uporablja drugačen način za njihovo shranjevanje. Če vaša zbirka podatkov na začetku je bil v različici 5.5 ali 5.1, nato pa ste posodobili na 5.7, boste morda morali narediti OPTIMIZE za nekatere mize. Nato bo MySQL posodobil podatkovne datoteke in jih prenesel v trenutno obliko zapisa za shranjevanje.

To lahko preverite tudi s pripomočkom 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',
...

če field_type Če imate enako 0, potem je v tabeli uporabljen stari tip - morate izvesti OPTIMIZE. Če pa je vrednost 246, že imate novo vrsto. Več informacij o vrstah najdete v Koda.

Poleg tega v ta hrošč Razmišljamo o drugem možnem razlogu, ki nas je obšel: odsotnost tabel InnoDB v sistemski tabeli INNODB_SYS_TABLESPACES, če so bile tabele ustvarjene v različici 5.1. Da bi se izognili težavam pri posodabljanju, lahko uporabite priložen skript SQL.

Zakaj na devu nismo imeli takšnih težav? Podatkovna baza se tja občasno kopira iz produkcije – torej mize so poustvarjene.

Na žalost v resnično delujoči veliki bazi podatkov ne boste mogli preprosto vzeti in izvesti univerzalne OPTIMIZE. percona-toolkit vam bo tukaj pomagal: pripomoček pt-online-schema-change je odličen za spletno operacijo OPTIMIZE.

Posodobljeni načrt je izgledal takole:

  1. Optimizirajte vse tabele.
  2. Posodobite baze podatkov.

Da bi to preverili in hkrati izvedeli čas posodobitve, smo onemogočili eno od replik in zagnali naslednji ukaz za vse tabele:

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

Tabele se posodabljajo brez dolgotrajnih zaklepanj zaradi dejstva, da pripomoček ustvari novo začasno tabelo, v katero kopira podatke iz glavne tabele. V trenutku, ko sta obe tabeli identični, se originalna tabela zaklene in nadomesti z novo. V našem primeru je testni zagon pokazal, da bo posodobitev vseh tabel trajala približno en dan, vendar je kopiranje podatkov povzročilo preveliko obremenitev diskov.

Da bi se temu izognili, smo v produkciji ukazu dodali argument --sleep z vrednostjo 10 - ta parameter prilagodi dolžino čakanja po prenosu paketa podatkov v novo tabelo. Na ta način lahko zmanjšate obremenitev, če je dejansko delujoča aplikacija zahtevna glede odzivnega časa.

Po izvedbi optimizacije je bila posodobitev uspešna.

... vendar ne popolnoma!

V pol ure po posodobitvi je stranka prišla s težavo. Baza podatkov je delovala zelo čudno: občasno so se začeli ponastavitev povezave. Takole je to izgledalo na spremljanju:

Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

Posnetek zaslona prikazuje žagasti graf zaradi dejstva, da so se nekatere niti strežnika MySQL občasno zrušile z napako. V aplikaciji so se pojavile napake:

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

Hiter pregled dnevnikov je pokazal, da demon mysqld ne more pridobiti zahtevanih virov iz operacijskega sistema. Med odpravljanjem napak smo odkrili v sistemu datoteke pravilnika apparmorja "sirote".:

# 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

Te datoteke so bile ustvarjene ob nadgradnji na MySQL 5.7 pred nekaj leti in pripadajo odstranjenemu paketu. Težavo sta rešila brisanje datotek in ponovni zagon storitve apparmor:

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

Na koncu

Vsaka, tudi najpreprostejša operacija lahko privede do nepričakovanih težav. In tudi dobro premišljen načrt ne zagotavlja vedno pričakovanega rezultata. Zdaj vsi načrti posodobitev, ki jih ima naša ekipa, vključujejo tudi obvezno čiščenje nepotrebnih datotek, ki bi se lahko pojavile kot posledica nedavnih dejanj.

In ob tej ne preveč profesionalni grafični ustvarjalnosti, bi rad rekel veliko hvala Perconi za njihove odlične izdelke!

Posodobitev MySQL (strežnik Percona) s 5.7 na 8.0

PS

Preberite tudi na našem blogu:

Vir: www.habr.com

Dodaj komentar