Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Jeg foreslår at læse udskriften af ​​rapporten fra begyndelsen af ​​2016 af Andrey Salnikov "Typiske fejl i applikationer, der fører til oppustethed i postgresql"

I denne rapport vil jeg analysere de vigtigste fejl i applikationer, der opstår på stadiet med design og skrivning af applikationskode. Og jeg vil kun tage de fejl, der fører til oppustethed i Postgresql. Som regel er dette begyndelsen på slutningen af ​​ydelsen af ​​dit system som helhed, selvom der i starten ikke blev set nogen forudsætninger for dette.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Glad for at byde alle velkommen! Denne rapport er ikke så teknisk som den forrige fra min kollega. Denne snak er rettet mod back-end systemudviklere, primært fordi vi har et ret stort antal kunder. Og de begår alle de samme fejl. Jeg vil fortælle dig om dem. Jeg vil forklare, hvad fatalt og dårligt disse fejl fører til.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Hvorfor begås der fejl? De udføres af to grunde: tilfældigt, måske vil det fungere ud fra uvidenhed om nogle mekanismer, der opstår på niveauet mellem basen og applikationen, såvel som i selve basen.

Jeg vil give dig tre eksempler med forfærdelige billeder af, hvordan det gik galt. Jeg vil kort beskrive den mekanisme, der opstår der. Og hvordan man håndterer dem, hvornår de skete, og hvilke forebyggende metoder man skal bruge for at forhindre fejl. Jeg vil fortælle dig om hjælpeværktøjer og give nyttige links.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Jeg brugte en testdatabase, hvor jeg havde to tabeller. Den ene plade med kundekonti, den anden med operationer på disse konti. Og med en vis periodicitet opdaterer vi saldi på disse konti.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

De indledende data for pladen: den er ret lille, 2 MB. Svartiden for databasen og specifikt for pladen er også meget god. Og en ret god belastning - 2 operationer i sekundet på pladen.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og gennem denne rapport vil jeg vise dig grafer, så det er tydeligt, hvad der sker. Der vil altid være 2 slides med grafer. Det første dias er, hvad der generelt sker på serveren.

Og i denne situation ser vi, at vi virkelig har en lille tallerken. Indekset er lille på 2 MB. Dette er det første diagram til venstre.

Den gennemsnitlige svartid på tværs af serveren er også stabil, lille. Dette er grafen øverst til højre.

Den nederste venstre graf er de længste transaktioner. Vi kan se, at transaktioner bliver gennemført hurtigt. Og autovakuum virker ikke her endnu, fordi - det var en start-test. Så vil det virke og være nyttigt for os.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Det andet objektglas vil altid være dedikeret til testpladen. I denne situation opdaterer vi løbende kundens kontosaldi. Og vi ser, at den gennemsnitlige responstid for opdateringsoperationen er ganske god, mindre end et millisekund. Vi ser, at processorressourcerne (dette er grafen øverst til højre) også forbruges jævnt og ret små.

Den nederste højre graf viser, hvor meget drifts- og diskhukommelse vi går igennem på jagt efter vores ønskede linje, før vi opdaterer den. Og antallet af operationer på pladen er 2 i sekundet, som jeg sagde i begyndelsen.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og nu har vi en tragedie. Af en eller anden grund opstår der en længe glemt transaktion. Årsagerne er normalt alle banale:

  • En af de mest almindelige er, at vi begyndte at få adgang til en ekstern tjeneste i applikationskoden. Og denne service svarer os ikke. Det vil sige, at vi åbnede en transaktion, lavede en ændring i databasen og gik fra applikationen til at læse mail eller til en anden tjeneste inden for vores infrastruktur, og af en eller anden grund svarer den os ikke. Og vores session hang i en tilstand - det vides ikke, hvornår det bliver løst.
  • Den anden situation er, når en undtagelse opstod i vores kode af en eller anden grund. Og vi behandlede ikke lukningen af ​​transaktionen i undtagelsen. Og vi fik en hængende session med en åben transaktion.
  • Og den sidste er også ret almindelig. Dette er kode af dårlig kvalitet. Nogle rammer åbner en transaktion. Den hænger, og du ved måske ikke i applikationen, at du har den hængende.

Hvor fører sådanne ting hen?

Til det faktum, at vores tabeller og indekser begynder at svulme dramatisk. Dette er nøjagtig den samme oppustede effekt. For databasen vil dette komme til udtryk ved, at vi vil få en meget kraftig stigning i databasens responstid, belastningen på databaseserveren vil stige. Og som et resultat vil vores ansøgning lide. For hvis du i din kode brugte 10 millisekunder på en anmodning til databasen, 10 millisekunder på din logik, så arbejdede din funktion 20 millisekunder. Og nu vil din situation være meget trist.

