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

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

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

Trening

Svako ažuriranje poslužitelja baze podataka najvjerojatnije je povezano s rekonfiguracijom baze podataka: promjenama u zahtjevima za ograničenje resursa sustava i ispravkom konfiguracija baze podataka koje je potrebno očistiti od zastarjelih direktiva.

Prije ažuriranja svakako ćemo pogledati službenu dokumentaciju:

I napravimo akcijski 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 s istim paketom.

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

VAŽNO! Postupak ažuriranja MySQL klastera temeljenog na Galeri ima svoje suptilnosti koje nisu opisane u članku. U ovom slučaju ne biste trebali koristiti ovu uputu.

1. dio: Provjera konfiguracija

MySQL je uklonjen u verziji 8 query_cache. Zapravo je bio proglasio zastarjelim natrag u verziji 5.7, ali sada potpuno izbrisani. Sukladno tome, potrebno je ukloniti pridružene direktive. A za predmemoriju zahtjeva sada možete koristiti vanjske alate - na primjer, ProxySQL.

Također su u konfiguraciji postojale zastarjele direktive o innodb_file_format. Ako je u MySQL 5.7 bilo moguće odabrati InnoDB format, tada osma verzija već radi samo s Barracuda formatom.

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 koristit ćemo Docker sliku Percona Servera. Smjestit ćemo konfiguraciju poslužitelja u direktorij mysql_config_test, a pored njega ćemo kreirati direktorije za podatke i zapisnike. Primjer testiranja konfiguracije poslužitelja 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

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

Evo što 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š smo morali otkriti kodiranje i zamijeniti zastarjelu direktivu expire-logs-days.

Dio 2: Provjera radnih instalacija

Dokumentacija ažuriranja sadrži 2 pomoćna programa za provjeru kompatibilnosti baze podataka. Njihova uporaba pomaže administratoru provjeriti 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) s 5.7 na 8.0

Osim toga, uslužni program dostupan je u modernim verzijama MySQL-a mysql-ljuska (u slučaju Percone ovo je paket percona-mysql-shell). Zamjena je za klasični mysql klijent i kombinira funkcije klijenta, uređivača SQL koda i MySQL alata za administraciju. Za provjeru poslužitelja prije ažuriranja, možete preko njega pokrenuti sljedeće naredbe:

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) s 5.7 na 8.0

Općenito, ništa kritično - samo upozorenja o kodiranju (Pogledaj ispod). Ukupni rezultat izvršenja:

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

Odlučili smo da bi ažuriranje trebalo proći bez problema.

Napomena o gornjim upozorenjima koja ukazuju na probleme s kodiranjem. Činjenica je da je UTF-8 donedavno u MySQL-u nije bio "pravi" UTF-8, budući da je pohranio samo 3 bajta umjesto 4. U MySQL 8 ovo je konačno odlučio to popraviti: alias utf8 uskoro će dovesti do kodiranja utf8mb4, a stari stupci u tablicama postat će utf8mb3. Daljnje kodiranje utf8mb3 bit će uklonjeno, ali ne u ovom izdanju. Stoga smo odlučili ispraviti kodiranje već na pokrenutoj DBMS instalaciji, nakon što je ažuriramo.

Dio 3: Ažuriranja poslužitelja

Što bi moglo poći po zlu kad postoji tako pametan plan?.. Dobro shvaćajući da se nijanse uvijek događaju, proveli smo prvi eksperiment na MySQL dev klasteru.

Kao što je već spomenuto, službena dokumentacija pokriva pitanje ažuriranja MySQL poslužitelja s replikama. Zaključak je da biste prvo trebali ažurirati sve replike (slave), budući da MySQL 8 može replicirati iz glavne verzije 5.7. Neka poteškoća leži u činjenici da koristimo način majstor majstor, kada je udaljeni glavni u načinu rada read-only. To jest, zapravo, borbeni promet ide u jedan podatkovni centar, a drugi je rezervni.

Topologija izgleda ovako:

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

