Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Teen ettepaneku lugeda Andrei Salnikovi 2016. aasta alguse raporti "Tüüpilised vead rakendustes, mis viivad postgresql-i paisumiseni" ärakirja.

Käesolevas aruandes analüüsin peamisi vigu rakendustes, mis ilmnevad rakenduse koodi kujundamise ja kirjutamise etapis. Ja ma võtan ainult need vead, mis põhjustavad Postgresqli paisumist. See on reeglina teie süsteemi kui terviku jõudluse lõpu algus, kuigi esialgu selleks eeldusi ei nähtud.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Rõõm tervitada kõiki! See aruanne ei ole nii tehniline kui mu kolleegi eelmine raport. See jutt on suunatud taustasüsteemide arendajatele eelkõige seetõttu, et meil on küllaltki palju kliente. Ja nad kõik teevad samu vigu. Ma räägin teile neist. Selgitan, milleni need vead saatuslikuks ja halvaks viivad.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Miks tehakse vigu? Neid tehakse kahel põhjusel: juhuslikult, võib-olla töötab see teadmatusest mõne baasi ja rakenduse vahelisel tasemel, aga ka baasis endas esinevate mehhanismide suhtes.

Toon kolm näidet koos kohutavate piltidega, kuidas asjad halvaks läksid. Kirjeldan lühidalt seal esinevat mehhanismi. Ja kuidas nendega toime tulla, millal need juhtusid ja milliseid ennetusmeetodeid kasutada vigade vältimiseks. Räägin teile abivahenditest ja annan kasulikke linke.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Kasutasin testandmebaasi, kus oli kaks tabelit. Üks plaat kliendikontodega, teine ​​nende kontode toimingutega. Ja teatud perioodilisusega värskendame nende kontode saldosid.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Plaadi algandmed: see on üsna väike, 2 MB. Väga hea on ka andmebaasi ja konkreetselt plaadi reageerimisaeg. Ja üsna hea koormus - 2 toimingut sekundis plaadil.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja selle aruande kaudu näitan teile graafikuid, et oleks selge, mis toimub. Alati on 2 slaidi graafikutega. Esimene slaid on see, mis serveris üldiselt toimub.

Ja selles olukorras näeme, et meil on tõesti väike taldrik. Indeks on väike, 2 MB. See on esimene vasakpoolne diagramm.

Keskmine reageerimisaeg kogu serveris on samuti stabiilne, väike. See on ülemine parem graafik.

Alumine vasak graafik on pikimad tehingud. Näeme, et tehingud valmivad kiiresti. Ja autovaakum siin veel ei tööta, sest - see oli start-test. Siis see toimib ja on meile kasulik.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Teine slaid on alati pühendatud katseplaadile. Selles olukorras uuendame pidevalt kliendi kontojääke. Ja me näeme, et keskmine reageerimisaeg värskendusoperatsioonil on üsna hea, alla millisekundi. Näeme, et protsessori ressursse (see on ülemine parem graafik) kulub samuti ühtlaselt ja üsna vähe.

Alumine parem graafik näitab, kui palju töö- ja kettamälu me soovitud rea otsimisel enne selle värskendamist läbime. Ja operatsioonide arv plaadil on 2 sekundis, nagu ma alguses ütlesin.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja nüüd on meil tragöödia. Millegipärast toimub ammu unustatud tehing. Põhjused on tavaliselt banaalsed:

  • Üks levinumaid on see, et alustasime rakenduse koodis juurdepääsu välisele teenusele. Ja see teenus ei vasta meile. See tähendab, et avasime tehingu, tegime andmebaasis muudatuse ja läksime rakendusest e-kirjade lugemisse või mõnele muule meie infrastruktuuri teenusele ning see mingil põhjusel ei vasta meile. Ja meie seanss rippus olekus - pole teada, millal see laheneb.
  • Teine olukord on see, kui meie koodis tekkis mingil põhjusel erand. Ja me ei töötlenud tehingu sulgemist erandis. Ja saime avatud tehinguga rippumise.
  • Ja viimane on ka üsna tavaline. See on halva kvaliteediga kood. Mõned raamistikud avavad tehingu. See ripub ja te ei pruugi rakenduses teada, et see ripub.

Kuhu sellised asjad viivad?

Sellele, et meie tabelid ja indeksid hakkavad hüppeliselt paisuma. See on täpselt sama puhitusefekt. Andmebaasi puhul väljendub see selles, et meil kasvab väga järsult andmebaasi reageerimisaeg, suureneb andmebaasiserveri koormus. Ja selle tulemusena kannatab meie rakendus. Sest kui oma koodis kulutasite andmebaasi päringu peale 10 millisekundit, loogikale 10 millisekundit, siis teie funktsioon töötas 20 millisekundit. Ja nüüd on teie olukord väga kurb.

Ja vaatame, mis juhtub. Alumine vasak graafik näitab, et meil on pikk pikk tehing. Ja kui vaatame ülemist vasakpoolset graafikut, näeme, et tabeli suurus hüppas kahelt megabaidilt 300 megabaidile. Samal ajal pole tabelis olevate andmete hulk muutunud, see tähendab, et prügi on üsna palju.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Mitme suurusjärgu võrra on muutunud ka üldine olukord serveri keskmise reageerimisaja osas. See tähendab, et kõik serveris olevad päringud hakkasid täielikult langema. Ja samal ajal käivitati autovaakumiga silmitsi seisvad Postgresi sisemised protsessid, mis üritavad midagi ära teha ja ressursse kulutada.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Mis saab meie taldrikust? Sama. Tahvelarvuti keskmine reageerimisaeg hüppas mitu suurusjärku. Kui konkreetselt tarbitud ressursside osas, siis näeme, et protsessori koormus on kõvasti kasvanud. See on ülemine parem graafik. Ja see on suurenenud, kuna protsessor peab vajaliku otsimisel läbima hulga kasutuid ridu. See on alumine parempoolne graafik. Selle tulemusena hakkas kõnede arv sekundis väga langema, kuna andmebaasil pole aega sama arvu taotluste töötlemiseks.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Peame ellu tagasi pöörduma. Ronime internetti ja saame teada, et pikad tehingud toovad kaasa probleemi. Leiame ja tapame selle tehingu. Ja meil läheb kõik hästi. Kõik töötab nii nagu peab.

Rahunesime maha, kuid mõne aja pärast hakkame märkama, et rakendus ei tööta nii nagu enne hädaolukorda. Taotlusi töödeldakse aeglasemalt ja palju aeglasemalt. Minu näites poolteist kuni kaks korda aeglasem. Samuti on serveri koormus suurem kui enne õnnetust.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja küsimus: "Mis juhtub baasiga sel hetkel?". Ja aluseks on järgmine olukord. Tehingute graafikul on näha, et see on peatunud ja pikaajalisi tehinguid tõesti ei ole. Kuid plaadi mõõtmed kasvasid õnnetuse ajal saatuslikult. Ja sellest ajast peale pole see vähenenud. Keskmine baasil oldud aeg on stabiliseerunud. Ja vastused näivad minevat meile vastuvõetava kiirusega adekvaatselt. Autovaakum muutus aktiivsemaks ja hakkas tahvelarvutiga midagi ette võtma, sest see vajab rohkem andmeid.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Täpsemalt testi tulemustabelil, kus vahetame saldosid: päringu reageerimisaeg näib olevat normaliseerunud. Aga tegelikult on see poolteist korda suurem.

Ja protsessori koormuse järgi näeme, et protsessori koormus ei taastunud enne krahhi soovitud väärtuseni. Ja põhjused peituvad just alumises paremas graafikus. On näha, et otsitakse mingit mälumahtu. See tähendab, et soovitud rea otsimiseks kulutame kasutute andmete sortimisel andmebaasiserveri ressursse. Tehingute arv sekundis on stabiliseerunud.

Üldiselt hea, aga olukord on hullem kui oli. Andmebaasi selge halvenemine selle andmebaasiga töötava rakenduse tõttu.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja selleks, et aru saada, mis seal toimub, kui te ei olnud eelmise raporti juures, siis nüüd natuke teooriat. Teooria sisemise protsessi kohta. Miks autovaakum ja mida see teeb?

Sõna otseses mõttes mõistmiseks. Mingil ajahetkel on meil laud. Meil on tabelis read. Need liinid võivad olla aktiivsed, elada, vajame kohe. Pildil on need märgitud rohelisega. Ja on surnud ridu, mis on juba välja töötatud, värskendatud, neile on ilmunud uued sissekanded. Ja neile on märgitud, et nad pole andmebaasi jaoks enam huvitavad. Aga need lebavad tabelis Postgresi iseärasuste tõttu.

Miks vajate autovaakumit? Autovaakum tuleb mingil hetkel, helistab andmebaasi ja küsib: "Palun andke mulle vanima tehingu ID, mis hetkel andmebaasis on avatud." Andmebaas tagastab selle ID. Ja autovaakum, tuginedes sellele, läbib tabeli ridu. Ja kui ta näeb, et mõni rida on muutunud palju vanemate tehingutega, siis on tal õigus need ridadeks märkida, mida saame edaspidi taaskasutada, kirjutades sinna uued andmed. See on taustprotsess.

Praegu jätkame tööd andmebaasiga, jätkame tabelis mõningate muudatuste tegemist. Ja nendele ridadele, mida saame taaskasutada, kirjutame uued andmed. Ja nii saame tsükli ehk sinna tekivad kogu aeg mingid surnud vanad read, nende asemele kirjutame üles uued, mida vajame. Ja see on PostgreSQL-i töö normaalne olek.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Mis juhtus õnnetuse ajal? Kuidas see protsess toimus?

Meil oli taldrik mõnes seisukorras, osa elus, osa surnud. Autovaakum on saabunud. Ta küsis andmebaasist, mis on meie vanim tehing, mis on selle id. Sain selle ID, mis võib olla mitu tundi vana, võib-olla kümme minutit vana. See sõltub sellest, kui suur koormus teil andmebaasis on. Ja ta läks otsima ridu, mida saab taaskasutatuks märkida. Ja selliseid ridu ma meie tabelist ei leidnud.

Kuid praegu jätkame tööd tabeliga. Teeme selles midagi, uuendame seda, muudame andmeid. Mida peaks andmebaas praegu tegema? Tal ei jää muud üle, kui lisada olemasoleva tabeli lõppu uued read. Ja seega hakkab tabeli suurus meie juures paisuma.

Meil on tõesti töötamiseks vaja rohelisi jooni. Kuid sellise probleemi käigus selgub, et roheliste joonte osakaal on kogu tabeli mahus äärmiselt madal.

Ja kui täidame päringu, peab andmebaas õige rea leidmiseks läbima kõik read, nii punased kui ka rohelised. Ja tabeli kasutute andmetega paisutamise efekti nimetatakse "paisutamiseks", mis sööb ka meie kettaruumi. Mäletate, see oli 2 MB, nüüd on see 300 MB? Nüüd muutke megabaidid gigabaitideks ja kaotate üsna kiiresti kõik oma kettaressursid.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Millised on selle tagajärjed meile?

  • Minu näites on tabel ja indeks kasvanud 150 korda. Mõnel meie kliendil on olnud fataalsemaid juhtumeid, kui kettaruum hakkas lihtsalt otsa saama.
  • Tabelid ei vähene kunagi iseenesest. Autovaakum võib mõnel juhul laua saba ära lõigata, kui on ainult surnud read. Aga kuna seal on pidev pöörlemine, siis võib üks roheline joon otsas rippuda ja seda ei uuendata ning kõik ülejäänu kuskil plaadi alguses salvestatakse. Kuid see on nii ebatõenäoline sündmus, et teie laud ise väheneb, nii et te ei tohiks sellele loota.
  • Andmebaas peab sorteerima läbi terve hunniku kasutuid ridu. Ja me raiskame kettaressursse, raiskame protsessoriressursse ja elektrit.
  • Ja see mõjutab otseselt meie rakendust, sest kui alguses kulutasime päringule 10 millisekundit, koodile 10 millisekundit, siis krahhi ajal hakkasime kulutama sekundi päringule ja 10 millisekundit koodile, st järjestuses rakenduste jõudlus vähenes. Ja kui õnnetus lahenes, hakkasime kulutama 20 millisekundit päringu kohta, 10 millisekundit koodi kohta. See tähendab, et jõudluse poolest vajusime ikkagi poolteist korda. Ja see kõik on ühe tehingu tõttu, mis rippus, ja võib-olla meie süül.
  • Ja küsimus: “Kuidas ma kõik tagasi saan?” Et meiega oleks kõik korras ja taotlused jooksevad sama kiiresti kui enne õnnetust.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Selleks on ette nähtud teatud töötsükkel.

Kõigepealt tuleb üles leida probleemsed tabelid, mis on ülespuhutud. Mõistame, et mõned tabelid salvestavad aktiivsemalt, mõned vähem aktiivselt. Ja selleks kasutame laiendit pgstattuple. Selle laienduse installimisel saate kirjutada päringuid, mis aitavad teil leida piisavalt ülespuhutud tabeleid.

Kui olete need tabelid leidnud, tuleb need kokku suruda. Selleks on juba vahendid olemas. Meie ettevõttes kasutame kolme tööriista. Esimene on sisseehitatud VACUUM FULL. Ta on julm, karm ja halastamatu, kuid mõnikord on ta väga kasulik. pg_repack и pgkompaktable on kolmanda osapoole utiliidid tabelite tihendamiseks. Ja nad on andmebaasi suhtes ettevaatlikumad.

Neid kasutatakse sõltuvalt sellest, mis on teile mugavam. Aga sellest räägin ma päris lõpus. Peaasi, et tööriistu on kolm. Valida on palju.

Pärast seda, kui oleme kõik parandanud ja veendunud, et kõik on korras, peaksime teadma, kuidas seda olukorda tulevikus vältida:

  • Seda on üsna lihtne ennetada. Peate peaserveris seansside kestust jälgima. Eriti ohtlikud seansid tehinguolekus jõudeolekus. Need on need, kes lihtsalt avasid tehingu, tegid midagi ja lahkusid või lihtsalt rippusid, läksid koodi vahele.
  • Ja teie kui arendajate jaoks on oluline koodi testida nende olukordade ilmnemisel. Seda pole raske teha. See on kasulik kontroll. Väldid paljusid "lapselikke" probleeme, mis on seotud pikkade tehingutega.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Nendel graafikutel tahtsin teile näidata, kuidas tabel ja andmebaasi käitumine muutusid pärast seda, kui ma antud juhul tabelil VACUUM FULL läbisin. See pole minu toodang.

Tabeli suurus naasis kohe normaalsesse paari megabaidisse tööolekusse. See ei mõjutanud oluliselt keskmist reageerimisaega kogu serveris.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Kuid konkreetselt meie testtabelis, kus värskendasime kontojääke, näeme, et tahvelarvutis olevate andmete värskendamise päringu keskmine reageerimisaeg vähenes krahhieelsele tasemele. Protsessori poolt selle päringu täitmiseks kulutatud ressursid langesid samuti krahhieelsele tasemele. Ja alumine parempoolne graafik näitab, et nüüd leiame täpselt selle rea, mida vajame, ilma et peaksime läbima surnud ridade hunnikut, mis olid enne tabeli tihendamist. Ja keskmine päringuaeg jäi ligikaudu samale tasemele. Kuid siin on minu riistvara viga.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Siin esimene lugu lõpeb. Ta on kõige levinum. Ja seda juhtub kõigiga, sõltumata kliendi kogemusest, kui kvalifitseeritud programmeerijad on. Varem või hiljem see juhtub.

Teine lugu, milles jagame koormust ja optimeerime serveriressursse

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

  • Oleme suureks kasvanud ja muutunud tõsisteks poisteks. Ja me saame aru, et meil on koopia ja meil oleks hea koormust tasakaalustada: kirjutada Masterile ja lugeda koopiast. Ja tavaliselt tekib selline olukord siis, kui tahame mingisuguseid aruandeid või ETL-i koostada. Ja äri on selle üle väga rahul. Ta tahab tõesti mitmesuguseid aruandeid koos hulga keeruka analüüsiga.
  • Aruanded kestavad mitu tundi, sest keerulist analüütikat ei saa millisekundites arvutada. Meie, nagu julged poisid, kirjutame koodi. Me teeme sisestusrakenduses, mille me Masterile salvestame, esitame koopia kohta aruandeid.
  • Jaotame koormuse.
  • Kõik töötab ideaalselt. Oleme suurepärased.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja kuidas see olukord välja näeb? Täpsemalt lisasin nendele graafikutele ka tehingute kestuse koopiast tehingu ajaks. Kõik muud graafikud viitavad ainult põhiserverile.

Selleks ajaks oli minu aruandetahvel kasvanud. Neid on rohkemgi. Näeme, et serveri keskmine reageerimisaeg on stabiilne. Näeme, et meil on koopiaga pikk tehing, mis kestab 2 tundi. Näeme autovaakumi vaikset tööd, mis töötleb surnud ridu. Ja meil on kõik hästi.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Täpsemalt jätkame testtableti järgi sealsete kontode saldode uuendamist. Ja meil on nõudmisel ka stabiilne reageerimisaeg, stabiilne ressursitarbimine. Meiega on kõik hästi.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Kõik on korras kuni hetkeni, mil need teated hakkavad meile vastutuld andma konfliktile replikatsiooniga. Ja nad tulistavad korrapäraste ajavahemike järel tagasi.

Me läheme võrku ja hakkame lugema, miks see nii juhtub. Ja leiame lahenduse.

Esimene lahendus on suurendada replikatsiooni latentsust. Teame, et meie aruanne kestab 3 tundi. Määrake replikatsiooni viivitus 3 tunniks. Me alustame kõike, kuid endiselt on meil jätkuvalt probleeme sellega, et aruandeid tuleb mõnikord tagasi.

Tahame, et kõik oleks täiuslik. Lähme edasi. Ja leiame Internetist laheda seade – hot_standby_feedback. Lülitame selle sisse. Hot_standby_feedback võimaldab meil hoida automaatvaakumit Masteris töötamas. Seega vabaneme replikatsioonikonfliktidest täielikult. Ja me kõik töötame aruannetega hästi.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja mis toimub põhiserveriga praegu? Ja põhiserveriga on meil täielik katastroof. Nüüd näeme diagramme, kus mõlemad seaded on sisse lülitatud. Ja me näeme, et koopia seanss hakkas kuidagi mõjutama põhiserveri olukorda. See avaldab mõju, sest see on peatanud autovaakumi, mis puhastab surnud read. Meie laua suurus on taas hüppeliselt tõusnud. Ka keskmine päringu täitmise aeg kogu andmebaasis tõusis hüppeliselt. Autovaakumid pingutasid veidi.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Täpsemalt näeme oma taldrikul, et ka sellel olev andmevärskendus hüppas taevasse. Protsessori ressursside tarbimine on samuti oluliselt kasvanud. Kordame taas üle suure hulga surnud kasutuid ridu. Ja selle tahvelarvuti reageerimisaeg, tehingute arv on langenud.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Kuidas see välja näeb, kui me ei tea, millest ma varem rääkisin?

  • Hakkame probleeme otsima. Kui esimeses osas tekkis probleeme, siis teame, et see võib olla pika tehingu põhjuseks ja ronime Masterile. Probleem on meistris. Vorstid teda. Ta teeb soojendust, tema koormuse keskmine on alla saja.
  • Seal päringud aeglustuvad, kuid me ei näe seal ühtegi pikaajalist tehingut. Ja me ei saa aru, mis toimub. Me ei tea, kust otsida.
  • Serveri riistvara kontrollimine. Võib-olla on meie haarang kokku kukkunud. Võib-olla põletasime mäluriba läbi. Jah, kõike võib olla. Aga ei, serverid on uued, kõik töötab hästi.
  • Kõik jooksevad: administraatorid, arendajad ja direktor. Miski ei aita.
  • Ja ühel hetkel hakkab kõik järsku ennast korrigeerima.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Koopial läks taotlus sel ajal korda ja lahkus. Saime raporti. Äri on endiselt rahul. Nagu näha, on meie tabel taas kasvanud ega kavatse kahaneda. Seanssidega diagrammile jätsin tüki sellest pikast tehingust koopiast, et saaksite hinnata, kui kaua kulub olukorra stabiliseerumiseks.

