Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

Edistyminen ei pysähdy, joten syyt päivittää MySQL:n uusimpiin versioihin ovat yhä pakottavampia. Ei kauan sitten yhdessä projektissamme oli aika päivittää mukavat Percona Server 5.7 -klusterit versioon 8. Kaikki tämä tapahtui Ubuntu Linux 16.04 -alustalla. Kuinka suorittaa tällainen toimenpide minimaalisella seisokkiajalla ja mitä ongelmia kohtasimme päivityksen aikana - lue tästä artikkelista.

Koulutus

Kaikki tietokantapalvelimen päivitykset liittyvät todennäköisimmin tietokannan uudelleenmääritykseen: muutokset järjestelmäresurssien rajoitusten vaatimuksiin ja tietokantakokoonpanojen korjaus, jotka on poistettava vanhentuneista ohjeista.

Ennen päivitystä tutustumme ehdottomasti viralliseen dokumentaatioon:

Ja laaditaan toimintasuunnitelma:

  1. Korjaa määritystiedostot poistamalla vanhentuneet käskyt.
  2. Tarkista yhteensopivuus apuohjelmien kanssa.
  3. Päivitä orjatietokannat asentamalla paketti percona-server-server.
  4. Päivitä master samalla paketilla.

Tarkastellaan jokaista suunnitelman kohtaa ja katsotaan, mikä voi mennä pieleen.

TÄRKEÄÄ! Galeraan perustuvan MySQL-klusterin päivitysmenettelyssä on omat hienovaraisuutensa, joita ei ole kuvattu artikkelissa. Älä käytä tätä ohjetta tässä tapauksessa.

Osa 1: Asetusten tarkistaminen

MySQL poistettiin versiossa 8 query_cache. Itse asiassa hän oli julistettu vanhentuneeksi takaisin versiossa 5.7, mutta nyt kokonaan poistettu. Sen vuoksi on tarpeen poistaa niihin liittyvät direktiivit. Ja välimuistipyyntöjen tallentamiseen voit nyt käyttää ulkoisia työkaluja - esim. ProxySQL.

Myös asetuksissa oli vanhentuneita ohjeita innodb_file_format. Jos MySQL 5.7:ssä oli mahdollista valita InnoDB-muoto, niin 8. versio toimii jo vain Barracuda-muodossa.

Tuloksemme on poistaa seuraavat direktiivit:

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

Käytämme tarkistamiseen Percona Serverin Docker-kuvaa. Asetamme palvelimen asetukset hakemistoon mysql_config_test, ja sen viereen luomme hakemistoja tiedoille ja lokeille. Percona-palvelimen konfigurointitestiesimerkki:

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

Bottom line: joko Dockerin lokeihin tai lokien hakemistoon - asetuksistasi riippuen - ilmestyy tiedosto, jossa ongelmalliset käskyt kuvataan.

Tässä mitä meillä oli:

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.

Siksi meidän piti vielä selvittää koodaukset ja korvata vanhentunut direktiivi expire-logs-days.

Osa 2: Toimivien asennusten tarkastus

Päivitysdokumentaatio sisältää 2 apuohjelmaa tietokannan yhteensopivuuden tarkistamiseksi. Niiden käyttö auttaa järjestelmänvalvojaa tarkistamaan olemassa olevan tietorakenteen yhteensopivuuden.

Aloitetaan klassisella mysqlcheck-apuohjelmalla. Juokse vain:

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

Jos ongelmia ei löydy, apuohjelma poistuu koodilla 0:

Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

Lisäksi MySQL:n moderneissa versioissa on saatavilla apuohjelma mysql-shell (Perconan tapauksessa tämä on paketti percona-mysql-shell). Se korvaa klassisen mysql-asiakkaan ja yhdistää asiakkaan toiminnot, SQL-koodieditorin ja MySQL-hallintatyökalut. Voit tarkistaa palvelimen ennen päivitystä suorittamalla seuraavat komennot sen kautta:

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

Tässä ovat saamamme kommentit:

Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

Yleensä ei mitään kriittistä - vain varoituksia koodauksista (Katso alempaa). Suorituksen kokonaistulos:

Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

Päätimme, että päivityksen pitäisi mennä ilman ongelmia.