Ažuriranje mora započeti s replikama mysql replika dc 2, mysql master dc 2 и mysql replica dc 1, a završiti s poslužiteljem mysql master dc 1. Da budemo pouzdaniji, zaustavili smo virtualne strojeve, snimili njihove snimke i neposredno prije ažuriranja zaustavili replikaciju naredbom STOP SLAVE. Ostatak ažuriranja izgleda ovako:

  1. Ponovno pokrećemo svaku repliku dodavanjem 3 opcije u konfiguracije: skip-networking, skip-slave-start, skip-log-bin. Činjenica je da ažuriranje baze podataka generira binarne zapisnike s ažuriranjima sistemskih tablica. Ove direktive jamče da neće biti promjena podataka aplikacije u bazi podataka, a informacije o ažuriranju sistemskih tablica neće biti uključene u binarne zapisnike. Time ćete izbjeći probleme prilikom nastavka replikacije.
  2. Instalacija paketa percona-server-server. Važno je napomenuti da u MySQL verziji 8 ne morate pokrenuti naredbu mysqlupgrade nakon ažuriranja poslužitelja.
  3. Nakon uspješnog pokretanja ponovno pokrećemo poslužitelj - bez parametara koji su dodani u prvom paragrafu.
  4. Osiguravamo da replikacija uspješno radi: provjerite SHOW SLAVE STATUS i vidjeti da su tablice s brojačima u bazi podataka ažurirane.

Sve izgleda prilično jednostavno: dev ažuriranje 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 razvojnog iskustva u proizvodnju nije prošao bez iznenađenja.

Srećom, sam proces ažuriranja počinje s replikama, pa kada smo naišli na poteškoće, zaustavili smo rad i vratili repliku sa snimke. Istraga problema odgođ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živanje arhiva raznih mailing lista na Googleu dovelo je do zaključka da se ovaj problem javlja zbog MySQL greška. Iako je ovo vjerojatnije greška u uslužnom programu 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 za njihovo pohranjivanje. Ako 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 učiniti OPTIMIZE za neke stolove. Tada će MySQL ažurirati podatkovne datoteke, prebacujući ih u trenutni format pohrane.

To 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 je jednak 0, tada se u tablici 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 kodirati.

Štoviše, u ova greška Razmatramo drugi mogući razlog, koji nas je zaobišao: nepostojanje InnoDB tablica u sistemskoj tablici INNODB_SYS_TABLESPACES, ako su one, tablice, stvorene u verziji 5.1. Da biste izbjegli probleme prilikom ažuriranja, možete koristiti priložena SQL skripta.

Zašto nismo imali takvih problema na devu? Baza podataka se tamo povremeno kopira iz proizvodnje - dakle, stolovi se rekreiraju.

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

Ažurirani plan je izgledao ovako:

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

Kako bismo to provjerili i ujedno saznali vrijeme ažuriranja, onemogućili smo jednu od replika i pokrenuli sljedeću naredbu za sve tablice:

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

Tablice se ažuriraju bez dugotrajnih zaključavanja zbog činjenice da uslužni program stvara novu privremenu tablicu u koju kopira podatke iz glavne tablice. U trenutku kada su obje tablice identične, originalna tablica se zaključava i zamjenjuje novom. U našem slučaju, probno pokretanje pokazalo je da će biti potrebno oko jedan dan da se ažuriraju sve tablice, ali kopiranje podataka uzrokovalo je preveliko opterećenje diskova.

Da bismo to izbjegli, u proizvodnji smo dodali argument naredbi --sleep s vrijednošću 10 - ovaj parametar prilagođava duljinu čekanja nakon prijenosa serije podataka u novu tablicu. Na taj način možete smanjiti opterećenje ako stvarno pokrenuta aplikacija zahtijeva vrijeme odziva.

Nakon izvođenja optimizacije ažuriranje je bilo uspješno.

... ali ne u potpunosti!

U roku od pola sata nakon ažuriranja, klijent je došao s problemom. Baza podataka radila je vrlo čudno: povremeno su počeli resetiranje veze. Ovako je to izgledalo u monitoringu:

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

Snimka zaslona prikazuje pilasti grafikon zbog činjenice da su se neke od niti MySQL poslužitelja povremeno srušile s pogreškom. Pojavile su se greške u aplikaciji:

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

Brzi pregled zapisa otkrio je da demon mysqld ne može dobiti potrebne resurse iz operativnog sustava. Razvrstavajući greške koje smo otkrili u sustavu "siroče" apparmor datoteke pravila:

# 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 su datoteke stvorene prilikom nadogradnje na MySQL 5.7 prije nekoliko godina i pripadaju uklonjenom paketu. Brisanje datoteka i ponovno pokretanje apparmor usluge riješilo je 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

Svaka, čak i najjednostavnija operacija, može dovesti do neočekivanih problema. Čak i dobro osmišljen plan ne jamči uvijek očekivani rezultat. Sada svi planovi ažuriranja koje naš tim ima također uključuju obavezno čišćenje nepotrebnih datoteka koje su se mogle pojaviti kao rezultat nedavnih radnji.

I uz ovu ne baš profesionalnu grafičku kreativnost, želio bih reći veliko hvala Perconi na njihovim izvrsnim proizvodima!

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

PS

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar