Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

Napredak ne miruje, pa su razlozi za nadogradnju na najnovije verzije MySQL-a sve uvjerljiviji. Ne tako davno, u jednom od naših projekata, došlo je vrijeme za ažuriranje ugodnih Percona Server 5.7 klastera na verziju 8. Sve se to dogodilo na Ubuntu Linux 16.04 platformi. Kako izvesti takvu operaciju uz minimalno zastoje i na koje smo probleme naišli tokom ažuriranja - pročitajte u ovom članku.

Trening

Svako ažuriranje servera baze podataka je najvjerovatnije povezano s rekonfiguracijom baze podataka: promjenama u zahtjevima za ograničenje sistemskih resursa i ispravkom konfiguracija baze podataka koje treba očistiti od zastarjelih direktiva.

Prije ažuriranja, svakako ćemo se pozvati na zvaničnu dokumentaciju:

I napravimo akcioni plan:

  1. Ispravite konfiguracijske datoteke uklanjanjem zastarjelih direktiva.
  2. Provjerite kompatibilnost s uslužnim programima.
  3. Ažurirajte slave baze podataka instaliranjem paketa percona-server-server.
  4. Ažurirajte master sa istim paketom.

Pogledajmo svaku tačku plana i vidimo šta bi moglo poći po zlu.

VAŽNO! Procedura za ažuriranje MySQL klastera zasnovanog na Galeri ima svoje suptilnosti koje nisu opisane u članku. U ovom slučaju ne biste trebali koristiti ovo uputstvo.

Dio 1: Provjera konfiguracija

MySQL je uklonjen u verziji 8 query_cache. Zapravo je bio proglašen zastarelim nazad u verziji 5.7, ali sada potpuno obrisano. Shodno tome, potrebno je ukloniti povezane direktive. A za keširanje zahtjeva sada možete koristiti vanjske alate - na primjer, ProxySQL.

Također u konfiguraciji su bile zastarjele direktive o innodb_file_format. Ako je u MySQL 5.7 bilo moguće odabrati InnoDB format, onda 8. verzija već radi samo u formatu Barracuda.

Naš rezultat je uklanjanje sljedećih direktiva:

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

Za provjeru ćemo koristiti Docker sliku Percona servera. Postavićemo konfiguraciju servera u direktorijum mysql_config_test, a pored njega ćemo kreirati direktorije za podatke i dnevnike. Primjer testa konfiguracije Percona-servera:

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

Zaključak: ili u zapisnicima Docker-a ili u direktoriju sa evidencijama - ovisno o vašim konfiguracijama - pojavit će se datoteka u kojoj će biti opisane problematične direktive.

Evo šta smo imali:

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.

Dakle, još uvijek smo trebali shvatiti kodiranja i zamijeniti zastarjelu direktivu expire-logs-days.

Dio 2: Provjera radnih instalacija

Dokumentacija za ažuriranje sadrži 2 uslužna programa za provjeru kompatibilnosti baze podataka. Njihova upotreba pomaže administratoru da provjeri kompatibilnost postojeće strukture podataka.

Počnimo s klasičnim uslužnim programom mysqlcheck. Jednostavno pokrenite:

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

Ako se ne pronađu problemi, uslužni program će izaći s kodom 0:

Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

Osim toga, pomoćni program je dostupan u modernim verzijama MySQL-a mysql-shell (u slučaju Percone ovo je paket percona-mysql-shell). On je zamjena za klasični mysql klijent i kombinira funkcije klijenta, uređivača SQL koda i MySQL administrativnih alata. Da provjerite server prije ažuriranja, možete pokrenuti sljedeće komande kroz njega:

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

Evo komentara koje smo dobili:

Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

Općenito, ništa kritično - samo upozorenja o kodiranju (vidi dolje). Ukupan rezultat izvršenja:

Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

Odlučili smo da ažuriranje prođe bez problema.