Og lad os se, hvad der sker. Den nederste venstre graf viser, at vi har en lang lang transaktion. Og hvis vi ser på grafen øverst til venstre, ser vi, at størrelsen af ​​tabellen sprang fra to megabyte til 300 megabyte. Samtidig har mængden af ​​data i tabellen ikke ændret sig, det vil sige, at der er en ret stor mængde affald.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Den overordnede situation med hensyn til den gennemsnitlige serversvartid har også ændret sig i flere størrelsesordener. Det vil sige, at alle anmodninger på serveren begyndte at synke fuldstændigt. Og samtidig blev de interne Postgres-processer i lyset af autovacuum lanceret, som forsøger at gøre noget og tære ressourcer.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Hvad sker der med vores tallerken? Det samme. Den gennemsnitlige responstid på tabletten steg flere størrelsesordener. Hvis det specifikt angår forbrugte ressourcer, så ser vi, at belastningen på processoren er steget kraftigt. Dette er grafen øverst til højre. Og det er steget, fordi processoren skal igennem en masse ubrugelige linjer på jagt efter den, du har brug for. Dette er den nederste højre graf. Og som et resultat begyndte antallet af opkald pr. sekund at falde meget, fordi databasen ikke har tid til at behandle det samme antal anmodninger.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Vi skal tilbage til livet. Vi går ind på internettet og finder ud af, at lange transaktioner fører til et problem. Vi finder og dræber denne transaktion. Og alt går godt for os. Alt fungerer som det skal.

Vi faldt til ro, men efter et stykke tid begynder vi at mærke, at applikationen ikke virker, som den gjorde før nødsituationen. Anmodninger behandles dog langsommere og meget langsommere. Halvanden til to gange langsommere specifikt i mit eksempel. Belastningen på serveren er også højere, end den var før ulykken.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og spørgsmålet: "Hvad sker der med basen i dette øjeblik?". Og med udgangspunkt er der en følgende situation. På transaktionsdiagrammet kan du se, at det er stoppet, og der er virkelig ingen langsigtede transaktioner. Men pladens dimensioner under ulykken voksede fatalt. Og det er ikke faldet siden da. Den gennemsnitlige tid på basen har stabiliseret sig. Og svarene ser ud til at gå tilstrækkeligt med en acceptabel hastighed for os. Autovacuum blev mere aktiv og begyndte at gøre noget med tabletten, fordi den skal skovle flere data.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Specifikt på testresultattavlen, hvor vi ændrer saldierne: Svartiden for anmodningen ser ud til at være normal igen. Men faktisk er den halvanden gang højere.

Og ved belastningen på processoren ser vi, at belastningen på processoren ikke vendte tilbage til den ønskede værdi før nedbruddet. Og årsagerne der ligger bare i den nederste højre graf. Det kan ses, at der er en søgning på en vis mængde hukommelse. Det vil sige, at for at søge efter den ønskede linje bruger vi ressourcerne på databaseserveren, når vi sorterer ubrugelige data. Antallet af transaktioner pr. sekund har stabiliseret sig.

Generelt godt, men situationen er værre, end den var. Eksplicit nedbrydning af databasen som følge af vores applikation, der fungerer med denne database.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og for at forstå, hvad der sker der, hvis du ikke var ved den forrige rapport, så nu en lille smule teori. Teori om den interne proces. Hvorfor autovacuum og hvad gør det?

Bogstaveligt talt i en nøddeskal for forståelse. På et tidspunkt har vi et bord. Vi har rækker i tabellen. Disse linjer kan være aktive, live, vi har brug for nu. De er markeret med grønt på billedet. Og der er deadlines, der allerede er løst, er blevet opdateret, nye poster er dukket op på dem. Og de er markeret med, at de ikke længere er interessante for databasen. Men de ligger i bordet på grund af Postgres' ejendommeligheder.

Hvorfor har du brug for en autovakuum? Autovacuum kommer på et tidspunkt, ringer til databasen og spørger den: "Giv mig venligst id'et for den ældste transaktion, der i øjeblikket er åben i databasen." Databasen returnerer dette id. Og autovakuum, afhængigt af det, går gennem linjerne i tabellen. Og hvis han ser, at nogle linjer er blevet ændret ved meget ældre transaktioner, så har han ret til at markere dem som linjer, som vi kan genbruge i fremtiden ved at skrive nye data der. Dette er en baggrundsproces.

På nuværende tidspunkt fortsætter vi med at arbejde med databasen, vi fortsætter med at lave nogle ændringer i tabellen. Og på disse linjer, som vi kan genbruge, skriver vi nye data. Og på den måde får vi en cyklus, det vil sige, at der hele tiden dukker nogle døde gamle linjer op der, i stedet for dem skriver vi nye linjer ned, som vi har brug for. Og dette er den normale tilstand for PostgreSQL at fungere.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Hvad skete der under ulykken? Hvordan foregik denne proces?

Vi havde en tallerken i en eller anden stand, nogle levende, nogle døde linjer. Autovakuum er ankommet. Han spurgte databasen om, hvad der er vores ældste transaktion, hvad er dens id. Jeg fik dette id, som kan være mange timer gammelt, måske ti minutter gammelt. Det afhænger af hvor stor belastning du har på databasen. Og han gik for at lede efter linjer, som han kan markere som genbrugt. Og jeg fandt ikke sådanne linjer i vores tabel.

