Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Predlagam, da si preberete zapis poročila Andreja Salnikova z začetka leta 2016 »Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql«

V tem poročilu bom analiziral glavne napake v aplikacijah, ki se pojavijo v fazi oblikovanja in pisanja kode aplikacije. In vzel bom samo tiste napake, ki povzročajo napihnjenost v Postgresqlu. Praviloma je to začetek konca delovanja vašega sistema kot celote, čeprav na začetku ni bilo vidnih predpogojev za to.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Z veseljem pozdravljam vse! To poročilo ni tako tehnično kot prejšnje mojega kolega. To poročilo je namenjeno predvsem razvijalcem zalednih sistemov, ker imamo precej veliko število strank. In vsi delajo enake napake. Povedal vam bom o njih. Pojasnil bom, do kakšnih usodnih in slabih stvari vodijo te napake.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Zakaj prihaja do napak? Delajo se iz dveh razlogov: naključno, morda se bo izšlo in zaradi nepoznavanja nekaterih mehanizmov, ki se pojavljajo na ravni med bazo in aplikacijo ter v sami bazi.

Dal vam bom tri primere s strašnimi slikami, kako slabe so stvari šle. Na kratko vam bom povedal o mehanizmu, ki se tam dogaja. In kako z njimi ravnati, kdaj so se zgodile in kakšne preventivne metode uporabiti, da do napak ne pride. Povedal vam bom o pomožnih orodjih in zagotovil uporabne povezave.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Uporabil sem testno bazo podatkov, kjer sem imel dve tabeli. Ena plošča z računi strank, druga s prometom na teh računih. In z določeno pogostostjo posodabljamo stanja na teh računih.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Začetni podatki plošče: je precej majhna, 2 MB. Zelo dober je tudi odzivni čas za bazo podatkov in posebej za znak. In dokaj dobra obremenitev - 2 operacij na sekundo glede na tablico.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

S tem poročilom vam bom pokazal grafe, da boste lahko jasno razumeli, kaj se dogaja. Vedno bosta 2 diapozitiva z grafi. Prvi diapozitiv je tisto, kar se na splošno dogaja na strežniku.

In v tej situaciji vidimo, da imamo res majhen znak. Indeks je majhen, 2 MB. To je prvi graf na levi.

Tudi povprečni odzivni čas na strežniku je stabilen in kratek. To je zgornji desni graf.

Spodnji levi graf prikazuje najdaljše transakcije. Vidimo, da se transakcije hitro zaključijo. In tukaj avtovakuum še ne deluje, ker je bil začetni test. Še naprej bo deloval in nam bo koristil.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Drugi diapozitiv bo vedno namenjen plošči, ki jo preskušamo. V tej situaciji stalno posodabljamo stanje na računu stranke. In vidimo, da je povprečni odzivni čas za operacijo posodobitve precej dober, manj kot milisekunde. Vidimo, da se tudi procesorska sredstva (to je zgornji desni graf) porabljajo enakomerno in precej malo.

Spodnji desni graf prikazuje, koliko operacijskega in diskovnega pomnilnika preletimo v iskanju želene vrstice, preden jo posodobimo. In število operacij glede na znak je 2 na sekundo, kot sem rekel na začetku.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

In zdaj imamo tragedijo. Iz neznanega razloga obstaja dolgo pozabljena transakcija. Razlogi so navadno banalni:

  • Eden najpogostejših je, da smo v kodi aplikacije začeli dostopati do zunanje storitve. In ta služba nam ne odgovarja. Se pravi, odprli smo transakcijo, naredili spremembo v bazi in šli iz aplikacije na branje pošte ali na drugo storitev znotraj naše infrastrukture, pa nam iz nekega razloga ne odgovori. In naša seja je obtičala v stanju, ko ni znano, kdaj bo razrešena.
  • Druga situacija je, ko je iz nekega razloga prišlo do izjeme v naši kodi. In izjemoma nismo obdelali zaključka transakcije. In končali smo s prekinjeno sejo z odprto transakcijo.
  • In zadnje je tudi dokaj pogost primer. To je koda nizke kakovosti. Nekatera ogrodja odprejo transakcijo. Visi in morda v aplikaciji ne veš, da ga imaš.

Kam take stvari vodijo?

Do te mere, da začnejo naše tabele in indeksi dramatično naraščati. To je popolnoma enak učinek napihnjenosti. Za bazo podatkov bo to pomenilo, da se bo odzivni čas baze podatkov zelo povečal in povečala se bo obremenitev strežnika baze podatkov. Posledično bo trpela naša aplikacija. Kajti če ste v svoji kodi porabili 10 milisekund za zahtevo v bazi podatkov, 10 milisekund za svojo logiko, potem je vaša funkcija za dokončanje potrebovala 20 milisekund. In zdaj bo vaš položaj zelo žalosten.

