Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

Progresi nuk qëndron ende, kështu që arsyet për të përmirësuar në versionet më të fundit të MySQL po bëhen gjithnjë e më bindëse. Jo shumë kohë më parë, në një nga projektet tona, ishte koha për të përditësuar grupet komode Percona Server 5.7 në versionin 8. E gjithë kjo ndodhi në platformën Ubuntu Linux 16.04. Si të kryeni një operacion të tillë me kohë minimale joproduktive dhe çfarë problemesh kemi hasur gjatë përditësimit - lexoni në këtë artikull.

Trajnimi

Çdo përditësim i serverit të bazës së të dhënave ka shumë të ngjarë të shoqërohet me rikonfigurimin e bazës së të dhënave: ndryshimet në kërkesat për kufijtë në burimet e sistemit dhe korrigjimi i konfigurimeve të bazës së të dhënave që duhet të pastrohen nga direktivat e vjetruara.

Para përditësimit, ne patjetër do t'i referohemi dokumentacionit zyrtar:

Dhe le të hartojmë një plan veprimi:

  1. Korrigjoni skedarët e konfigurimit duke hequr direktivat e vjetruara.
  2. Kontrolloni përputhshmërinë me shërbimet komunale.
  3. Përditësoni bazat e të dhënave skllav duke instaluar paketën percona-server-server.
  4. Përditëso masterin me të njëjtën paketë.

Le të shohim çdo pikë të planit dhe të shohim se çfarë mund të shkojë keq.

KUJDES! Procedura për përditësimin e një grupi MySQL bazuar në Galera ka hollësitë e veta që nuk përshkruhen në artikull. Ju nuk duhet ta përdorni këtë udhëzim në këtë rast.

Pjesa 1: Kontrollimi i konfigurimeve

MySQL u hoq në versionin 8 query_cache. Në fakt ai ishte shpallur i vjetëruar përsëri në versionin 5.7, por tani fshirë plotësisht. Prandaj, është e nevojshme të hiqen direktivat e lidhura. Dhe për të memorizuar kërkesat, tani mund të përdorni mjete të jashtme - për shembull, ProxySQL.

Gjithashtu në konfigurim kishte direktiva të vjetruara rreth innodb_file_format. Nëse në MySQL 5.7 ishte e mundur të zgjidhni formatin InnoDB, atëherë versioni i 8-të tashmë funksionon vetëm me format Barracuda.

Rezultati ynë është heqja e udhëzimeve të mëposhtme:

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

Për të kontrolluar, ne do të përdorim imazhin Docker të Serverit Percona. Ne do të vendosim konfigurimin e serverit në drejtori mysql_config_test, dhe pranë tij do të krijojmë direktori për të dhënat dhe regjistrat. Shembull i testit të konfigurimit të serverit 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

Përfundimi: ose në regjistrat e Docker ose në drejtorinë me regjistrat - në varësi të konfigurimeve tuaja - do të shfaqet një skedar në të cilin do të përshkruhen direktivat problematike.

Ja çfarë kishim:

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.

Kështu, ne ende na duhej të kuptonim kodimet dhe të zëvendësonim direktivën e vjetëruar expire-logs-days.

Pjesa 2: Kontrolli i instalimeve të punës

Dokumentacioni i përditësimit përmban 2 shërbime për kontrollimin e pajtueshmërisë së bazës së të dhënave. Përdorimi i tyre ndihmon administratorin të kontrollojë përputhshmërinë e strukturës ekzistuese të të dhënave.

Le të fillojmë me mjetin klasik mysqlcheck. Thjesht vraponi:

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

Nëse nuk gjenden probleme, programi do të dalë me kodin 0:

Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

Përveç kësaj, një mjet është i disponueshëm në versionet moderne të MySQL mysql-shell (në rastin e Percona kjo është paketa percona-mysql-shell). Është një zëvendësim për klientin klasik mysql dhe kombinon funksionet e një klienti, një redaktues kodi SQL dhe mjetet e administrimit të MySQL. Për të kontrolluar serverin përpara se të përditësoni, mund të ekzekutoni komandat e mëposhtme përmes tij:

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

Këtu janë komentet që kemi marrë:

Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

Në përgjithësi, asgjë kritike - vetëm paralajmërime në lidhje me kodimet (Shikoni më poshtë). Rezultati i përgjithshëm i ekzekutimit:

Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

Ne vendosëm që përditësimi të shkojë pa probleme.