Seanss on läinud. Ja alles mõne aja pärast tuleb server enam-vähem korda. Ja päringute keskmine reageerimisaeg põhiserveris normaliseerub. Sest lõpuks sai autovaakum võimaluse need surnud piirid välja puhastada, märkida. Ja ta hakkas oma tööd tegema. Ja kui kiiresti ta seda teeb, nii kiiresti saame korda.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Testtabelil, kus uuendame kontojääke, näeme täpselt sama pilti. Ka keskmine konto värskendamise aeg normaliseerub järk-järgult. Samuti vähenevad protsessori tarbitavad ressursid. Ja tehingute arv sekundis on taas normaalne. Aga jällegi tagasi normaalsesse olekusse, mitte samamoodi nagu enne õnnetust.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Igal juhul saame jõudluses maha, nagu esimesel juhul, poolteist kuni kaks korda ja mõnikord isegi rohkem.

Tundub, et oleme teinud kõik õigesti. Jaotage koormus. Seadmed ei seisa jõude. Mõistuse järgi murdsid nad taotlusi, kuid siiski läks kõik halvasti.

  • Kas te ei luba hot_standby_feedbacki? Jah, ilma eriti tugevate põhjusteta pole soovitatav seda sisse lülitada. Sest see pööre mõjutab otseselt Master Serverit ja peatab sealse autovaakumi töö. Kui lülitate selle mõnel koopial sisse ja unustate selle, võite Masteri tappa ja rakendusega suuri probleeme tekkida.
  • Kas suurendada max_standby_streaming_delay? Jah, aruannete jaoks on see nii. Kui teil on kolmetunnine aruanne ja te ei soovi, et see replikatsioonikonfliktide tõttu kokku jookseks, suurendage lihtsalt viivitust. Pikk aruanne ei nõua kunagi andmeid, mis on praegu andmebaasi sisestatud. Kui teil on see kolm tundi, siis kasutate seda mõne vana andmeperioodi jooksul. Ja teie, see kolm tundi hilinemist, see kuus tundi hilinemist - ei mängi mingit rolli, kuid saate aruandeid järjepidevalt ega tea nende kukkumisega seotud probleeme.
  • Loomulikult peate kontrollima pikki koopiate seansse, eriti kui otsustate lubada koopial hot_standby_feedback. Sest see võib olla ükskõik milline. Andsime selle märkuse arendajale, et ta taotlusi testiks. Ta kirjutas hullu palve. Ta alustas ja läks teed jooma ning saime loodud Meistri. Või käivitasime seal vale rakenduse. Olukorrad on erinevad. Koopiate seansse tuleb juhtida sama hoolikalt kui Masteris.
  • Ja kui teil on koopiate kohta kiireid ja pikki päringuid, on sel juhul parem need koormuse jaotamiseks jagada. See on link lehele streaming_delay. Kiireks, et saada üks koopia väikese replikatsiooniviivitusega. Pikaajaliste aruandlustaotluste jaoks kasutage koopiat, mis võib päevas 6 tundi maha jääda. See on täiesti normaalne olukord.

Me kõrvaldame tagajärjed samal viisil:

  • Leiame ülespuhutud lauad.
  • Ja me surume kokku kõige mugavama tööriistaga, mis meile sobib.

Teine lugu lõpeb siin. Liigume edasi kolmanda loo juurde.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ka meie jaoks üsna tavaline, kus me migratsiooni teeme.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

  • Iga tarkvaratoode kasvab. Nõuded muutuvad. Igal juhul tahame areneda. Ja juhtub, et peame tabelis olevaid andmeid värskendama, nimelt värskenduse käivitamiseks seoses uuele funktsioonile üleminekuga, mida oma arenduse raames rakendame.
  • Vana andmevorming ei sobi. Oletame, et läheme nüüd teise tabeli juurde, kus mul on nende kontodega toimingud. Ja oletame, et need olid rublades ja me otsustasime täpsust suurendada ja teha seda kopikates. Ja selleks peame tegema värskenduse: korrutage väli toimingu summaga sajaga.
  • Tänapäeva maailmas kasutame automatiseeritud andmebaasi versioonide loomise tööriistu. Ütleme Liquibase. Registreerime seal oma rände. Testime seda oma testibaasis. Kõik on korras. Värskendus töötab. Plokid töötavad mõnda aega, kuid saame värskendatud andmeid. Ja me saame käivitada selle jaoks uued funktsioonid. Kõik testitud ja kontrollitud. Kõik kinnitatud.
  • Teostatud plaanitööd, teostatud migratsioon.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Siin on migratsioon koos teie ees esitatud värskendusega. Kuna mul on kontodega toimingud, siis plaat oli 15 GB. Ja kuna me uuendame iga rida, oleme tabeli suurust kahekordistanud, kuna oleme iga rea ​​üle kirjutanud.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Migreerimise ajal ei saanud me selle sildiga midagi teha, kuna kõik selle taotlused olid järjekorda pandud ja ootasid selle värskenduse lõppemist. Kuid siin tahan juhtida teie tähelepanu numbritele, mis asuvad vertikaalteljel. See tähendab, et meil on keskmine päringuaeg enne migreerimist umbes 5 millisekundit ja protsessori koormus, kettamälu lugemise plokitoimingute arv on alla 7,5.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Kolisime ja tekkisid jälle probleemid.

Üleminek oli edukas, kuid:

  • Vana funktsionaalsus hakkas kauem töötama.
  • Laud on taas suuremaks kasvanud.
  • Serveri koormus on jälle muutunud suuremaks, kui oli.
  • Ja loomulikult askeldame endiselt hästi toimiva funktsionaalsuse kallal, täiustasime seda veidi.

Ja see on jälle paistetus, mis jällegi meie elu ära rikub.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Siin demonstreerin, et tabel, nagu ka kahel eelmisel juhul, ei lähe tagasi eelmiste suuruste juurde. Serveri keskmine koormus tundub olevat piisav.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja kui me pöördume kontode tabeli poole, siis näeme, et selle tabeli keskmine päringuaeg on kahekordistunud. Protsessori koormus ja mälus sorteeritavate ridade arv hüppas üle 7,5, kuid see oli väiksem. Ja hüppas protsessorite puhul 2 korda, plokkoperatsioonide puhul 1,5 korda, st saime serveri jõudluse halvenemise. Ja selle tulemusena - meie rakenduse jõudluse halvenemine. Kõnede arv jäi samal ajal ligikaudu samale tasemele.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Ja siin on peamine mõista, kuidas selliseid rände õigesti teha. Ja need tuleb ära teha. Teeme neid migratsioone üsna regulaarselt.

  • Nii suuri migratsioone ei tehta automaatselt. Neid tuleb alati kontrollida.
  • Vajab teadliku inimese juhendamist. Kui teil on meeskonnas DBA, laske DBA-l seda teha. See on tema töö. Kui ei, siis las teeb seda kõige kogenum, kes oskab andmebaasidega töötada.
  • Uue andmebaasi skeemi, isegi kui värskendame ühte veergu, valmistame alati ette etapiviisiliselt, st enne rakenduse uue versiooni väljalaskmist:
  • Lisatakse uued väljad, kuhu kirjutame ainult uuendatud andmed.
  • Edastame andmed vanalt põllult uuele väikeste osadena. Miks me seda teeme? Esiteks kontrollime alati selle protsessi protsessi. Teame, et oleme juba nii palju partiisid üle kandnud ja nii palju on jäänud.
  • Ja teine ​​positiivne efekt on see, et iga sellise partii vahel sulgeme tehingu, avame uue ja see võimaldab autovaakumil töötada plaadi järgi, tähistada taaskasutamise tähtaegu.
  • Rakenduse töötamise ajal ilmuvate ridade jaoks (meil on endiselt vana rakendus) lisame päästiku, mis kirjutab uutele väljadele uued väärtused. Meie puhul on see vana väärtuse korrutamine sajaga.
  • Kui oleme täiesti kangekaelsed ja tahame sama välja, siis kõigi migratsioonide lõppedes ja enne rakenduse uue versiooni käivitamist nimetame väljad lihtsalt ümber. Vanad väljad mingiks väljamõeldud nimeks ja uued väljad nimetame ümber vanadeks.
  • Ja alles pärast seda käivitame rakenduse uue versiooni.

Ja samal ajal me ei punni ega lange jõudluses alla.

See on kolmanda loo lõpp.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei 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

Ja nüüd natuke lähemalt vahenditest, mida mainisin juba esimeses loos.

Enne kõhupuhituse otsimist peate laienduse installima pgstattuple.

Selleks, et te taotlusi välja ei mõtleks, oleme need taotlused juba oma töös kirja pannud. Saate neid kasutada. Siin on kaks taotlust.

  • Esimene võtab üsna kaua aega, kuid see näitab teile tabeli järgi täpseid paistetuse väärtusi.
  • Teine töötab kiiremini ja on väga tõhus, kui on vaja kiiresti hinnata, kas tabelis on paistetus või mitte. Samuti peaksite mõistma, et Postgresi tabelis on alati paistetus. See on tema MVCC mudeli tunnusjoon.
  • Ja 20% paistetus sobib enamikul juhtudel laudade jaoks. See tähendab, et te ei peaks muretsema ja seda tabelit kokku suruma.

Mõtlesime välja, kuidas tuvastada tabeleid, mis on meiega paisunud, pealegi siis, kui need on kasutute andmetega paisunud.

Nüüd, kuidas puhitus parandada:

  • Kui meil on väike plaat ja korralikud kettad ehk siis kuni gigabaidisel plaadil, siis on täiesti võimalik kasutada VACUUM FULL. Ta võtab sinult mõneks sekundiks eksklusiivse luku, ja olgu, aga ta teeb kõike kiiresti ja karmilt. Mida VACUUM FULL teeb? See võtab lauale eksklusiivse luku ja kirjutab reaalajas read vanadest tabelitest ümber uude tabelisse. Ja lõpuks asendab ta need. Kustutab vanad failid, asendab vanad uutega. Kuid oma töö ajaks võtab see lauale eksklusiivse luku. See tähendab, et te ei saa selle tabeliga midagi teha: ei kirjuta, ei loe ega muuda. Ja VACUUM FULL nõuab andmete kirjutamiseks täiendavat kettaruumi.
  • Järgmine tööriist pg_repack. Oma põhimõttelt on see väga sarnane VACUUM FULLiga, kuna kirjutab ka vanadest failidest andmed üle uutesse ja asendab need tabelis. Kuid samal ajal ei võta ta eksklusiivset lukku lauale kohe oma töö alguses, vaid võtab selle alles hetkel, kui tal on failide asendamiseks valmis andmed. Sellel on samad kettaressursinõuded kui VACUUM FULL. Vajate täiendavat kettaruumi ja see on mõnikord kriitiline, kui teil on terabaiditabelid. Ja ta on protsessori suhtes üsna ablas, kuna töötab aktiivselt I / O-ga.
  • Kolmas utiliit on pgkompaktable. See käsitleb ressursse hoolikamalt, sest see töötab veidi erinevatel põhimõtetel. Rakenduse pgcompacttable põhiolemus seisneb selles, et see liigutab kõik reaalajas read tabeli värskendustega tabeli algusesse. Ja siis algab sellel laual vaakum, sest me teame, et meil on alguses elavad read ja lõpus surnud read. Ja vaakum ise lõikab selle saba ära, see tähendab, et see ei nõua palju täiendavat kettaruumi. Ja samas saab seda ikkagi ressurssidega pigistada.

