
Napredak ne miruje, stoga razlozi za ažuriranje na najnovije verzije MySQL postaju sve važniji. Nedavno je došlo vrijeme za ažuriranje naših udobnih klastera Percona Server 5.7 na 8. verziju. Sve se to odvijalo na platformi Ubuntu Linux 16.04. Kako izvesti takvu operaciju s minimalnim zastojećem i s kojim problemima smo se susreli tijekom ažuriranja — pročitajte u ovom članku.
Priprema
Svako ažuriranje servera baza podataka najvjerojatnije je povezano s ponovnom konfiguracijom baze: promjenama zahtjeva za ograničenjima na sustavskim resursima i ispravljanjem konfiguracijskih datoteka koje treba osloboditi od zastarjelih direktiva.
Prije ažuriranja obavezno ćemo se obratiti službenoj dokumentaciji:
- ;
- ;
- ;
- .
I sastavit ćemo plan djelovanja:
- Ispraviti konfiguracijske datoteke uklanjanjem zastarjelih direktiva.
- Provjeriti kompatibilnost alatima.
- Ažurirati slave baze, instalirati paket
percona-server-server. - Ažurirati master, instalirati isti paket.
Razmotrit ćemo svaki korak plana i vidjeti što bi moglo poći po zlu.
VAŽNO! Postupak ažuriranja MySQL klastera temeljenog na Galeri ima svoje nijanse koje nisu opisane u ovom članku. Ne preporučuje se koristiti ovu uputu u takvom slučaju.
Dio 1: Provjera konfiguracija
U 8. verziji MySQL-a uklonili su query_cache. Uglavnom je bio još u verziji 5.7, no sada je i . Shodno tome, potrebno je ukloniti povezane direktive. A za keširanje upita sada se mogu koristiti vanjski alati — primjerice, .
Također su se u konfiguraciji našle zastarjele direktive o innodb_file_format. Ako je u MySQL 5.7 postojala mogućnost izbora InnoDB formata, 8. verzija sada radi .
Naš zaključak — uklanjanje sljedećih direktiva:
-
query_cache_type,query_cache_limitiquery_cache_size; -
innodb_file_formatiinnodb_file_format_max.
Za provjeru koristit ćemo Docker slikom Percona Servera. Konfiguraciju servera stavit ćemo u direktorij mysql_config_test, a pored toga stvorit ćemo direktorije za podatke i logove. Primjer testa konfiguracije percona-server:
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-centosZaključak: ili u Docker logovima ili u direktoriju s logovima — 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] Sintaksa 'expire-logs-days' je zastarjela i bit će uklonjena u budućem izdanju. Molimo koristite binlog_expire_logs_seconds umjesto toga.
2020-04-03T12:44:19.671678Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' trenutno je alias za skup znakova UTF8MB3, ali će u budućem izdanju biti alias za UTF8MB4. Molimo razmotrite korištenje UTF8MB4 radi jasnosti.
2020-04-03T12:44:19.671682Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' je kolacija zastarjelog skupa znakova UTF8MB3. Molimo razmotrite korištenje UTF8MB4 s odgovarajućom kolacijom umjesto toga. Dakle, trebali smo još razjasniti kodiranja i zamijeniti zastarjelu direktivu expire-logs-days.
Dio 2: Provjera radnih instalacija
U dokumentaciji za nadogradnju postoje 2 alatke za provjeru baze na kompatibilnost. Njihova upotreba pomaže administratoru da provjeri kompatibilnost postojeće strukture podataka.
Započnimo s klasičnom alatkom mysqlcheck. Dovoljno je jednostavno pokrenuti:
mysqlcheck -u root -p --all-databases --check-upgradeAko problemi nisu otkriveni, alatka će se završiti s kodom 0:

Osim toga, u modernim verzijama MySQL dostupna je alatka (u slučaju Percone to je paket percona-mysql-shell). Ona je zamjena klasičnom klijentu mysql i objedinjuje funkcije klijenta, uređivača SQL koda i alate za administraciju MySQL-a. Za provjeru servera prije nadogradnje možete kroz nju izvršiti sljedeću komandu:
mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=\/etc\/mysql\/my.cnfI evo koje smo primjedbe dobili:

Uglavnom, ništa kritično — samo upozorenja o kodiranjima. (vidi dolje)Ukupni rezultat izvođenja:

Odlučili smo da bi nadogradnja trebala proći bez problema.
Primjedba o upozorenjima iznad, koja ukazuju na probleme s kodiranjima. Naime, UTF-8 u MySQL-u do nedavno , budući da je čuvala samo 3 bajta umjesto 4. U MySQL 8 to je konačno alias utf8 uskoro će voditi na kodiranje utf8mb4, a stari stupci u tablicama bit će utf8mb3.U budućnosti će kodiranje utf8mb3. biti uklonjeno, ali ne u ovom izdanju. Stoga smo odlučili ispraviti kodiranja već na radnoj instalaciji SGBD-a, nakon njene nadogradnje.
Dio 3: Nadogradnja servera
Što sve može poći po zlu kada imamo tako sjajan plan?.. Savršeno razumijevajući da se detalji uvijek događaju, prvi eksperiment proveli smo na dev klasteru MySQL.
Kao što je već spomenuto, raspravlja o pitanju ažuriranja MySQL poslužitelja s replikama. Bit je da treba prvo ažurirati sve replike (slave), jer MySQL 8 može replikati s majstora verzije 5.7. Određena složenost leži u tome što koristimo režim master master, kada je udaljeni majstor u režimu read-only. To jest, praktično borbeni promet ide u jedan centar podataka, a drugi je rezervni.
Topologija izgleda ovako:

