{"id":81089,"date":"2020-05-11T01:42:24","date_gmt":"2020-05-10T23:42:24","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov"},"modified":"2020-05-11T01:42:24","modified_gmt":"2020-05-10T23:42:24","slug":"tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","title":{"rendered":"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Jeg vil gerne pr\u00e6sentere en gennemgang af rapporten fra begyndelsen af 2016 af Andrei Salkin \"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL\"<\/strong><\/p>\n<p><\/p>\n<p>I denne pr\u00e6sentation vil jeg gennemg\u00e5 de prim\u00e6re fejl i applikationer, der opst\u00e5r i designfasen og under kodningen af applikationen. Jeg vil kun tage de fejl, der f\u00f8rer til bloat i PostgreSQL. Som regel markerer dette begyndelsen p\u00e5 enden af din systems samlede ydeevne, selvom der i starten ikke var nogen \u00e5benlyse tegn p\u00e5 det.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a9e199bfe2e01c76966b32868790f8f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Jeg gl\u00e6der mig til at byde alle velkommen! Denne pr\u00e6sentation er ikke s\u00e5 teknisk som den forrige fra min kollega. Denne pr\u00e6sentation er prim\u00e6rt rettet mod udviklere af backend-systemer, fordi vi har et tilstr\u00e6kkeligt antal kunder. Og alle beg\u00e5r de samme fejl. Om dem vil jeg fort\u00e6lle jer. Jeg vil forklare, hvad disse fejl kan f\u00f8re til forf\u00e6rdelige og d\u00e5rlige konsekvenser. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c6c84dbafc595ae3068cd8bf804ccee7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvorfor opst\u00e5r fejltagelser? De opst\u00e5r af to grunde: ved at tage chancer, m\u00e5ske vil det g\u00e5, og p\u00e5 grund af manglende viden om de mekanismer, der sker mellem databasen og applikationen, samt i selve databasen. <\/p>\n<p><\/p>\n<p>Jeg vil give jer tre eksempler med forf\u00e6rdelige billeder af, hvordan alting er blevet d\u00e5rligt. Kort fort\u00e6lle om mekanismen, der foreg\u00e5r der, og hvordan man kan h\u00e5ndtere dem, n\u00e5r de opst\u00e5r, samt hvilke pr\u00e6ventive metoder der kan anvendes til at forhindre fejl. Jeg vil fort\u00e6lle om hj\u00e6lpemidler og give nyttige links. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b0230d992f5b44f0e542df2e4b4d526f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jeg brugte en testdatabase, hvor jeg havde to tabeller. Den ene tabel indeholdt kundernes konti, den anden med transaktioner p\u00e5 disse konti. Og med en vis regelm\u00e6ssighed opdaterer vi saldi p\u00e5 disse konti.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/1d2a21278b095b07546e1bb870819dbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Oprindelige data for tabellen: den er ret lille, 2 MB. Svar tiden p\u00e5 databasen og specifikt p\u00e5 tabellen er ogs\u00e5 meget god. Og en god belastning \u2013 2.000 operationer pr. sekund p\u00e5 tabellen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/dea5a4b1ac7952f8cfed0e2e1cfc10dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og gennem denne pr\u00e6sentation vil jeg vise jer grafikker, s\u00e5 det er tydeligt, hvad der sker. Der vil altid v\u00e6re 2 slides med grafer. Den f\u00f8rste slide viser, hvad der generelt sker p\u00e5 serveren. <\/p>\n<p><\/p>\n<p>Og i denne situation ser vi, at vores tabel virkelig er af lille st\u00f8rrelse. Indekset er lille p\u00e5 2 MB. Dette er den f\u00f8rste graf til venstre. <\/p>\n<p><\/p>\n<p>Den gennemsnitlige svartid p\u00e5 serveren er ogs\u00e5 stabil og lav. Dette er den \u00f8verste h\u00f8jre graf. <\/p>\n<p><\/p>\n<p>Den nederste venstre graf viser de l\u00e6ngste transaktioner. Vi kan se, at transaktioner udf\u00f8res hurtigt. Og auto-vakuumet fungerer endnu ikke, fordi det var en starttest. Fremadrettet vil det fungere og v\u00e6re nyttigt for os.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e9b46acd9a878ff70ca4a7850adff09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Den anden slide vil altid v\u00e6re dedikeret til den testede tabel. I denne situation opdaterer vi konstant balancerne p\u00e5 kundens konti. Og vi ser, at den gennemsnitlige svartid for opdateringsoperationen er ganske god, mindre end et millisekund. Vi kan ogs\u00e5 se, at CPU-ressourcerne (den \u00f8verste h\u00f8jre graf) forbruges j\u00e6vnt og i ganske sm\u00e5 m\u00e6ngder. <\/p>\n<p><\/p>\n<p>Den nederste h\u00f8jre graf viser, hvor meget operativ- og diskhukommelse vi gennemg\u00e5r i jagten p\u00e5 den n\u00f8dvendige linje, f\u00f8r vi opdaterer den. Og antallet af operationer p\u00e5 tabellen er 2.000 per sekund, som jeg n\u00e6vnte i begyndelsen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/84760d52716209b8dcfffb462c67a8e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og nu sker der en tragedie. Af en eller anden grund opst\u00e5r der en lang glemt transaktion. \u00c5rsagerne er som regel banale: <\/p>\n<p><\/p>\n<ul>\n<li>En af de mest almindelige \u00e5rsager er, at vi i applikationskoden er begyndt at anmode om en ekstern service. Og denne service svarer ikke. Det vil sige, at vi \u00e5bnede en transaktion, foretog en \u00e6ndring i databasen og gik for at l\u00e6se e-mails eller til en anden service inden for vores infrastruktur, og af en eller anden grund svarer den ikke. Og vi har en session, der h\u00e6nger i en tilstand \u2013 det er uklart, hvorn\u00e5r den vil blive l\u00f8st.<\/li>\n<li>Den anden situation opst\u00e5r, n\u00e5r der i koden af en eller anden grund opstod en exception. Og vi h\u00e5ndterede ikke lukningen af transaktionen i exception. Og vi har en h\u00e6ngende session med en \u00e5ben transaktion. <\/li>\n<li>Og den sidste \u2013 det er ogs\u00e5 et ret almindeligt tilf\u00e6lde. Det er d\u00e5rlig kvalitet p\u00e5 koden. Nogle frameworks \u00e5bner en transaktion. Den h\u00e6nger, og du kan v\u00e6re uvidende i applikationen om, at den h\u00e6nger. <\/li>\n<\/ul>\n<p><\/p>\n<p>Hvad f\u00f8rer s\u00e5danne ting til? <\/p>\n<p><\/p>\n<p>Til at vores tabeller og indekser begynder at svulme op. Det er lige pr\u00e6cis den effekt, vi kalder bloat. For databasen vil det udtrykke sig i, at vi pludselig f\u00e5r en dramatisk stigning i svartiden for databasen, og belastningen p\u00e5 database-serveren vil \u00f8ges. Og som f\u00f8lge heraf vil applikationen lide. Fordi hvis du i koden brugte 10 millisekunder p\u00e5 at anmode databasen, 10 millisekunder p\u00e5 din logik, s\u00e5 sluttede din funktion p\u00e5 20 millisekunder. Men nu vil din situation v\u00e6re helt trist. <\/p>\n<p><\/p>\n<p>Lad os se, hvad der sker. Den nederste venstre grafik viser, at vi har en langvarig transaktion. Og hvis vi ser p\u00e5 den \u00f8verste venstre grafik, kan vi se, at st\u00f8rrelsen p\u00e5 tabellen, som var 2 megabyte, pludselig er steget til 300 megabyte. Samtidig er m\u00e6ngden af data i tabellen ikke \u00e6ndret, dvs. der er en betydelig m\u00e6ngde affald.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b1947f6487e440a770a1251a955e62d2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Den overordnede situation med den gennemsnitlige serverresponsstid er ogs\u00e5 \u00e6ndret betydeligt. Dvs. alle anmodninger til serveren er begyndt at falde kraftigt. Og samtidig er interne PostgreSQL-processer, i form af autovacuum, startet, som pr\u00f8ver at g\u00f8re noget og bruger ressourcer.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/8e91f035d1dd04e72e842d714cc611a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvad sker der med vores tabel? Det samme. Den gennemsnitlige svarstid for tabellen er steget markant. Hvis vi ser specifikt p\u00e5 de forbrugte ressourcer, kan vi se, at belastningen p\u00e5 CPU'en er steget voldsomt. Dette er den \u00f8verste h\u00f8jre grafik. Og den er steget, fordi CPU'en skal sortere gennem en masse ubrugelige linjer p\u00e5 jagt efter \u00e9n, der er n\u00f8dvendig. Dette er den nederste h\u00f8jre grafik. Som et resultat er antallet af opkald pr. sekund begyndt at falde dramatisk, fordi databasen ikke kan behandles i samme omfang som f\u00f8r. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/424685ce852bc5f3ef77151f8d3d7289.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vi skal komme tilbage til livet. Vi g\u00e5r p\u00e5 internettet og finder ud af, at lange transaktioner f\u00f8rer til problemer. Vi identificerer og dr\u00e6ber denne transaktion. Og alt fungerer normalt. Alt fungerer som det skal. <\/p>\n<p><\/p>\n<p>Vi har taget det roligt, men efter et stykke tid begynder vi at bem\u00e6rke, at applikationen ikke fungerer som f\u00f8r h\u00e6ndelsen. Anmodningerne behandles stadig langsommere, og det er v\u00e6sentligt langsommere. I mit specifikke eksempel langsommere med 1,5-2 gange. Belastningen p\u00e5 serveren er ogs\u00e5 h\u00f8jere end f\u00f8r h\u00e6ndelsen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3037719a31f8d18fc42745716c4da5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og sp\u00f8rgsm\u00e5let er: 'Hvad sker der med databasen i dette \u00f8jeblik?'. Og med databasen sker der f\u00f8lgende. P\u00e5 transaktionsgrafikken kan du se, at den er stoppet, og der er faktisk ingen lange transaktioner. Men st\u00f8rrelsen p\u00e5 tabellen er dramatisk steget under h\u00e6ndelsen. Og siden da er den ikke blevet mindre. Den gennemsnitlige tid for databasen har stabiliseret sig. Og responsen ser ud til at v\u00e6re rimelig med en acceptabel hastighed for os. Autovacuum er blevet mere aktivt og er begyndt at h\u00e5ndtere tabellen, fordi det skal bearbejde en st\u00f8rre m\u00e6ngde data. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/f6205242c4024dc3ed4cade5844dbf76.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specifikt for den testede tabel med konti, hvor vi \u00e6ndrer saldoer: svartiden p\u00e5 anmodningen ser ud til at v\u00e6re tilbage til det normale. Men i virkeligheden er den 1,5 gange h\u00f8jere.<\/p>\n<p><\/p>\n<p>Og hvad ang\u00e5r belastningen p\u00e5 processoren, ser vi, at belastningen ikke er vendt tilbage til det \u00f8nskede niveau efter ulykken. \u00c5rsagerne ligger netop i det nederste h\u00f8jre diagram. Det er tydeligt, at der sker en overskridelse af noget hukommelse. Det vil sige, at vi bruger serverens database ressourcer p\u00e5 at gennemg\u00e5 un\u00f8dvendige data for at finde den \u00f8nskede r\u00e6kke. Antallet af transaktioner pr. sekund har stabiliseret sig. <\/p>\n<p><\/p>\n<p>Overordnet set er det godt, men situationen er v\u00e6rre end f\u00f8r. Der er en klar degradering af databasen som f\u00f8lge af vores applikation, der arbejder med denne database. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/0dfc9cd453fd84bc639ffd99cf189fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Og for at forst\u00e5, hvad der foreg\u00e5r, hvis du ikke var til det tidligere opl\u00e6g, s\u00e5 her er lidt teori. Teori om den interne proces. Hvad er autovacuum og hvad g\u00f8r det?<\/p>\n<p><\/p>\n<p>Bare kort for forst\u00e5elsens skyld. P\u00e5 et tidspunkt har vi en tabel. I tabellen har vi r\u00e6kker. Disse r\u00e6kker kan v\u00e6re aktive, levende, n\u00f8dvendige for os lige nu. P\u00e5 billedet er de markeret med gr\u00f8n farve. Og der er d\u00f8de r\u00e6kker, som allerede er blevet behandlet, er blevet opdateret, og hvor der er blevet tilf\u00f8jet nye poster. Og de er markeret som ikke interessante for databasen l\u00e6ngere. Men de ligger stadig i tabellen p\u00e5 grund af Postgres' egenskaber.<\/p>\n<p><\/p>\n<p>Hvad er form\u00e5let med autovacuum? Autovacuum kontakter p\u00e5 et tidspunkt databasen og sp\u00f8rger: \"Giv mig venligst id'et p\u00e5 den \u00e6ldste transaktion, der aktuelt er \u00e5ben i databasen.\" Databasen returnerer dette id. Og autovacuum, baseret p\u00e5 det, gennemg\u00e5r r\u00e6kkerne i tabellen. Og hvis det ser, at nogle r\u00e6kker er blevet \u00e6ndret af meget \u00e6ldre transaktioner, har det ret til at markere dem som r\u00e6kker, som vi kan genbruge i fremtiden ved at skrive nye data til dem. Dette er en baggrundsproces.<\/p>\n<p><\/p>\n<p>Imens forts\u00e6tter vi med at arbejde med databasen, forts\u00e6tter med at foretage \u00e6ndringer i tabellen. Og til de r\u00e6kker, vi kan genbruge, skriver vi nye data. Og s\u00e5ledes f\u00e5r vi et kredsl\u00f8b, hvor der hele tiden opst\u00e5r nogle d\u00f8de gamle r\u00e6kker, som vi i stedet skriver nye r\u00e6kker til, som vi har brug for. Og dette er en normal tilstand for at arbejde med PostgreSQL.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/98dd4451a7ca5f418775f72822c2840c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvad skete der under ulykken? Hvordan foregik denne proces der?<\/p>\n<p><\/p>\n<p>Vi havde en tabel i en eller anden tilstand, nogle r\u00e6kker var levende, og nogle var d\u00f8de. S\u00e5 kom autovakuum. Han spurgte databasen om, hvad der var den \u00e6ldste transaktion, og hvad dens id var. Han fik denne id, der kan v\u00e6re flere timer gammel, eller m\u00e5ske ti minutter. Det afh\u00e6nger af, hvor meget belastning du har p\u00e5 din database. Og s\u00e5 gik han p\u00e5 jagt efter r\u00e6kker, som han kunne markere som genbrugelige. Og han fandt ingen s\u00e5danne r\u00e6kker i vores tabel. <\/p>\n<p><\/p>\n<p>Men i mellemtiden forts\u00e6tter vi med at arbejde p\u00e5 tabellen. Vi g\u00f8r noget indeni, opdaterer, \u00e6ndrer data. Hvad skal databasen s\u00e5 g\u00f8re i mellemtiden? Den har ikke andet valg end at tilf\u00f8je nye r\u00e6kker i slutningen af den eksisterende tabel. Og p\u00e5 den m\u00e5de begynder st\u00f8rrelsen af tabellen at vokse. <\/p>\n<p><\/p>\n<p>Faktisk har vi brug for de gr\u00f8nne r\u00e6kker til vores arbejde. Men under et s\u00e5dant problem ender vi med, at procentdelen af de gr\u00f8nne r\u00e6kker er ekstremt lav i hele tabelens omfang. <\/p>\n<p><\/p>\n<p>N\u00e5r vi udf\u00f8rer en foresp\u00f8rgsel, er databasen n\u00f8dt til at gennemg\u00e5 alle r\u00e6kkerne: b\u00e5de de r\u00f8de og de gr\u00f8nne for at finde den rigtige r\u00e6kke. Og effekten af at tabe pladser til unyttige data kaldes \"bloat\", som ogs\u00e5 \u00e6der vores diskplads. Kan du huske, det var 2 MB, nu er det blevet 300 MB? Og nu skal du \u00e6ndre megabyte til gigabyte, s\u00e5 mister du hurtigt alle dine diskressourcer.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/fe7cb6b5c99610744ebcfe5ad7235d1e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvilke konsekvenser kan der v\u00e6re for os? <\/p>\n<p><\/p>\n<ul>\n<li>I mit eksempel voksede tabellen og indekset 150 gange. Nogle af vores kunder har haft mere fatale tilf\u00e6lde, hvor der simpelthen ikke var plads p\u00e5 disken. <\/li>\n<li>St\u00f8rrelsen p\u00e5 tabellerne vil aldrig falde af sig selv. Autovakuum kan i nogle tilf\u00e6lde sk\u00e6re enden af tabellen, hvis der kun er d\u00f8de r\u00e6kker. Men da der sker en konstant rotation, kan en gr\u00f8n r\u00e6kke h\u00e6nge i slutningen og ikke blive opdateret, mens alle andre bliver skrevet et eller andet sted i begyndelsen af tabellen. Men det er s\u00e5 usandsynligt, at din tabel vil falde i st\u00f8rrelse, at det ikke er v\u00e6rd at h\u00e5be p\u00e5. <\/li>\n<li>Databasen skal gennemg\u00e5 hele bunken af unyttige r\u00e6kker. Og vi bruger diskressourcer, CPU-ressourcer og elektricitet. <\/li>\n<li>Og det p\u00e5virker direkte vores applikation, fordi hvis vi i starten brugte 10 millisekunder p\u00e5 en foresp\u00f8rgsel, 10 millisekunder p\u00e5 vores kode, s\u00e5 begyndte vi under nedbruddet at bruge et sekund p\u00e5 foresp\u00f8rgslen og 10 millisekunder p\u00e5 koden, dvs. applikationens ydeevne faldt med en faktor. Og n\u00e5r nedbruddet blev l\u00f8st, begyndte vi at bruge 20 millisekunder p\u00e5 foresp\u00f8rgslen, 10 millisekunder p\u00e5 koden. Det betyder, at vi stadig er faldet med halvanden gang i ydeevne. Og det er alt sammen p\u00e5 grund af en transaktion, der hang, muligvis p\u00e5 grund af vores egen fejl. <\/li>\n<li>Og sp\u00f8rgsm\u00e5let er: \"Hvordan f\u00e5r vi det hele tilbage?\", s\u00e5 alt fungerer godt igen, og foresp\u00f8rgslerne k\u00f8rer lige s\u00e5 hurtigt som f\u00f8r nedbruddet. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/1bf46e8cd9b28ca2862f978f2ca85819.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Derfor er der en bestemt arbejdsproces, der udf\u00f8res. <\/p>\n<p><\/p>\n<p>F\u00f8rst skal vi finde de problematiske tabeller, som er vokset for meget. Vi forst\u00e5r, at nogle tabeller har en mere aktiv skrive aktivitet, mens andre har mindre. Og til dette bruges udvidelsen <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>. N\u00e5r du har installeret denne udvidelse, kan du skrive foresp\u00f8rgsler, der hj\u00e6lper dig med at finde de tabeller, der er vokset betydeligt. <\/p>\n<p><\/p>\n<p>N\u00e5r du har fundet disse tabeller, skal de komprimeres. Der er allerede v\u00e6rkt\u00f8jer til dette. I vores virksomhed bruger vi tre v\u00e6rkt\u00f8jer. Det f\u00f8rste \u2013 den indbyggede VACUUM FULL. Det er brutalt, h\u00e5rdt og ubarmhjertigt, men nogle gange er det meget nyttigt. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Pg_repack<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex> \u2013 det er tredjeparts v\u00e6rkt\u00f8jer til at komprimere tabeller. Og de er mere sk\u00e5nsomme over for databasen. <\/p>\n<p><\/p>\n<p>De bruges afh\u00e6ngigt af hvad der er mest praktisk for dig. Men jeg vil tale om det til sidst. Det vigtigste er, at der er tre v\u00e6rkt\u00f8jer. Der er valg. <\/p>\n<p><\/p>\n<p>N\u00e5r vi har rettet alt og sikret os, at alt er i orden, skal vi vide, hvordan vi kan forhindre denne situation i fremtiden:<\/p>\n<p><\/p>\n<ul>\n<li>Det er ret let at forebygge. Man skal holde \u00f8je med sessionernes varighed p\u00e5 Master-serveren. <strong>Is\u00e6r farlige sessioner i tilstanden idle in transaction<\/strong>. Det er dem, der lige har \u00e5bnet en transaktion, lavet noget og derefter forlod eller bare hang, mistede sig selv i koden. <\/li>\n<li>Og for jer, som udviklere, er det vigtigt at teste koden p\u00e5 tidspunktet for opst\u00e5en af disse situationer. Det er ikke sv\u00e6rt at g\u00f8re. Det vil v\u00e6re en nyttig kontrol. I vil undg\u00e5 mange \"b\u00f8rnesygdomme\" relateret til lange transaktioner. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/d55465d96c4018db733954867d23aaba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00e5 disse diagrammer ville jeg vise, hvordan tabellen og adf\u00e6rden i databasen \u00e6ndrede sig, efter at jeg i dette tilf\u00e6lde k\u00f8rte VACUUM FULL p\u00e5 tabellen. Dette er ikke i produktion.<\/p>\n<p><\/p>\n<p>St\u00f8rrelsen p\u00e5 tabellen vendte straks tilbage til en normal driftsstatus p\u00e5 et par megabyte. Det havde ikke stor indflydelse p\u00e5 den gennemsnitlige svartid p\u00e5 serveren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/cbb07ad24dba899395223d1ca25e438e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Men specifikt for vores testtabel, hvor vi opdaterede saldi p\u00e5 konti, ser vi, at den gennemsnitlige svartid for opdateringsforesp\u00f8rgsler er faldet til det pr\u00e6-katastrofale niveau. Ressourcerne, der forbruges af processoren til at udf\u00f8re denne foresp\u00f8rgsel, er ogs\u00e5 faldet til det pr\u00e6-katastrofale niveau. Og det h\u00f8jre nederste diagram viser, at vi nu hurtigt finder den \u00f8nskede r\u00e6kke uden at gennemg\u00e5 en masse d\u00f8de r\u00e6kker, som var til stede f\u00f8r komprimeringen af tabellen. Den gennemsnitlige foresp\u00f8rgselstid er dog forblevet omtrent p\u00e5 samme niveau. Men dette kan skyldes en fejlmargin i mit udstyr.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c1d90c5442e02fce209dc40e048a8ca2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dette afslutter den f\u00f8rste historie. Den er meget almindelig. Og den sker for alle, uanset kundens erfaring og hvor kvalificerede programm\u00f8rer der er. Det sker f\u00f8r eller siden. <\/p>\n<p><\/p>\n<p>Den anden historie, hvor vi fordelte belastningen og optimerede serverressourcerne.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/cda421c554d1329107ddc935045cc1b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Vi er vokset og er blevet seri\u00f8se. Vi forst\u00e5r, at vi har en replika, og det ville v\u00e6re godt at balancere belastningen: skrive til Master og l\u00e6se fra replika. Denne situation opst\u00e5r normalt, n\u00e5r vi \u00f8nsker at forberede nogle rapporter eller ETL. Og virksomheden er meget glad for det. De \u00f8nsker meget forskellige rapporter med kompleks analyse. <\/li>\n<li>Rapporter tager timer, fordi kompleks analyse ikke kan beregnes p\u00e5 millisekunder. Vi, som de seje fyre, skriver kode. Vi laver inds\u00e6tninger i applikationen, s\u00e5 vi skriver til Master og udf\u00f8rer rapporter p\u00e5 replika. <\/li>\n<li>Vi fordeler belastningen. <\/li>\n<li>Det hele fungerer glimrende. Vi er dygtige. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/e94c8c492197a5015ac8aae79389a4c2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvordan ser denne situation ud? Specifikt p\u00e5 disse diagrammer har jeg ogs\u00e5 tilf\u00f8jet varigheden af transaktioner fra replikaen. Alle andre diagrammer vedr\u00f8rer kun Master-serveren. <\/p>\n<p><\/p>\n<p>Rapport tabellen er vokset p\u00e5 dette tidspunkt. Der er blevet flere af dem. Vi kan se, at den gennemsnitlige svartid p\u00e5 serveren er stabil. Vi kan se, at der p\u00e5 replikaen er en langvarig transaktion, der k\u00f8rer i 2 timer. Vi ser, at autovacuumet arbejder tilfredsstillende og behandler d\u00f8de r\u00e6kker. Alt er godt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2da8acf098d12d6f146ab9b9dcb54b81.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specifikt vedr\u00f8rende den unders\u00f8gte tabel forts\u00e6tter vi med at opdatere saldoerne p\u00e5 kontiene. Og vi har ogs\u00e5 en stabil svartid p\u00e5 foresp\u00f8rgslerne, stabil ressourceforbrug. Alt er godt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/3621ef723017bac6fb635caf0a5f4de6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Alt er godt, indtil rapporterne begynder at blive afvist p\u00e5 grund af konflikter med replikationen. Og de afvises med konstant periodicitet. <\/p>\n<p><\/p>\n<p>Vi g\u00e5r p\u00e5 internettet og begynder at l\u00e6se, hvorfor dette sker. Og vi finder en l\u00f8sning. <\/p>\n<p><\/p>\n<p>Den f\u00f8rste l\u00f8sning er at \u00f8ge replikationsforsinkelsen. Vi ved, at vores rapport k\u00f8rer i 3 timer. Vi indstiller replikationsforsinkelsen til 3 timer. Vi starter alt, men vi har stadig problemer med, at rapporterne nogle gange bliver afvist. <\/p>\n<p><\/p>\n<p>Vi vil gerne have, at alt er perfekt. Vi dykker videre ned i informationen og finder en fantastisk indstilling - hot_standby_feedback. Vi aktiverer det. Hot_standby_feedback g\u00f8r det muligt for os at holde arbejdet med autovacuumet tilbage p\u00e5 Masteren. Dermed slipper vi helt for replikationskonflikter. Og alt fungerer godt med rapporterne.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3c315168bdd3f392d2e8a1c5861004.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvad sker der med Master-serveren i mellemtiden? Med Master-serveren er der totale problemer. Lige nu observerer vi graferne, n\u00e5r jeg har aktiveret begge disse indstillinger. Og vi kan se, at sessionen p\u00e5 replikaen p\u00e5 en eller anden m\u00e5de er begyndt at p\u00e5virke situationen p\u00e5 Master-serveren. Den p\u00e5virker faktisk, fordi den har suspenderet autovacuumet, der rydder d\u00f8de r\u00e6kker. St\u00f8rrelsen p\u00e5 tabellen er steget himmelh\u00f8jt igen. Den gennemsnitlige foresp\u00f8rgselstid i hele databasen er ogs\u00e5 steget himmelh\u00f8jt. Autovacuumene er blevet lidt mere pressede. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/980611dcce8b189dc50f422ffd3d2d72.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specifikt for vores tabel kan vi se, at dataopdateringen ogs\u00e5 er steget himmelh\u00f8jt. CPU-forbrugsniveauet er ogs\u00e5 steget meget. Vi gennemg\u00e5r igen et stort antal d\u00f8de, ubrugelige r\u00e6kker. Og svartiden for denne tabel, antallet af transaktioner, er faldet. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a648fd313a5dccf45f0056dc13c54263.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvordan vil det se ud, hvis vi ikke ved, hvad jeg har talt om tidligere?<\/p>\n<p><\/p>\n<ul>\n<li>Vi begynder at se efter problemer. Hvis vi har st\u00e5et overfor problemer i f\u00f8rste del, ved vi, at det kan skyldes en lang transaktion, og vi kigger p\u00e5 Master. Problemet er hos os p\u00e5 Master. Det ryster. Det varmer op, og dets Load Average er under hundrede. <\/li>\n<li>Anmodningerne der bremser, men vi ser ingen langvarige transaktioner. Og vi forst\u00e5r ikke, hvad problemet er. Vi ved ikke, hvor vi skal lede. <\/li>\n<li>Vi tjekker serverens udstyr. M\u00e5ske har vores RAID svigtet. M\u00e5ske er en RAM-brik br\u00e6ndt ud. Hvad som helst kan v\u00e6re tilf\u00e6ldet. Men nej, serverne er nye, og alt fungerer perfekt. <\/li>\n<li>Alle l\u00f8ber rundt: administratorer, udviklere og direkt\u00f8ren. Intet hj\u00e6lper. <\/li>\n<li>Og p\u00e5 et tidspunkt begynder alt pludselig at rette sig selv. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/7d4f6417bc5cb3cec33679d843c6661d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00e5 replikaen har vi i mellemtiden f\u00e5et en anmodning til at k\u00f8re og afslutte. Vi har modtaget en rapport. Virksomheden er stadig tilfreds. Som vi ser, er tabellen vokset igen og ser ikke ud til at ville mindske sig. P\u00e5 grafen med sessioner har jeg efterladt et stykke af denne lange transaktion fra replikaen, s\u00e5 I kan vurdere, hvor lang tid der g\u00e5r, f\u00f8r situationen stabiliserer sig. <\/p>\n<p><\/p>\n<p>Sessionen er forsvundet. Og f\u00f8rst efter noget tid kommer serveren mere eller mindre i orden. Og den gennemsnitlige svartid for anmodningerne p\u00e5 Master-serveren kommer tilbage til normalen. Fordi autobekr\u00e6ftelse endelig har f\u00e5et mulighed for at rense op, markere disse d\u00f8de r\u00e6kker. Og hvor hurtigt det g\u00f8r det, s\u00e5 hurtigt vil vi komme i orden.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/547d195e08de1566da818150a47218eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00e5 den testede tabel, hvor vi opdaterer balanceoplysningerne, ser vi et helt ensartet billede. Den gennemsnitlige opdateringstid for kontoen normaliseres ogs\u00e5 gradvist. Ressourcerne, der forbruges af CPU'en, falder ogs\u00e5. Og antallet af transaktioner pr. sekund vender tilbage til normal. Men igen, ikke til den norm, vi havde f\u00f8r uheldet. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/29372a5e9124690931485a7aea65befc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vi oplever i hvert fald et fald i ydeevnen, ligesom i f\u00f8rste tilf\u00e6lde, p\u00e5 en og halv til to gange, nogle gange endda mere. <\/p>\n<p><\/p>\n<p>Vi har tilsyneladende gjort alt rigtigt. Fordelt belastningen. Udstyret st\u00e5r ikke stille. Vi har fornuftigt opdelt anmodningerne, men det er stadig g\u00e5et d\u00e5rligt. <\/p>\n<p><\/p>\n<ul>\n<li>Skal hot_standby_feedback ikke aktiveres? Ja, det anbefales ikke at aktivere det uden gode grunde. Fordi denne indstilling p\u00e5virker Master-serveren direkte og s\u00e6nker autoscrubberens arbejde der. Hvis du aktiverer det p\u00e5 en replika og glemmer det, kan du dr\u00e6be Master og f\u00e5 store problemer med applikationen. <\/li>\n<li>Skal max_standby_streaming_delay \u00f8ges? Ja, det er s\u00e5dan for rapporter. Hvis du har en rapport, der tager tre timer, og du ikke \u00f8nsker, at den falder p\u00e5 grund af replikationskonflikter, s\u00e5 \u00f8g blot forsinkelsen. En lang rapport kr\u00e6ver aldrig data, der lige er kommet ind i databasen. Hvis den tager tre timer, betyder det, at du k\u00f8rer den for en \u00e6ldre periode. Og for dig betyder det ingen forskel om der er tre eller seks timers forsinkelse; du vil stadig f\u00e5 rapporterne stabilt uden problemer med nedbrud. <\/li>\n<li>Det er naturligvis n\u00f8dvendigt at overv\u00e5ge lange sessioner p\u00e5 de replikerede enheder, is\u00e6r hvis du har besluttet at aktivere hot_standby_feedback p\u00e5 en replika. For der kan ske hvad som helst. Du har givet denne replika til en udvikler for at teste foresp\u00f8rgsler. Han skrev en vanvittig foresp\u00f8rgsel. Startede og gik for at drikke te, mens vi fik en overbelastet Master. Eller vi gav ikke den rigtige applikation adgang. Situationerne er mangeartede. Sessioner p\u00e5 replikaer skal overv\u00e5ges lige s\u00e5 omhyggeligt som p\u00e5 Master. <\/li>\n<li>Og hvis du har hurtige og langvarige foresp\u00f8rgsler fra replikaer, s\u00e5 er det bedre at fordele belastningen ved at splitte dem op. Dette er en reference til streaming_delay. For hurtige foresp\u00f8rgsler, hav en replika med en lille replikationsforsinkelse. For lange rapporteringsforesp\u00f8rgsler, hav en replika, der kan v\u00e6re forsinket med 6 timer eller en dag. Det er en helt normal situation. <\/li>\n<\/ul>\n<p><\/p>\n<p>Vi afhj\u00e6lper konsekvenserne p\u00e5 samme m\u00e5de:<\/p>\n<p><\/p>\n<ul>\n<li>Vi finder oppustede tabeller.<\/li>\n<li>Og vi komprimerer dem med det mest hensigtsm\u00e6ssige v\u00e6rkt\u00f8j, vi har. <\/li>\n<\/ul>\n<p><\/p>\n<p>Den anden historie er slut her. Vi g\u00e5r videre til den tredje historie. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c8784e0be27883640cb8f6919a1c25e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Denne er ogs\u00e5 ret almindelig for os, hvor vi laver migration. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a04b9cd88a0e7e8a3b960ef930eb2657.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Ethvert softwareprodukt vokser. Kravene til det \u00e6ndres. Vi \u00f8nsker alle at udvikle os. Og nogle gange er det n\u00f8dvendigt at opdatere dataene i tabellen, nemlig at k\u00f8re en opdatering i forbindelse med vores migration for at implementere den nye funktionalitet, som vi indf\u00f8rer i l\u00f8bet af vores udvikling. <\/li>\n<li>Den gamle dataformat fungerer ikke l\u00e6ngere. Lad os antage, at vi nu henviser til den anden tabel, hvor jeg har operationer p\u00e5 disse konti. Og lad os sige, at de var i rubler, men vi har besluttet at \u00f8ge pr\u00e6cisionen og g\u00f8re det i kopejek. For dette skal vi lave en opdatering: feltet med operationsbel\u00f8bet skal ganges med hundrede. <\/li>\n<li>I den moderne verden bruger vi automatiserede v\u00e6rkt\u00f8jer til versionskontrol af databaser. Lad os antage, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a><\/noindex>. Vi skriver vores migration der. Tester den p\u00e5 vores testdatabase. Alt er godt. Opdateringen g\u00e5r igennem. Den blokerer arbejdet i et stykke tid, men vi f\u00e5r opdaterede data. Og vi kan k\u00f8re nye funktioner p\u00e5 dette. Alt er testet, kontrolleret. Alt er bekr\u00e6ftet. <\/li>\n<li>Vi har udf\u00f8rt planlagte arbejder, gennemf\u00f8rt migrationen. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e046583f7b1723fc1eaf61a03900918.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Her er migrationen med opdateringen pr\u00e6senteret for dig. Da det drejer sig om operationer p\u00e5 konti, var tabellen 15 GB stor. Og da vi opdaterer hver enkelt r\u00e6kke, har vi fordoblet st\u00f8rrelsen p\u00e5 tabellen med opdateringen, fordi vi har overskrevet hver r\u00e6kke. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/06120c98ea43d0568045e71935c23592.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Under migrationen kunne vi ikke g\u00f8re noget med denne tabel, fordi alle foresp\u00f8rgsler til den blev sat i k\u00f8 og ventede p\u00e5, at denne opdatering blev afsluttet. Men her vil jeg gerne henlede din opm\u00e6rksomhed p\u00e5 tallene p\u00e5 den lodrette akse. Det vil sige, at vi har den gennemsnitlige foresp\u00f8rgselstid f\u00f8r migrationen p\u00e5 omkring 5 millisekunder, og belastningen p\u00e5 CPU'en, antallet af blokoperationer til l\u00e6sning fra disken, er mindre end 7,5. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/69a3ba4d1d0cec7d39284e09e9d3055b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vi gennemf\u00f8rte migrationen og fik igen problemer. <\/p>\n<p><\/p>\n<p>Migrationen var vellykket, men:<\/p>\n<p><\/p>\n<ul>\n<li>Den gamle funktionalitet tog l\u00e6ngere tid at udf\u00f8re. <\/li>\n<li>Tabellen voksede igen i st\u00f8rrelse. <\/li>\n<li>Belastningen p\u00e5 serveren blev igen st\u00f8rre, end den var. <\/li>\n<li>Og selvf\u00f8lgelig, mens vi stadig besk\u00e6ftiger os med den funktionalitet, der tidligere fungerede godt, har vi forbedret den en smule. <\/li>\n<\/ul>\n<p><\/p>\n<p>Og dette er igen bloat, som skaber problemer for os. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/becd7cce3a1c8821c81c96257f41202b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Her viser jeg, at tabellen, ligesom i de tidligere to tilf\u00e6lde, ikke har t\u00e6nkt sig at vende tilbage til de tidligere st\u00f8rrelser. Den gennemsnitlige belastning p\u00e5 serveren synes at v\u00e6re passende. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4d703a60d43a3460bc3782d49865b690.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvis vi kigger p\u00e5 regnearkslisten, kan vi se, at den gennemsnitlige foresp\u00f8rgselstid er steget med det dobbelte i forhold til dette ark. Belastningen p\u00e5 CPU'en og antallet af gennemk\u00f8rte r\u00e6kker i hukommelsen er steget over 7,5, hvor det tidligere var lavere. Og CPU'ernes belastning er steget med det dobbelte, mens belastningen ved blokoperationer er steget med 1,5 gange, det vil sige, vi har oplevet en nedgang i serverens ydeevne. Og som en konsekvens \u2013 en nedgang i vores applikations ydeevne. I mellemtiden er antallet af kald forblevet p\u00e5 omtrent samme niveau. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/80772afa0643b29f5314a2482c9dfe0d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Her er det vigtigt at forst\u00e5, hvordan man korrekt udf\u00f8rer s\u00e5danne migrationer. Og de skal udf\u00f8res. Vi foretager ret konstant disse migrationer.<\/p>\n<p><\/p>\n<ul>\n<li>Store migrationer foretages ikke automatisk. De skal altid v\u00e6re kontrollerede. <\/li>\n<li>Der er behov for kontrol fra en person med viden. Hvis I har en DBA p\u00e5 holdet, s\u00e5 lad DBA'en g\u00f8re det. Det er hans job. Hvis ikke, s\u00e5 lad den mest erfarne person g\u00f8re det, som ved hvordan man arbejder med databaser. <\/li>\n<li>Den nye databaseskema, selv hvis vi blot opdaterer \u00e9n kolonne, bliver altid forberedt i faser, det vil sige p\u00e5 forh\u00e5nd f\u00f8r den nye version af applikationen bliver rullet ud:<\/li>\n<li>Der tilf\u00f8jes nye felter, hvor vi netop vil gemme de opdaterede data. <\/li>\n<li>Vi flytter data fra det gamle felt til det nye felt i sm\u00e5 portioner. Hvorfor g\u00f8r vi det? For det f\u00f8rste har vi altid kontrol over denne proces. Vi ved, at vi allerede har flyttet s\u00e5 mange batches, og at der er s\u00e5 mange tilbage. <\/li>\n<li>En anden fordel er, at mellem hver batch afslutter vi transaktionen, \u00e5bner en ny, og det giver mulighed for, at autovacuumet kan arbejde p\u00e5 tabellen og markere d\u00f8de r\u00e6kker til genbrug. <\/li>\n<li>For de r\u00e6kker, der vil dukke op under applikationens drift (vi har stadig den gamle applikation k\u00f8rende), tilf\u00f8jer vi en trigger, der skriver de nye v\u00e6rdier til de nye felter. I vores tilf\u00e6lde er det en gang med hundrede af den gamle v\u00e6rdi. <\/li>\n<li>Hvis vi er st\u00e6dige og \u00f8nsker at bruge det samme felt, s\u00e5 \u00e6ndrer vi blot navnene p\u00e5 felterne efter at alle migrationer er afsluttet, og f\u00f8r den nye version af applikationen rulles ud. De gamle navne gives et p\u00e5fundet navn, og de nye felter gives de gamle navne. <\/li>\n<li>Og f\u00f8rst efter dette starter vi den nye version af applikationen. <\/li>\n<\/ul>\n<p><\/p>\n<p>Og samtidig vil vi ikke opleve bloat og vil ikke falde i ydeevne. <\/p>\n<p><\/p>\n<p>Dette er slutningen p\u00e5 den tredje historie. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2afab2906b5ccd30e4c8772248818057.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Lad os nu se lidt n\u00e6rmere p\u00e5 de v\u00e6rkt\u00f8jer, jeg n\u00e6vnte i den f\u00f8rste historie. <\/p>\n<p><\/p>\n<p>F\u00f8r du begynder at lede efter bloat, skal du s\u00f8rge for at installere udvidelsen. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>For at du ikke skal finde p\u00e5 foresp\u00f8rgsler, har vi allerede skrevet disse foresp\u00f8rgsler i vores arbejde. Du kan bruge dem. Her pr\u00e6senteres to foresp\u00f8rgsler. <\/p>\n<p><\/p>\n<ul>\n<li>Den f\u00f8rste k\u00f8rer relativt l\u00e6nge, men den viser dig n\u00f8jagtige bloatv\u00e6rdier for tabellen. <\/li>\n<li>Den anden k\u00f8rer hurtigere og er meget effektiv, n\u00e5r du hurtigt skal vurdere \u2013 om der er bloat eller ej i tabellen. Og du skal ogs\u00e5 forst\u00e5, at bloat i en Postgres-tabel altid er til stede. Det er en funktion i dens MVCC-model. <\/li>\n<li>Og 20 % bloat er normalt for tabeller i de fleste tilf\u00e6lde. Det vil sige, at du ikke beh\u00f8ver at bekymre dig og komprimere denne tabel. <\/li>\n<\/ul>\n<p><\/p>\n<p>Hvordan man identificerer tabeller, der er blevet oppustet, har vi fundet ud af, is\u00e6r n\u00e5r de er blevet oppustet med ubrugelige data. <\/p>\n<p><\/p>\n<p>Nu til, hvordan man retter bloat:<\/p>\n<p><\/p>\n<ul>\n<li>Hvis vi har en lille tabel og gode drev, det vil sige, at for en tabel p\u00e5 op til en gigabyte, kan VACUUM FULL bruges. Den vil tage en eksklusiv l\u00e5s p\u00e5 tabellen i et par sekunder, men til geng\u00e6ld g\u00f8r den det hurtigt og effektivt. Hvad g\u00f8r VACUUM FULL? Den tager en eksklusiv l\u00e5s p\u00e5 tabellen og kopierer de levende r\u00e6kker fra gamle tabeller til en ny tabel. Og til sidst bytter den dem om. De gamle filer slettes, nye erstatter de gamle. Men under sin arbejdsproces tager den en eksklusiv l\u00e5s p\u00e5 tabellen. Dette betyder, at du ikke kan g\u00f8re noget med denne tabel: hverken skrive til, l\u00e6se fra eller modificere den. Og VACUUM FULL kr\u00e6ver ekstra plads p\u00e5 disken for at skrive dataene.<\/li>\n<li>Det n\u00e6ste v\u00e6rkt\u00f8j <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">pg_repack<\/a><\/noindex>. I princippet minder det meget om VACUUM FULL, fordi det ogs\u00e5 omskriver data fra gamle filer til nye og udskifter dem i tabellen. Men i begyndelsen tager det ikke en eksklusiv l\u00e5s p\u00e5 tabellen, men f\u00f8rst n\u00e5r det har de n\u00f8dvendige data klar til at udskifte filerne. Kravene til diskressourcer er de samme som ved VACUUM FULL. Du har brug for ekstra plads p\u00e5 disken, og det kan v\u00e6re kritisk, hvis du har terabyte store tabeller. Og det er ogs\u00e5 ret kr\u00e6vende for processoren, fordi det arbejder aktivt med input\/output. <\/li>\n<li>Det tredje v\u00e6rkt\u00f8j er <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex>Den er mere sk\u00e5nsom mod ressourcerne, fordi den arbejder lidt ud fra andre principper. Hovedideen med pgcompacttable er, at den med opdateringer i tabellen flytter alle aktive r\u00e6kker til begyndelsen af tabellen. Derefter k\u00f8rer den vacuum p\u00e5 denne tabel, fordi vi ved, at vi har de aktive i starten og de d\u00f8de i slutningen. Vacuumet sk\u00e6rer s\u00e5 selv den hale af, s\u00e5 det kr\u00e6ver ikke meget ekstra diskplads. Og samtidig kan det ogs\u00e5 optimeres i forhold til ressourcerne. <\/li>\n<\/ul>\n<p><\/p>\n<p>Med v\u00e6rkt\u00f8jerne er alt i orden. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typiske fejl i applikationer, der f\u00f8rer til bloat i PostgreSQL. Andrey Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4187915e54e54a0b85a342fe0280f78f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hvis emnet med bloat virker interessant for dig i forhold til at grave dybere, s\u00e5 her er nogle nyttige links:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres\">https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres<\/a><\/noindex> \u2013 det er en pr\u00e6sentation af min kollega. Den er generel omkring, hvor pladsen g\u00e5r hen i Postgres under dens drift og liv. Og der er en meget stor og detaljeret teknisk sektion for databaseadministratorer om bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\">https:\/\/github.com\/dataegret\/pg-utils<\/a><\/noindex> \u2013 det er et link til vores repository, hvor vi gemmer en masse nyttige scripts til at tjekke databasens tilstand. Her kan du finde scripts til at finde bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Tredje<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">fjerde<\/a><\/noindex> links til v\u00e6rkt\u00f8jer, der kan hj\u00e6lpe dig med at optimere tabeller. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html\">http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html<\/a><\/noindex> \u2013 det er et indl\u00e6g fra min kollega. Der forklarer han bloat ganske grundigt og teknisk, is\u00e6r p\u00e5 et niveau t\u00e6ttere p\u00e5 administratorerne. <\/li>\n<\/ul>\n<p><\/p>\n<p>Jeg har her fors\u00f8gt at vise skr\u00e6mmebilleder for udviklerne, fordi de er vores direkte kunder af databaserne og skal forst\u00e5, hvilke handlinger f\u00f8rer til hvad. Jeg h\u00e5ber, jeg har lykkedes med det. Tak for opm\u00e6rksomheden!<\/p>\n<p><\/p>\n<p>Sp\u00f8rgsm\u00e5l<\/p>\n<p><\/p>\n<p><em>Tak for pr\u00e6sentationen! Du talte om, hvordan man kan identificere problemer. Men hvordan kan man forebygge dem? Jeg havde en situation, hvor foresp\u00f8rgsler h\u00e6ngte, ikke kun fordi de henvendte sig til eksterne tjenester. Det var simpelthen nogle vilde joins. Der var nogle sm\u00e5, harml\u00f8se foresp\u00f8rgsler, der hang i et d\u00f8gn, og derefter begyndte at lave noget sk\u00f8rt. Det ligner meget det, du beskriver. Hvordan kan man holde \u00f8je med det? Skal man sidde og konstant kigge p\u00e5, hvilken foresp\u00f8rgsel der h\u00e6nger? Hvordan kan man forebygge det?<\/em><\/p>\n<p><\/p>\n<p>I dette tilf\u00e6lde er det en opgave for administratorerne i jeres virksomhed, ikke n\u00f8dvendigvis for DBA'er.<\/p>\n<p><\/p>\n<p><em>Jeg er administrator.<\/em><\/p>\n<p><\/p>\n<p>I PostgreSQL er der en visning kaldet pg_stat_activity, hvor h\u00e6ngende foresp\u00f8rgsler vises. Og du kan se, hvor l\u00e6nge den har h\u00e6ngt der.<\/p>\n<p><\/p>\n<p><em>Skal jeg tjekke hver 5. minut?<\/em><\/p>\n<p><\/p>\n<p>S\u00e6t cron op og kontroller. Hvis du har en langvarig foresp\u00f8rgsel, s\u00e5 skriv en e-mail, og det er det. Det vil sige, at du ikke beh\u00f8ver at holde \u00f8je med det, det kan automatiseres. Du f\u00e5r en e-mail, og du reagerer p\u00e5 den. Eller du kan skyde den af automatisk.<\/p>\n<p><\/p>\n<p><em>Er der klare grunde til, at dette sker?<\/em><\/p>\n<p><\/p>\n<p>Jeg har n\u00e6vnt nogle. Andre er mere komplekse eksempler. Og der kan v\u00e6re en lang samtale.<\/p>\n<p><\/p>\n<p><em>Tak for rapporten! Jeg ville gerne pr\u00e6cisere noget om v\u00e6rkt\u00f8jet pg_repack. Hvis det ikke laver en eksklusiv l\u00e5s, s\u00e5\u2026<\/em><\/p>\n<p><\/p>\n<p>Det laver en eksklusiv l\u00e5s. <\/p>\n<p><\/p>\n<p>\u2026 <em>s\u00e5 kan jeg potentielt miste data. M\u00e5 mit program ikke skrive noget i mellemtiden?<\/em><\/p>\n<p><\/p>\n<p>Nej, det fungerer fint med tabellen, det vil sige, at pg_repack f\u00f8rst overf\u00f8rer alle de levende r\u00e6kker, der findes. Naturligvis sker der et eller andet skrivning til tabellen. Det er bare det sidste stykke, der tilf\u00f8jes. <\/p>\n<p><\/p>\n<p><em>Det vil sige, at det g\u00f8r det til sidst?<\/em><\/p>\n<p><\/p>\n<p>Til sidst tager det en eksklusiv l\u00e5s for at bytte de filer om. <\/p>\n<p><\/p>\n<p><em>Bliver det hurtigere end VACUUM FULL?<\/em><\/p>\n<p><\/p>\n<p>VACUUM FULL, s\u00e5 snart det starter, tager straks en eksklusiv l\u00e5s. Og indtil det er f\u00e6rdigt, slipper det ikke. Men pg_repack tager en eksklusiv l\u00e5s kun i det \u00f8jeblik, hvor filerne udskiftes. P\u00e5 det tidspunkt kan du ikke skrive der, men dataene g\u00e5r ikke tabt, alt vil v\u00e6re i orden. <\/p>\n<p><\/p>\n<p><em>Hej! Du fortalte om hvordan autovacuum fungerer. Der var et diagram med r\u00f8de, gule og gr\u00f8nne celler til optagelse. Det vil sige, at de gule er blevet markeret som slettet. Og som f\u00f8lge deraf kan man skrive noget nyt i dem?<\/em><\/p>\n<p><\/p>\n<p>Ja. Postgres sletter ikke r\u00e6kker. Det er dens s\u00e6rlige karakteristika. Hvis vi opdaterer en r\u00e6kke, markerer vi den gamle som slettet. Der s\u00e6ttes en transaktions-id, der \u00e6ndrede denne r\u00e6kke, og vi skriver den nye r\u00e6kke. Og vi har sessioner, der potentielt kan l\u00e6se dem. P\u00e5 et tidspunkt bliver de meget gamle. Og essensen af autovacuumets arbejde er, at det g\u00e5r igennem disse r\u00e6kker og markerer dem som un\u00f8dvendige. Og man kan overskrive data der. <\/p>\n<p><\/p>\n<p><em>Jeg forst\u00e5r. Men sp\u00f8rgsm\u00e5let handler lidt om noget andet. Jeg n\u00e5ede ikke at sige det. Antag, at vi har en tabel. Der er felter med variabel st\u00f8rrelse. Og hvis jeg fors\u00f8ger at inds\u00e6tte noget nyt, s\u00e5 kan det simpelthen ikke v\u00e6re plads i den gamle celle.<\/em> <\/p>\n<p><\/p>\n<p>Nej, hele linjen opdateres i hvert fald. I Postgres er der to datalagringsmodeller. Den v\u00e6lges ud fra datatypen. Nogle data gemmes direkte i tabellen, mens der ogs\u00e5 er tos-data. Det er store datam\u00e6ngder: tekst, json. De gemmes i separate tabeller. Og for disse tabeller sker der det samme med bloat, dvs. alt er det samme. Bare de er adskilt. <\/p>\n<p><\/p>\n<p><em>Tak for pr\u00e6sentationen! Hvor acceptabelt er det at bruge statement timeout for at begr\u00e6nse varigheden af foresp\u00f8rgsler?<\/em><\/p>\n<p><\/p>\n<p>Meget acceptabelt. Vi bruger det overalt. Da vi ikke har vores egne tjenester, men yder fjernsupport, har vi ganske forskellige kunder. Og alle er ret tilfredse med dette. Dvs. vi har opgaver i cron, der tjekker. Det aftales blot med kunden, hvor l\u00e6nge sessionerne skal vare, f\u00f8r vi afbryder. Det kan v\u00e6re et minut, det kan v\u00e6re 10 minutter. Det afh\u00e6nger af belastningen p\u00e5 databasen og dens form\u00e5l. Men vi bruger pg_stat_activity hos alle.<\/p>\n<p><\/p>\n<p><em>Tak for pr\u00e6sentationen! Jeg pr\u00f8ver at tilpasse din pr\u00e6sentation til mine applikationer. Og det ser ud til, at vi altid starter en transaktion, og altid afslutter den eksplicit. Hvis der opst\u00e5r en exception, bliver der stadig udf\u00f8rt rollback. Og her t\u00e6nkte jeg p\u00e5 det. Det er muligt, at transaktionen kan starte uden at v\u00e6re eksplicit. Det er en anmodning til pigen, tror jeg. Hvis jeg blot opdaterer en post, vil transaktionen starte i PostgreSQL og afsluttes f\u00f8rst, n\u00e5r forbindelsen afbrydes?<\/em><\/p>\n<p><\/p>\n<p>Hvis du taler om applikationsniveauet, s\u00e5 afh\u00e6nger det af den driver, du bruger, og den ORM, der anvendes. Der er mange indstillinger. Hvis auto commit er aktiveret, s\u00e5 starter transaktionen og afsluttes med det samme.<\/p>\n<p><\/p>\n<p><em>Dvs. den afsluttes lige efter opdateringen?<\/em><\/p>\n<p><\/p>\n<p>Det afh\u00e6nger af indstillingerne. En indstilling har jeg n\u00e6vnt. Det er auto commit on. Den er ret udbredt. Hvis den er aktiveret, \u00e5bnes og lukkes transaktionen. Hvis du ikke eksplicit har sagt \"start transaction\" og \"end transaction\", men blot har startet en foresp\u00f8rgsel i sessionen. <\/p>\n<p><\/p>\n<p><em>Hej! Tak for pr\u00e6sentationen! Lad os forestille os, at vi har en database, som vokser og vokser, og pludselig slipper der plads p\u00e5 serveren. Er der nogle v\u00e6rkt\u00f8jer til at rette op p\u00e5 denne situation?<\/em> <\/p>\n<p><\/p>\n<p>Pladsen p\u00e5 serveren b\u00f8r ideelt set overv\u00e5ges. <\/p>\n<p><\/p>\n<p><em>For eksempel, hvis DBA'en er g\u00e5et for at drikke te, eller var p\u00e5 ferie osv.<\/em><\/p>\n<p><\/p>\n<p>N\u00e5r et filsystem oprettes, bliver der i det mindste oprettet noget reserveret plads, hvor data ikke skrives. <\/p>\n<p><\/p>\n<p><em>Og hvis det helt skal ned til nul?<\/em><\/p>\n<p><\/p>\n<p>Det kaldes faktisk reserved space, dvs. det kan frig\u00f8res afh\u00e6ngigt af hvor stort det er blevet oprettet, og s\u00e5 har du lidt frit plads. Som standard ved jeg ikke, hvor meget der er der. I et andet tilf\u00e6lde skal man levere diske, s\u00e5 du har plads til at udf\u00f8re en genoprettelsesoperation. Man kan slette en tabel, som du garanteret ikke har brug for. <\/p>\n<p><\/p>\n<p><em>Er der ingen andre v\u00e6rkt\u00f8jer?<\/em><\/p>\n<p><\/p>\n<p>Det er altid manuelt arbejde. Og p\u00e5 stedet findes der en vurdering af, hvad man bedst kan g\u00f8re, fordi der er kritiske og ikke-kritiske data. Og for hver database og det program, der arbejder med det, afh\u00e6nger det af forretningen. Det besluttes altid p\u00e5 stedet. <\/p>\n<p><\/p>\n<p><em>Tak for pr\u00e6sentationen! Jeg har to sp\u00f8rgsm\u00e5l. For det f\u00f8rste viste du dias, hvor det blev demonstreret, at i tilf\u00e6lde af h\u00e6ngende transaktioner stiger b\u00e5de st\u00f8rrelsen af tabelrummet og st\u00f8rrelsen af indekset. Og l\u00e6ngere fremme i pr\u00e6sentationen var der en hel del v\u00e6rkt\u00f8jer, der pakker tabellen. Hvad med indekset?<\/em><\/p>\n<p><\/p>\n<p>De pakker dem ogs\u00e5. <\/p>\n<p><\/p>\n<p><em>Men vakuum p\u00e5virker ikke indekset?<\/em><\/p>\n<p><\/p>\n<p>Nogle arbejder med indekset. For eksempel pg_rapack, pgcompacttable. Vakuum genskaber indekserne, det p\u00e5virker dem. Hovedideen med VACUUM FULL er at omskrive alt, dvs. det arbejder med alt. <\/p>\n<p><\/p>\n<p><em>Og det andet sp\u00f8rgsm\u00e5l. Jeg forstod ikke, hvorfor rapporter p\u00e5 replikaer s\u00e5 meget afh\u00e6nger af selve replikationen. Jeg troede, at rapporter var l\u00e6sning, mens replikation var skrivning.<\/em> <\/p>\n<p><\/p>\n<p>Hvor opst\u00e5r konflikten i replikationen? Vi har en Master, hvor processerne finder sted. Der er en autovakuum. Hvad g\u00f8r autovakuum i praksis? Det fjerner nogle gamle r\u00e6kker. Hvis vi p\u00e5 det tidspunkt har en foresp\u00f8rgsel p\u00e5 replikaen, der l\u00e6ser disse gamle r\u00e6kker, og p\u00e5 Masteren er der sket en situation, hvor autovakuum har markeret disse r\u00e6kker som mulige til overskrivning, s\u00e5 overskriver vi dem. Og s\u00e5 kommer der et datapakke, n\u00e5r vi skal overskrive de r\u00e6kker, der er n\u00f8dvendige for foresp\u00f8rgslen p\u00e5 replikaen, vil replikationsprocessen vente p\u00e5 den timeout, som du har indstillet. Og s\u00e5 vil PostgreSQL afg\u00f8re, hvad der er vigtigere for det. Og replikation er vigtigere for det end foresp\u00f8rgslen, s\u00e5 det vil give slip p\u00e5 foresp\u00f8rgslen for at udf\u00f8re disse \u00e6ndringer p\u00e5 replikaen. <\/p>\n<p><\/p>\n<p><em>Andr\u00e9, jeg har et sp\u00f8rgsm\u00e5l. Er disse fantastiske grafer, som du viste under pr\u00e6sentationen, resultatet af et eller andet v\u00e6rkt\u00f8j, du har lavet? Hvilket program blev brugt til at lave graferne?<\/em><\/p>\n<p><\/p>\n<p>Det er en tjeneste <noindex><a rel=\"nofollow\" href=\"https:\/\/okmeter.io\/\">Okmeter<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><em>Er dette et kommercielt produkt?<\/em><\/p>\n<p><\/p>\n<p>Ja. Dette er et kommercielt produkt.<\/p>\n<p>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/501040\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u0432\u043e\u0437\u044c\u043c\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 Postgresql. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":81090,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-81089","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Typiske fejl i applikationer, der for\u00e5rsager bloat i PostgreSQL. Andr\u00e9 Salnikov | ProHoster","description":"Jeg foresl\u00e5r, at du tager et kig p\u00e5 optagelsen af Andreas Salnikovs rapport fra begyndelsen af 2016 \"Typiske fejl i applikationer, der for\u00e5rsager bloat i PostgreSQL\". I denne rapport vil jeg gennemg\u00e5 de grundl\u00e6ggende.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-10T23:42:24+00:00","article:modified_time":"2020-05-10T23:42:24+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"81089","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:05:22","updated":"2022-09-27 16:01:50","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/81089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=81089"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/81089\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/81090"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=81089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=81089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=81089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}