Kõik koos tööriistadega.

Tüüpilised rakendusevead, mis põhjustavad postgresql-i paisumist. Andrei Salnikov

Kui tunnete, et paistetuse teema on huvitav, et saaksite rohkem sissepoole kaevata, siis siin on teile mõned kasulikud lingid:

Siin üritasin näidata arendajatele mõeldud õuduslugu, sest nemad on meie otsesed andmebaaside kliendid ja peavad aru saama, milleni ja milleni tegevused viivad. Loodan, et see õnnestus. Täname tähelepanu eest!

küsimused

Täname raporti eest! Rääkisite sellest, kuidas probleeme tuvastada. Kuidas saab neid hoiatada? See tähendab, et mul oli olukord, kus taotlused rippusid mitte ainult sellepärast, et nad pöördusid mõne välisteenuse poole. See oli lihtsalt metsik ühinemine. Seal olid väikesed, kahjutud taotlused, mis jäid päevaks ringi ja hakkasid siis mingit jama tegema. See tähendab, et see on väga sarnane teie kirjeldatule. Kuidas seda jälgida? Istu ja vaata pidevalt, milline taotlus on kinni jäänud? Kuidas seda ära hoida?

Sel juhul on see ülesanne teie ettevõtte administraatoritele, mitte tingimata DBA-le.

Olen administraator.

PostgreSQL-il on vaade nimega pg_stat_activity, mis näitab ootel päringuid. Ja näete, kui kaua see seal ripub.

Pean iga 5 minuti tagant sisse tulema ja vaatama?

Seadistage cron ja kontrollige. Kui sul on pikk soov, siis kirjuta kiri ja ongi kõik. See tähendab, et te ei pea oma silmadega vaatama, seda saab automatiseerida. Saate kirja, vastate sellele. Või saate pildistada automaatselt.

Kas on selgeid põhjuseid, miks see juhtub?

Loetlesin mõned. Muud keerulisemad näited. Ja võib olla pikk vestlus.

Täname raporti eest! Tahtsin selgitada utiliidi pg_repack kohta. Kui selleks ei ole vaja eksklusiivset lukku, siis...

Ta teeb eksklusiivse luku.

... siis võin andmed kaotada. Kas mu rakendus ei peaks praegu midagi salvestama?

Ei, see töötab tabeliga vaikselt, st pg_repack kannab kõigepealt üle kõik seal olevad live read. Loomulikult on tabelis käimas mingi rekord. Ta lihtsalt viskab seda hobusesaba.

See tähendab, kas ta teeb seda ikka lõpuks?

Lõpuks kulub nende failide vahetamiseks eksklusiivne lukk.

Kas see on kiirem kui VACUUM FULL?

VACUUM FULL, nagu algas, võttis kohe eksklusiivse luku. Ja kuni ta kõike ei tee, ei lase ta teda lahti. Ja pg_repack võtab eksklusiivse luku ainult failide asendamise ajal. Siinkohal sa sinna ei kirjuta, aga andmed kaotsi ei lähe, kõik saab korda.

Tere! Rääkisite autovaakumi tööst. Seal oli graafik rekordi punaste, kollaste ja roheliste lahtritega. Ehk siis kollased – ta märkis need kustutatuks. Ja selle tulemusena saate neisse midagi uut kirjutada?

Jah. Postgres ei eemalda ridu. Tal on selline spetsiifika. Kui uuendasime rida, märkisime vana kustutatuks. Tehingu ID, mis seda rida muutis, tõuseb sinna ja me kirjutame uue rea. Ja meil on seansse, mis võivad neid lugeda. Mingil hetkel muutuvad nad üsna vanaks. Ja autovaakumi olemus seisneb selles, et see jookseb läbi nende joonte ja märgib need mittevajalikeks. Ja seal saate andmed üle kirjutada.

ma saan aru. Kuid küsimus ei ole selles. Ma ei nõustunud. Oletame, et meil on laud. Sellel on muutuva suurusega väljad. Ja kui proovin midagi uut sisestada, ei pruugi see lihtsalt vanasse lahtrisse mahtuda.

Ei, igal juhul uuendatakse kogu rida. Postgresil on kaks salvestusmudelit. See valib andmetüübist. On andmeid, mis salvestatakse otse tabelisse, ja on ka tos-andmeid. Need on suured andmemahud: tekst, json. Neid hoitakse eraldi tablettides. Ja nende tablettide järgi juhtub sama lugu puhitusega ehk kõik on sama. Need on lihtsalt eraldi loetletud.