Napomena o gornjim upozorenjima koja ukazuju na probleme sa kodiranjem. Činjenica je da je UTF-8 u MySQL donedavno nije bio "pravi" UTF-8, pošto je pohranio samo 3 bajta umjesto 4. U MySQL 8 ovo je konačno odlučio da to popravi: alias utf8 uskoro će dovesti do kodiranja utf8mb4, a stare kolone u tabelama će postati utf8mb3. Dalje kodiranje utf8mb3 će biti uklonjeno, ali ne u ovom izdanju. Stoga smo odlučili da ispravimo kodiranja već na pokrenutoj instalaciji DBMS-a, nakon što smo je ažurirali.

Dio 3: Ažuriranja servera

Šta bi moglo poći po zlu kada postoji tako pametan plan?.. Dobro razumijevajući da se nijanse uvijek događaju, izveli smo prvi eksperiment na MySQL dev klasteru.

Kao što je već spomenuto, službena dokumentacija pokriva pitanje ažuriranja MySQL servera replikama. Suština je da biste prvo trebali ažurirati sve replike (slave), pošto MySQL 8 može replicirati sa glavne verzije 5.7. Određena poteškoća leži u činjenici da koristimo način rada master <-> master, kada je daljinski master u modu samo za čitanje. To jest, u stvari, borbeni promet ide u jedan data centar, a drugi je rezervni.

Topologija izgleda ovako:

Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

Ažuriranje mora početi s replikama replika mysql dc 2, mysql master dc 2 и mysql replica dc 1, a završava se serverom mysql master dc 1. Da bismo bili pouzdaniji, zaustavili smo virtuelne mašine, napravili njihove snimke i neposredno prije ažuriranja zaustavili replikaciju naredbom STOP SLAVE. Ostatak ažuriranja izgleda ovako:

  1. Ponovo pokrećemo svaku repliku dodavanjem 3 opcije u konfiguracije: skip-networking, skip-slave-start, skip-log-bin. Činjenica je da ažuriranje baze podataka generiše binarne dnevnike sa ažuriranjima sistemskih tabela. Ove direktive garantuju da neće biti promena u podacima aplikacije u bazi podataka, a informacije o ažuriranju sistemskih tabela neće biti uključene u binarne evidencije. Ovo će izbjeći probleme prilikom nastavka replikacije.
  2. Instaliranje paketa percona-server-server. Važno je napomenuti da u MySQL verziji 8 ne morate pokrenuti naredbu mysqlupgrade nakon ažuriranja servera.
  3. Nakon uspješnog pokretanja, ponovo pokrećemo server - bez parametara koji su dodati u prvom pasusu.
  4. Uvjeravamo se da replikacija radi uspješno: provjerite SHOW SLAVE STATUS i provjerite da li su tablice sa brojačima u aplikacijskoj bazi podataka ažurirane.

Sve izgleda prilično jednostavno: ažuriranje za programere je bilo uspješno. U redu, možete sigurno zakazati noćno ažuriranje za proizvodnju.

Nije bilo tuge - ažurirali smo prod

Međutim, prijenos uspješnog dev iskustva u produkciju nije prošao bez iznenađenja.

Srećom, sam proces ažuriranja počinje sa replikama, pa smo, kada smo naišli na poteškoće, prekinuli rad i vratili repliku sa snimka. Istraga o problemima odložena je za sljedeće jutro. Dnevnici su sadržavali sljedeće unose:

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

Istraživanjem arhiva raznih mailing lista na Google-u došlo se do saznanja da do ovog problema dolazi zbog MySQL greška. Iako je ovo vjerovatnije greška uslužnog programa mysqlcheck и mysqlsh.

Ispostavilo se da je MySQL promijenio način na koji predstavljaju podatke za decimalna polja (int, tinyint, itd.), tako da mysql-server koristi drugačiji način da ih pohrani. Ako je vaša baza podataka u početku bio u verziji 5.5 ili 5.1, a zatim ste ažurirali na 5.7, tada ćete možda morati OPTIMIZE za neke stolove. Zatim će MySQL ažurirati datoteke podataka, prenoseći ih u trenutni format za skladištenje.

