Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Predlažem da pročitate transkript izvješća s početka 2016. Andreya Salnikova “Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresql-u”

U ovom izvješću analizirat ću glavne pogreške u aplikacijama koje se javljaju u fazi projektiranja i pisanja aplikacijskog koda. I uzet ću samo one pogreške koje dovode do nadutosti u Postgresqlu. U pravilu je to početak kraja performansi vašeg sustava u cjelini, iako u početku nisu bili vidljivi nikakvi preduvjeti za to.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Drago mi je pozdraviti sve! Ovo izvješće nije toliko tehničko kao prethodno od mog kolege. Ovo je izvješće uglavnom namijenjeno programerima pozadinskih sustava jer imamo prilično velik broj klijenata. I svi rade iste greške. Pričat ću vam o njima. Objasnit ću do kakvih kobnih i loših stvari vode te greške.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Zašto se prave pogreške? Rade se iz dva razloga: nasumično, možda i uspije te zbog nepoznavanja nekih mehanizama koji se javljaju na razini između baze i aplikacije, kao iu samoj bazi.

Dat ću vam tri primjera s užasnim slikama koliko su stvari postale loše. Ukratko ću vam reći o mehanizmu koji se tamo događa. I kako se s njima nositi, kada su se dogodile i koje preventivne metode koristiti da spriječite pogreške. Reći ću vam o pomoćnim alatima i dati korisne veze.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Koristio sam testnu bazu podataka gdje sam imao dvije tablice. Jedna ploča s računima kupaca, druga s prometom po tim računima. I s određenom učestalošću ažuriramo stanja na tim računima.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Početni podaci ploče: prilično je mala, 2 MB. Vrijeme odgovora za bazu podataka i posebno za znak također je vrlo dobro. I prilično dobro opterećenje - 2 operacija u sekundi prema tablici.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

I kroz ovo izvješće pokazat ću vam grafikone kako biste mogli jasno razumjeti što se događa. Uvijek će biti 2 slajda s grafikonima. Prvi slajd je ono što se općenito događa na poslužitelju.

I u ovoj situaciji vidimo da stvarno imamo mali znak. Indeks je mali i iznosi 2 MB. Ovo je prvi grafikon lijevo.

Prosječno vrijeme odgovora na poslužitelju također je stabilno i kratko. Ovo je gornji desni grafikon.

Donji lijevi grafikon prikazuje najdulje transakcije. Vidimo da se transakcije brzo završavaju. A autovakuum ovdje još ne radi, jer je bio početni test. Nastavit će raditi i bit će nam od koristi.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Drugi slajd će uvijek biti posvećen ploči koja se testira. U ovoj situaciji stalno ažuriramo stanje na računu klijenta. I vidimo da je prosječno vrijeme odgovora za operaciju ažuriranja prilično dobro, manje od milisekunde. Vidimo da se resursi procesora (ovo je gornji desni grafikon) također troše ravnomjerno i prilično malo.

Donji desni grafikon pokazuje koliko operativne i diskovne memorije prolazimo u potrazi za željenom linijom prije nego što je ažuriramo. A broj operacija prema znaku je 2 u sekundi, kao što sam rekao na početku.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

A sada imamo tragediju. Iz nekog razloga postoji davno zaboravljena transakcija. Razlozi su obično banalni:

  • Jedan od najčešćih je da smo počeli pristupati vanjskoj usluzi u kodu aplikacije. A ova služba nam ne odgovara. Odnosno, otvorili smo transakciju, napravili izmjenu u bazi i otišli s aplikacije na čitanje pošte ili na neki drugi servis unutar naše infrastrukture, a ona nam iz nekog razloga ne odgovara. I naša je sesija zapela u stanju u kojem se ne zna kada će se riješiti.
  • Druga situacija je kada se iz nekog razloga dogodi iznimka u našem kodu. A u izuzetnim slučajevima nismo obradili zatvaranje transakcije. I završili smo s hanging sessionom s otvorenom transakcijom.
  • I posljednji je također prilično čest slučaj. Ovo je kod niske kvalitete. Neki okviri otvaraju transakciju. Visi, a možda ne znate u aplikaciji da vam visi.

Kamo takve stvari vode?

Do te mjere da naše tablice i indeksi počinju dramatično rasti. Ovo je potpuno isti učinak nadutosti. Za bazu podataka to će značiti da će se vrijeme odziva baze podataka vrlo naglo povećati i opterećenje poslužitelja baze podataka će se povećati. Kao rezultat toga, naša će aplikacija patiti. Jer ako ste potrošili 10 milisekundi u svom kodu na zahtjev bazi podataka, 10 milisekundi na svoju logiku, onda je vašoj funkciji trebalo 20 milisekundi da se dovrši. I sada će vaša situacija biti potpuno tužna.