Men på nuværende tidspunkt arbejder vi videre med bordet. Vi gør noget i det, opdaterer det, ændrer dataene. Hvad skal databasen gøre på dette tidspunkt? Hun har intet andet valg end at tilføje nye linjer til slutningen af ​​den eksisterende tabel. Og dermed hos os begynder størrelsen af ​​bordet at blive pustet op.

Vi har virkelig brug for grønne linjer for at fungere. Men under et sådant problem viser det sig, at procentdelen af ​​grønne linjer er ekstremt lav i hele bordets volumen.

Og når vi udfører en forespørgsel, skal databasen gennemgå alle linjer, både røde og grønne, for at finde den rigtige linje. Og effekten af ​​at puste bordet op med ubrugelige data kaldes "bloat", hvilket også æder vores diskplads. Husk, det var 2 MB, nu er det 300 MB? Skift nu megabyte til gigabyte, og du vil miste alle dine diskressourcer ret hurtigt.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Hvad er konsekvenserne for os?

  • I mit eksempel er tabellen og indekset vokset 150 gange. Nogle af vores klienter har haft flere fatale tilfælde, hvor diskplads simpelthen begyndte at løbe tør.
  • Borde vil aldrig krympe af sig selv. Autovakuum kan i nogle tilfælde afskære bordets hale, hvis der kun er deadlines. Men da der er en konstant rotation, kan en grøn streg hænge i slutningen og ikke blive opdateret, og alle resten et sted i begyndelsen af ​​pladen vil blive optaget. Men dette er en så usandsynlig begivenhed, at dit bord selv vil falde i størrelse, så du skal ikke håbe på det.
  • Databasen skal sortere gennem hele bunken af ​​ubrugelige linjer. Og vi spilder diskressourcer, spilder processorressourcer og elektricitet.
  • Og dette påvirker vores applikation direkte, for hvis vi i begyndelsen brugte 10 millisekunder på en anmodning, 10 millisekunder på vores kode, så begyndte vi under nedbruddet at bruge et sekund på en anmodning og 10 millisekunder på kode, dvs. applikationsydelsen faldt. Og da ulykken var løst, begyndte vi at bruge 20 millisekunder pr. anmodning, 10 millisekunder pr. kode. Det betyder, at vi stadig sank halvanden gang rent præstationsmæssigt. Og det er alt sammen på grund af en transaktion, der hang, og måske på grund af vores skyld.
  • Og spørgsmålet: “Hvordan kan jeg få det hele tilbage?” Så alt er i orden hos os og anmodninger kører lige så hurtigt som før ulykken.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Til dette er der en vis cyklus af arbejde, der udføres.

Først skal vi finde de problematiske tabeller, der er oppustede. Vi forstår, at nogle tabeller optager mere aktivt, nogle mindre aktivt. Og til dette bruger vi udvidelsen pgstattuple. Ved at installere denne udvidelse kan du skrive forespørgsler for at hjælpe dig med at finde tabeller, der er oppustede nok.

Når du har fundet disse tabeller, skal de komprimeres. Der findes allerede værktøjer til dette. I vores virksomhed bruger vi tre værktøjer. Den første er den indbyggede VACUUM FULL. Han er grusom, barsk og nådesløs, men nogle gange er han meget nyttig. pg_repack и pgcompacttable er tredjepartsværktøjer til at komprimere tabeller. Og de er mere forsigtige med databasen.

De bruges afhængigt af, hvad der er mere bekvemt for dig. Men jeg vil tale om dette til allersidst. Det vigtigste er, at der er tre værktøjer. Der er masser at vælge imellem.

Efter at vi har rettet alt og sikret, at alt er i orden, bør vi vide, hvordan vi forhindrer denne situation i fremtiden:

  • Det er ret nemt at forebygge. Du skal overvåge varigheden af ​​sessioner på Master-serveren. Særligt farlige sessioner i inaktiv i transaktionstilstand. Det er dem, der lige har åbnet en transaktion, gjort noget og forladt, eller blot hængt, fortabt sig i koden.
  • Og for jer som udviklere er det vigtigt at teste koden på det tidspunkt, hvor disse situationer opstår. Det er ikke svært at gøre. Dette vil være en nyttig kontrol. Du vil undgå en masse "barnlige" problemer forbundet med lange transaktioner.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

På disse grafer ville jeg vise dig, hvordan tabellen og databasens adfærd ændrede sig, efter at jeg i dette tilfælde passerede VACUUM FULL på bordet. Dette er ikke min produktion.

Størrelsen af ​​bordet vendte straks tilbage til sin normale arbejdstilstand på et par megabyte. Dette påvirkede ikke i høj grad den gennemsnitlige svartid på tværs af serveren.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Men specifikt i vores testtabel, hvor vi opdaterede kontosaldierne, ser vi, at den gennemsnitlige svartid på en anmodning om at opdatere dataene i tabletten blev reduceret til niveauer før nedbrud. De ressourcer, som processoren brugte til at udføre denne anmodning, faldt også til niveauer før nedbrud. Og den nederste højre graf viser, at nu finder vi præcis den linje, som vi har brug for med det samme, uden at gå gennem bunken af ​​døde linjer, der var før bordet blev komprimeret. Og den gennemsnitlige forespørgselstid forblev omtrent på samme niveau. Men her har jeg snarere fejlen i min hardware.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Her slutter den første historie. Hun er den mest almindelige. Og det sker for alle, uanset klientens erfaring, hvor kvalificerede programmører der er. Før eller siden sker det.