In poglejmo, kaj se zgodi. Spodnji levi graf kaže, da imamo dolgo dolgo transakcijo. In če pogledamo zgornji levi graf, vidimo, da je velikost naše tabele nenadoma poskočila z dveh megabajtov na 300 megabajtov. Hkrati se količina podatkov v tabeli ni spremenila, tj. tam je precej velika količina smeti.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Za več stopenj velikosti se je spremenilo tudi splošno stanje glede povprečnega odzivnega časa strežnika. To pomeni, da so vse zahteve na strežniku začele popolnoma padati. In hkrati so bili sproženi interni procesi Postgres v obliki avtovakuma, ki poskušajo nekaj narediti in porabljajo vire.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Kaj se dogaja z našim znakom? Enako. Naš povprečni odzivni čas glede na predznak je poskočil za nekaj velikosti. Konkretno pri porabljenih virih vidimo, da se je obremenitev procesorja močno povečala. To je zgornji desni graf. Povečalo pa se je, ker mora procesor sortirati kup neuporabnih vrstic v iskanju tiste, ki jo potrebuje. To je spodnji desni graf. In posledično je naše število klicev na sekundo začelo zelo padati, ker baza podatkov ni imela časa za obdelavo enakega števila zahtevkov.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Moramo se vrniti v življenje. Gremo na splet in ugotovimo, da dolge transakcije povzročajo težave. Najdemo in uničimo to transakcijo. In vse nam postaja normalno. Vse deluje kot mora.

Pomirili smo se, čez nekaj časa pa začnemo opažati, da aplikacija ne deluje tako kot pred urgenco. Zahtevki se še vedno obdelujejo počasneje, in to bistveno počasneje. Eno in pol do dvakrat počasneje konkretno v mojem primeru. Tudi obremenitev strežnika je večja, kot je bila pred nesrečo.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

In vprašanje: "Kaj se v tem trenutku dogaja z bazo?" In s podlago se zgodi naslednja situacija. Na transakcijskem grafikonu lahko vidite, da se je ustavil in res ni nobenih dolgoročnih transakcij. Toda velikost znaka se je med nesrečo usodno povečala. In od takrat se niso zmanjšale. Povprečni čas na bazi se je stabiliziral. In zdi se, da odgovori prihajajo ustrezno s hitrostjo, ki je za nas sprejemljiva. Avtovakuum je postal bolj aktiven in začel nekaj delati z znakom, ker mora presejati več podatkov.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Natančneje, glede na testno ploščo z računi, kjer spreminjamo stanja: zdi se, da se je odzivni čas na zahtevo normaliziral. Toda v resnici je enkrat in pol višja.

In iz obremenitve procesorja vidimo, da se obremenitev procesorja ni vrnila na zahtevano vrednost pred sesutjem. In razlogi se skrivajo ravno v spodnjem desnem grafu. Vidi se, da se tam išče določena količina pomnilnika. To pomeni, da za iskanje zahtevane vrstice zapravimo vire strežnika baze podatkov, medtem ko razvrščamo neuporabne podatke. Število transakcij na sekundo se je stabiliziralo.

Na splošno dobro, vendar je stanje slabše, kot je bilo. Jasna degradacija baze podatkov kot posledica naše aplikacije, ki deluje s to bazo podatkov.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

In da bi razumeli, kaj se tam dogaja, če niste bili pri prejšnjem poročilu, si zdaj malo teorije. Teorija o notranjem procesu. Zakaj avtomobilski sesalnik in kaj počne?

Dobesedno na kratko za razumevanje. V nekem trenutku imamo mizo. V tabeli imamo vrstice. Te linije so lahko aktivne, žive in tisto, kar potrebujemo zdaj. Na sliki so označeni z zeleno. In obstajajo skrajne vrstice, ki so že bile obdelane, posodobljene in na njih so se pojavili novi vnosi. In označeni so, da za bazo niso več zanimivi. Vendar so v tabeli zaradi funkcije Postgres.

Zakaj potrebujete avtomobilski sesalnik? Na neki točki pride avtovakuum, dostopa do baze podatkov in jo vpraša: "Prosim, dajte mi ID najstarejše transakcije, ki je trenutno odprta v bazi podatkov." Baza podatkov vrne ta ID. In avtovakuum, ki se zanaša na to, razvrsti vrstice v tabeli. In če vidi, da so bile nekatere vrstice spremenjene z veliko starejšimi transakcijami, potem jih ima pravico označiti kot vrstice, ki jih lahko v prihodnosti ponovno uporabimo tako, da tja zapišemo nove podatke. To je proces v ozadju.

V tem času nadaljujemo z delom z bazo podatkov in nadaljujemo z nekaterimi spremembami v tabeli. In v te vrstice, ki jih lahko ponovno uporabimo, zapišemo nove podatke. In tako dobimo cikel, tj. Ves čas, ko se tam pojavijo mrtve stare vrstice, namesto njih zapišemo nove vrstice, ki jih potrebujemo. In to je normalno stanje za delovanje PostgreSQL.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Kaj se je zgodilo med nesrečo? Kako je potekal ta proces tam?

Imeli smo znak v določenem stanju, nekaj v živo, nekaj mrtvih. Sesalnik za avto je prišel. Bazo podatkov je vprašal, katera je naša najstarejša transakcija in kakšen je njen ID. Prejel sem ta ID, kar bi lahko bilo pred veliko urami, morda pred desetimi minutami. Odvisno je od obremenitve podatkovne baze. In šel je iskat vrstice, ki bi jih lahko označil kot ponovno uporabljene. In v naši tabeli nisem našel takih vrstic.

Toda v tem času nadaljujemo z delom z mizo. V njem nekaj naredimo, posodobimo, spremenimo podatke. Kaj naj baza podatkov stori v tem trenutku? Ne preostane ji drugega, kot da doda nove vrstice na konec obstoječe tabele. In tako se velikost naše mize začne povečevati.

V resnici potrebujemo zelene črte za delovanje. Toda med takim problemom se izkaže, da je odstotek zelenih črt izjemno nizek po celotni tabeli.

In ko izvedemo poizvedbo, mora baza podatkov pregledati vse vrstice: rdeče in zelene, da najde želeno vrstico. Učinek napihnjenosti tabele z neuporabnimi podatki se imenuje "napihnjenost", ki nam prav tako poje prostor na disku. Se spomnite, bilo je 2 MB, postalo je 300 MB? Zdaj spremenite megabajte v gigabajte in hitro boste izgubili vse svoje diskovne vire.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Kakšne posledice bi to lahko imelo za nas?

  • V mojem primeru sta se tabela in indeks povečala 150-krat. Nekatere naše stranke so imele več usodnih primerov, ko jim je preprosto začelo zmanjkovati prostora na disku.
  • Sama velikost tabel se ne bo nikoli zmanjšala. Avtovakuum lahko v nekaterih primerih odreže rep mize, če so samo mrtve črte. A ker je stalno kroženje, lahko ena zelena črta na koncu zamrzne in se ne posodobi, vse ostale pa bodo zapisane nekje na začetku tablice. Toda to je tako malo verjeten dogodek, da se bo vaša miza sama zmanjšala, zato ne smete upati na to.
  • Baza podatkov mora razvrstiti cel kup neuporabnih vrstic. In zapravljamo diskovne vire, zapravljamo procesorske vire in elektriko.
  • In to neposredno vpliva na našo aplikacijo, kajti če smo na začetku porabili 10 milisekund za zahtevo, 10 milisekund za našo kodo, potem smo med zrušitvijo začeli porabiti sekundo za zahtevo in 10 milisekund za kodo, tj. obseg delovanja aplikacije se je zmanjšal. In ko je bila nesreča rešena, smo začeli porabiti 20 milisekund za zahtevo, 10 milisekund za kodo. To pomeni, da smo produktivnost vseeno znižali za XNUMX-krat. In vse to zaradi ene transakcije, ki je zamrznila, morda po naši krivdi.
  • In vprašanje: »Kako vse dobiti nazaj?«, da bo z nami vse v redu in bodo zahteve prihajale tako hitro kot pred nesrečo.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

V ta namen se izvaja določen cikel dela.

Najprej moramo najti problematične mize, ki so napihnjene. Razumemo, da je pri nekaterih tabelah snemanje bolj aktivno, pri drugih manj aktivno. In za to uporabljamo razširitev pgstattuple. Z namestitvijo te razširitve lahko pišete poizvedbe, ki vam bodo pomagale najti tabele, ki so precej napihnjene.

Ko najdete te tabele, jih morate stisniti. Orodja za to že obstajajo. V našem podjetju uporabljamo tri orodja. Prvi je vgrajeni VACUUM FULL. Je krut, oster in neusmiljen, a včasih zelo koristen. Pg_repack и pgcompacttable - To so pripomočki tretjih oseb za stiskanje tabel. In z bazo podatkov ravnajo bolj skrbno.

Uporabljajo se glede na to, kaj vam bolj ustreza. Toda o tem vam bom povedal čisto na koncu. Glavna stvar je, da obstajajo tri orodja. Na izbiro je veliko.

Ko smo vse popravili in se prepričali, da je vse v redu, moramo vedeti, kako to situacijo preprečiti v prihodnosti:

  • Preprečiti ga je mogoče precej enostavno. Na glavnem strežniku morate spremljati trajanje sej. Še posebej nevarne seje v mirovanju v stanju transakcije. To so tisti, ki so pravkar odprli transakcijo, nekaj naredili in odšli ali pa preprosto obviseli, se izgubili v kodi.
  • In za vas, kot razvijalce, je pomembno, da preizkusite svojo kodo, ko se pojavijo te situacije. Ni težko narediti. To bo koristen pregled. Izognili se boste številnim "otročjim" težavam, povezanim z dolgimi transakcijami.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

V teh grafih sem vam želel pokazati, kako sta se znak in obnašanje baze podatkov spremenila, potem ko sem v tem primeru šel skozi znak z VACUUM FULL. To zame ni produkcija.

Velikost tabele se je takoj vrnila v normalno delovno stanje nekaj megabajtov. To ni bistveno vplivalo na povprečni odzivni čas strežnika.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Toda posebej za naš testni znak, kjer smo posodobili stanja na računu, vidimo, da se je povprečni odzivni čas za zahtevo za posodobitev podatkov v znaku zmanjšal na raven pred izrednimi dogodki. Viri, ki jih porabi procesor za dokončanje te zahteve, so prav tako padli na raven pred zrušitvijo. In spodnji desni graf kaže, da zdaj najdemo točno tisto vrstico, ki jo potrebujemo takoj, ne da bi šli skozi kupe mrtvih vrstic, ki so bile tam, preden je bila tabela stisnjena. In povprečni čas zahteve je ostal na približno enaki ravni. Tukaj pa imam napako v strojni opremi.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Tu se prva zgodba konča. Najpogostejši je. In to se zgodi vsem, ne glede na izkušnje naročnika in usposobljenost programerjev. Prej ali slej se to zgodi.

Druga zgodba, v kateri porazdelimo obremenitev in optimiziramo strežniške vire

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

  • Smo že zrasli in postali resni fantje. In razumemo, da imamo repliko in bi bilo dobro, da uravnotežimo obremenitev: pišemo Mojstru in beremo iz replike. In običajno se ta situacija pojavi, ko želimo pripraviti nekatera poročila ali ETL. In podjetja so tega zelo vesela. Resnično želi raznolika poročila z veliko zapletene analitike.
  • Poročila trajajo veliko ur, saj kompleksne analitike ni mogoče izračunati v milisekundah. Mi, kot pogumni fantje, pišemo kodo. V vstavitveni aplikaciji naredimo snemanje na Master, poročila pa izvedemo na repliko.
  • Porazdelitev bremena.
  • Vse deluje odlično. Super smo.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

In kako izgleda ta situacija? Konkretno na teh grafih sem za trajanje transakcije dodal tudi trajanje transakcij iz replike. Vsi ostali grafi se nanašajo samo na glavni strežnik.

Do takrat se je moja poročilna komisija že povečala. Več jih je. Vidimo, da je povprečni odzivni čas strežnika stabilen. Vidimo, da imamo na repliki dolgotrajno transakcijo, ki teče 2 uri. Vidimo tiho delovanje avtovakuma, ki obdeluje mrtve črte. In pri nas je vse v redu.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Natančneje, glede na testirano tablico tam nadaljujemo s posodabljanjem stanja na računih. In imamo tudi stabilen odzivni čas za zahteve, stabilno porabo virov. Pri nas je vse v redu.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Vse je v redu do trenutka, ko se ta poročila začnejo vračati zaradi konflikta z replikacijo. In streljajo nazaj v rednih intervalih.

Gremo na splet in začnemo brati, zakaj se to dogaja. In najdemo rešitev.

Prva rešitev je povečati zakasnitev replikacije. Vemo, da naše poročilo traja 3 ure. Zakasnitev replikacije smo nastavili na 3 ure. Zaženemo vse, vendar imamo še vedno težave s poročili, ki so včasih preklicana.

Želimo, da je vse popolno. Vzpenjamo se naprej. In na internetu smo našli kul nastavitev - hot_standby_feedback. Vklopimo ga. Hot_standby_feedback nam omogoča, da zadržimo avtovakuum na Masterju. Tako se popolnoma znebimo replikacijskih konfliktov. In s poročili nam vse dobro uspeva.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

In kaj se trenutno dogaja z glavnim strežnikom? In imamo popolne težave z glavnim strežnikom. Zdaj vidimo grafe, ko imam omogočeni obe nastavitvi. In vidimo, da je seja na naši replici nekako začela vplivati ​​na stanje na glavnem strežniku. Ima učinek, ker je prekinila avtovakuum, ki počisti mrtve črte. Velikost naše mize je spet poskočila. Tudi povprečni čas izvajanja poizvedbe v celotni zbirki podatkov je skokovito narasel. Avtovakumi so se malo zategnili.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Natančneje, z našega krožnika vidimo, da je tudi posodobitev podatkov na njem skočila v nebo. Podobno se je močno povečala poraba procesorja. Spet gremo skozi veliko število mrtvih, neuporabnih vrstic. Odzivni čas za ta znak in število transakcij sta padla.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Kako bo izgledalo, če ne bomo vedeli, o čem sem prej govoril?

  • Začnemo iskati težave. Če smo v prvem delu naleteli na težave, vemo, da je to lahko posledica dolge transakcije, in pojdimo k Masterju. Imamo problem z Masterjem. Klobasa ga. Se segreje, njegova obremenitev je približno sto.
  • Zahteve so počasne, vendar tam ne vidimo dolgotrajnih transakcij. In ne razumemo, kaj je narobe. Ne razumemo, kje iskati.
  • Preverjamo strežniško opremo. Mogoče se je naš napad ponesrečil. Morda je naš spominski ključ pregorel. Ja, vse se lahko zgodi. Ampak ne, strežniki so novi, vse deluje v redu.
  • Vsi tečejo: skrbniki, razvijalci in direktor. Nič ne pomaga.
  • In na neki točki se vse nenadoma začne popravljati.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

V tem času je bila zahteva za našo repliko obdelana in zapuščena. Prejeli smo poročilo. Posel je še vedno srečen. Kot vidite, je naš znak spet zrasel in se ne namerava zmanjšati. Na grafu s sejami sem pustil delček te dolge transakcije iz replike, da lahko ocenite, koliko časa traja, da se stanje stabilizira.

Seje je konec. In šele čez nekaj časa pride strežnik bolj ali manj v redu. In povprečni odzivni čas za zahteve na glavnem strežniku se vrne v normalno stanje. Ker ima končno avtovakuum možnost, da počisti in označi te slepe črte. In začel je opravljati svoje delo. In kako hitro to naredi, tako hitro se bomo spravili v red.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Glede na preizkušeno tablico, kjer posodabljamo stanje na računu, vidimo popolnoma enako sliko. Tudi povprečni čas posodobitve računa se postopoma normalizira. Zmanjšajo se tudi viri, ki jih porabi procesor. In število transakcij na sekundo se vrne v normalno stanje. Ampak spet smo spet v normalnem stanju, ne več isti kot smo bili pred nesrečo.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

V vsakem primeru dobimo zmanjšanje zmogljivosti, kot v prvem primeru, za en in pol do dvakrat, včasih pa tudi več.

Zdi se, da smo naredili vse prav. Razporedite obremenitev. Oprema ne miruje. Zahteve smo razdelili po svoji pameti, a se je vseeno vse slabo izšlo.

  • Ne omogočite hot_standby_feedback? Da, ni priporočljivo, da ga vklopite brez posebej močnih razlogov. Ker ta zasuk neposredno vpliva na glavni strežnik in prekine delovanje avtovakuma tam. Če ga omogočite na neki repliki in pozabite nanj, lahko ubijete Master in imate velike težave z aplikacijo.
  • Povečati max_standby_streaming_delay? Da, za poročila je to res. Če imate triurno poročilo in ne želite, da se zruši zaradi konfliktov replikacije, preprosto povečajte zakasnitev. Dolgoročno poročilo nikoli ne zahteva podatkov, ki so trenutno prispeli v bazo podatkov. Če ga imate tri ure, potem ga uporabljate za neko staro podatkovno obdobje. In za vas ne bo pomembno, ali bo prišlo do triurne ali šesturne zamude, vendar boste poročila prejemali dosledno in ne boste imeli težav z njihovim padcem.
  • Seveda morate nadzorovati dolge seje na replikah, še posebej, če se odločite omogočiti hot_standby_feedback na repliki. Kajti vse se lahko zgodi. To repliko smo dali razvijalcu, da je lahko preizkusil zahteve. Napisal je noro prošnjo. Zagnal ga je in šel piti čaj in dobili smo uveljavljenega Mojstra. Ali pa smo morda noter vstavili napačno aplikacijo. Situacije so različne. Seje na replikah je treba spremljati enako skrbno kot na Masterju.
  • In če imate hitre in dolge poizvedbe o replikah, je v tem primeru bolje, da jih razdelite, da porazdelite obremenitev. To je povezava do streaming_delay. Za hitre imejte eno repliko z majhno zakasnitvijo replikacije. Za dolgotrajne zahteve za poročanje imejte repliko, ki lahko zaostaja 6 ur ali en dan. To je povsem normalna situacija.

Posledice odpravimo na enak način:

  • Najdemo napihnjene mize.
  • In stisnemo ga z najbolj priročnim orodjem, ki nam ustreza.

Druga zgodba se tukaj konča. Preidimo k tretji zgodbi.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Tudi pri nas, kjer se selimo, je precej običajno.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

  • Vsak programski izdelek raste. Zahteve zanj se spreminjajo. V vsakem primeru se želimo razvijati. In zgodi se, da moramo posodobiti podatke v tabeli, in sicer zagnati posodobitev v smislu naše migracije za novo funkcionalnost, ki jo uvajamo v okviru našega razvoja.
  • Stari format podatkov ni zadovoljiv. Recimo, da se zdaj obrnemo na drugo tabelo, kjer imam transakcije na teh računih. In recimo, da so bili v rubljih, in odločili smo se, da povečamo natančnost in to storimo v kopejkah. In za to moramo izvesti posodobitev: polje z zneskom transakcije pomnožimo s sto.
  • V današnjem svetu uporabljamo avtomatizirana orodja za nadzor različic baze podatkov. Recimo Liquibase. Tam registriramo svojo selitev. Preizkušamo ga na naši testni bazi. Vse je vredu. Posodobitev poteka. Za nekaj časa blokira delo, vendar dobimo posodobljene podatke. In na tem lahko lansiramo novo funkcionalnost. Vse je bilo testirano in preverjeno. Vse je bilo potrjeno.
  • Izvajali smo načrtno delo in izvedli selitev.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Tukaj je selitev s posodobitvijo, ki je predstavljena pred vami. Ker so to transakcije mojega računa, je bila plošča 15 GB. In ker posodobimo vsako vrstico, smo s posodobitvijo podvojili velikost tabele, ker smo vsako vrstico prepisali.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Med selitvijo s to ploščo nismo mogli storiti ničesar, ker so bile vse zahteve zanjo postavljene v čakalno vrsto in so čakale, dokler se ta posodobitev ne zaključi. Tukaj pa želim opozoriti na številke, ki so na navpični osi. To pomeni, da imamo povprečni čas zahteve pred selitvijo približno 5 milisekund in obremenitev procesorja, število blokovnih operacij za branje diskovnega pomnilnika je manjše od 7,5.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Izvedli smo selitev in spet naleteli na težave.

Selitev je bila uspešna, vendar:

  • Dokončanje stare funkcije zdaj traja dlje.
  • Miza se je spet povečala.
  • Obremenitev strežnika je spet postala večja kot prej.
  • In seveda se še vedno ukvarjamo s funkcionalnostjo, ki je dobro delovala, malo smo jo izboljšali.

In to je spet napihnjenost, ki nam spet greni življenje.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Tukaj dokazujem, da se tabela, tako kot prejšnja dva primera, ne bo vrnila na prejšnje velikosti. Povprečna obremenitev strežnika se zdi primerna.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

In če se obrnemo na tabelo z računi, bomo videli, da se je povprečni čas zahteve za to tabelo podvojil. Obremenitev procesorja in število vrstic, razvrščenih v pomnilnik, je poskočilo nad 7,5, a je bilo nižje. In pri procesorjih je poskočil 2-krat, pri bločnih operacijah 1,5-krat, torej dobili smo poslabšanje delovanja strežnika. In kot rezultat - poslabšanje delovanja naše aplikacije. Hkrati je število klicev ostalo približno na enaki ravni.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

In glavna stvar tukaj je razumeti, kako pravilno izvajati takšne migracije. In jih je treba narediti. Te selitve izvajamo precej dosledno.

  • Tako velike selitve se ne zgodijo samodejno. Vedno morajo biti pod nadzorom.
  • Potreben je nadzor usposobljene osebe. Če imate v svoji ekipi DBA, naj to stori DBA. To je njegovo delo. Če ne, naj to naredi najbolj izkušena oseba, ki se spozna na delo z bazami podatkov.
  • Novo shemo baze podatkov, tudi če posodobimo en stolpec, vedno pripravimo po stopnjah, torej vnaprej, preden se uvede nova različica aplikacije:
  • Dodana so nova polja, v katera bomo beležili posodobljene podatke.
  • Podatke iz starega polja v novo polje prenašamo v majhnih delih. Zakaj to počnemo? Prvič, vedno nadzorujemo proces tega procesa. Vemo, da smo toliko serij že prenesli in da nam jih je še toliko ostalo.
  • In drugi pozitivni učinek je, da med vsakim takšnim paketom transakcijo zapremo, odpremo novo in to omogoča, da avtovakuum deluje po tablici, označimo roke za ponovno uporabo.
  • Za vrstice, ki se bodo pojavile med delovanjem aplikacije (še vedno imamo zagnano staro aplikacijo), dodamo sprožilec, ki zapiše nove vrednosti v nova polja. V našem primeru je to množenje stare vrednosti s sto.
  • Če smo popolnoma trmasti in želimo isto polje, potem po končanih vseh migracijah in pred uvedbo nove različice aplikacije polja enostavno preimenujemo. Stara dobijo neko izmišljeno ime, nova polja pa preimenujejo v stara.
  • In šele po tem zaženemo novo različico aplikacije.

In hkrati ne bomo dobili napihnjenosti in ne bomo trpeli glede zmogljivosti.

Tu se tretja zgodba konča.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. 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

In zdaj malo več podrobnosti o orodjih, ki sem jih omenil v prvi zgodbi.

Preden iščete bloat, morate namestiti razširitev pgstattuple.

Da vam ne bo treba postavljati poizvedb, smo te poizvedbe že zapisali v našem delu. Lahko jih uporabite. Tukaj sta dve zahtevi.

  • Prvi traja precej dolgo, da deluje, vendar vam bo pokazal natančne vrednosti napihnjenosti iz tabele.
  • Drugi deluje hitreje in je zelo učinkovit, ko je treba po tabeli hitro oceniti, ali je napihnjenost ali ne. Prav tako morate razumeti, da je napihnjenost vedno prisotna v tabeli Postgres. To je značilnost njegovega modela MVCC.
  • In 20% napihnjenost je v večini primerov normalna za mize. Se pravi, ne bi smeli skrbeti in stiskati te tabele.

Ugotovili smo, kako prepoznati tabele, ki so polne neuporabnih podatkov.

Zdaj pa o tem, kako odpraviti napihnjenost:

  • Če imamo majhno tablico in dobre diske, torej na tablici do gigabajta, je čisto možno uporabiti VACUUM FULL. Za nekaj sekund vam bo vzel ekskluzivno ključavnico na mizi in v redu, vendar bo vse naredil hitro in ostro. Kaj počne VACUUM FULL? Potrebuje ekskluzivno zaklepanje tabele in prepisuje žive vrstice iz starih tabel v novo tabelo. In na koncu jih zamenja. Izbriše stare datoteke in zamenja stare z novimi. Toda za čas svojega dela potrebuje izključno ključavnico na mizi. To pomeni, da s to tabelo ne morete narediti ničesar: niti pisati vanjo, niti brati vanjo, niti je spreminjati. In VACUUM FULL zahteva dodaten prostor na disku za zapisovanje podatkov.
  • Naslednje orodje pg_repack. Po svojem principu je zelo podoben VACUUM FULL, saj prav tako prepisuje podatke iz starih datotek v nove in jih nadomešča v tabeli. Toda hkrati ne prevzame ekskluzivne ključavnice na mizi na samem začetku svojega dela, ampak jo prevzame šele v trenutku, ko ima že pripravljene podatke za zamenjavo datotek. Njegove zahteve glede diskovnih sredstev so podobne tistim za VACUUM FULL. Potrebujete dodaten prostor na disku, kar je včasih kritično, če imate terabajtne tabele. In je precej procesorsko požrešen, ker aktivno deluje z I/O.
  • Tretji pripomoček je pgcompacttable. Z viri je bolj previden, ker deluje po nekoliko drugačnih principih. Glavna ideja pgcompacttable je, da premakne vse žive vrstice na začetek tabele z uporabo posodobitev v tabeli. In potem na tej tabeli zažene vakuum, ker vemo, da imamo žive vrstice na začetku in mrtve vrstice na koncu. In sam vakuum odreže ta rep, torej ne zahteva veliko dodatnega prostora na disku. In hkrati ga je mogoče še stiskati glede sredstev.