I da vidimo što će se dogoditi. Donji lijevi grafikon pokazuje da imamo dugu dugu transakciju. A ako pogledamo gornji lijevi grafikon, vidimo da je veličina naše tablice odjednom skočila s dva megabajta na 300 megabajta. Istovremeno, količina podataka u tablici se nije promijenila, tj. tamo je prilično velika količina smeća.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Opća situacija u vezi s prosječnim vremenom odgovora poslužitelja također se promijenila za nekoliko redova veličine. Odnosno, svi zahtjevi na poslužitelju počeli su potpuno padati. A u isto vrijeme pokrenuti su interni Postgres procesi u obliku autovakuuma koji pokušavaju nešto učiniti i troše resurse.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Što se događa s našim znakom? Isto. Naše prosječno vrijeme odgovora prema znaku skočilo je nekoliko redova veličine. Konkretno što se tiče potrošenih resursa, vidimo da je opterećenje procesora jako poraslo. Ovo je gornji desni grafikon. A povećao se jer procesor mora sortirati hrpu beskorisnih redaka u potrazi za onim potrebnim. Ovo je donji desni grafikon. Kao rezultat toga, naš broj poziva u sekundi počeo je značajno padati, jer baza podataka nije imala vremena obraditi isti broj zahtjeva.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Moramo se vratiti u život. Idemo na internet i otkrivamo da duge transakcije dovode do problema. Pronalazimo i prekidamo ovu transakciju. I sve nam postaje normalno. Sve radi kako treba.

Smirili smo se, ali nakon nekog vremena počinjemo primjećivati ​​da aplikacija ne radi isto kao prije hitne. Zahtjevi se i dalje obrađuju sporije, i to znatno sporije. Jedan i pol do dva puta sporiji konkretno u mom primjeru. Opterećenje poslužitelja također je veće nego što je bilo prije nesreće.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

I pitanje: "Što se događa s bazom u ovom trenutku?" A s bazom se događa sljedeća situacija. Na grafikonu transakcija možete vidjeti da je prestao i stvarno nema dugoročnih transakcija. Ali veličina znaka smrtno se povećala tijekom nesreće. I od tada se nisu smanjile. Prosječno vrijeme na bazi se stabiliziralo. A čini se da odgovori stižu primjereno nama prihvatljivom brzinom. Autovakuum se aktivirao i počeo nešto raditi sa znakom, jer treba probrati još podataka.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Konkretno, prema testnoj tablici s računima, gdje mijenjamo stanja: čini se da se vrijeme odgovora na zahtjev vratilo u normalu. Ali u stvarnosti je jedan i pol puta veći.

A iz opterećenja procesora vidimo da se opterećenje procesora nije vratilo na potrebnu vrijednost prije rušenja. A razlozi za to leže upravo u donjem desnom grafikonu. Vidi se da se tu traži određena količina memorije. To jest, da bismo pronašli traženi redak, gubimo resurse poslužitelja baze podataka dok sortiramo beskorisne podatke. Broj transakcija u sekundi se stabilizirao.

Općenito dobro, ali situacija je gora nego što je bila. Jasna degradacija baze podataka kao posljedica naše aplikacije koja radi s ovom bazom podataka.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

A da biste razumjeli što se tamo događa, ako niste bili na prethodnom izvješću, idemo sada malo teorije. Teorija o unutarnjem procesu. Zašto usisivač za auto i čemu služi?

Doslovno ukratko za razumijevanje. U nekom trenutku imamo stol. Imamo redove u tablici. Ove linije mogu biti aktivne, žive i ono što nam sada treba. Na slici su označeni zelenom bojom. A postoje rokovi koji su već razrađeni, ažurirani i na njima su se pojavili novi unosi. I oni su označeni da više nisu zanimljivi bazi podataka. Ali oni su u tablici zbog značajke Postgresa.

Zašto vam je potreban usisivač za auto? U nekom trenutku dolazi autovacuum, pristupa bazi i pita je: “Molim vas dajte mi ID najstarije transakcije koja je trenutno otvorena u bazi.” Baza podataka vraća ovaj ID. A autovakuum, oslanjajući se na njega, razvrstava redove u tablici. A ako vidi da su neke linije promijenjene puno starijim transakcijama, onda ih ima pravo označiti kao linije koje možemo ponovno koristiti u budućnosti upisujući tamo nove podatke. Ovo je pozadinski proces.

U ovom trenutku nastavljamo raditi s bazom podataka i nastavljamo unositi neke izmjene u tablicu. I na tim linijama, koje možemo ponovno koristiti, upisujemo nove podatke. I tako dobijemo ciklus, tj. stalno se pojavljuju neki mrtvi stari redovi, umjesto njih upisujemo nove retke koji su nam potrebni. I ovo je normalno stanje za rad PostgreSQL-a.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Što se dogodilo tijekom nesreće? Kako se taj proces dogodio tamo?

Imali smo znak u nekom stanju, neki žive, neki mrtve linije. Stigao je usisivač za auto. Pitao je bazu podataka koja je naša najstarija transakcija i koji je njen ID. Primio sam ovaj ID, što bi moglo biti prije mnogo sati, možda prije deset minuta. Ovisi o opterećenosti baze podataka. I otišao je tražiti retke koje bi mogao označiti kao ponovno korištene. I nisam našao takve retke u našoj tablici.