Ažuriranje treba započeti s replikama mysql replica dc 2, mysql master dc 2 i mysql replica dc 1, a završiti na poslužitelju mysql master dc 1. Radi dodatne pouzdanosti, zaustavili smo virtualne strojeve, napravili njihove snimke, a neposredno prije ažuriranja zaustavili repliciranje naredbom STOP SLAVE. U ostalom, ažuriranje izgleda ovako:
- Svaku replikaciju ponovo pokrećemo, dodajući u konfiguracije 3 opcije:
skip-networking,skip-slave-start,skip-log-bin. Naime, ažuriranje baze generira binarne logove s ažuriranjem sistemskih tablica. Ove direktive osiguravaju da u bazi ne dođe do promjene podataka aplikacije, a da u binarne logove ne dospije informacija o ažuriranju sistemskih tablica. To će omogućiti izbjegavanje problema prilikom obnavljanja replikacije. - Instaliramo paket
percona-server-server. Važno je napomenuti da u verziji MySQL 8 ne treba pokrenuti naredbumysqlupgradenakon ažuriranja poslužitelja. - Nakon uspješnog pokretanja još jednom ponovo pokrećemo poslužitelj — već bez parametara koji su dodani u prvom koraku.
- Provjeravamo da repliciranje uspješno radi: provjeravamo
SHOW SLAVE STATUSi gledamo da se ažuriraju tablice sa brojačima u bazi aplikacije.
Sve to izgleda prilično jednostavno: ažuriranje dev prošlo je uspješno. U redu, možemo mirno planirati noćno ažuriranje za produkciju.
Nije bilo žalosti — prod smo ažurirali
Međutim, prenijeti uspješno iskustvo dev na produkciju nije prošlo bez iznenađenja.
Srećom, sam proces ažuriranja započinje s replikama, pa smo, susrevši poteškoće, prekinuli radove i obnovili replikaciju iz snimke. Istraživanje problema prebacili smo na sljedeće jutro. U logovima su se našle sljedeće zabilješke:
2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] tablica: t1 ima 19 kolona, ali InnoDB rječnik ima 20 kolona
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Greška u ispravljanju SE podataka za db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Neuspjeh pri popunjavanju DD tablica.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Prekidanje Istraživanje arhiva raznih email pošiljki na Googleu dovelo je do spoznaje da se takav problem javlja zbog . Iako je vjerovatnije da se radi o bagovima alata mysqlcheck i mysqlsh.
Ispostavlja se da je u MySQL-u promijenjen način predstavljanja podataka za decimalna polja (int, tinyint itd.), te se stoga unutar mysql-servera koristi drugi način njihove pohrane. Ako je vaša baza podataka prvotno bila u verziji 5.5 ili 5.1, a zatim ste se ažurirali na 5.7, možda ćete morati provesti OPTIMIZE za neke tablice. Tada će MySQL ažurirati datoteke sa podacima, prenoseći ih na aktuelni format pohrane.
Također, to se može provjeriti alatom mysqlfrm:
mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
'field_length': 8,
'field_type': 246, # format polja
'field_type_name': 'decimal',
'flags': 3,
'flags_extra': 67,
'interval_nr': 0,
'name': 'your_decimal_column',
... Ako field_type je 0, tada se u tablici koristi stari tip — treba provesti OPTIMIZE. Međutim, ako je vrijednost 246 — već imate novi tip. Više informacija o tipovima možete pronaći u .
Štoviše, u razmatra se drugi mogući uzrok, koji nam je promakao — to je nedostatak InnoDB tablica u sistemskoj tablici INNODB_SYS_TABLESPACES, ako su te tablice kreirane u verziji 5.1. Kako biste izbjegli probleme prilikom ažuriranja, možete iskoristiti .
Zašto nismo imali takvih problema na dev? Baza se periodično kopira s produkcije — tako se tablice ponovo kreiraju.
Nažalost, na stvarnoj velikoj bazi podataka neće biti moguće jednostavno izvesti sveobuhvatan OPTIMIZE. Ovdje pomaže percona-toolkit: za online OPTIMIZE operaciju, alat pt-online-schema-change odlično odgovara.
Ažurirani plan je postao sljedeći:
- Izvršiti optimizaciju svih tablica.
- Izvršiti ažuriranje baza podataka.
Kako bismo provjerili i saznali vrijeme ažuriranja, isključili smo jednu od replika, a za sve tablice pokrenuli sljedeću komandu:
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=t1Ažuriranje tablica se odvija bez dugotrajnih blokada zahvaljujući tome što alat stvara novu privremenu tablicu, u koju kopira podatke iz glavne tablice. U trenutku kada su obje tablice jednake, izvorna tablica se blokira i zamjenjuje novom. U našem slučaju, testno pokretanje je pokazalo da će za ažuriranje svih tablica biti potrebno oko jednog dana, ali pritom je kopiranje podataka stvaralo preveliko opterećenje na diskovima.
Kako bismo to izbjegli, na produkciji smo dodali argument --sleep s vrijednošću 10 — ovaj parametar regulira dužinu čekanja nakon prijenosa paketa podataka u novu tablicu. Tako se može smanjiti opterećenje, ako je stvarno pokrenuta aplikacija zahtjevna za vrijeme odgovora.
Nakon optimizacije, ažuriranje je prošlo uspješno.
… ali ne do kraja!
Već nakon pola sata od ažuriranja klijent je došao s problemom. Baza je radila vrlo čudno: povremeno su počeli padaji veza. Ovako je to izgledalo u monitoringu:

Na snimci zaslona vidi se zubasti grafikon, povezan s tim što su neki tokovi MySQL servera povremeno padali s greškom. U aplikaciji su se pojavile greške:
[PDOException] SQLSTATE[HY000] [2002] Veza odbijenaBrzi pregled logova otkrio je da demon mysqld nije mogao dobiti potrebne resurse od operativnog sustava. Proučavajući greške, otkrili smo u sustavu «napuštene» datoteke politika 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 amd64Ove datoteke su nastale tijekom ažuriranja na MySQL 5.7 prije nekoliko godina i pripadaju uklonjenom paketu. Brišući datoteke i ponovno pokrećući uslugu apparmor, problem je riješen:
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 apparmorZa kraj
Svaka, čak i najjednostavnija operacija, može dovesti do neočekivanih problema. Čak ni postojanje promišljenog plana ne jamči uvijek očekivani rezultat. Sada u svaki plan ažuriranja našeg tima uključena je i obaveznačišćenje suvišnih datoteka koje su mogle nastati uslijed posljednjih akcija.
Ovim ne baš profesionalnim grafičkim djelom želim se zahvaliti tvrtki Percona na njihovim izvrsnim proizvodima!

P.S.
Pročitajte i na našem blogu:
- «»;
- «»;
- «»;
- «»;
- «».
Izvor: habr.com