Vse z orodjem.

Tipične napake v aplikacijah, ki povzročajo napihnjenost v postgresql. Andrej Salnikov

Če se vam zdi tema o napihnjenosti zanimiva v smislu nadaljnjega poglabljanja, je tukaj nekaj uporabnih povezav:

Poskušal sem bolj prikazati grozljivo zgodbo za razvijalce, ker so naše neposredne stranke baz podatkov in morajo razumeti, kaj in do katerih dejanj vodi. Upam da mi je uspelo. Hvala za vašo pozornost!

vprašanja

Hvala za poročilo! Govorili ste o tem, kako lahko prepoznate težave. Kako jih je mogoče opozoriti? Se pravi, imel sem situacijo, ko so zahteve visele ne samo zato, ker so dostopali do nekaterih zunanjih storitev. To so bili le neki divji spoji. Bilo je nekaj drobnih, neškodljivih prošenj, ki so ležale en dan, potem pa so začele početi neumnosti. Se pravi, zelo podobno temu, kar opisujete. Kako temu slediti? Sedite in nenehno opazujte, katera zahteva se je zataknila? Kako to preprečiti?

V tem primeru je to naloga za skrbnike vašega podjetja, ne nujno za DBA.

Sem administrator.

PostgreSQL ima pogled, imenovan pg_stat_activity, ki prikazuje viseče poizvedbe. In lahko vidite, kako dolgo visi tam.

Ali moram priti in pogledat vsakih 5 minut?

Nastavite cron in preverite. Če imate dolgoročno zahtevo, napišite pismo in to je to. To pomeni, da vam ni treba gledati z očmi, lahko je avtomatizirano. Prejeli boste pismo, nanj se boste odzvali. Lahko pa streljate samodejno.

Ali obstajajo očitni razlogi, zakaj se to zgodi?

Nekatere sem naštel. Drugi bolj zapleteni primeri. In pogovor lahko traja dolgo časa.

Hvala za poročilo! Želel sem pojasniti o pripomočku pg_repack. Če ne naredi ekskluzivnega zaklepanja, potem ...

Dela ekskluzivno ključavnico.

... potem bi lahko potencialno izgubil podatke. Ali naj moja aplikacija v tem času ne beleži ničesar?

Ne, s tabelo deluje gladko, tj. pg_repack najprej prenese vse žive vrstice, ki obstajajo. Seveda pride do neke vrste vstopa v tabelo. Samo vrže ta čop ven.

Se pravi, na koncu to dejansko naredi?

Na koncu vzame ekskluzivno ključavnico za zamenjavo teh datotek.

Bo hitrejši od VACUUM FULL?

VACUUM FULL, takoj ko se je začelo, takoj vzel ekskluzivno ključavnico. In dokler ne naredi vsega, je ne bo izpustil. In pg_repack se ekskluzivno zaklene samo v času zamenjave datoteke. V tem trenutku tam ne boste pisali, vendar podatki ne bodo izgubljeni, vse bo v redu.

Zdravo! Govorili ste o delovanju avtomobilskega sesalnika. Tam je bil graf z rdečimi, rumenimi in zelenimi snemalnimi celicami. Se pravi rumene - označil jih je za izbrisane. In posledično se lahko vanje zapiše kaj novega?

ja Postgres ne briše vrstic. Ima takšno specifičnost. Če smo posodobili vrstico, smo staro označili kot izbrisano. Tam se pojavi ID transakcije, ki je spremenila to vrstico, in napišemo novo vrstico. In imamo seje, ki bi jih potencialno lahko prebrale. Na neki točki postanejo precej stari. In bistvo delovanja avtovakuma je, da gre skozi te črte in jih označi kot nepotrebne. In tam lahko prepišete podatke.

Razumem. Vendar vprašanje ni o tem. Nisem končal. Recimo, da imamo mizo. Ima polja spremenljive velikosti. In če poskušam vstaviti nekaj novega, se morda preprosto ne prilega stari celici.

Ne, v vsakem primeru se tam posodobi celotna linija. Postgres ima dva modela shranjevanja podatkov. Izbira med vrstami podatkov. Obstajajo podatki, ki so shranjeni neposredno v tabeli, in obstajajo tudi tos podatki. To so velike količine podatkov: tekst, json. Shranjeni so v ločenih krožnikih. In glede na te tablete se zgodi ista zgodba z napihnjenostjo, torej je vse po starem. Samo navedeni so ločeno.