Ali u ovom trenutku nastavljamo raditi sa stolom. U njemu nešto radimo, ažuriramo, mijenjamo podatke. Što baza podataka treba raditi u ovom trenutku? Ne preostaje joj ništa drugo nego dodati nove retke na kraj postojeće tablice. I tako veličina našeg stola počinje rasti.

U stvarnosti su nam potrebne zelene linije za rad. Ali tijekom takvog problema ispada da je postotak zelenih linija izuzetno nizak u cijeloj tablici.

A kada izvršimo upit, baza podataka mora proći kroz sve retke: i crvene i zelene, kako bi pronašla željenu liniju. A učinak napuhavanja tablice beskorisnim podacima naziva se "napuhavanje", što također troši prostor na disku. Sjećate se, bilo je 2 MB, postalo je 300 MB? Sada promijenite megabajte u gigabajte i brzo ćete izgubiti sve svoje diskovne resurse.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Kakve bi mogle biti posljedice za nas?

  • U mom primjeru, tablica i indeks su porasli 150 puta. Neki od naših klijenata imali su više kobnih slučajeva kada im je jednostavno počelo ponestajati prostora na disku.
  • Veličina samih stolova nikada se neće smanjiti. Autovacuum u nekim slučajevima može odrezati rep stola ako postoje samo mrtve linije. Ali budući da postoji stalna rotacija, jedna zelena linija može se zamrznuti na kraju i neće se ažurirati, dok će sve ostale biti zapisane negdje na početku ploče. Ali ovo je tako malo vjerojatan događaj da će se sam vaš stol smanjiti, pa se tome ne biste trebali nadati.
  • Baza podataka mora sortirati čitavu hrpu beskorisnih redaka. I uzalud trošimo resurse diska, trošimo resurse procesora i električnu energiju.
  • I to izravno utječe na našu aplikaciju, jer ako smo na početku potrošili 10 milisekundi na zahtjev, 10 milisekundi na naš kod, onda smo tijekom pada počeli trošiti sekundu na zahtjev i 10 milisekundi na kod, tj. redoslijed veličina izvedbe aplikacije smanjena. A kad je nesreća riješena, počeli smo trošiti 20 milisekundi na zahtjev, 10 milisekundi na šifru. To znači da smo ipak pali jedan i pol puta u produktivnosti. I to zbog jedne transakcije koja se zamrznula, možda našom krivnjom.
  • I pitanje: “Kako sve vratiti?” da kod nas bude sve u redu i da zahtjevi stižu jednako brzo kao i prije nesreće.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

U tu svrhu postoji određeni ciklus rada koji se provodi.

Prvo moramo pronaći problematične stolove koji su napuhani. Razumijemo da je u nekim tablicama snimanje aktivnije, u drugima manje. I za ovo koristimo ekstenziju pgstattuple. Instaliranjem ove ekstenzije možete pisati upite koji će vam pomoći pronaći tablice koje su prilično napuhane.

Nakon što ste pronašli ove tablice, morate ih komprimirati. Za to već postoje alati. U našoj tvrtki koristimo tri alata. Prvi je ugrađeni VACUUM FULL. Okrutan je, grub i nemilosrdan, ali ponekad je vrlo koristan. Pg_repack и pgcompacttable - Ovo su pomoćni programi trećih strana za sažimanje tablica. I pažljivije postupaju s bazom podataka.

Koriste se ovisno o tome što vam više odgovara. Ali o ovome ću vam reći na samom kraju. Glavna stvar je da postoje tri alata. Postoji mnogo toga za izabrati.

Nakon što smo sve ispravili i uvjerili se da je sve u redu, moramo znati kako spriječiti ovu situaciju u budućnosti:

  • Može se vrlo lako spriječiti. Morate pratiti trajanje sesija na glavnom poslužitelju. Osobito opasne sesije u stanju mirovanja u transakciji. To su oni koji su samo otvorili transakciju, napravili nešto i otišli, ili jednostavno ostali, izgubili se u šifri.
  • A za vas, kao programere, važno je da testirate svoj kod kada dođe do takvih situacija. Nije to teško učiniti. Ovo će biti korisna provjera. Izbjeći ćete veliki broj "djetinjastih" problema povezanih s dugim transakcijama.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

U ovim sam vam grafikonima želio pokazati kako su se znak i ponašanje baze podataka promijenili nakon što sam u ovom slučaju prošao kroz znak s VACUUM FULL. Ovo za mene nije proizvodnja.

Veličina tablice odmah se vratila u normalno radno stanje od nekoliko megabajta. To nije uvelike utjecalo na prosječno vrijeme odgovora poslužitelja.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Ali konkretno za naš testni znak, gdje smo ažurirali stanja računa, vidimo da je prosječno vrijeme odgovora na zahtjev za ažuriranje podataka u znaku smanjeno na razine prije hitnog stanja. Resursi koje procesor troši za dovršenje ovog zahtjeva također su pali na razine prije pada. A donji desni grafikon pokazuje da sada nalazimo točno onaj redak koji nam treba odmah, bez prolaska kroz hrpe mrtvih redaka koji su bili tamo prije nego što je tablica komprimirana. A prosječno vrijeme zahtjeva ostalo je na približno istoj razini. Ali ovdje imam grešku u hardveru.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Tu prva priča završava. Najčešći je. I to se događa svima, bez obzira na iskustvo klijenta i koliko su kvalificirani programeri. Prije ili kasnije to se dogodi.