Ovo također možete provjeriti pomoću uslužnog programa 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',
...

ako field_type Ako ga imate jednako 0, tada se u tabeli koristi stari tip - morate izvršiti OPTIMIZE. Međutim, ako je vrijednost 246, već imate novi tip. Više informacija o vrstama možete pronaći u kod.

Štaviše, u ovu grešku Razmatramo drugi mogući razlog, koji nas je zaobišao: odsustvo InnoDB tabela u sistemskoj tabeli INNODB_SYS_TABLESPACES, ako su one, tabele, kreirane u verziji 5.1. Da biste izbjegli probleme prilikom ažuriranja, možete koristiti priložena SQL skripta.

Zašto nismo imali takve probleme na dev-u? Baza podataka se periodično kopira tamo iz proizvodnje - dakle, tabele su ponovo kreirane.

Nažalost, na velikoj bazi podataka koja zaista radi, nećete moći samo uzeti i izvršiti univerzalni OPTIMIZE. percona-toolkit će vam pomoći: uslužni program pt-online-schema-change je odličan za online operaciju OPTIMIZE.

Ažurirani plan je izgledao ovako:

  1. Optimizirajte sve tabele.
  2. Ažurirajte baze podataka.

Da bismo to provjerili i u isto vrijeme saznali vrijeme ažuriranja, onemogućili smo jednu od replika i pokrenuli sljedeću naredbu za sve 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 ažuriraju bez dugih zaključavanja zbog činjenice da uslužni program kreira novu privremenu tabelu u koju kopira podatke iz glavne tabele. U trenutku kada su obje tablice identične, originalna tablica se zaključava i zamjenjuje novom. U našem slučaju, probni rad je pokazao da bi za ažuriranje svih tabela trebalo oko jedan dan, ali je kopiranje podataka izazvalo preveliko opterećenje diskova.

Da bismo to izbjegli, u proizvodnji smo dodali argument naredbi --sleep sa vrijednošću 10 - ovaj parametar prilagođava dužinu čekanja nakon prijenosa serije podataka u novu tablicu. Na ovaj način možete smanjiti opterećenje ako stvarna aplikacija koja radi zahtijeva vrijeme odgovora.

Nakon izvršene optimizacije, ažuriranje je bilo uspješno.

... ali ne u potpunosti!

U roku od pola sata nakon ažuriranja, klijent je došao sa problemom. Baza podataka je radila vrlo čudno: povremeno su počinjali veza se resetuje. Ovako je to izgledalo u monitoringu:

Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

Na snimku ekrana je prikazan pilasti graf zbog činjenice da su neke od MySQL serverskih niti povremeno padale sa greškom. Greške su se pojavile u aplikaciji:

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

Brza inspekcija dnevnika otkrila je da mysqld demon nije mogao dobiti potrebne resurse iz operativnog sistema. Prilikom sređivanja grešaka, otkrili smo u sistemu datoteke politike "siroče" apparmor:

# 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

Ove datoteke su kreirane prilikom nadogradnje na MySQL 5.7 prije nekoliko godina i pripadaju uklonjenom paketu. Brisanje datoteka i ponovno pokretanje apparmor servisa riješili su problem:

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

U zaključku

Bilo koja, čak i najjednostavnija operacija, može dovesti do neočekivanih problema. Čak i dobro osmišljen plan ne garantuje uvijek očekivani rezultat. Sada svaki plan ažuriranja koji naš tim uključuje i obavezno čišćenje nepotrebnih datoteka koje su se mogle pojaviti kao rezultat nedavnih radnji.

I sa ovom ne baš profesionalnom grafičkom kreativnošću, želio bih reći veliko hvala Perconi na njihovim odličnim proizvodima!

Ažuriranje MySQL (Percona Server) sa 5.7 na 8.0

PS

Pročitajte i na našem blogu:

izvor: www.habr.com

Dodajte komentar