Den anden historie, hvor vi fordeler belastningen og optimerer serverressourcer

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

  • Vi er vokset op og blevet seriøse fyre. Og vi forstår, at vi har en kopi, og det ville være godt for os at balancere belastningen: skriv til Mesteren og læs fra replikaen. Og normalt opstår denne situation, når vi ønsker at udarbejde en form for rapporter eller ETL. Og erhvervslivet er meget glade for det. Han ønsker virkelig en række forskellige rapporter med en masse komplekse analyser.
  • Rapporter varer i mange timer, fordi komplekse analyser ikke kan beregnes i millisekunder. Vi, som modige fyre, skriver kode. Vi gør i indsættelsesapplikationen, som vi optager på Master, vi udfører rapporter på replikaen.
  • Vi fordeler belastningen.
  • Alt fungerer perfekt. Vi er fantastiske.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og hvordan ser denne situation ud? Specifikt på disse diagrammer tilføjede jeg også varigheden af ​​transaktioner fra replikaen for transaktionens varighed. Alle andre grafer refererer kun til masterserveren.

På dette tidspunkt var min rapporttavle vokset. Dem er der flere af. Vi kan se, at den gennemsnitlige serversvarstid er stabil. Vi kan se, at vi har en lang kørende transaktion på replikaen, der kører i 2 timer. Vi ser det stille arbejde i autovakuum, som behandler deadlines. Og vi har det alle sammen.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Konkret fortsætter vi ifølge testtabletten med at opdatere saldi på konti der. Og vi har også en stabil responstid på forespørgsel, stabilt ressourceforbrug. Alt er fint med os.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Alt er fint indtil det øjeblik, hvor disse rapporter begynder at skyde tilbage på os på en konflikt med replikering. Og de skyder tilbage med jævne mellemrum.

Vi går på nettet og begynder at læse, hvorfor det sker. Og vi finder en løsning.

Den første løsning er at øge replikationsforsinkelsen. Vi ved, at vores rapport kører i 3 timer. Indstil replikationsforsinkelsen til 3 timer. Vi starter alt, men vi har stadig problemer med, at rapporter nogle gange bliver skudt tilbage.

Vi ønsker, at alt skal være perfekt. Lad os gå videre. Og vi finder en cool indstilling på internettet - hot_standby_feedback. Vi tænder den. Hot_standby_feedback giver os mulighed for at holde autovakuum kørende på Master. Dermed slipper vi helt for replikationskonflikter. Og vi arbejder alle godt med rapporter.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og hvad sker der med Master-serveren på dette tidspunkt? Og med Master-serveren har vi en total katastrofe. Vi ser nu diagrammer med begge disse indstillinger slået til. Og vi ser, at sessionen på replikaen på en eller anden måde begyndte at påvirke situationen på Master-serveren. Det gør en indvirkning, fordi det har suspenderet autovakuum, der renser ud i deadlines. Vores bordstørrelse er skudt i vejret igen. Den gennemsnitlige udførelsestid for forespørgsler på tværs af hele databasen steg også i vejret. Autostøvsugerne strammede lidt op.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Helt konkret ser vi på vores plade, at dataopdateringen på den også sprang ind i himlen. Forbruget af processorressourcer er tilsvarende steget meget. Vi itererer igen over et stort antal døde ubrugelige linjer. Og responstiden på denne tablet, antallet af transaktioner er faldet.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Hvordan vil det se ud, hvis vi ikke ved, hvad jeg talte om før?

  • Vi begynder at lede efter problemer. Hvis vi stødte på problemer i den første del, ved vi, at dette kan være årsagen til en lang transaktion, og vi klatrer op på Mesteren. Problemet ligger hos Mesteren. Pølser ham. Han varmer op, han har et belastningsgennemsnit på under hundrede.
  • Forespørgsler bremser der, men vi ser ikke nogen langsigtede transaktioner der. Og vi forstår ikke, hvad der foregår. Vi ved ikke, hvor vi skal lede.
  • Tjek serverhardware. Måske er vores raid kollapset. Måske har vi brændt hukommelsesbjælken ud. Ja, alt kan være. Men nej, serverne er nye, alt fungerer fint.
  • Alle løber: administratorer, udviklere og direktøren. Intet hjælper.
  • Og på et tidspunkt begynder alting pludselig at rette sig selv.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

På replikaen på det tidspunkt lykkedes anmodningen og gik. Vi har modtaget en rapport. Forretningen er stadig glad. Som du kan se, er vores tabel vokset igen og kommer ikke til at falde. På diagrammet med sessioner efterlod jeg et stykke af denne lange transaktion fra replikaen, så du kan vurdere, hvor lang tid det tager, før situationen stabiliserer sig.