Druga priča, u kojoj raspoređujemo opterećenje i optimiziramo resurse poslužitelja

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

  • Već smo odrasli i postali ozbiljni momci. I mi razumijemo da imamo repliku i bilo bi dobro da izbalansiramo opterećenje: pišite Majstoru i čitajte iz replike. I obično se ova situacija dogodi kada želimo pripremiti neka izvješća ili ETL. I posao je vrlo sretan zbog ovoga. On stvarno želi raznolika izvješća s mnogo složene analitike.
  • Izvješća traju mnogo sati jer se složena analitika ne može izračunati u milisekundama. Mi, kao hrabri momci, pišemo kod. U aplikaciji za umetanje vršimo snimanje na Masteru, a izvještaje izvršavamo na replici.
  • Raspodjela tereta.
  • Sve radi savršeno. super smo.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

I kako izgleda ova situacija? Konkretno na ovim grafovima dodao sam i trajanje transakcija iz replike za trajanje transakcije. Svi ostali grafikoni odnose se samo na glavni poslužitelj.

Do tog vremena moja je ploča za izvješćivanje narasla. Ima ih više. Vidimo da je prosječno vrijeme odgovora poslužitelja stabilno. Vidimo da na replici imamo dugotrajnu transakciju koja traje 2 sata. Vidimo tihi rad autovakuma koji obrađuje mrtve linije. I sve je u redu kod nas.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Konkretno, prema testiranoj tablici, tamo nastavljamo ažurirati stanja računa. A imamo i stabilno vrijeme odgovora na zahtjeve, stabilnu potrošnju resursa. Kod nas je sve u redu.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Sve je u redu do trenutka kada se ova izvješća počnu javljati zbog sukoba s replikacijom. I uzvraćaju vatru u pravilnim intervalima.

Idemo na internet i počinjemo čitati zašto se to događa. I nađemo rješenje.

Prvo rješenje je povećati latenciju replikacije. Znamo da naše izvješće traje 3 sata. Postavili smo odgodu replikacije na 3 sata. Pokrećemo sve, ali i dalje imamo problema s izvješćima koja se ponekad otkazuju.

Želimo da sve bude savršeno. Penjemo se dalje. A na internetu smo pronašli cool postavku - hot_standby_feedback. Uključimo ga. Hot_standby_feedback nam omogućuje da zadržimo autovakuum na Masteru. Tako se u potpunosti rješavamo sukoba replikacije. I sve nam dobro ide s izvješćima.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

A što se trenutno događa s glavnim poslužiteljem? A mi smo u totalnim problemima s glavnim poslužiteljem. Sada vidimo grafikone kada su obje ove postavke omogućene. I vidimo da je sesija na našoj replici nekako počela utjecati na situaciju na Master serveru. Ona ima učinka jer je pauzirala autovakuum, što čisti mrtve redove. Veličina našeg stola ponovno je naglo porasla. Prosječno vrijeme izvršenja upita u cijeloj bazi podataka također je naglo poraslo. Autovakumi su se malo zategnuli.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Naime, s naše ploče vidimo da je i ažuriranje podataka na njemu skočilo u nebo. Potrošnja CPU-a također se znatno povećala. Ponovno prolazimo kroz veliki broj mrtvih, beskorisnih linija. I vrijeme odgovora za ovaj znak i broj transakcija su pali.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Kako će to izgledati ako ne znamo o čemu sam prije govorio?

  • Počinjemo tražiti probleme. Ako smo naišli na probleme u prvom dijelu, znamo da je to možda zbog duge transakcije i idemo Masteru. Imamo problem s Masterom. Kobasice ga. Grije se, Prosjek opterećenja mu je stotinjak.
  • Zahtjevi su spori, ali tamo ne vidimo dugotrajne transakcije. I ne razumijemo u čemu je stvar. Ne razumijemo gdje tražiti.
  • Provjeravamo serversku opremu. Možda je naš napad pao. Možda nam je memory stick pregorio. Da, svašta se može dogoditi. Ali ne, serveri su novi, sve radi kako treba.
  • Svi trče: administratori, programeri i direktor. Ništa ne pomaže.
  • I u jednom trenutku sve se odjednom počinje ispravljati.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

U ovom trenutku, zahtjev za našu repliku je obrađen i ostavljen. Dobili smo prijavu. Posao je i dalje sretan. Kao što vidite, naš znak je ponovno narastao i neće se smanjivati. Na grafu sa sesijama ostavio sam dio ove duge transakcije iz replike da možete procijeniti koliko je potrebno da se situacija stabilizira.