Hvala za poročilo! Ali je sprejemljivo uporabljati poizvedbe o časovni omejitvi izjave za omejitev trajanja?

Zelo sprejemljivo. To uporabljamo povsod. In ker nimamo svojih storitev, nudimo podporo na daljavo, imamo precej različnih strank. In s tem so vsi popolnoma zadovoljni. To pomeni, da imamo opravila cron, ki preverjajo. Trajanje srečanj se preprosto dogovori s stranko, pred tem pa se ne dogovarjamo. Lahko je minuta, lahko 10 minut. Odvisno je od obremenitve podlage in njenega namena. Toda vsi uporabljamo pg_stat_activity.

Hvala za poročilo! Vaše poročilo poskušam uporabiti pri svojih aplikacijah. In zdi se, kot da transakcijo začnemo povsod in jo jasno zaključimo povsod. Če obstaja kakšna izjema, se vrnitev še vedno zgodi. In potem sem začel razmišljati. Navsezadnje se transakcija morda ne bo začela izrecno. To je verjetno namig dekletu. Če samo posodobim zapis, ali se bo transakcija začela v PostgreSQL in dokončala šele, ko bo povezava prekinjena?

Če zdaj govorite o ravni aplikacije, je to odvisno od gonilnika, ki ga uporabljate, od ORM, ki se uporablja. Tam je veliko nastavitev. Če imate omogočeno samodejno potrditev, se transakcija začne tam in takoj zapre.

Se pravi, da se zapre takoj po posodobitvi?

Odvisno od nastavitev. Eno nastavitev sem poimenoval. To je samodejna zaveza. To je precej pogosto. Če je omogočeno, je transakcija odprta in zaprta. Razen če ste izrecno rekli "začetek transakcije" in "končanje transakcije", ampak preprosto sprožili zahtevo v sejo.

Zdravo! Hvala za poročilo! Predstavljajmo si, da imamo podatkovno bazo, ki narašča in narašča, nato pa zmanjka prostora na strežniku. Ali obstajajo kakšna orodja za rešitev te situacije?

Prostor na strežniku je treba ustrezno nadzorovati.

Na primer, DBA je šel na čaj, bil v letovišču itd.

Ko se ustvari datotečni sistem, se ustvari vsaj nekakšen rezervni prostor, kamor se podatki ne zapisujejo.

Kaj pa, če je popolnoma pod ničlo?

Tam se imenuje rezerviran prostor, kar pomeni, da se lahko sprosti in glede na to, kako velik je bil ustvarjen, dobite prosti prostor. Privzeto ne vem, koliko jih je. In v drugem primeru dostavite diske, da imate prostor za izvedbo rekonstruktivne operacije. Izbrišete lahko nekatere tabele, ki jih zagotovo ne boste potrebovali.

Ali obstajajo še kakšna druga orodja?

Vedno je ročno delo. In lokalno postane jasno, kaj je tam najbolje storiti, ker so nekateri podatki kritični, nekateri pa niso kritični. Za vsako bazo podatkov in aplikacijo, ki z njo dela, je odvisno od posla. Vedno se odloča lokalno.

Hvala za poročilo! Imam dve vprašanji. Najprej ste pokazali diapozitive, ki so pokazali, da ko se transakcije zataknejo, povečata tako velikost prostora tabel kot velikost indeksa. In nadaljevanje poročila je bilo kup pripomočkov, ki pakirajo tablico. Kaj pa indeks?

Pakirajo jih tudi.

A vakuum ne vpliva na indeks?

Nekateri delajo z indeksom. Na primer, pg_rapack, pgcompacttable. Vakuum ponovno ustvari indekse in vpliva nanje. Z VACUUM FULL je ideja prepisati vse, kar pomeni, da deluje z vsemi.

In drugo vprašanje. Ne razumem, zakaj so poročila o replikah tako odvisna od same replikacije. Zdelo se mi je, da se poročila berejo, replikacija pa piše.

Kaj povzroča konflikt replikacije? Imamo Mojstra, na katerem potekajo procesi. Imamo sesanje avtomobila. Kaj pravzaprav počne avtovakuum? Reže nekaj starih vrstic. Če imamo v tem trenutku zahtevo na replici, ki bere te stare vrstice, na Masterju pa se je zgodila situacija, da je avtovakuum te vrstice označil kot možne za prepisovanje, potem smo jih prepisali. Prejeli smo podatkovni paket, ko moramo na repliko prepisati tiste vrstice, ki jih zahteva zahteva, bo postopek replikacije čakal na časovno omejitev, ki ste jo konfigurirali. In potem se bo PostgreSQL odločil, kaj mu je bolj pomembno. In replikacija mu je pomembnejša od zahteve, in on bo posnel zahtevo, da bi naredil te spremembe na repliki.

Andrej, imam vprašanje. Ali so ti čudoviti grafi, ki ste jih pokazali med predstavitvijo, rezultat dela kakšnega vašega pripomočka? Kako so bili narejeni grafi?

To je storitev Okmeter.

Je to komercialni izdelek?

ja To je komercialni izdelek.

Vir: www.habr.com

Dodaj komentar