Täname raporti eest! Kui vastuvõetav on väljavõtte ajalõpu taotluste kasutamine kestuse piiramiseks?

Väga vastuvõetav. Me kasutame seda igal pool. Ja kuna meil oma teenuseid pole, pakume kaugtuge, kliente on päris palju. Ja kõik on sellega üsna rahul. See tähendab, et meil on cronis töökohti, mis kontrollivad. Lihtsalt seansside kestus lepitakse kliendiga kokku, enne mida me naelu ei löö. See võib olla minut, see võib olla 10 minutit. See sõltub aluse koormusest ja selle eesmärgist. Kuid me kõik kasutame pg_stat_activity.

Täname raporti eest! Proovin teie aruannet oma rakenduste jaoks proovida. Ja tundub, et me alustame tehingut igal pool ja teeme selle igal pool selgesõnaliselt lõpule. Kui mõni erand, siis toimub sama tagasipööramine. Ja siis ma mõtlesin. Lõppude lõpuks ei saa tehingut otseselt alustada. See on vist vihje tüdrukule. Kui ma lihtsalt värskendan kirjet, kas tehing algab PostgreSQL-is ja lõpeb alles siis, kui ühendus katkeb?

Kui räägite praegu rakenduse tasemest, siis see sõltub teie kasutatavast draiverist ja kasutatavast ORM-ist. Seal on palju seadeid. Kui teil on automaatne kinnistamine lubatud, algab tehing seal ja suletakse kohe.

See tähendab, et see suletakse kohe pärast värskendust?

Oleneb seadetest. Nimetasin ühe seadistuse. See on automaatne kinnitamine. Ta on üsna tavaline. Kui see on lubatud, siis tehing avati ja suleti. Välja arvatud juhul, kui olete sõnaselgelt öelnud "alusta tehingut" ja "lõpeta tehing", vaid lihtsalt käivitasite seansi päringu.

Tere! Täname raporti eest! Kujutage ette, et meil on andmebaas, mis paisub ja paisub ja siis saab serveris ruum otsa. Kas on mingeid vahendeid selle olukorra parandamiseks?

Koht serveris heas mõttes vajab jälgimist.

Näiteks DBA käis teed joomas, oli kuurordis jne.

Failisüsteemi loomisel luuakse vähemalt reservruum, kuhu andmeid ei kirjutata.

Mis siis, kui see on täiesti null?

Seal nimetatakse seda reserveeritud ruumiks, see tähendab, et seda saab vabastada ja olenevalt sellest, kui suur see loodi, saate vaba ruumi. Vaikimisi ma ei tea, kui palju neid on. Ja teisel juhul tarnige kettad, et teil oleks koht, kus taasteoperatsioon läbi viia. Saate kustutada mõne tabeli, mida te kindlasti ei vaja.

Kas muid tööriistu pole?

See on alati käsitsi valmistatud. Ja kohas selgub, mida seal on parem teha, sest on andmeid, mis on kriitilised, on mittekriitilised. Ja iga sellega töötava andmebaasi ja rakenduse puhul sõltub see ettevõttest. See otsustatakse alati kohapeal.

Täname raporti eest! Mul on kaks küsimust. Esmalt näitasite slaide, kus näidati, et riputatud tehingute puhul kasvab nii tabelipind kui ka indeksi suurus. Ja edasi aruandes oli hulk utiliite, mis tahvelarvutit pakkivad. Ja kuidas on indeksiga?

Nad pakivad ka neid.

Aga vaakum indeksit ei mõjuta?

Mõned töötavad indeksiga. Näiteks pg_rapack, pgcompacttable. Vaakum taasloob indeksid, mõjutab neid. VACUUM FULLi olemus on kõike üle kirjutada, st see töötab kõigiga.

Ja teine ​​küsimus. Ma ei saanud aru, miks koopiate aruanded sõltuvad nii palju replikatsioonist endast. Mulle tundus, et aruanded loevad ja paljundamine on kirjutamine.

Mis põhjustab replikatsioonikonflikti? Meil on meister, mille peal protsessid toimuvad. Meil on autovaakum. Autovaakum tegelikult, mida see teeb? Ta lõikab välja mõned vanad read. Kui meil on praegu päring koopial, mis loeb neid vanu ridu ja Masteris oli olukord, et autovaakum märkis need read ümberkirjutamise võimalikuks, siis kirjutasime need üle. Ja saime andmepaketi, kui peame replikas ümber kirjutama need read, mida taotlus vajab, siis ootab replikatsiooniprotsess teie seadistatud ajalõpu. Ja siis otsustab PostgreSQL, mis on tema jaoks olulisem. Ja replikatsioon on tema jaoks olulisem kui taotlus ja ta esitab taotluse nende muudatuste tegemiseks koopias.

Andrew, mul on küsimus. Kas see suurepärane graafika, mida esitluse ajal näitasite, on mõne teie utiliidi töö tulemus? Kuidas edetabelid tehti?

See on teenus Okmeeter.

Kas see on kaubanduslik toode?

Jah. See on kaubanduslik toode.

Allikas: www.habr.com

Lisa kommentaar