Sjednica je gotova. I tek nakon nekog vremena poslužitelj dođe koliko-toliko u red. I prosječno vrijeme odgovora za zahtjeve na glavnom poslužitelju vraća se u normalu. Jer, konačno, autovakuum ima priliku očistiti i označiti ove mrtve linije. I počeo je raditi svoj posao. A koliko on to brzo učini, tako ćemo se brzo i mi dovesti u red.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Prema testiranom tabletu, gdje ažuriramo stanje računa, vidimo potpuno istu sliku. Prosječno vrijeme ažuriranja računa također se postupno normalizira. Resursi koje troši procesor također su smanjeni. I broj transakcija u sekundi vraća se u normalu. Ali opet smo se vratili u normalu, nismo isti kao prije nesreće.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

U svakom slučaju, dobivamo pad performansi, kao u prvom slučaju, jedan i pol do dva puta, a ponekad i više.

Čini se da smo sve napravili kako treba. Rasporedite teret. Oprema ne miruje. Podijelili smo zahtjeve prema svojoj pameti, ali ipak je sve loše ispalo.

  • Ne omogućiti hot_standby_feedback? Da, ne preporučuje se uključivanje bez posebno jakih razloga. Budući da ovaj zaokret izravno utječe na glavni poslužitelj i obustavlja rad autovakuuma tamo. Ako ga uključite na nekoj replici i zaboravite na njega, možete ubiti Mastera i imati velike probleme s aplikacijom.
  • Povećati max_standby_streaming_delay? Da, za izvješća je to točno. Ako imate trosatno izvješće i ne želite da se sruši zbog sukoba replikacije, jednostavno povećajte odgodu. Dugoročno izvješće nikad ne zahtijeva podatke koji su upravo sada stigli u bazu podataka. Ako ga imate tri sata, onda ga koristite za neko staro podatkovno razdoblje. A za vas, hoće li doći do kašnjenja od tri sata ili šest sati, neće biti nikakve razlike, ali ćete izvješća primati dosljedno i nećete imati problema s njihovim padom.
  • Naravno, morate kontrolirati duge sesije na replici, posebno ako odlučite omogućiti hot_standby_feedback na replici. Jer svašta se može dogoditi. Dali smo ovu repliku programeru kako bi mogao testirati zahtjeve. Napisao je ludi zahtjev. Pustio ga je i otišao popiti čaj i dobili smo etabliranog Učitelja. Ili smo možda tamo stavili pogrešnu aplikaciju. Situacije su razne. Sesije na replikama moraju se pratiti jednako pažljivo kao i na Masteru.
  • A ako imate brze i duge upite o replikama, onda je u ovom slučaju bolje da ih podijelite kako biste rasporedili opterećenje. Ovo je poveznica na streaming_delay. Za one brze, imajte jednu repliku s malom odgodom replikacije. Za dugotrajne zahtjeve za izvješćivanjem imajte repliku koja može kasniti 6 sati ili dan. To je sasvim normalna situacija.

Posljedice otklanjamo na isti način:

  • Nalazimo napuhane stolove.
  • I komprimiramo ga najprikladnijim alatom koji nam odgovara.

Druga priča ovdje završava. Prijeđimo na treću priču.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Također prilično uobičajeno za nas u kojima radimo migraciju.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

  • Svaki softverski proizvod raste. Zahtjevi za to se mijenjaju. U svakom slučaju, želimo se razvijati. I događa se da trebamo ažurirati podatke u tablici, odnosno pokrenuti ažuriranje u smislu naše migracije za novu funkcionalnost koju uvodimo u sklopu našeg razvoja.
  • Stari format podataka nije zadovoljavajući. Recimo da se sada okrenemo drugoj tablici, gdje imam transakcije na ovim računima. I recimo da su bile u rubljama, a mi smo odlučili povećati točnost i učiniti to u kopejkama. A za ovo moramo napraviti ažuriranje: pomnožiti polje s iznosom transakcije sa sto.
  • U današnjem svijetu koristimo automatizirane alate za kontrolu verzija baze podataka. Recimo Liquibase. Tamo registriramo svoju migraciju. Testiramo ga na našoj testnoj bazi. Sve je u redu. Ažuriranje je u tijeku. Neko vrijeme blokira rad, ali dobivamo ažurirane podatke. I možemo pokrenuti novu funkcionalnost na ovome. Sve je testirano i provjereno. Sve se potvrdilo.
  • Planski smo radili i izvršili migraciju.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Ovdje je migracija s ažuriranjem predstavljena pred vama. Pošto su to moje transakcije po računu, ploča je bila 15 GB. A budući da ažuriramo svaki redak, ažuriranjem smo udvostručili veličinu tablice jer smo svaki redak prepisali.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Tijekom migracije nismo mogli učiniti ništa s ovom pločom jer su svi zahtjevi za nju stavljeni u red čekanja i čekali su dok ovo ažuriranje ne završi. Ali ovdje vam želim skrenuti pozornost na brojeve koji su na okomitoj osi. Odnosno, imamo prosječno vrijeme zahtjeva prije migracije od oko 5 milisekundi i opterećenje procesora, broj blok operacija za čitanje diskovne memorije manji je od 7,5.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Proveli smo migraciju i opet smo imali problema.