Sessionen er væk. Og først efter noget tid kommer serveren mere eller mindre i orden. Og den gennemsnitlige responstid for anmodninger på Master-serveren vender tilbage til normalen. For endelig fik autostøvsugeren mulighed for at rense ud, markere disse deadlines. Og han begyndte at udføre sit arbejde. Og hvor hurtigt han gør det, så hurtigt vil vi være i orden.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

På testbordet, hvor vi opdaterer kontosaldierne, ser vi præcis det samme billede. Den gennemsnitlige kontoopdateringstid normaliseres også gradvist. De ressourcer, der forbruges af processoren, reduceres også. Og antallet af transaktioner pr. sekund er tilbage til det normale. Men igen, tilbage til normalen, ikke det samme, som vi havde før ulykken.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Under alle omstændigheder får vi en reduktion i ydeevnen, som i det første tilfælde, halvanden til to gange, og nogle gange endda mere.

Vi ser ud til at have gjort alt rigtigt. Fordel belastningen. Udstyret er ikke inaktivt. Ifølge sindet brød de anmodningerne, men alligevel gik alt dårligt.

  • Aktiverer du ikke hot_standby_feedback? Ja, det anbefales ikke at tænde det uden særlig stærke grunde. Fordi denne drejning direkte påvirker Master Server og suspenderer arbejdet med autovakuum der. Ved at slå det til på en eller anden kopi og glemme det, kan du dræbe Mesteren og få store problemer med applikationen.
  • Vil du øge max_standby_streaming_delay? Ja, for rapporter er det. Hvis du har en tre-timers rapport, og du ikke ønsker, at den skal gå ned på grund af replikeringskonflikter, skal du blot øge forsinkelsen. En lang rapport kræver aldrig data, der er kommet ind i databasen lige nu. Hvis du har det i tre timer, så kører du det i en gammel dataperiode. Og du, de tre timers forsinkelse, de seks timers forsinkelse - vil ikke spille nogen rolle, men du vil modtage rapporter konsekvent og ikke kende problemerne med deres fald.
  • Naturligvis skal du kontrollere lange sessioner på replikaer, især hvis du beslutter dig for at aktivere hot_standby_feedback på en replika. For det kan være hvad som helst. Vi gav denne bemærkning til udvikleren, så han ville teste anmodningerne. Han skrev en vanvittig anmodning. Han begyndte og gik for at drikke te, og vi fik den etablerede Mester. Eller vi lancerede den forkerte applikation der. Situationerne er forskellige. Sessioner på replikaer skal kontrolleres lige så omhyggeligt som på Master.
  • Og hvis du har hurtige og lange forespørgsler på replikaer, så er det i dette tilfælde bedre at opdele dem for at fordele belastningen. Dette er et link til streaming_delay. For hurtigt at have én replika med en lille replikeringsforsinkelse. For langvarige rapporteringsanmodninger skal du have en replika, der kan halte bagud med 6 timer om dagen. Dette er en helt normal situation.

Vi fjerner konsekvenserne på samme måde:

  • Vi finder oppustede borde.
  • Og vi komprimerer med det mest praktiske værktøj, der passer til os.

Den anden historie slutter her. Lad os gå videre til den tredje historie.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Også ret almindeligt for os, hvor vi foretager migreringen.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

  • Ethvert softwareprodukt vokser. Kravene ændrer sig. Vi vil i hvert fald gerne udvikle os. Og det sker, at vi skal opdatere dataene i tabellen, nemlig at køre opdateringen i forhold til vores migrering til den nye funktionalitet, som vi implementerer som en del af vores udvikling.
  • Det gamle dataformat passer ikke. Lad os sige, at vi nu vender os til den anden tabel, hvor jeg har operationer på disse konti. Og lad os sige, at de var i rubler, og vi besluttede at øge nøjagtigheden og gøre det i kopek. Og for dette skal vi lave en opdatering: gange feltet med mængden af ​​operationen med hundrede.
  • I dagens verden bruger vi automatiserede databaseversioneringsværktøjer. Lad os sige Liquibase. Vi registrerer vores migration dertil. Vi tester det på vores testbase. Alt er fint. Opdateringen kører. Blokke virker i et stykke tid, men vi får opdaterede data. Og vi kan lancere ny funktionalitet på dette. Alle testet og kontrolleret. Alle bekræftet.
  • Udførte planlagt arbejde, udført migrering.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Her er migreringen med opdateringen præsenteret foran dig. Da jeg har operationer på konti, var pladen 15 GB. Og da vi opdaterer hver linje, har vi fordoblet pladen med opdateringen, fordi vi har overskrevet hver linje.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Under migreringen kunne vi ikke gøre noget med denne etiket, fordi alle anmodninger om den blev sat i kø og ventede på, at denne opdatering var færdig. Men her vil jeg henlede din opmærksomhed på de tal, der er på den lodrette akse. Det vil sige, at vi har en gennemsnitlig anmodningstid før migrering i området på 5 millisekunder og en belastning på processoren, antallet af blokoperationer til læsning af diskhukommelse er mindre end 7,5.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Vi migrerede og fik problemer igen.