Huomautus yllä olevista varoituksista, jotka osoittavat koodausongelmia. Tosiasia on, että UTF-8 MySQL:ssä viime aikoihin asti ei ollut "tosi" UTF-8, koska se tallensi vain 3 tavua neljän sijasta. MySQL 4:ssa tämä on vihdoin päätti korjata sen: alias utf8 johtaa pian koodaukseen utf8mb4, ja taulukoiden vanhoista sarakkeista tulee utf8mb3. Lisää koodausta utf8mb3 poistetaan, mutta ei tässä julkaisussa. Siksi päätimme korjata koodaukset jo käynnissä olevassa DBMS-asennuksessa sen päivityksen jälkeen.

Osa 3: Palvelinpäivitykset

Mikä voisi mennä pieleen, kun on niin älykäs suunnitelma?... Ymmärsimme täysin, että vivahteita tapahtuu aina, teimme ensimmäisen kokeilun MySQL-kehitysklusterilla.

Kuten jo mainittiin, virallinen dokumentaatio kattaa MySQL-palvelimien päivittämisen replikoilla. Tärkeintä on, että sinun tulee ensin päivittää kaikki kopiot (orjat), koska MySQL 8 voi replikoida pääversiosta 5.7. Jotkut vaikeudet ovat siinä, että käytämme tilaa mestari <-> mestari, kun kaukosäädin on tilassa vain luku. Eli itse asiassa taisteluliikenne menee yhteen datakeskukseen ja toinen on varakeskus.

Topologia näyttää tältä:

Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

Päivityksen on aloitettava replikoista mysql replica dc 2, mysql master dc 2 и mysql replica dc 1, ja päättyy mysql master dc 1 -palvelimeen. Luotettavuuden lisäämiseksi pysäytimme virtuaalikoneet, otimme niistä tilannekuvia ja lopetimme replikoinnin juuri ennen päivitystä komennolla STOP SLAVE. Loput päivityksestä näyttää tältä:

  1. Käynnistämme jokaisen replikan uudelleen lisäämällä 3 vaihtoehtoa asetuksiin: skip-networking, skip-slave-start, skip-log-bin. Tosiasia on, että tietokannan päivittäminen luo binäärilokeja järjestelmätaulukoiden päivityksillä. Nämä direktiivit takaavat, että tietokannan sovellustietoihin ei tapahdu muutoksia, eivätkä tiedot järjestelmätaulukoiden päivittämisestä sisälly binäärilokeihin. Tämä välttää ongelmat replikointia jatkettaessa.
  2. Paketin asentaminen percona-server-server. On tärkeää huomata, että MySQL-versiossa 8 ei sinun on suoritettava komento mysqlupgrade palvelinpäivityksen jälkeen.
  3. Onnistuneen käynnistyksen jälkeen käynnistämme palvelimen uudelleen - ilman ensimmäisessä kappaleessa lisättyjä parametreja.
  4. Varmistamme, että replikointi toimii onnistuneesti: tarkista SHOW SLAVE STATUS ja tarkista, että sovellustietokannan laskureilla varustetut taulukot päivitetään.

Kaikki näyttää melko yksinkertaiselta: dev-päivitys onnistui. Ok, voit turvallisesti ajoittaa iltapäiväpäivityksen tuotantoa varten.

Ei ollut surua - päivitimme tuotteen

Menestyneen kehityskokemuksen siirtyminen tuotantoon ei kuitenkaan sujunut ilman yllätyksiä.

Onneksi itse päivitysprosessi alkaa replikoista, joten kun kohtasimme vaikeuksia, lopetimme työn ja palautimme replikan tilannevedosta. Ongelman selvittäminen siirrettiin seuraavaan aamuun. Lokit sisälsivät seuraavat merkinnät:

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

Googlen eri postituslistojen arkistojen tutkiminen johti ymmärtämään, että tämä ongelma johtuu MySQL bugi. Vaikka tämä on todennäköisemmin apuohjelmavirhe mysqlcheck и mysqlsh.

Osoittautuu, että MySQL muutti tapaa, jolla ne esittävät tietoja desimaalikentille (int, tinyint jne.), joten mysql-server käyttää eri tapaa tallentaa ne. Jos tietokantasi ensin oli versiossa 5.5 tai 5.1, ja päivitit sitten versioon 5.7, niin sinun on ehkä tehtävä OPTIMIZE joihinkin pöytiin. Sitten MySQL päivittää datatiedostot siirtämällä ne nykyiseen tallennusmuotoon.