Një shënim në lidhje me paralajmërimet e mësipërme që tregojnë probleme me kodimet. Fakti është se UTF-8 në MySQL deri vonë nuk ishte "e vërtetë" UTF-8, pasi ruante vetëm 3 bajt në vend të 4. Në MySQL 8 kjo është më në fund vendosi ta rregullonte: pseudonimi utf8 së shpejti do të çojë në kodim utf8mb4, dhe kolonat e vjetra në tabela do të bëhen utf8mb3. Kodimi i mëtejshëm utf8mb3 do të hiqet, por jo në këtë version. Prandaj, ne vendosëm të korrigjojmë kodimet tashmë në instalimin e DBMS që po funksionon, pas përditësimit të tij.

Pjesa 3: Përditësimet e serverit

Çfarë mund të shkojë keq kur ekziston një plan kaq i zgjuar?.. Duke kuptuar plotësisht se nuancat ndodhin gjithmonë, ne kryem eksperimentin e parë në një grup të devijimeve MySQL.

Siç është përmendur tashmë, dokumentacion zyrtar mbulon çështjen e përditësimit të serverëve MySQL me kopje. Përfundimi është se së pari duhet të përditësoni të gjitha kopjet (skllevërit), pasi MySQL 8 mund të përsëritet nga një version master 5.7. Disa vështirësi qëndrojnë në faktin se ne përdorim modalitetin mjeshtër mjeshtër, kur masteri në distancë është në modalitet Lexo vetem. Kjo është, në fakt, trafiku luftarak shkon në një qendër të dhënash, dhe e dyta është një rezervë.

Topologjia duket si kjo:

Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

Përditësimi duhet të fillojë me kopje kopje mysql dc 2, Mysql master dc 2 и mysql replica dc 1, dhe përfundoni me serverin master mysql dc 1. Për të qenë më të besueshëm, ne ndaluam makinat virtuale, bëmë fotografi të tyre dhe menjëherë para përditësimit ndaluam replikimin me komandën STOP SLAVE. Pjesa tjetër e përditësimit duket si kjo:

  1. Ne rifillojmë çdo kopje duke shtuar 3 opsione në konfigurime: skip-networking, skip-slave-start, skip-log-bin. Fakti është se përditësimi i bazës së të dhënave gjeneron regjistra binare me përditësime në tabelat e sistemit. Këto direktiva garantojnë se nuk do të ketë ndryshime në të dhënat e aplikacionit në bazën e të dhënave dhe informacioni rreth përditësimit të tabelave të sistemit nuk do të përfshihet në regjistrat binare. Kjo do të shmangë problemet kur rifilloni përsëritjen.
  2. Instalimi i paketës percona-server-server. Është e rëndësishme të theksohet se në versionin 8 të MySQL jo ju duhet të ekzekutoni komandën mysqlupgrade pas përditësimit të serverit.
  3. Pas një fillimi të suksesshëm, ne rifillojmë përsëri serverin - pa parametrat që u shtuan në paragrafin e parë.
  4. Sigurohemi që replikimi të funksionojë me sukses: kontrolloni SHOW SLAVE STATUS dhe shikoni që tabelat me numërues në bazën e të dhënave të aplikacionit janë përditësuar.

Gjithçka duket mjaft e thjeshtë: përditësimi i dev ishte i suksesshëm. Në rregull, mund të planifikoni me siguri një përditësim çdo natë për prodhim.

Nuk kishte trishtim - ne përditësuam prod

Sidoqoftë, transferimi i përvojës së suksesshme të dev në prodhim nuk ishte pa surpriza.

Për fat të mirë, vetë procesi i përditësimit fillon me kopje, kështu që kur hasëm vështirësi, ndaluam punën dhe rivendosëm kopjen nga fotografia. Hetimi i problemeve u shty për të nesërmen në mëngjes. Regjistrat përmbanin shënimet e mëposhtme:

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

Hulumtimi i arkivave të listave të ndryshme të postimeve në Google çoi në të kuptuarit se ky problem ndodh për shkak të Bug MySQL. Edhe pse ky ka më shumë të ngjarë një gabim i shërbimeve mysqlcheck и mysqlsh.

Rezulton se MySQL ndryshoi mënyrën se si ato përfaqësojnë të dhënat për fushat dhjetore (int, tinyint, etj.), kështu që mysql-server përdor një mënyrë tjetër për t'i ruajtur ato. Nëse databaza juaj fillimisht ishte në versionin 5.5 ose 5.1, dhe më pas e keni përditësuar në 5.7, atëherë mund t'ju duhet të bëni OPTIMIZE për disa tavolina. Më pas MySQL do të përditësojë skedarët e të dhënave, duke i transferuar ato në formatin aktual të ruajtjes.

Ju gjithashtu mund ta kontrolloni këtë me programin 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',
...

Nëse field_type Nëse e keni të barabartë me 0, atëherë lloji i vjetër përdoret në tabelë - duhet ta kryeni OPTIMIZE. Megjithatë, nëse vlera është 246, ju tashmë keni një lloj të ri. Më shumë informacion rreth llojeve mund të gjeni në kodi.

Për më tepër, në këtë të metë Po shqyrtojmë arsyen e dytë të mundshme, e cila na ka anashkaluar: mungesa e tabelave InnoDB në tabelën e sistemit. INNODB_SYS_TABLESPACES, nëse ato, tabelat, janë krijuar në versionin 5.1. Për të shmangur problemet gjatë përditësimit, mund të përdorni skripti SQL i bashkangjitur.

Pse nuk kemi pasur probleme të tilla në dev? Baza e të dhënave kopjohet periodikisht atje nga prodhimi - kështu, tabelat janë rikrijuar.

Fatkeqësisht, në një bazë të dhënash të madhe që funksionon vërtet, nuk do të jeni në gjendje të merrni dhe ekzekutoni thjesht një universale OPTIMIZE. percona-toolkit do të ndihmojë këtu: mjeti pt-online-schema-change është i shkëlqyer për funksionimin në internet OPTIMIZE.

Plani i përditësuar dukej kështu:

  1. Optimizo të gjitha tabelat.
  2. Përditësoni bazat e të dhënave.

Për ta kontrolluar atë dhe në të njëjtën kohë për të gjetur kohën e përditësimit, ne çaktivizuam një nga kopjet dhe ekzekutuam komandën e mëposhtme për të gjitha tabelat:

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

Tabelat përditësohen pa kyçje të gjata për shkak të faktit se programi krijon një tabelë të re të përkohshme në të cilën kopjon të dhënat nga tabela kryesore. Në momentin kur të dyja tabelat janë identike, tabela origjinale bllokohet dhe zëvendësohet me të renë. Në rastin tonë, një test test tregoi se do të duhej rreth një ditë për të përditësuar të gjitha tabelat, por kopjimi i të dhënave shkaktoi shumë ngarkesë në disqe.

Për të shmangur këtë, në prodhim shtuam argumentin në komandë --sleep me një vlerë 10 - ky parametër rregullon gjatësinë e pritjes pas transferimit të një grupi të dhënash në një tabelë të re. Në këtë mënyrë ju mund të zvogëloni ngarkesën nëse aplikacioni aktual aktual kërkon kohën e përgjigjes.

Pas kryerjes së optimizimit, përditësimi ishte i suksesshëm.

... por jo plotësisht!

Brenda gjysmë ore pas përditësimit, klienti erdhi me një problem. Baza e të dhënave funksionoi shumë çuditërisht: periodikisht ata filluan rivendosja e lidhjes. Kështu dukej në monitorim:

Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

Pamja e ekranit tregon një grafik me dhëmb sharrë për shkak të faktit se disa nga fijet e serverit MySQL u përplasën periodikisht me një gabim. Gabimet u shfaqën në aplikacion:

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

Një inspektim i shpejtë i regjistrave zbuloi se daemon mysqld nuk mund të merrte burimet e kërkuara nga sistemi operativ. Gjatë renditjes së gabimeve, ne zbuluam në sistem Skedarët e politikave apparmor "jetim".:

# 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

Këta skedarë u krijuan kur u azhurnuan në MySQL 5.7 disa vjet më parë dhe i përkasin një pakete të hequr. Fshirja e skedarëve dhe rinisja e shërbimit apparmor e zgjidhi problemin:

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

Në përfundim

Çdo operacion, madje edhe më i thjeshtë, mund të çojë në probleme të papritura. Dhe madje edhe të kesh një plan të mirëmenduar nuk garanton gjithmonë rezultatin e pritur. Tani, çdo plan përditësimi që ekipi ynë ka përfshirë gjithashtu pastrimin e detyrueshëm të skedarëve të panevojshëm që mund të ishin shfaqur si rezultat i veprimeve të fundit.

Dhe me këtë krijimtari grafike jo shumë profesionale, do të doja të them një falenderim të madh për Percona për produktet e tyre të shkëlqyera!

Përditësimi i MySQL (Server Percona) nga 5.7 në 8.0

PS

Lexoni edhe në blogun tonë:

Burimi: www.habr.com

Shto një koment