Migreringen lykkedes, men:

  • Den gamle funktionalitet begyndte at køre længere.
  • Bordet er igen vokset i størrelse.
  • Belastningen på serveren er igen blevet mere, end den var.
  • Og selvfølgelig roder vi stadig med den funktionalitet, der fungerede godt, vi forbedrede den lidt.

Og dette er igen oppustethed, som igen ødelægger vores liv.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Her demonstrerer jeg, at bordet, ligesom de to foregående tilfælde, ikke kommer til at vende tilbage til de tidligere størrelser. Den gennemsnitlige belastning på serveren ser ud til at være tilstrækkelig.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og hvis vi vender os til tabellen med regnskaber, så vil vi se, at den gennemsnitlige anmodningstid er fordoblet for denne tabel. Belastningen på processoren og antallet af linjer, der skal sorteres fra i hukommelsen, hoppede over 7,5, men det var lavere. Og hoppede i tilfælde af processorer med 2 gange, i tilfælde af blokoperationer med 1,5 gange, dvs. vi fik en forringelse af serverens ydeevne. Og som et resultat - forringelsen af ​​ydeevnen af ​​vores applikation. Samtidig forblev antallet af opkald nogenlunde på samme niveau.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Og her er det vigtigste at forstå, hvordan man gør sådanne migrationer korrekt. Og de skal gøres. Vi foretager disse migrationer ret regelmæssigt.

  • Sådanne store migreringer sker ikke automatisk. De skal altid kontrolleres.
  • Har brug for supervision fra en kyndig person. Hvis du har en DBA på holdet, så lad DBA gøre det. Det er hans job. Hvis ikke, så lad den mest erfarne person gøre det, som ved, hvordan man arbejder med databaser.
  • Det nye databaseskema, selvom vi opdaterer en kolonne, forbereder vi os altid i etaper, dvs. på forhånd før den nye version af applikationen ruller ud:
  • Der tilføjes nye felter, hvor vi kun skriver de opdaterede data.
  • Vi overfører data fra den gamle mark til den nye mark i små dele. Hvorfor gør vi dette? For det første kontrollerer vi altid processen i denne proces. Vi ved, at vi allerede har overført så mange partier, og vi har så mange tilbage.
  • Og den anden positive effekt er, at vi mellem hver sådan batch lukker en transaktion, åbner en ny, og dette gør det muligt for autovakuum at arbejde i henhold til pladen, at markere deadlines for genbrug.
  • For de linjer, der vises under driften af ​​applikationen (vi har stadig den gamle applikation), tilføjer vi en trigger, der skriver nye værdier til nye felter. I vores tilfælde er dette en multiplikation med hundrede af den gamle værdi.
  • Hvis vi er helt stædige og vil have det samme felt, så omdøber vi blot felterne efter afslutning af alle migreringer og inden vi ruller den nye version af applikationen. De gamle til et eller andet opfundet navn, og vi omdøber de nye felter til de gamle.
  • Og først efter det lancerer vi en ny version af applikationen.

Og på samme tid vil vi ikke få oppustethed og vil ikke synke i ydeevne.

Dette er slutningen på den tredje historie.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey 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

Og nu lidt mere om de værktøjer, som jeg nævnte i den allerførste historie.

Før du leder efter bloat, skal du installere udvidelsen pgstattuple.

For at du ikke skal opfinde anmodninger, har vi allerede skrevet disse anmodninger i vores arbejde. Du kan bruge dem. Der er to anmodninger her.

  • Den første tager ret lang tid, men den vil vise dig de nøjagtige værdier af oppustethed ifølge tabellen.
  • Den anden virker hurtigere og er meget effektiv, når du hurtigt skal vurdere, om der er en oppustethed eller ej i tabellen. Og du bør også forstå, at der altid er en oppustethed i et Postgres-bord. Dette er et træk ved hans MVCC-model.
  • Og 20% ​​oppustethed er fint til borde i de fleste tilfælde. Det vil sige, du skal ikke bekymre dig og komprimere denne tabel.

Vi fandt ud af, hvordan man identificerer tabeller, der er hævede hos os, desuden, når de er hævede med ubrugelige data.

Nu om, hvordan man løser oppustethed:

  • Hvis vi har en lille plade og gode diske, altså på en plade op til en gigabyte, er det sagtens muligt at bruge VACUUM FULL. Han vil tage en eksklusiv lås fra dig i et par sekunder, og okay, men han vil gøre alt hurtigt og hårdt. Hvad gør VACUUM FULL? Den tager en eksklusiv lås på bordet og omskriver live-rækkerne fra de gamle borde til det nye bord. Og til sidst erstatter han dem. Sletter gamle filer, erstatter nye med gamle. Men i hele sit arbejde tager den en eksklusiv lås på bordet. Det betyder, at du ikke kan gøre noget med denne tabel: hverken skrive til den, læse i den eller ændre den. Og VACUUM FULL kræver ekstra diskplads for at skrive data.
  • Næste værktøj pg_repack. I princippet minder den meget om VACUUM FULL, fordi den også overskriver data fra gamle filer til nye og erstatter dem i tabellen. Men samtidig tager den ikke en eksklusiv lås på bordet i begyndelsen af ​​sit arbejde, men tager den kun i det øjeblik, hvor den har færdige data for at erstatte filerne. Den har samme diskressourcekrav som VACUUM FULL. Du har brug for ekstra diskplads, og det er nogle gange kritisk, hvis du har terabyte-tabeller. Og han er ret glubsk på processoren, fordi han arbejder aktivt med I/O.
  • Det tredje værktøj er pgcompacttable. Den behandler ressourcer mere omhyggeligt, fordi den fungerer efter lidt andre principper. Hovedessensen af ​​pgcompacttable er, at den flytter alle live rækker til begyndelsen af ​​tabellen med opdateringer i tabellen. Og så starter det vakuum på dette bord, for vi ved, at vi har levende rækker i begyndelsen og døde rækker i slutningen. Og selve vakuumet afskærer denne hale, det vil sige, det kræver ikke meget ekstra diskplads. Og samtidig kan det stadig blive presset af ressourcer.

Alt med værktøj.

Typiske applikationsfejl, der fører til oppustethed i postgresql. Andrey Salnikov

Hvis du finder bloat-emnet interessant i forhold til at grave længere ind, så er her nogle nyttige links til dig:

Her forsøgte jeg at vise en skrækhistorie for udviklere, fordi de er vores direkte kunder af databaser og skal forstå, hvad og hvilke handlinger fører til. Jeg håber, det lykkedes. Tak for din opmærksomhed!

R'RѕRїSЂRѕSЃS <

Tak for rapporten! Du talte om, hvordan problemer kan identificeres. Hvordan kan de advares? Det vil sige, jeg havde en situation, hvor anmodninger hang, ikke kun fordi de henvendte sig til nogle eksterne tjenester. Det var bare nogle vilde joins. Der var nogle bittesmå, harmløse anmodninger, der hang rundt i en dag, og så begyndte at lave en eller anden form for nonsens. Det vil sige, at det minder meget om det, du beskriver. Hvordan sporer man det? Sidde og konstant se, hvilken anmodning sidder fast? Hvordan kan dette forhindres?

I dette tilfælde er det en opgave for administratorerne i din virksomhed, ikke nødvendigvis for DBA.

Jeg er administrator.

PostgreSQL har en visning kaldet pg_stat_activity, der viser afventende forespørgsler. Og du kan se, hvor længe den hænger der.

Jeg skal komme ind hvert 5. minut og kigge?

Opsæt cron og tjek. Hvis du har en lang anmodning, så skriv et brev, og det er det. Det vil sige, at du ikke behøver at se med øjnene, dette kan automatiseres. Du modtager et brev, du svarer på det. Eller du kan skyde automatisk.

Er der klare grunde til, at dette sker?

Jeg har nævnt nogle. Andre mere komplekse eksempler. Og der kan blive en lang samtale.

Tak for rapporten! Jeg ønskede at afklare om pg_repack-værktøjet. Hvis det ikke kræver en eksklusiv lås, så...

Hun laver en eksklusiv lås.

... så kan jeg potentielt miste data. Burde min app ikke optage noget på nuværende tidspunkt?

Nej, det fungerer stille og roligt med bordet, dvs. pg_repack overfører først alle de live linjer, der er der. Der er naturligvis en form for rekord i tabellen. Han kaster bare denne hestehale.

Det vil sige, gør han det stadig til sidst?

Til sidst kræver det en eksklusiv lås på at bytte disse filer.

Vil det være hurtigere end VACUUM FULL?

VACUUM FULL, som det startede, tog straks en eksklusiv lås. Og indtil han gør alt, vil han ikke lade hende gå. Og pg_repack tager kun en eksklusiv lås på tidspunktet for udskiftning af filer. På dette tidspunkt skriver du ikke der, men dataene går ikke tabt, alt vil være i orden.

Hej! Du talte om arbejdet med autovakuum. Der var en graf med røde, gule og grønne celler af posten. Det vil sige gule - han markerede dem som slettede. Og som et resultat, kan du skrive noget nyt i dem?

Ja. Postgres fjerner ikke rækker. Han har sådan en specificitet. Hvis vi opdaterede linjen, markerede vi den gamle som slettet. Transaktions-id'et, der ændrede denne linje, kommer derop, og vi skriver en ny linje. Og vi har sessioner, der potentielt kan læse dem. På et tidspunkt bliver de ret gamle. Og essensen af ​​autovakuum er, at det løber gennem disse linjer og markerer dem som unødvendige. Og der kan du overskrive dataene.

Jeg forstår. Men spørgsmålet handler ikke om det. Jeg var ikke enig. Lad os sige, at vi har et bord. Den har felter med variabel størrelse. Og hvis jeg forsøger at indsætte noget nyt, så passer det måske simpelthen ikke ind i den gamle celle.

Nej, der er i hvert fald hele linjen opdateret. Postgres har to opbevaringsmodeller. Den vælger fra datatypen. Der er data, der er gemt direkte i tabellen, og der er også tos-data. Disse er store mængder data: tekst, json. De opbevares i separate tabletter. Og ifølge disse tabletter sker den samme historie med oppustethed, det vil sige, at alt er det samme. De er blot opført separat.

Tak for rapporten! Hvor acceptabelt er det at bruge erklæringstimeoutanmodninger til at begrænse varigheden?

Meget acceptabelt. Vi bruger det overalt. Og da vi ikke har vores egne tjenester, yder vi fjernsupport, der er en række forskellige kunder. Og alle er ganske tilfredse med dette. Det vil sige, at vi har jobs i cron, der tjekker. Det er bare, at varigheden af ​​sessionerne forhandles med klienten, før som vi ikke negler. Det kunne være et minut, det kunne være 10 minutter. Det afhænger af belastningen på basen og dens formål. Men vi bruger alle pg_stat_activity.

Tak for rapporten! Jeg prøver at prøve din rapport til mine ansøgninger. Og det ser ud til, at vi starter en transaktion overalt, og vi fuldfører den eksplicit overalt. Hvis der er en undtagelse, sker den samme tilbagerulning. Og så tænkte jeg. Efter alt, kan transaktionen starte ikke eksplicit. Det er vel et tip til pigen. Hvis jeg bare laver en rekordopdatering, vil transaktionen starte i PostgreSQL og først slutte, når forbindelsen afbrydes?

Hvis du nu taler om applikationsniveauet, så afhænger det af den driver du bruger, af den ORM der bliver brugt. Der er mange indstillinger der. Hvis du har aktiveret automatisk commit på, starter en transaktion der og lukker med det samme.

Det vil sige, den lukker umiddelbart efter opdateringen?

Det afhænger af indstillingerne. Jeg navngav én indstilling. Dette er automatisk commit på. Hun er ret almindelig. Hvis det er aktiveret, blev transaktionen åbnet og lukket. Medmindre du udtrykkeligt sagde "start transaktion" og "afslut transaktion", men blot lancerede en anmodning i sessionen.

Hej! Tak for rapporten! Forestil dig, at vi har en database, der svulmer og svulmer, og så løber serveren tør for plads. Er der nogen værktøjer til at løse denne situation?

Stedet på serveren skal på en god måde overvåges.

Fx gik DBA for at drikke te, var på resort mv.

Når et filsystem oprettes, skabes der i det mindste noget reserveplads, hvor data ikke skrives.

Hvad hvis det er helt nul?

Der kaldes det reserveret plads, det vil sige, at det kan frigøres, og alt efter hvor stort det blev skabt, fik man fri plads. Som standard ved jeg ikke hvor mange der er. Og i et andet tilfælde skal du levere diske, så du har et sted at udføre en gendannelsesoperation. Du kan slette en tabel, som du med garanti ikke får brug for.

Er der ikke andre værktøjer?

Det er altid håndlavet. Og på stedet afsløres det, hvad der er bedre at gøre der, for der er data, der er kritiske, der er ikke-kritiske. Og for hver database og applikation, der arbejder med den, afhænger det af virksomheden. Det afgøres altid på stedet.

Tak for rapporten! Jeg har to spørgsmål. Først viste du slides, hvor det blev vist, at i tilfælde af hængte transaktioner vokser både mængden af ​​tablespace og størrelsen af ​​indekset. Og længere fremme i rapporten var der en masse hjælpeprogrammer, der pakker tabletten. Og hvad med indekset?

De pakker dem også.

Men vakuumet påvirker ikke indekset?

Nogle arbejder med et indeks. For eksempel pg_rapack, pgcompacttable. Vakuum genskaber indekser, påvirker dem. VACUUM FULL har essensen af ​​at overskrive alt, dvs. det virker med alle.

Og det andet spørgsmål. Jeg forstod ikke, hvorfor rapporter om replikaer afhænger så meget af selve replikeringen. Det forekom mig, at rapporter læser, og replikering er at skrive.

Hvad forårsager en replikationskonflikt? Vi har en Master, som processer finder sted på. Vi har en autovakuum. Autovacuum faktisk, hvad gør det? Han skærer nogle gamle streger ud. Hvis vi på dette tidspunkt har en anmodning på replikaen, der læser disse gamle linjer, og på Mesteren var der en situation, hvor autovakuum markerede disse linjer som mulige til omskrivning, så overskrev vi dem. Og vi modtog en datapakke, når vi skal omskrive de linjer, som anmodningen skal bruge på replikaen, så vil replikeringsprocessen vente på den timeout, du har konfigureret. Og så vil PostgreSQL beslutte, hvad der er vigtigere for det. Og replikering er vigtigere for ham end en anmodning, og han vil skyde anmodningen om at foretage disse ændringer på replikaen.

Andrew, jeg har et spørgsmål. Denne vidunderlige grafik, som du viste under præsentationen, er dette resultatet af noget arbejde i dit hjælpeprogram? Hvordan blev diagrammerne lavet?

Dette er en service Okmeter.

Er dette et kommercielt produkt?

Ja. Dette er et kommercielt produkt.

Kilde: www.habr.com

Tilføj en kommentar