Voit myös tarkistaa tämän apuohjelmalla 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',
...

Jos field_type Jos se on yhtä suuri kuin 0, taulukossa käytetään vanhaa tyyppiä - sinun on suoritettava OPTIMIZE. Jos arvo on 246, sinulla on jo uusi tyyppi. Lisätietoa tyypeistä löytyy osoitteesta koodi.

Lisäksi sisään tämä bugi Harkitsemme toista mahdollista syytä, joka ohitti meidät: InnoDB-taulukoiden puuttuminen järjestelmätaulukosta INNODB_SYS_TABLESPACES, jos ne, taulukot, on luotu versiossa 5.1. Voit välttää ongelmat päivityksen aikana liitteenä SQL-skripti.

Miksi meillä ei ollut tällaisia ​​ongelmia kehittäjällä? Tietokanta kopioidaan sinne ajoittain tuotannosta - näin taulukot luodaan uudelleen.

Valitettavasti todella toimivassa suuressa tietokannassa et voi vain ottaa ja suorittaa universaalia OPTIMIZE. percona-toolkit auttaa tässä: pt-online-schema-change -apuohjelma on erinomainen online-OPTIMOINTI-toimintoon.

Päivitetty suunnitelma näytti tältä:

  1. Optimoi kaikki taulukot.
  2. Päivitä tietokannat.

Tarkistaaksemme sen ja samalla selvittääksemme päivitysajan, otimme yhden replikoista pois käytöstä ja suoritimme seuraavan komennon kaikille taulukoille:

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

Taulukot päivitetään ilman pitkiä lukkoja, koska apuohjelma luo uuden väliaikaisen taulukon, johon se kopioi tiedot päätaulukosta. Sillä hetkellä, kun molemmat pöydät ovat identtisiä, alkuperäinen pöytä lukitaan ja korvataan uudella. Meidän tapauksessamme testiajo osoitti, että kaikkien taulukoiden päivittäminen kestäisi noin päivän, mutta tietojen kopioiminen kuormitti levyjä liikaa.

Tämän välttämiseksi lisäsimme tuotannossa argumentin komentoon --sleep arvolla 10 - tämä parametri säätää odotusaikaa sen jälkeen, kun tietoerä on siirretty uuteen taulukkoon. Näin voit vähentää kuormitusta, jos todellinen käynnissä oleva sovellus vaatii vasteaikaa.

Optimoinnin jälkeen päivitys onnistui.

... mutta ei kokonaan!

Puolen tunnin sisällä päivityksestä asiakkaalla oli ongelma. Tietokanta toimi hyvin oudosti: ajoittain ne alkoivat yhteys nollautuu. Tältä se näytti seurannassa:

Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

Kuvakaappauksessa näkyy sahahammaskaavio, joka johtuu siitä, että jotkin MySQL-palvelimen säikeistä kaatui ajoittain virheen takia. Sovelluksessa esiintyi virheitä:

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

Lokien nopea tarkastus paljasti, että mysqld-daemon ei voinut saada tarvittavia resursseja käyttöjärjestelmästä. Virheitä selvitettäessä havaitsimme järjestelmästä "orpojen" apparmor-käytäntötiedostot:

# 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

Nämä tiedostot on luotu päivitettäessä MySQL 5.7:ään pari vuotta sitten ja kuuluvat poistettuun pakettiin. Tiedostojen poistaminen ja apparmor-palvelun käynnistäminen uudelleen ratkaisi ongelman:

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

lopuksi

Mikä tahansa, jopa yksinkertaisin toimenpide, voi johtaa odottamattomiin ongelmiin. Ja edes hyvin harkittu suunnitelma ei aina takaa odotettua tulosta. Nyt kaikkiin tiimimme päivityssuunnitelmiin kuuluu myös tarpeettomien tiedostojen pakollinen puhdistaminen, jotka ovat saattaneet ilmestyä viimeaikaisten toimien seurauksena.

Ja tällä ei kovin ammattimaisella graafisella luovuudella haluan sanoa valtavat kiitokset Perconalle heidän erinomaisista tuotteistaan!

Päivitetään MySQL (Percona Server) versiosta 5.7 versioon 8.0

PS.

Lue myös blogistamme:

Lähde: will.com

Lisää kommentti