Migracija je bila uspješna, ali:

  • Za dovršetak stare funkcije sada treba više vremena.
  • Stol je ponovno porastao.
  • Opterećenje poslužitelja ponovno je postalo veće nego prije.
  • I, naravno, još uvijek petljamo s funkcionalnošću koja je dobro funkcionirala, malo smo je poboljšali.

I ovo je opet nadutost, koja nam opet uništava živote.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Ovdje pokazujem da se stol, kao i prethodna dva slučaja, neće vratiti na svoje prethodne veličine. Čini se da je prosječno opterećenje poslužitelja odgovarajuće.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

A ako pogledamo tablicu s računima, vidjet ćemo da se prosječno vrijeme zahtjeva za ovu tablicu udvostručilo. Opterećenje procesora i broj razvrstanih linija u memoriji skočio je iznad 7,5, ali je bio manji. I skočio je 2 puta u slučaju procesora, 1,5 puta u slučaju blok operacija, tj. dobili smo degradaciju u radu poslužitelja. I kao rezultat - degradacija performansi naše aplikacije. Pritom je broj poziva ostao približno na istoj razini.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

A glavna stvar ovdje je razumjeti kako ispravno raditi takve migracije. I treba ih učiniti. Ove migracije provodimo prilično dosljedno.

  • Tako velike migracije ne događaju se automatski. Uvijek moraju biti pod kontrolom.
  • Potreban je nadzor stručne osobe. Ako imate DBA u svom timu, dopustite DBA da to učini. To je njegov posao. Ako ne, onda neka to učini najiskusnija osoba koja zna raditi s bazama podataka.
  • Novu shemu baze podataka, čak i ako ažuriramo jedan stupac, uvijek pripremamo u fazama, tj. unaprijed prije izvođenja nove verzije aplikacije:
  • Dodana su nova polja u koja ćemo bilježiti ažurirane podatke.
  • Podatke iz starog u novo polje prenosimo u malim dijelovima. Zašto ovo radimo? Prvo, uvijek kontroliramo proces ovog procesa. Znamo da smo već toliko serija prebacili i toliko nam je ostalo.
  • A drugi pozitivan učinak je da između svake takve serije zatvaramo transakciju, otvaramo novu, a to omogućuje da autovakuum radi prema tablici, označava krajnje rokove za ponovnu upotrebu.
  • Za retke koji će se pojaviti dok aplikacija radi (još uvijek imamo staru aplikaciju pokrenutu), dodajemo okidač koji upisuje nove vrijednosti u nova polja. U našem slučaju to je množenje stare vrijednosti sa sto.
  • Ako smo potpuno tvrdoglavi i želimo isto polje, onda po završetku svih migracija, a prije izlaska nove verzije aplikacije, polja jednostavno preimenujemo. Stara dobivaju neka izmišljena imena, a nova polja se preimenuju u stara.
  • I tek nakon toga pokrećemo novu verziju aplikacije.

A u isto vrijeme nećemo dobiti nadutost i nećemo patiti u pogledu performansi.

Tu treća priča završava.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

https://github.com/dataegret/pg-utils/blob/master/sql/table_bloat.sql

https://github.com/dataegret/pg-utils/blob/master/sql/table_bloat_approx.sql

A sada malo detaljnije o alatima koje sam spomenuo u prvoj priči.

Prije traženja bloat, morate instalirati proširenje pgstattuple.

Kako ne biste morali postavljati upite, te smo upite već napisali u našem radu. Možete ih koristiti. Ovdje postoje dva zahtjeva.

  • Prvom treba dosta vremena da radi, ali će vam pokazati točne vrijednosti nadutosti iz tablice.
  • Drugi djeluje brže i vrlo je učinkovit kada prema tablici treba brzo procijeniti postoji li nadutost ili ne. Također biste trebali razumjeti da je bloat uvijek prisutan u Postgres tablici. Ovo je karakteristika njegovog modela MVCC.
  • A 20% nadutosti je normalno za stolove u većini slučajeva. To jest, ne biste trebali brinuti i komprimirati ovu tablicu.

Shvatili smo kako prepoznati tablice koje su nabujale beskorisnim podacima.

Sada o tome kako riješiti nadutost:

  • Ako imamo mali tablet i dobre diskove, dakle na tabletu do gigabajta, sasvim je moguće koristiti VACUUM FULL. Uzet će vam ekskluzivnu bravu na stolu na nekoliko sekundi i ok, ali će sve učiniti brzo i oštro. Što radi VACUUM FULL? Potrebno je ekskluzivno zaključavanje tablice i prepisuje žive retke iz starih tablica u novu tablicu. I na kraju ih zamijeni. Briše stare datoteke i zamjenjuje stare novima. Ali za vrijeme trajanja svog rada potrebno je isključivo zaključavanje stola. To znači da s ovom tablicom ne možete učiniti ništa: niti pisati u nju, niti čitati u nju, niti je mijenjati. A VACUUM FULL zahtijeva dodatni prostor na disku za pisanje podataka.
  • Sljedeći alat pg_repack. Po svom principu vrlo je sličan VACUUM FULL-u, jer također prepisuje podatke iz starih datoteka u nove i zamjenjuje ih u tablici. Ali pritom ne preuzima ekskluzivno zaključavanje stola na samom početku svog rada, već ga preuzima tek u trenutku kada već ima spremne podatke za zamjenu datoteka. Njegovi zahtjevi za diskovnim resursima slični su onima za VACUUM FULL. Potreban vam je dodatni prostor na disku, a to je ponekad kritično ako imate terabajtne tablice. I dosta je procesorski gladan jer aktivno radi s I/O.
  • Treća korisnost je pgcompacttable. Oprezniji je s resursima jer radi po malo drugačijim principima. Glavna ideja pgcompacttable je da premješta sve žive retke na početak tablice pomoću ažuriranja u tablici. I onda radi vakuum na ovoj tablici, jer znamo da imamo žive redove na početku i mrtve redove na kraju. A sam vakuum odsijeca taj rep, tj. ne zahtijeva puno dodatnog prostora na disku. A u isto vrijeme, još uvijek se može stisnuti u smislu resursa.

Sve uz alat.

Tipične pogreške u aplikacijama koje dovode do nadimanja u postgresqlu. Andrej Salnikov

Ako smatrate da je tema nadutosti zanimljiva u smislu dubljeg zalaženja, evo nekoliko korisnih poveznica:

Pokušao sam više prikazati horor priču za programere, jer su oni naši izravni klijenti baza podataka i moraju razumjeti što i do čega vode akcije. Nadam se da sam uspio. Hvala na pozornosti!

pitanja

Hvala na izvješću! Govorili ste o tome kako možete identificirati probleme. Kako ih se može upozoriti? Odnosno, imao sam situaciju u kojoj su zahtjevi visili ne samo zato što su pristupili nekim vanjskim uslugama. To su bili samo neki divlji spojevi. Bilo je nekih sićušnih, bezopasnih zahtjeva koji su visjeli jedan dan, a onda su počeli raditi neke gluposti. Odnosno, vrlo slično onome što opisujete. Kako to pratiti? Sjediti i stalno gledati koji je zahtjev zapeo? Kako se to može spriječiti?

U ovom slučaju, ovo je zadatak za administratore vaše tvrtke, ne nužno za DBA.

Ja sam administrator.

PostgreSQL ima prikaz pod nazivom pg_stat_activity koji prikazuje viseće upite. I možete vidjeti koliko dugo tamo visi.

Moram li dolaziti i gledati svakih 5 minuta?

Postavite cron i provjerite. Ako imate dugoročni zahtjev, napišite pismo i to je to. Odnosno, ne morate gledati očima, to se može automatizirati. Dobit ćete pismo, reagirat ćete na njega. Ili možete pucati automatski.

Postoje li očiti razlozi zašto se to događa?

Nabrojao sam neke. Ostali složeniji primjeri. I može se dugo razgovarati.

Hvala na izvješću! Htio sam razjasniti o uslužnom programu pg_repack. Ako ne napravi ekskluzivnu bravu, onda...

Ona radi ekskluzivnu bravu.

... tada bih potencijalno mogao izgubiti podatke. Ne bi li moja aplikacija trebala za to vrijeme ništa bilježiti?

Ne, radi glatko s tablicom, tj. pg_repack prvo prenosi sve žive linije koje postoje. Naravno, tu se događa neka vrsta ulaska u tablicu. Samo izbacuje ovaj konjski rep.

Odnosno, on to zapravo na kraju i učini?

Na kraju uzima ekskluzivno zaključavanje kako bi zamijenio te datoteke.

Hoće li biti brži od VACUUM FULL?

VACUUM FULL, čim je krenuo, odmah uzeo ekskluzivnu bravu. I dok sve ne učini, neće je pustiti. A pg_repack uzima ekskluzivno zaključavanje samo u vrijeme zamjene datoteke. U ovom trenutku nećete tamo pisati, ali podaci neće biti izgubljeni, sve će biti u redu.

Zdravo! Govorili ste o radu usisavača za automobile. Tu je bio grafikon s crvenim, žutim i zelenim ćelijama za snimanje. Odnosno žutih – označio ih je kao obrisane. I kao rezultat, u njih se može upisati nešto novo?

Da. Postgres ne briše retke. On ima takvu specifičnost. Ako smo ažurirali redak, označili smo stari kao izbrisan. Tamo se pojavljuje ID transakcije koja je promijenila ovaj redak, a mi pišemo novi redak. I imamo sesije koje bi ih potencijalno mogle pročitati. U nekom trenutku postanu prilično stari. A bit kako autovakuum radi je da prolazi kroz te linije i označava ih kao nepotrebne. I tamo možete prebrisati podatke.

Razumijem. Ali pitanje nije o tome. Nisam završio. Pretpostavimo da imamo stol. Ima polja promjenjive veličine. A ako pokušam umetnuti nešto novo, možda jednostavno neće stati u staru ćeliju.

Ne, u svakom slučaju tamo se ažurira cijela linija. Postgres ima dva modela pohrane podataka. Odabire vrstu podataka. Postoje podaci koji se spremaju izravno u tablicu, a postoje i tos podaci. To su velike količine podataka: tekst, json. Čuvaju se u posebnim tanjurima. I po ovim tabletama se događa ista priča s nadutošću, tj. sve je isto. Oni su samo zasebno navedeni.

Hvala na izvješću! Je li prihvatljivo koristiti upite vremenskog ograničenja izjave za ograničenje trajanja?

Vrlo prihvatljivo. Ovo koristimo posvuda. A budući da nemamo vlastite usluge, pružamo podršku na daljinu, imamo dosta različitih klijenata. I svi su time potpuno zadovoljni. Odnosno, imamo cron poslove koji provjeravaju. Trajanje seansi se jednostavno dogovara s klijentom, prije čega se ne dogovaramo. Može biti minuta, može biti 10 minuta. Ovisi o opterećenju baze i njegovoj namjeni. Ali svi koristimo pg_stat_activity.

Hvala na izvješću! Pokušavam primijeniti vaše izvješće na svoje prijave. I čini se kao da posvuda započinjemo transakciju i posvuda je jasno dovršavamo. Ako postoji neka iznimka, vraćanje se ipak događa. A onda sam počeo razmišljati. Uostalom, transakcija možda neće eksplicitno započeti. Ovo je vjerojatno nagovještaj djevojci. Ako samo ažuriram zapis, hoće li transakcija započeti u PostgreSQL-u i završiti tek kada se veza prekine?

Ako sada govorite o razini aplikacije, onda to ovisi o upravljačkom programu koji koristite, o ORM-u koji se koristi. Tu ima puno postavki. Ako ste omogućili automatsko preuzimanje, tada transakcija počinje tamo i odmah se zatvara.

Odnosno, zatvara se odmah nakon ažuriranja?

Ovisi o postavkama. Imenovao sam jednu postavku. Ovo je uključeno automatsko preuzimanje. Prilično je uobičajeno. Ako je omogućeno, tada je transakcija otvorena i zatvorena. Osim ako ste eksplicitno rekli "započni transakciju" i "završi transakciju", nego ste jednostavno pokrenuli zahtjev u sesiji.

Zdravo! Hvala na izvješću! Zamislimo da imamo bazu podataka koja raste i raste i onda ponestane prostora na poslužitelju. Postoje li alati za popravljanje ove situacije?

Prostor na poslužitelju treba pravilno nadzirati.

Na primjer, DBA je otišao na čaj, bio u odmaralištu itd.

Kada se kreira datotečni sustav, stvara se barem neka vrsta rezervnog prostora gdje se podaci ne zapisuju.

Što ako je potpuno ispod nule?

Tamo se to zove rezervirani prostor, tj. može se osloboditi i ovisno o tome koliko je velik nastao, dobivate slobodan prostor. Standardno ne znam koliko ih ima. A u drugom slučaju isporučite diskove kako biste imali mjesta za rekonstruktivnu operaciju. Možete izbrisati neku tablicu koja vam zajamčeno neće trebati.

Postoje li neki drugi alati?

Uvijek je ručni rad. I lokalno postaje jasno što je tamo najbolje učiniti, jer su neki podaci kritični, a neki nekritični. A za svaku bazu podataka i aplikaciju koja radi s njom, ovisi o poslu. Uvijek se odlučuje lokalno.

Hvala na izvješću! Imam dva pitanja. Prvo ste pokazali slajdove koji su pokazali da kada transakcije zapnu, raste i veličina prostora tablice i veličina indeksa. A dalje u izvješću bila je hrpa uslužnih programa koji pakiraju tablet. Što je s indeksom?

Pakiraju i njih.

Ali vakum ne utječe na indeks?

Neki rade s indeksom. Na primjer, pg_rapack, pgcompacttable. Vakuum ponovno stvara indekse i utječe na njih. S VACUUM FULL-om ideja je prebrisati sve, tj. radi sa svima.

I drugo pitanje. Ne razumijem zašto izvješća o replikama toliko ovise o samoj replikaciji. Činilo mi se da se izvještaji čitaju, a replikacija piše.

Što uzrokuje sukob replikacije? Imamo Učitelja na kojem se odvijaju procesi. U tijeku je usisavanje automobila. Što zapravo radi autovakuum? Reže neke stare retke. Ako u ovom trenutku imamo zahtjev na replici koja čita ove stare retke, a na Masteru se dogodila situacija da je autovacuum označio te retke kao moguće za prebrisanje, onda smo ih prebrisali. I primili smo podatkovni paket, kada trebamo prepisati one retke koje zahtijeva zahtjev na replici, proces replikacije će čekati vremensko ograničenje koje ste konfigurirali. A onda će PostgreSQL odlučiti što mu je važnije. A replikacija mu je važnija od zahtjeva i on će upucati zahtjev kako bi napravio te promjene na replici.

Andrej, imam pitanje. Jesu li ovi divni grafikoni koje ste pokazali tijekom prezentacije rezultat rada nekog vašeg uslužnog programa? Kako su napravljeni grafikoni?

Ovo je usluga Okmetar.

Je li ovo komercijalni proizvod?

Da. Ovo je komercijalni proizvod.

Izvor: www.habr.com

Dodajte komentar