{"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\/sv\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","title":{"rendered":"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Jag vill att ni ska ta del av sammanfattningen av rapporten fr\u00e5n b\u00f6rjan av 2016 av Andrey Salnikov \"Typiska fel i applikationer som leder till bloat i PostgreSQL\"<\/strong><\/p>\n<p><\/p>\n<p>I den h\u00e4r rapporten kommer jag att g\u00e5 igenom de vanligaste felen i applikationer som uppst\u00e5r under design- och kodningsfasen av applikationen. Jag kommer endast att ta upp de fel som leder till bloat i PostgreSQL. Vanligtvis \u00e4r detta b\u00f6rjan p\u00e5 slutet f\u00f6r systemets prestanda som helhet, \u00e4ven om det fr\u00e5n b\u00f6rjan inte fanns n\u00e5gra tecken p\u00e5 detta.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej 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>Jag h\u00e4lsar er alla v\u00e4lkomna! Denna f\u00f6rel\u00e4sning \u00e4r inte lika teknisk som den f\u00f6reg\u00e5ende fr\u00e5n min kollega. Den h\u00e4r f\u00f6rel\u00e4sningen riktar sig fr\u00e4mst till utvecklare av backend-system, eftersom vi har ett ganska stort antal kunder. Och alla g\u00f6r samma misstag. Det \u00e4r om dessa jag kommer att ber\u00e4tta. Jag kommer att f\u00f6rklara vilka katastrofala och negativa konsekvenser dessa fel kan leda till. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c6c84dbafc595ae3068cd8bf804ccee7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Varf\u00f6r uppst\u00e5r felen? De uppst\u00e5r av tv\u00e5 anledningar: antingen genom tur, att det kanske fungerar, eller av okunskap om vissa mekanismer som h\u00e4nder p\u00e5 niv\u00e5n mellan databasen och applikationen, samt i sj\u00e4lva databasen. <\/p>\n<p><\/p>\n<p>Jag kommer att ge er tre exempel med hemska bilder av hur allt blev d\u00e5ligt. Jag kommer kort att beskriva de mekanismer som f\u00f6rekommer d\u00e4r. Och hur man kan hantera dem n\u00e4r de intr\u00e4ffar, samt vilka f\u00f6rebyggande metoder som kan anv\u00e4ndas f\u00f6r att undvika fel. Jag kommer att ber\u00e4tta om hj\u00e4lpprogram och ge anv\u00e4ndbara l\u00e4nkar. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b0230d992f5b44f0e542df2e4b4d526f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jag anv\u00e4nde en testdatabas d\u00e4r jag hade tv\u00e5 tabeller. En tabell f\u00f6r kundkonton och den andra f\u00f6r transaktioner p\u00e5 dessa konton. Med viss periodicitet uppdaterar vi saldona p\u00e5 dessa konton.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/1d2a21278b095b07546e1bb870819dbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ursprungliga data f\u00f6r tabellen: den \u00e4r ganska liten, 2 MB. Svarstiden f\u00f6r databasen och specifikt f\u00f6r tabellen \u00e4r ocks\u00e5 mycket bra. Och en ganska bra belastning \u2013 2 000 operationer per sekund p\u00e5 tabellen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/dea5a4b1ac7952f8cfed0e2e1cfc10dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Och genom denna f\u00f6rel\u00e4sning kommer jag att visa er grafer s\u00e5 att det tydligt ska framg\u00e5 vad som h\u00e4nder. Det kommer alltid att finnas 2 bilder med grafer. Den f\u00f6rsta bilden visar vad som h\u00e4nder i allm\u00e4nhet p\u00e5 servern. <\/p>\n<p><\/p>\n<p>Och i denna situation ser vi att vi verkligen har en tabell av liten storlek. Indexet \u00e4r litet, p\u00e5 2 MB. Detta \u00e4r den f\u00f6rsta grafen till v\u00e4nster. <\/p>\n<p><\/p>\n<p>Den genomsnittliga svarstiden f\u00f6r servern \u00e4r ocks\u00e5 stabil och l\u00e5g. Detta \u00e4r den \u00f6vre grafen till h\u00f6ger. <\/p>\n<p><\/p>\n<p>Den nedersta v\u00e4nstra grafen visar de l\u00e4ngsta transaktionerna. Vi ser att transaktionerna genomf\u00f6rs snabbt. Och autovakuum fungerar \u00e4nnu inte h\u00e4r, eftersom det var ett starttest. Fram\u00f6ver kommer det att fungera och vara till nytta f\u00f6r oss.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e9b46acd9a878ff70ca4a7850adff09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Den andra bilden kommer alltid att handla om den testade tabellen. I den h\u00e4r situationen uppdaterar vi kontinuerligt saldot p\u00e5 kundens konton. Och vi ser att den genomsnittliga svarstiden f\u00f6r uppdateringsoperationen \u00e4r ganska bra, mindre \u00e4n en millisekund. Vi ser ocks\u00e5 att CPU-resurserna (det \u00e4r den \u00f6vre h\u00f6gra grafen) f\u00f6rbrukas j\u00e4mnt och i ganska sm\u00e5 m\u00e4ngder. <\/p>\n<p><\/p>\n<p>Den nedre h\u00f6gra grafen visar hur mycket operativ och diskminne vi g\u00e5r igenom i s\u00f6kandet efter v\u00e5r n\u00f6dv\u00e4ndiga rad innan vi uppdaterar den. Och antalet operationer p\u00e5 tabellen \u2013 2000 per sekund, precis som jag n\u00e4mnde tidigare. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/84760d52716209b8dcfffb462c67a8e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Och nu h\u00e4nder det en tragedi. Av n\u00e5gon anledning uppst\u00e5r en l\u00e5ng gl\u00f6md transaktion. Orsakerna \u00e4r vanligtvis banala: <\/p>\n<p><\/p>\n<ul>\n<li>En av de vanligaste situationerna \u00e4r att vi i applikationskoden b\u00f6rjar anropa en extern tj\u00e4nst. Och den tj\u00e4nsten svarar inte oss. Det vill s\u00e4ga, vi \u00f6ppnade en transaktion, gjorde en \u00e4ndring i databasen och gick f\u00f6r att l\u00e4sa e-post i applikationen eller till en annan tj\u00e4nst i v\u00e5r infrastruktur, och av n\u00e5gon anledning svarar den inte oss. Och v\u00e5r session h\u00e4nger i ett tillst\u00e5nd \u2013 oklart n\u00e4r det ska l\u00f6sas.<\/li>\n<li>Den andra situationen \u00e4r n\u00e4r det i koden av n\u00e5gon anledning uppstod ett undantag. Och vi i undantaget inte hanterade st\u00e4ngningen av transaktionen. Och vi har f\u00e5tt en h\u00e4ngande session med en \u00f6ppen transaktion. <\/li>\n<li>Och den sista \u2013 det \u00e4r ocks\u00e5 ett ganska vanligt fall. Det handlar om underm\u00e5lig kod. Vissa ramverk \u00f6ppnar en transaktion. Den h\u00e4nger, och du kan vara ovetande om att den h\u00e4nger i applikationen. <\/li>\n<\/ul>\n<p><\/p>\n<p>Vad leder s\u00e5dana saker till? <\/p>\n<p><\/p>\n<p>Till att v\u00e5ra tabeller och index b\u00f6rjar sv\u00e4lla kraftigt. Det h\u00e4r \u00e4r just den effekt som kallas bloat. F\u00f6r databasen kommer det att inneb\u00e4ra att vi f\u00e5r en dramatisk \u00f6kning i databasens svarstid, \u00f6kad belastning p\u00e5 databasservern. Och som ett resultat kommer applikationen att lida. F\u00f6r om du i koden tog 10 millisekunder f\u00f6r en f\u00f6rfr\u00e5gan till databasen, 10 millisekunder f\u00f6r din logik, s\u00e5 fungerade din funktion p\u00e5 20 millisekunder. Men nu kommer situationen att bli helt sorglig. <\/p>\n<p><\/p>\n<p>L\u00e5t oss se vad som h\u00e4nder. Den v\u00e4nstra nedre grafen visar att vi har en l\u00e5ngvarig transaktion. Och om vi tittar p\u00e5 den v\u00e4nstra \u00f6vre grafen ser vi att storleken p\u00e5 tabellen, som var tv\u00e5 megabyte, pl\u00f6tsligt har \u00f6kat till 300 megabyte. Samtidigt har m\u00e4ngden data i tabellen inte f\u00f6r\u00e4ndrats, dvs. det finns en stor m\u00e4ngd skr\u00e4p.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b1947f6487e440a770a1251a955e62d2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Den \u00f6vergripande situationen f\u00f6r medelservartid har ocks\u00e5 f\u00f6r\u00e4ndrats flera g\u00e5nger. Det vill s\u00e4ga alla f\u00f6rfr\u00e5gningar till servern har b\u00f6rjat sjunka kraftigt. Samtidigt har interna Postgres-processer i form av autovakuum startat, som f\u00f6rs\u00f6ker g\u00f6ra n\u00e5got och f\u00f6rbrukar resurser.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/8e91f035d1dd04e72e842d714cc611a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vad h\u00e4nder med v\u00e5r tabell? Samma sak. Medel svarstid f\u00f6r tabellen har \u00f6kat flera g\u00e5nger. N\u00e4r vi ser p\u00e5 de anv\u00e4nda resurserna, ser vi att belastningen p\u00e5 processorn har \u00f6kat kraftigt. Det \u00e4r den \u00f6vre h\u00f6gra grafen. Den har \u00f6kat eftersom processorn m\u00e5ste g\u00e5 igenom massor av v\u00e4rdel\u00f6sa rader f\u00f6r att hitta en enda som beh\u00f6vs. Det \u00e4r den nedre h\u00f6gra grafen. Som ett resultat har antalet anrop per sekund b\u00f6rjat sjunka kraftigt eftersom databasen inte hinner bearbeta samma m\u00e4ngd f\u00f6rfr\u00e5gningar. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/424685ce852bc5f3ef77151f8d3d7289.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vi m\u00e5ste komma tillbaka till livet. Vi g\u00e5r in p\u00e5 internet och f\u00e5r reda p\u00e5 att l\u00e5ngvariga transaktioner orsakar problem. Vi hittar och d\u00f6dar denna transaktion. Och nu fungerar allt som det ska. Allt fungerar bra. <\/p>\n<p><\/p>\n<p>Vi lugnar ner oss, men efter ett tag b\u00f6rjar vi m\u00e4rka att applikationen inte fungerar som den gjorde f\u00f6re incidenten. F\u00f6rfr\u00e5gningar bearbetas fortfarande l\u00e5ngsammare, och faktiskt betydligt l\u00e5ngsammare. I mitt fall \u00e4r det en och en halv till tv\u00e5 g\u00e5nger l\u00e5ngsammare. Belastningen p\u00e5 servern \u00e4r ocks\u00e5 h\u00f6gre \u00e4n den var f\u00f6re incidenten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3037719a31f8d18fc42745716c4da5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Och fr\u00e5gan \u00e4r: \"Vad h\u00e4nder med databasen vid det tillf\u00e4llet?\". Med databasen sker f\u00f6ljande: I grafen f\u00f6r transaktioner ser ni att den har stannat och det finns verkligen inga l\u00e5ngvariga transaktioner d\u00e4r. Men storleken p\u00e5 tabellen har under incidenten \u00f6kat katastrofalt. Och har inte minskat sedan dess. Medeltiden f\u00f6r databasen har stabiliserats. Svaren verkar komma fram i en acceptabel hastighet f\u00f6r oss. Autovakuum har blivit mer aktivt och har b\u00f6rjat g\u00f6ra n\u00e5got med tabellen, f\u00f6r det beh\u00f6ver bearbeta en st\u00f6rre m\u00e4ngd data. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/f6205242c4024dc3ed4cade5844dbf76.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specifikt f\u00f6r den testade fakturatabellen, d\u00e4r vi \u00e4ndrar saldon: svarstiden p\u00e5 f\u00f6rfr\u00e5gan verkar ha \u00e5terg\u00e5tt till det normala. Men i sj\u00e4lva verket \u00e4r den en och en halv g\u00e5ng h\u00f6gre.<\/p>\n<p><\/p>\n<p>Och n\u00e4r det g\u00e4ller CPU-belastningen ser vi att den inte har \u00e5terg\u00e5tt till r\u00e4tt niv\u00e5 innan kraschen. Orsaken d\u00f6ljer sig precis i den nedre h\u00f6gra grafen. Det \u00e4r tydligt att n\u00e5got slags minnes\u00f6verskott sker d\u00e4r. D.v.s. f\u00f6r att hitta den n\u00f6dv\u00e4ndiga raden f\u00f6rbrukar vi serverresurser i databasen n\u00e4r vi g\u00e5r igenom on\u00f6diga data. Antalet transaktioner per sekund har stabiliserats. <\/p>\n<p><\/p>\n<p>\u00d6verlag \u00e4r det bra, men situationen \u00e4r v\u00e4rre \u00e4n vad den var. En tydlig nedg\u00e5ng i databasen som en f\u00f6ljd av v\u00e5r applikation som arbetar med denna databas. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/0dfc9cd453fd84bc639ffd99cf189fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Och f\u00f6r att f\u00f6rst\u00e5 vad som h\u00e4nder d\u00e4r, om ni inte var p\u00e5 den f\u00f6reg\u00e5ende presentationen, s\u00e5 kommer lite teori nu. Teorin om den interna processen. Vad \u00e4r autovakuum och vad g\u00f6r det?<\/p>\n<p><\/p>\n<p>Kort sagt f\u00f6r att f\u00f6rst\u00e5. Vid n\u00e5gon tidpunkt har vi en tabell. I tabellen finns rader. Dessa rader kan vara aktiva, livliga, viktiga f\u00f6r oss nu. P\u00e5 bilden \u00e4r de markerade i gr\u00f6nt. Och det finns d\u00f6da rader, som redan har anv\u00e4nts, har uppdaterats, nya poster har tillkommit. De \u00e4r markerade eftersom de inte l\u00e4ngre intresserar databasen. Men de ligger kvar i tabellen p\u00e5 grund av PostgreSQL:s egenskaper.<\/p>\n<p><\/p>\n<p>Vad beh\u00f6vs autovakuum f\u00f6r? Autovakuum kommer vid n\u00e5got tillf\u00e4lle, kontaktar databasen och fr\u00e5gar: \"Ge mig v\u00e4nligen id f\u00f6r den \u00e4ldsta transaktionen som f\u00f6r n\u00e4rvarande \u00e4r \u00f6ppen i databasen.\" Databasen returnerar detta id. Och autovakuum, baserat p\u00e5 detta, g\u00e5r igenom raderna i tabellen. Om det ser att vissa rader har f\u00f6r\u00e4ndrats av betydligt \u00e4ldre transaktioner, har det r\u00e4tt att markera dem som rader som vi kan \u00e5teranv\u00e4nda i framtiden genom att skriva nya data d\u00e4r. Detta \u00e4r en bakgrundsprocess.<\/p>\n<p><\/p>\n<p>Under tiden forts\u00e4tter vi att arbeta med databasen, forts\u00e4tter att g\u00f6ra olika \u00e4ndringar i tabellen. Och p\u00e5 dessa rader, som vi kan \u00e5teranv\u00e4nda, skriver vi ny data. P\u00e5 s\u00e5 s\u00e4tt f\u00e5r vi ett kretslopp, d.v.s. hela tiden uppst\u00e5r det d\u00f6da gamla rader, ist\u00e4llet skriver vi nya rader som vi beh\u00f6ver. Och detta \u00e4r ett normalt tillst\u00e5nd f\u00f6r att arbeta med PostgreSQL.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/98dd4451a7ca5f418775f72822c2840c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vad h\u00e4nde under kraschen? Hur gick processen till d\u00e4r?<\/p>\n<p><\/p>\n<p>Vi hade en tabell i n\u00e5got tillst\u00e5nd, vissa rader levande och andra d\u00f6da. Autofragmentering kom. Den fr\u00e5gade databasen om vilken som var v\u00e5r \u00e4ldsta transaktion och vilket id den hade. Den fick det id som kan vara flera timmar gammalt eller bara tio minuter. Det beror p\u00e5 hur h\u00f6g belastning ni har i databasen. Sedan b\u00f6rjade den leta efter rader som den kan m\u00e4rka som \u00e5teranv\u00e4ndbara. Men den hittade inga s\u00e5dana rader i v\u00e5r tabell. <\/p>\n<p><\/p>\n<p>Men under tiden forts\u00e4tter vi att arbeta med tabellen. Vi g\u00f6r n\u00e5got i den, uppdaterar, \u00e4ndrar data. Vad har databasen att g\u00f6ra under tiden? Den har inget annat att g\u00f6ra \u00e4n att skriva nya rader i slutet av den befintliga tabellen. P\u00e5 s\u00e5 s\u00e4tt b\u00f6rjar storleken p\u00e5 tabellen att \u00f6ka. <\/p>\n<p><\/p>\n<p>F\u00f6r v\u00e5rt arbete beh\u00f6ver vi egentligen gr\u00f6na rader. Men under ett s\u00e5dant problem f\u00e5r vi att procentandelen gr\u00f6na rader \u00e4r extremt l\u00e5g i hela tabellen. <\/p>\n<p><\/p>\n<p>N\u00e4r vi g\u00f6r en f\u00f6rfr\u00e5gan m\u00e5ste databasen g\u00e5 igenom alla rader: b\u00e5de r\u00f6da och gr\u00f6na, f\u00f6r att hitta den n\u00f6dv\u00e4ndiga raden. Effekten av att tabellen svullnar upp med on\u00f6diga data kallas 'bloat', som ocks\u00e5 slukar v\u00e5rt diskutrymme. Kommer ni ih\u00e5g, det var 2 MB, nu \u00e4r det 300 MB? Och nu, byt megabyte mot gigabyte s\u00e5 kommer ni snabbt att f\u00f6rlora alla era disresurser.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/fe7cb6b5c99610744ebcfe5ad7235d1e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vilka konsekvenser kan det f\u00e5 f\u00f6r oss? <\/p>\n<p><\/p>\n<ul>\n<li>I mitt exempel har tabellen och indexet vuxit med 150 g\u00e5nger. Hos vissa av v\u00e5ra kunder har det intr\u00e4ffat mer fatala fall n\u00e4r det helt enkelt b\u00f6rjar ta slut p\u00e5 diskutrymme. <\/li>\n<li>Storleken p\u00e5 tabellerna minskar aldrig av sig sj\u00e4lv. Autofragmentering kan i vissa fall klippa av svansen p\u00e5 tabellen om det bara finns d\u00f6da rader. Men eftersom en konstant rotation sker kan en gr\u00f6n rad h\u00e4nga kvar i slutet och inte uppdateras, medan alla andra kommer att skrivas n\u00e5gonstans i b\u00f6rjan av tabellen. Men det \u00e4r ett s\u00e5 osannolikt scenario att ni inte b\u00f6r hoppas p\u00e5 att er tabell kommer att minska i storlek. <\/li>\n<li>Databasen m\u00e5ste g\u00e5 igenom hela h\u00f6gen av on\u00f6diga rader. Och vi sl\u00f6sar med disresurser, sl\u00f6sar med CPU-resurser och elektricitet. <\/li>\n<li>Och detta p\u00e5verkar direkt v\u00e5r applikation, f\u00f6r om vi i b\u00f6rjan anv\u00e4nde 10 millisekunder f\u00f6r en beg\u00e4ran, 10 millisekunder f\u00f6r v\u00e5r kod, s\u00e5 b\u00f6rjade vi under kraschen att anv\u00e4nda en sekund f\u00f6r beg\u00e4ran och 10 millisekunder f\u00f6r koden, det vill s\u00e4ga applikationens prestanda sj\u00f6nk ordentligt. N\u00e4r kraschen l\u00f6stes b\u00f6rjade vi anv\u00e4nda 20 millisekunder f\u00f6r beg\u00e4ran och 10 millisekunder f\u00f6r koden. Det betyder att vi fortfarande har en prestandaf\u00f6rlust p\u00e5 en och en halv g\u00e5ng. Och allt detta p\u00e5 grund av en transaktion som fryst, m\u00f6jligtvis p\u00e5 v\u00e5rt fel. <\/li>\n<li>Och fr\u00e5gan \u00e4r: \"Hur f\u00e5r vi tillbaka allt?\" S\u00e5 att allt fungerar bra och beg\u00e4rningarna g\u00e5r lika snabbt som f\u00f6re kraschen. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/1bf46e8cd9b28ca2862f978f2ca85819.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>F\u00f6r detta finns en viss arbetscykel som genomf\u00f6rs. <\/p>\n<p><\/p>\n<p>F\u00f6rst m\u00e5ste vi hitta de problematiska tabellerna som har svullnat. Vi f\u00f6rst\u00e5r att f\u00f6r vissa tabeller g\u00e5r inspelningen mer aktivt, f\u00f6r andra mindre aktivt. Och f\u00f6r detta anv\u00e4nds till\u00e4gget <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>. Genom att installera detta till\u00e4gg kan du skriva fr\u00e5gor som hj\u00e4lper dig att hitta tabeller som har svullnat kraftigt. <\/p>\n<p><\/p>\n<p>Efter att du har funnit dessa tabeller m\u00e5ste de komprimeras. F\u00f6r detta finns redan verktyg. I v\u00e5rt f\u00f6retag anv\u00e4nder vi tre verktyg. Den f\u00f6rsta \u00e4r den inbyggda VACUUM FULL. Den \u00e4r grym, strikt och obarmh\u00e4rtig, men ibland \u00e4r den mycket anv\u00e4ndbar. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Pg_repack<\/a><\/noindex> och <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex> \u2013 detta \u00e4r externa verktyg f\u00f6r komprimering av tabeller. Och de \u00e4r mer skonsamma mot databasen. <\/p>\n<p><\/p>\n<p>De anv\u00e4nds beroende p\u00e5 vad som \u00e4r mer bekv\u00e4mt f\u00f6r dig. Men jag kommer att ber\u00e4tta mer om detta i slutet. Det viktiga \u00e4r att det finns tre verktyg. Det finns att v\u00e4lja p\u00e5. <\/p>\n<p><\/p>\n<p>Efter att vi har gjort alla korrigeringar och s\u00e4kerst\u00e4llt att allt fungerar bra, m\u00e5ste vi veta hur vi hindrar denna situation i framtiden:<\/p>\n<p><\/p>\n<ul>\n<li>Det \u00e4r ganska enkelt att f\u00f6rebygga. Man beh\u00f6ver h\u00e5lla koll p\u00e5 l\u00e4ngden p\u00e5 sessionerna p\u00e5 m\u00e4sterservern. <strong>S\u00e4rskilt farliga sessioner i tillst\u00e5ndet idle in transaction<\/strong>. Det \u00e4r de som precis har \u00f6ppnat en transaktion, gjort n\u00e5got och sedan g\u00e5tt d\u00e4rifr\u00e5n eller bara fryst, f\u00f6rlorat sig i koden. <\/li>\n<li>Och f\u00f6r er, som utvecklare, \u00e4r det viktigt att testa koden vid uppkomsten av s\u00e5dana situationer. Det \u00e4r inte sv\u00e5rt att g\u00f6ra. Det kommer att vara en nyttig kontroll. Ni undviker m\u00e5nga \"barnsjukdomar\" relaterade till l\u00e5nga transaktioner. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/d55465d96c4018db733954867d23aaba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I wanted to show you on these graphs how the table and database behavior changed after I performed a VACUUM FULL on the table. This is not in production.<\/p>\n<p><\/p>\n<p>The table size immediately returned to a normal working state of a few megabytes. This did not significantly affect the average response time on the server. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/cbb07ad24dba899395223d1ca25e438e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>However, specifically for our test table, where we updated the account balances, we see that the average response time for the data update query has decreased to pre-incident levels. The CPU resources consumed for executing this query have also fallen to pre-incident levels. The bottom right graph shows that we are now finding exactly the row we need immediately, without sifting through a bunch of dead rows that existed before the table compression. The average query response time has remained approximately at the same level, but here I might have a deviation due to my hardware.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c1d90c5442e02fce209dc40e048a8ca2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>This concludes the first story. It is the most common one and happens to everyone, regardless of the client's experience or how qualified the programmers are. Sooner or later, this occurs. <\/p>\n<p><\/p>\n<p>The second story, where we distribute the load and optimize server resources.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/cda421c554d1329107ddc935045cc1b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>We have grown and become quite serious. We understand that we have a replica and it would be good to balance the load: write to the Master and read from the replica. This situation usually arises when we want to prepare some reports or ETL. The business is very pleased with this. It greatly desires various reports with plenty of complex analysis. <\/li>\n<li>The reports take hours, as complex analytics can't be computed in milliseconds. We, as diligent folks, write the code. We perform inserts in the application, writing to the Master and executing reports on the replica. <\/li>\n<li>We distribute the load. <\/li>\n<li>Everything works excellently. We are doing great. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/e94c8c492197a5015ac8aae79389a4c2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>And how does this situation look? Specifically on these graphs, I also added the duration of transactions from the replica. All other graphs pertain only to the Master server. <\/p>\n<p><\/p>\n<p>Rapporttabellen har vuxit vid det h\u00e4r laget. Vi ser att den genomsnittliga svarstiden f\u00f6r servern \u00e4r stabil. Vi noterar att det finns en l\u00e5ngvarig transaktion p\u00e5 repliken som p\u00e5g\u00e5r i tv\u00e5 timmar. Vi ser att autovakuumen arbetar lugnt och bearbetar d\u00f6da rader. Allt \u00e4r bra. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2da8acf098d12d6f146ab9b9dcb54b81.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specifikt f\u00f6r den aktuella tabellen forts\u00e4tter vi att uppdatera saldon. Vi har ocks\u00e5 stabil svarstid f\u00f6r f\u00f6rfr\u00e5gan och stabil resursanv\u00e4ndning. Allt \u00e4r bra. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/3621ef723017bac6fb635caf0a5f4de6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Allt \u00e4r bra tills dessa rapporter b\u00f6rjar skjutas upp p\u00e5 grund av konflikter med replikationen. De skjuts upp med konstant periodicitet. <\/p>\n<p><\/p>\n<p>Vi g\u00e5r ut p\u00e5 n\u00e4tet och b\u00f6rjar l\u00e4sa varf\u00f6r detta h\u00e4nder. Och vi hittar en l\u00f6sning. <\/p>\n<p><\/p>\n<p>Den f\u00f6rsta l\u00f6sningen \u00e4r att \u00f6ka replikationsf\u00f6rdr\u00f6jningen. Vi vet att v\u00e5r rapport tar tre timmar. Vi s\u00e4tter replikationsf\u00f6rdr\u00f6jningen till tre timmar. Vi startar allt, men vi har fortfarande problem med att rapporterna ibland skjuts upp. <\/p>\n<p><\/p>\n<p>Vi vill att allt ska vara perfekt. Vi forts\u00e4tter leta. Och vi hittar en fantastisk inst\u00e4llning p\u00e5 n\u00e4tet \u2013 hot_standby_feedback. Vi aktiverar det. Hot_standby_feedback l\u00e5ter oss h\u00e5lla autovakuumets arbete p\u00e5 Master. P\u00e5 s\u00e5 s\u00e4tt slipper vi helt konflikter vid replikation. Allt fungerar bra med rapporterna.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3c315168bdd3f392d2e8a1c5861004.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Och vad h\u00e4nder med Master-servern under tiden? Med Master-servern har vi total katastrof. Just nu observerar vi graferna n\u00e4r jag aktiverade b\u00e5da dessa inst\u00e4llningar. Vi ser att sessionen p\u00e5 repliken p\u00e5 n\u00e5got s\u00e4tt b\u00f6rjar p\u00e5verka situationen p\u00e5 Master-servern. Det p\u00e5verkar verkligen, eftersom den har pausat autovakuumet som rensar d\u00f6da rader. Storleken p\u00e5 tabellen har \u00e5terigen skjutit i h\u00f6jden. Den genomsnittliga fr\u00e5getiden f\u00f6r hela databasen har ocks\u00e5 skjutit i h\u00f6jden. Autovakuumen har blivit n\u00e5got anstr\u00e4ngda. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/980611dcce8b189dc50f422ffd3d2d72.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Specifikt f\u00f6r v\u00e5r tabell ser vi att datan ocks\u00e5 har skjutit i h\u00f6jden. Resursanv\u00e4ndningen f\u00f6r CPU har ocks\u00e5 \u00f6kat kraftigt. Vi g\u00e5r \u00e5terigen igenom ett stort antal d\u00f6da, meningsl\u00f6sa rader. Och svarstiden f\u00f6r denna tabell och antalet transaktioner har minskat. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a648fd313a5dccf45f0056dc13c54263.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hur skulle det se ut om vi inte visste vad jag pratat om tidigare?<\/p>\n<p><\/p>\n<ul>\n<li>Vi b\u00f6rjar leta efter problem. Om vi har st\u00f6tt p\u00e5 problem i f\u00f6rsta delen vet vi att det kan bero p\u00e5 en l\u00e5ng transaktion och vi kollar p\u00e5 Master. Problemet finns p\u00e5 v\u00e5r Master. Den har problem. Den blir varm och dess Load Average n\u00e4rmar sig hundra. <\/li>\n<li>F\u00f6rfr\u00e5gningar d\u00e4r h\u00e4nger sig, men vi ser inga l\u00e5ngvariga transaktioner. Och vi f\u00f6rst\u00e5r inte vad som \u00e4r fel. Vi f\u00f6rst\u00e5r inte var vi ska leta. <\/li>\n<li>Vi kontrollerar serverh\u00e5rdvaran. Kanske har v\u00e5r raid kraschat. Kanske har ett minnesmodul brunnit. Vad som helst kan h\u00e4nda. Men nej, servrarna \u00e4r nya, allt fungerar utm\u00e4rkt. <\/li>\n<li>Alla springer omkring: administrat\u00f6rer, utvecklare och direkt\u00f6ren. Inget hj\u00e4lper. <\/li>\n<li>Och pl\u00f6tsligt b\u00f6rjar allt oannonserat att \u00e5terst\u00e4llas av sig sj\u00e4lvt. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/7d4f6417bc5cb3cec33679d843c6661d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00e5 replikan har en f\u00f6rfr\u00e5gan under tiden utf\u00f6rts och skickats iv\u00e4g. Vi fick en rapport. F\u00f6retaget \u00e4r fortfarande n\u00f6jt. Som vi ser har v\u00e5r tabell v\u00e4xt igen och visar inga tecken p\u00e5 minskning. P\u00e5 grafen med sessioner har jag l\u00e4mnat ett stycke av denna l\u00e5nga transaktion fr\u00e5n replikan s\u00e5 att ni kan bed\u00f6ma hur l\u00e5ng tid det tar innan situationen stabiliseras. <\/p>\n<p><\/p>\n<p>Sessionen har avslutats. Och f\u00f6rst efter en tid kommer servern mer eller mindre i ordning. Och den genomsnittliga svarstiden p\u00e5 f\u00f6rfr\u00e5gningar p\u00e5 Master-servern normaliseras. F\u00f6r \u00e4ntligen har autovacuum f\u00e5tt m\u00f6jlighet att rensa upp, markera dessa d\u00f6da rader. Och ju snabbt det arbetar, desto snabbare kommer vi i ordning.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/547d195e08de1566da818150a47218eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u00e5 den testade tabellen, d\u00e4r vi uppdaterar saldon p\u00e5 konton, ser vi ett exakt samma m\u00f6nster. Den genomsnittliga tiden f\u00f6r kontouppdatering normaliseras ocks\u00e5 gradvis. CPU-anv\u00e4ndningen minskar ocks\u00e5. Och antalet transaktioner per sekund \u00e5terg\u00e5r till det normala. Men inte till det normala som vi hade innan avbrottet. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/29372a5e9124690931485a7aea65befc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>I vilket fall f\u00e5r vi en prestationsf\u00f6rlust precis som i f\u00f6rsta fallet, en och en halv till tv\u00e5 g\u00e5nger, ibland \u00e4nnu mer. <\/p>\n<p><\/p>\n<p>Vi verkar ha gjort allt r\u00e4tt. F\u00f6rdelat lasten. Utrustningen st\u00e5r inte still. Vi har f\u00f6rnuftigt delat upp f\u00f6rfr\u00e5gningarna, men \u00e4nd\u00e5 blev allt d\u00e5ligt. <\/p>\n<p><\/p>\n<ul>\n<li>Ska vi inte aktivera hot_standby_feedback? Ja, det rekommenderas vanligtvis inte att aktivera det utan starka sk\u00e4l. Eftersom den h\u00e4r inst\u00e4llningen direkt p\u00e5verkar Master-servern och pausar autovakuumet d\u00e4r. Om du aktiverar det p\u00e5 en replik och gl\u00f6mmer bort det kan du skada Master och f\u00e5 stora problem med applikationen. <\/li>\n<li>Ska vi \u00f6ka max_standby_streaming_delay? Ja, det \u00e4r faktiskt s\u00e5. Om du har en tre timmar l\u00e5ng rapport och inte vill att den ska krascha p\u00e5 grund av replikationskonflikter, s\u00e5 \u00f6ka bara f\u00f6rdr\u00f6jningen. L\u00e5nga rapporter kr\u00e4ver aldrig data som just nu kommit in i databasen. Om den \u00e4r tre timmar l\u00e5ng, k\u00f6r du den f\u00f6r n\u00e5gon gammal dataperiod. Tre timmars f\u00f6rdr\u00f6jning eller sex timmars f\u00f6rdr\u00f6jning spelar ingen roll, men d\u00e5 f\u00e5r du stabilt dina rapporter och slipper krascher. <\/li>\n<li>Sj\u00e4lvklart m\u00e5ste vi \u00f6vervaka l\u00e5nga sessioner p\u00e5 repliker, s\u00e4rskilt om du har best\u00e4mt dig f\u00f6r att aktivera hot_standby_feedback p\u00e5 repliken. F\u00f6r det kan h\u00e4nda vad som helst. Vi gav denna replik till en utvecklare f\u00f6r att han skulle testa f\u00f6rfr\u00e5gningar. Han skrev en besynnerlig f\u00f6rfr\u00e5gan. Startade den och gick f\u00f6r att dricka te, och vi fick en \u00f6verbelastad Master. Eller vi l\u00e4t ett ol\u00e4mpligt program g\u00e5 dit. Situationerna \u00e4r olika. Sessioner p\u00e5 repliker m\u00e5ste \u00f6vervakas lika noggrant som p\u00e5 Master. <\/li>\n<li>Och om du har snabba och l\u00e5nga f\u00f6rfr\u00e5gningar p\u00e5 repliker, s\u00e5 \u00e4r det b\u00e4ttre att dela upp dem f\u00f6r belastningsf\u00f6rdelning. Det h\u00e4r h\u00e4nvisar till streaming_delay. F\u00f6r snabba f\u00f6rfr\u00e5gningar, ha en replik med liten replikationsf\u00f6rdr\u00f6jning. F\u00f6r l\u00e5nga rapporteringsf\u00f6rfr\u00e5gningar, ha en replik som kan ligga efter med 6 timmar eller en dag. Det \u00e4r en helt normal situation. <\/li>\n<\/ul>\n<p><\/p>\n<p>Vi eliminerar konsekvenserna p\u00e5 samma s\u00e4tt:<\/p>\n<p><\/p>\n<ul>\n<li>Vi hittar uppbl\u00e5sta tabeller.<\/li>\n<li>Och komprimerar dem med det mest l\u00e4mpliga verktyget f\u00f6r oss. <\/li>\n<\/ul>\n<p><\/p>\n<p>Den andra historien har nu avslutats. L\u00e5t oss g\u00e5 vidare till den tredje historien. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c8784e0be27883640cb8f6919a1c25e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ocks\u00e5 ganska vanlig f\u00f6r oss, d\u00e4r vi g\u00f6r en migrering. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a04b9cd88a0e7e8a3b960ef930eb2657.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Varje programprodukt v\u00e4xer. Kraven p\u00e5 den f\u00f6r\u00e4ndras. Vi vill alltid utvecklas. Och ibland h\u00e4nder det att vi m\u00e5ste uppdatera data i tabellen, genomf\u00f6ra en uppdatering inom ramen f\u00f6r v\u00e5r migrering f\u00f6r den nya funktionalitet som vi introducerar i v\u00e5r utveckling. <\/li>\n<li>Det gamla dataformatet fungerar inte l\u00e4ngre. Anta att vi nu g\u00e5r till den andra tabellen d\u00e4r jag har transaktioner f\u00f6r dessa konton. Och s\u00e4g att de var i rubel, men vi har beslutat att \u00f6ka noggrannheten och g\u00f6ra det i kopecker. F\u00f6r detta beh\u00f6ver vi g\u00f6ra en uppdatering: f\u00e4ltet med transaktionssumman multiplicera med hundra. <\/li>\n<li>I den moderna v\u00e4rlden anv\u00e4nder vi automatiserade verktyg f\u00f6r versionskontroll av databaser. L\u00e5t oss anta att <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a><\/noindex>. Vi skriver ner v\u00e5r migration d\u00e4r. Testar den p\u00e5 v\u00e5r testdatabas. Allt \u00e4r utm\u00e4rkt. Uppdateringen lyckas. Det blockerar arbetet under en tid, men vi f\u00e5r den uppdaterade datan. Och vi kan k\u00f6ra ny funktionalitet p\u00e5 detta. Vi har testat allt, kontrollerat. Allt \u00e4r bekr\u00e4ftat. <\/li>\n<li>Vi genomf\u00f6rde planerat arbete, genomf\u00f6rde migrationen. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e046583f7b1723fc1eaf61a03900918.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>H\u00e4r \u00e4r migrationen med uppdateringen presenterad f\u00f6r er. Eftersom detta handlar om transaktioner f\u00f6r konton var tabellen 15 GB. Och eftersom vi uppdaterar varje rad har vi genom uppdateringen f\u00f6rdubblat tabellen, eftersom vi har skrivit \u00f6ver varje rad. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/06120c98ea43d0568045e71935c23592.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Under migrationen kunde vi inte g\u00f6ra n\u00e5got med den h\u00e4r tabellen, eftersom alla f\u00f6rfr\u00e5gningar till den k\u00f6ades och v\u00e4ntade p\u00e5 att denna uppdatering skulle avslutas. Men h\u00e4r vill jag p\u00e5peka siffrorna p\u00e5 den vertikala axeln. Allts\u00e5 hade vi genomsnittlig f\u00f6rfr\u00e5gningstid f\u00f6re migrationen p\u00e5 cirka 5 millisekunder och belastning p\u00e5 processorn, antal blockoperationer f\u00f6r minnesl\u00e4sning av disken mindre \u00e4n 7,5. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/69a3ba4d1d0cec7d39284e09e9d3055b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vi genomf\u00f6rde migrationen och fick \u00e5terigen problem. <\/p>\n<p><\/p>\n<p>Migrationen lyckades, men:<\/p>\n<p><\/p>\n<ul>\n<li>Den gamla funktionaliteten tar l\u00e4ngre tid att utf\u00f6ra. <\/li>\n<li>Tabellen har \u00e5terigen v\u00e4xt i storlek. <\/li>\n<li>Belastningen p\u00e5 servern har \u00e5terigen blivit st\u00f6rre \u00e4n den var. <\/li>\n<li>Och naturligtvis, medan vi fortfarande arbetar med den funktionalitet som fungerade bra, har vi f\u00f6rb\u00e4ttrat den lite grann. <\/li>\n<\/ul>\n<p><\/p>\n<p>Och det \u00e4r \u00e5terigen bloat som \u00e5terigen f\u00f6rsv\u00e5rar v\u00e5rt liv. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/becd7cce3a1c8821c81c96257f41202b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>H\u00e4r visar jag att tabellen, precis som i de tidigare tv\u00e5 fallen, inte t\u00e4nker \u00e5terv\u00e4nda till sina tidigare storlekar. Den genomsnittliga belastningen p\u00e5 servern verkar vara rimlig. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4d703a60d43a3460bc3782d49865b690.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Om vi tittar p\u00e5 tabellen med r\u00e4kningar, s\u00e5 ser vi att den genomsnittliga f\u00f6rfr\u00e5gan har dubblats f\u00f6r denna tabell. Belastningen p\u00e5 processorn och antalet rader som bearbetas i minnet har \u00f6kat till \u00f6ver 7,5, j\u00e4mf\u00f6rt med tidigare. F\u00f6r processorerna har det \u00f6kat med 2 g\u00e5nger, f\u00f6r blockoperationerna med 1,5 g\u00e5nger, dvs. vi har f\u00e5tt en degradering av serverns prestanda. Och f\u00f6ljaktligen \u00e4r det en degradering av prestandan f\u00f6r v\u00e5r applikation. Samtidigt har antalet anrop f\u00f6rblivit ungef\u00e4r p\u00e5 samma niv\u00e5. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/80772afa0643b29f5314a2482c9dfe0d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Och det viktigaste h\u00e4r \u00e4r att f\u00f6rst\u00e5 hur man korrekt g\u00f6r s\u00e5dana migreringar. Och de m\u00e5ste g\u00f6ras. Vi g\u00f6r dessa migreringar ganska ofta.<\/p>\n<p><\/p>\n<ul>\n<li>S\u00e5dana stora migreringar g\u00f6rs inte automatiskt. De m\u00e5ste alltid \u00f6vervakas. <\/li>\n<li>Det beh\u00f6vs kontroll fr\u00e5n en kunnig person. Om du har en DBA i teamet, l\u00e5t denne g\u00f6ra det. Det \u00e4r deras jobb. Om inte, s\u00e5 b\u00f6r den mest erfarna personen som vet hur man arbetar med databaser g\u00f6ra det. <\/li>\n<li>Den nya databasschemat, \u00e4ven om vi uppdaterar en kolumn, f\u00f6rbereder vi alltid i steg, dvs. i f\u00f6rv\u00e4g innan den nya versionen av applikationen rullas ut:<\/li>\n<li>Nya f\u00e4lt l\u00e4ggs till d\u00e4r vi kommer att lagra de uppdaterade data. <\/li>\n<li>Vi flyttar data fr\u00e5n det gamla f\u00e4ltet till det nya f\u00e4ltet i sm\u00e5 delar. Varf\u00f6r g\u00f6r vi detta? F\u00f6r det f\u00f6rsta kontrollerar vi alltid processen under den h\u00e4r processen. Vi vet att vi redan har flyttat s\u00e5 och s\u00e5 m\u00e5nga batchar och har s\u00e5 och s\u00e5 m\u00e5nga kvar. <\/li>\n<li>En annan positiv effekt \u00e4r att vi mellan varje s\u00e5dan batch st\u00e4nger en transaktion, \u00f6ppnar en ny, och detta ger m\u00f6jligheten f\u00f6r autovakuumet att arbeta p\u00e5 tabellen, m\u00e4rka d\u00f6da rader f\u00f6r \u00e5teranv\u00e4ndning. <\/li>\n<li>F\u00f6r rader som kommer att dyka upp under applikationens g\u00e5ng (v\u00e5r gamla applikation k\u00f6r fortfarande) l\u00e4gger vi till en trigger som skriver nya v\u00e4rden i de nya f\u00e4lten. I v\u00e5rt fall \u2013 det inneb\u00e4r multiplikation med hundra av det gamla v\u00e4rdet. <\/li>\n<li>Om vi \u00e4r helt envisa och vill ha samma f\u00e4lt, s\u00e5 vid slutet av alla migreringar och innan vi rullar ut den nya versionen av applikationen, byter vi helt enkelt namn p\u00e5 f\u00e4lten. De gamla till ett p\u00e5hittat namn och de nya f\u00e4lten byter vi namn till gamla. <\/li>\n<li>Och f\u00f6rst efter detta lanserar vi den nya versionen av applikationen. <\/li>\n<\/ul>\n<p><\/p>\n<p>Och p\u00e5 s\u00e5 s\u00e4tt kommer vi inte att f\u00e5 bloat och vi kommer inte att f\u00e5 en s\u00e4nkning av prestanda. <\/p>\n<p><\/p>\n<p>H\u00e4r avslutades den tredje historien. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej 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>Och nu ska vi g\u00e5 lite mer in p\u00e5 verktygen som jag n\u00e4mnde i den allra f\u00f6rsta historien. <\/p>\n<p><\/p>\n<p>Innan du b\u00f6rjar leta efter bloat, b\u00f6r du definitivt installera till\u00e4gget <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>F\u00f6r att ni inte ska beh\u00f6va hitta p\u00e5 fr\u00e5gorna sj\u00e4lva, har vi redan skrivit dessa fr\u00e5gor i v\u00e5rt arbete. Ni kan anv\u00e4nda dem. H\u00e4r presenteras tv\u00e5 fr\u00e5gor. <\/p>\n<p><\/p>\n<ul>\n<li>Den f\u00f6rsta tar ganska l\u00e5ng tid att k\u00f6ra, men den ger dig exakta v\u00e4rden f\u00f6r bloat i tabellen. <\/li>\n<li>Den andra g\u00e5r snabbare och \u00e4r mycket effektiv n\u00e4r du beh\u00f6ver g\u00f6ra en snabb bed\u00f6mning \u2013 finns det bloat eller inte i tabellen. Och du b\u00f6r ocks\u00e5 f\u00f6rst\u00e5 att bloat i en Postgres-tabell alltid finns. Det \u00e4r en egenhet av dess MVCC-modell. <\/li>\n<li>Och 20 % bloat \u00e4r normalt f\u00f6r tabeller i de flesta fall. Det vill s\u00e4ga, du beh\u00f6ver inte oroa dig och komprimera denna tabell. <\/li>\n<\/ul>\n<p><\/p>\n<p>Hur man identifierar tabeller som har sv\u00e4llt, det har vi klargjort, s\u00e4rskilt n\u00e4r de har sv\u00e4llt med on\u00f6diga data. <\/p>\n<p><\/p>\n<p>Nu om hur man \u00e5tg\u00e4rdar bloat:<\/p>\n<p><\/p>\n<ul>\n<li>Om vi har en liten tabell och bra diskar, det vill s\u00e4ga f\u00f6r en tabell under en gigabyte g\u00e5r det bra att anv\u00e4nda VACUUM FULL. Det kommer att ta en exklusiv l\u00e5s p\u00e5 tabellen i n\u00e5gra sekunder och sen klarar det allt snabbt och effektivt. Vad g\u00f6r VACUUM FULL? Det tar en exklusiv l\u00e5s p\u00e5 tabellen och kopierar levande rader fr\u00e5n gamla tabeller till en ny tabell. Och i slutet byter det plats p\u00e5 dem. Gamla filer tas bort, nya s\u00e4tts ist\u00e4llet f\u00f6r de gamla. Men under sin operation tar det en exklusiv l\u00e5s p\u00e5 tabellen. Det betyder att du inte kan g\u00f6ra n\u00e5got med denna tabell: varken skriva till den, l\u00e4sa fr\u00e5n den eller modifiera den. Och VACUUM FULL kr\u00e4ver extra diskutrymme f\u00f6r att lagra data.<\/li>\n<li>N\u00e4sta verktyg <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">pg_repack<\/a><\/noindex>. I sin funktion \u00e4r det mycket lik VACUUM FULL, eftersom det ocks\u00e5 kopierar data fr\u00e5n gamla filer till nya och byter ut dem i tabellen. Men det tar inte en exklusiv l\u00e5s p\u00e5 tabellen i b\u00f6rjan av sin operation, utan g\u00f6r det f\u00f6rst n\u00e4r det har f\u00e4rdiga data f\u00f6r att byta ut filerna. Diskresurskraven \u00e4r liknande VACUUM FULL. Du beh\u00f6ver extra utrymme p\u00e5 disken, vilket ibland kan vara kritiskt om du har terabyte-stora tabeller. Och det \u00e4r ganska resurskr\u00e4vande p\u00e5 processorn, eftersom det arbetar aktivt med in- och utdata. <\/li>\n<li>Det tredje verktyget \u00e4r <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex>. Den hanterar resurser p\u00e5 ett mer varsamt s\u00e4tt eftersom den fungerar enligt n\u00e5got andra principer. Huvudpo\u00e4ngen med pgcompacttable \u00e4r att den vid uppdateringar flyttar alla levande rader till b\u00f6rjan av tabellen. Och sedan k\u00f6r den vacuum p\u00e5 denna tabell, eftersom vi vet att vi har levande rader i b\u00f6rjan och d\u00f6da rader i slutet. Vacuum sk\u00e4r sedan bort den svansen, det vill s\u00e4ga att det inte kr\u00e4ver mycket extra diskutrymme. Dessutom kan det ocks\u00e5 optimeras f\u00f6r resurser. <\/li>\n<\/ul>\n<p><\/p>\n<p>Allt med verktygen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Vanliga misstag i applikationer som leder till bloat i PostgreSQL. Andrej Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4187915e54e54a0b85a342fe0280f78f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Om du tycker att \u00e4mnet med bloat \u00e4r intressant och vill gr\u00e4va djupare, h\u00e4r \u00e4r n\u00e5gra anv\u00e4ndbara l\u00e4nkar:<\/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 \u00e4r en presentation av min kollega. Den handlar allm\u00e4nt om vart utrymmet tar v\u00e4gen i Postgres under dess arbete och liv. Och det finns en v\u00e4ldigt stor och detaljerad teknisk del f\u00f6r databasadministrat\u00f6rer 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 \u00e4r en l\u00e4nk till v\u00e5rt repository, d\u00e4r vi lagrar en massa anv\u00e4ndbara skript f\u00f6r att kontrollera databasens tillst\u00e5nd. D\u00e4r kan du hitta skript f\u00f6r att s\u00f6ka efter bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Tredje<\/a><\/noindex> och <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">fj\u00e4rde<\/a><\/noindex> l\u00e4nkar till verktyg som hj\u00e4lper dig att optimera 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 \u00e4r ett inl\u00e4gg av min kollega. D\u00e4r g\u00e5r han ganska seri\u00f6st och detaljerat in p\u00e5 bloat p\u00e5 en niv\u00e5 n\u00e4ra databasadministrat\u00f6rer. <\/li>\n<\/ul>\n<p><\/p>\n<p>Jag har h\u00e4r f\u00f6rs\u00f6kt att visa en skr\u00e4mselhicka f\u00f6r utvecklarna, eftersom de \u00e4r v\u00e5ra direkta kunder till databaser och m\u00e5ste f\u00f6rst\u00e5 vilka konsekvenser olika handlingar kan leda till. Jag hoppas att jag lyckades. Tack f\u00f6r uppm\u00e4rksamheten!<\/p>\n<p><\/p>\n<p>Fr\u00e5gor<\/p>\n<p><\/p>\n<p><em>Tack f\u00f6r presentationen! Du pratade om hur man kan identifiera problem. Men hur kan man f\u00f6rhindra dem? Det vill s\u00e4ga, jag hade en situation d\u00e4r f\u00f6rfr\u00e5gningar h\u00e4ngde inte bara f\u00f6r att de kontaktade externa tj\u00e4nster. Det var bara n\u00e5gra galna joins. Det fanns n\u00e5gra sm\u00e5 harml\u00f6sa f\u00f6rfr\u00e5gningar som h\u00e4ngde i ett dygn och sedan b\u00f6rjade skapa kaos. Det liknar mycket det du beskriver. Hur kan man \u00f6vervaka detta? Ska man st\u00e4ndigt sitta och kolla vilken f\u00f6rfr\u00e5gan som h\u00e4nger? Hur kan man f\u00f6rhindra detta?<\/em><\/p>\n<p><\/p>\n<p>I det h\u00e4r fallet \u00e4r det en uppgift f\u00f6r administrat\u00f6rerna i ditt f\u00f6retag, inte n\u00f6dv\u00e4ndigtvis f\u00f6r DBA.<\/p>\n<p><\/p>\n<p><em>Jag \u00e4r administrat\u00f6r.<\/em><\/p>\n<p><\/p>\n<p>I PostgreSQL finns det en vy som heter pg_stat_activity, d\u00e4r h\u00e4ngande f\u00f6rfr\u00e5gningar visas. Och du kan se hur l\u00e4nge den har h\u00e4ngt d\u00e4r.<\/p>\n<p><\/p>\n<p><em>M\u00e5ste jag g\u00e5 in och kolla var femte minut?<\/em><\/p>\n<p><\/p>\n<p>St\u00e4ll in cron och kontrollera. Om du har en l\u00e5ngvarig beg\u00e4ran, skriv ett mail och allt. Det vill s\u00e4ga, du beh\u00f6ver inte titta med \u00f6gonen, det g\u00e5r att automatisera. Du f\u00e5r ett mail, och du reagerar p\u00e5 det. Eller s\u00e5 kan du avfyra det automatiskt.<\/p>\n<p><\/p>\n<p><em>Finns det uppenbara orsaker till varf\u00f6r detta h\u00e4nder?<\/em><\/p>\n<p><\/p>\n<p>Jag har n\u00e4mnt n\u00e5gra. Andra mer komplexa exempel. Och diskussionen kan ta l\u00e5ng tid.<\/p>\n<p><\/p>\n<p><em>Tack f\u00f6r presentationen! Jag ville klarg\u00f6ra kring verktyget pg_repack. Om det inte g\u00f6r en exklusiv l\u00e5sning, d\u00e5\u2026<\/em><\/p>\n<p><\/p>\n<p>Det g\u00f6r en exklusiv l\u00e5sning. <\/p>\n<p><\/p>\n<p>\u2026 <em>...kan jag potentiellt f\u00f6rlora data. Ska min applikation inte registrera n\u00e5got under den tiden?<\/em><\/p>\n<p><\/p>\n<p>Nej, den fungerar lugnt med tabellen, det vill s\u00e4ga pg_repack flyttar f\u00f6rst alla levande rader som finns. Sj\u00e4lvklart sker det n\u00e5gon registrering i tabellen. Den l\u00e4gger bara till den sista biten. <\/p>\n<p><\/p>\n<p><em>Det vill s\u00e4ga, g\u00f6r den i slut\u00e4nden faktiskt?<\/em><\/p>\n<p><\/p>\n<p>I slutet tar den en exklusiv l\u00e5sning f\u00f6r att byta plats p\u00e5 de h\u00e4r filerna. <\/p>\n<p><\/p>\n<p><em>Kommer det att g\u00e5 snabbare \u00e4n VACUUM FULL?<\/em><\/p>\n<p><\/p>\n<p>VACUUM FULL, n\u00e4r det startade, tog direkt en exklusiv l\u00e5sning. Och f\u00f6rr\u00e4n den har gjort allt, sl\u00e4pper den den inte. Och pg_repack tar en exklusiv l\u00e5sning endast vid tidpunkten f\u00f6r filbyten. Just d\u00e5 kan du inte skriva dit, men alla data g\u00e5r inte f\u00f6rlorade, allt kommer att vara i ordning. <\/p>\n<p><\/p>\n<p><em>Hej! Du pratade om hur autovacuum fungerar. Det fanns en graf med r\u00f6da, gula och gr\u00f6na celler. Det vill s\u00e4ga, de gula \u2013 han markerade dem som raderade. Och f\u00f6ljaktligen kan man skriva n\u00e5got nytt i dem?<\/em><\/p>\n<p><\/p>\n<p>Ja. Postgres tar inte bort rader. Det \u00e4r dess specifikation. Om vi uppdaterar en rad, markerar vi den gamla som raderad. D\u00e4r s\u00e4tts id f\u00f6r transaktionen som \u00e4ndrade den raden, och vi skriver in en ny rad. Och vi har sessioner som potentiellt kan l\u00e4sa dem. Vid n\u00e5gon tidpunkt blir de helt gamla. Och syftet med autovacuum \u00e4r att den g\u00e5r igenom dessa rader och markerar dem som on\u00f6diga. Och dit kan man skriva om data. <\/p>\n<p><\/p>\n<p><em>Jag f\u00f6rst\u00e5r. Men fr\u00e5gan handlar lite inte om det. Jag har inte avslutat. L\u00e5t oss anta att vi har en tabell. Den har f\u00e4lt med variabel storlek. Och om jag f\u00f6rs\u00f6ker s\u00e4tta in n\u00e5got nytt kan det kanske inte f\u00e5 plats i den gamla cellen.<\/em> <\/p>\n<p><\/p>\n<p>Nej, hela raden uppdateras oavsett. Postgres har tv\u00e5 datalagermodeller. Den v\u00e4ljer baserat p\u00e5 datatyp. Det finns data som lagras direkt i tabellen, och s\u00e5 finns det tos-data. Det handlar om stora datam\u00e4ngder: text, json. De lagras i separata tabeller. Och i dessa tabeller h\u00e4nder samma sak med bloat, det vill s\u00e4ga exakt samma sak. De \u00e4r bara separerade. <\/p>\n<p><\/p>\n<p><em>Tack f\u00f6r presentationen! Hur acceptabelt \u00e4r det att anv\u00e4nda statement timeout f\u00f6r att begr\u00e4nsa l\u00e4ngden p\u00e5 f\u00f6rfr\u00e5gningar?<\/em><\/p>\n<p><\/p>\n<p>Mycket acceptabelt. Vi anv\u00e4nder det \u00f6verallt. Och eftersom vi inte har v\u00e5ra egna tj\u00e4nster, utan erbjuder fj\u00e4rrsupport, s\u00e5 finns det en ganska varierad kundbas. Alla \u00e4r ganska n\u00f6jda med det. Det finns cron-jobb som g\u00f6r kontroller. Det diskuteras helt enkelt l\u00e4ngden p\u00e5 sessionerna med kunden, innan vi avslutar dem. Det kan vara en minut, det kan vara 10 minuter. Det beror p\u00e5 belastningen p\u00e5 databasen och dess syfte. Men vi anv\u00e4nder pg_stat_activity f\u00f6r alla.<\/p>\n<p><\/p>\n<p><em>Tack f\u00f6r presentationen! Jag f\u00f6rs\u00f6ker anpassa din presentation till mina applikationer. Och det verkar som om vi alltid startar en transaktion, och alltid avslutar den. Om n\u00e5got undantag intr\u00e4ffar, s\u00e5 sker rollback \u00e4nd\u00e5. Och h\u00e4r b\u00f6rjade jag fundera. En transaktion kan ju startas implicit. Det \u00e4r nog en vink till tjejen. Om jag bara g\u00f6r en uppdatering av en post, startar transaktionen i PostgreSQL och avslutas den f\u00f6rst n\u00e4r anslutningen kopplas ur?<\/em><\/p>\n<p><\/p>\n<p>Om du pratar om applikationsniv\u00e5n nu, s\u00e5 beror det p\u00e5 vilken drivrutin du anv\u00e4nder, vilken ORM som anv\u00e4nds. Det finns mycket inst\u00e4llningar. Om auto commit \u00e4r aktiverat d\u00e5 startar och avslutas transaktionen direkt.<\/p>\n<p><\/p>\n<p><em>Det vill s\u00e4ga, avslutas den genast efter uppdateringen?<\/em><\/p>\n<p><\/p>\n<p>Det beror p\u00e5 inst\u00e4llningarna. Jag n\u00e4mnde en inst\u00e4llning. Denna auto commit. Den \u00e4r ganska utbredd. Om den \u00e4r aktiverad s\u00e5 \u00f6ppnas och st\u00e4ngs transaktionen. Om du inte uttryckligen sa \"start transaction\" och \"end transaction\", utan bara k\u00f6rde en fr\u00e5ga i sessionen. <\/p>\n<p><\/p>\n<p><em>Hej! Tack f\u00f6r presentationen! T\u00e4nk att vi har en databas som v\u00e4xer och v\u00e4xer och nu tar det slut p\u00e5 utrymmet p\u00e5 servern. Finns det n\u00e5gra verktyg f\u00f6r att \u00e5tg\u00e4rda denna situation?<\/em> <\/p>\n<p><\/p>\n<p>Utrymmet p\u00e5 servern b\u00f6r helst \u00f6vervakas. <\/p>\n<p><\/p>\n<p><em>Till exempel, om DBA f\u00e5r en kopp kaffe, var p\u00e5 semester, osv.<\/em><\/p>\n<p><\/p>\n<p>N\u00e4r ett filsystem skapas, s\u00e5 reserveras \u00e5tminstone en del utrymme d\u00e4r inga data skrivs. <\/p>\n<p><\/p>\n<p><em>Och om det blir helt noll?<\/em><\/p>\n<p><\/p>\n<p>Det kallas reserverat utrymme, vilket inneb\u00e4r att det kan frig\u00f6ras och beroende p\u00e5 hur stort det \u00e4r, s\u00e5 f\u00e5r ni ledigt utrymme. Jag vet inte hur mycket det \u00e4r som standard. I ett annat fall kan man beh\u00f6va leverera diskar f\u00f6r att ha tillr\u00e4ckligt med utrymme f\u00f6r att utf\u00f6ra \u00e5terst\u00e4llningsoperationen. Man kan ta bort en tabell som man garanterat inte beh\u00f6ver. <\/p>\n<p><\/p>\n<p><em>Finns det andra verktyg?<\/em><\/p>\n<p><\/p>\n<p>Det \u00e4r alltid manuellt arbete. Man ser p\u00e5 plats vad som \u00e4r b\u00e4st att g\u00f6ra, eftersom det finns kritiska och icke-kritiska data. Och f\u00f6r varje databas och till\u00e4mpning som arbetar med den beror det p\u00e5 f\u00f6retaget. Beslutet fattas alltid p\u00e5 plats. <\/p>\n<p><\/p>\n<p><em>Tack f\u00f6r presentationen! Jag har tv\u00e5 fr\u00e5gor. F\u00f6r det f\u00f6rsta, ni visade bilder d\u00e4r ni visade att vid h\u00e4ngande transaktioner \u00f6kar b\u00e5de storleken p\u00e5 tabellutrymmet och storleken p\u00e5 indexet. Och l\u00e4ngre fram i presentationen fanns m\u00e5nga verktyg som packar tabellen. Men vad h\u00e4nder med indexet?<\/em><\/p>\n<p><\/p>\n<p>De packar ocks\u00e5. <\/p>\n<p><\/p>\n<p><em>Men vakuum p\u00e5verkar inte indexet?<\/em><\/p>\n<p><\/p>\n<p>Vissa verktyg arbetar med indexet. Till exempel pg_rapack, pgcompacttable. Vakuum \u00e5terskapar index, det p\u00e5verkar dem. Syftet med VACUUM FULL \u00e4r att skriva om allt, det arbetar med allt. <\/p>\n<p><\/p>\n<p><em>Och den andra fr\u00e5gan. Jag f\u00f6rstod inte varf\u00f6r rapporter p\u00e5 repliker s\u00e5 starkt beror p\u00e5 sj\u00e4lva replikeringen. Jag hade f\u00f6r mig att rapporter \u00e4r l\u00e4sning och replikering \u00e4r skrivning.<\/em> <\/p>\n<p><\/p>\n<p>Var uppst\u00e5r konflikten vid replikering? Vi har en Master d\u00e4r processerna sker. Vi har en autovakuumprocess. Vad g\u00f6r autovakuum egentligen? Det tar bort gamla rader. Om vi har en beg\u00e4ran p\u00e5 repliken under tiden som l\u00e4ser dessa gamla rader, och p\u00e5 Master har det h\u00e4nt att autovakuum markerat dessa rader som m\u00f6jliga f\u00f6r \u00f6verskrivning, s\u00e5 har vi skrivit om dem. N\u00e4r ett paket data kommer och vi m\u00e5ste skriva om de rader som beg\u00e4ran p\u00e5 repliken beh\u00f6ver, d\u00e5 kommer replikationsprocessen att v\u00e4nta p\u00e5 den timeout ni har st\u00e4llt in. Sedan kommer PostgreSQL att avg\u00f6ra vad som \u00e4r viktigare f\u00f6r den. Och replikeringen \u00e4r viktigare \u00e4n beg\u00e4ran, och den kommer att avbryta beg\u00e4ran f\u00f6r att genomf\u00f6ra dessa \u00e4ndringar p\u00e5 repliken. <\/p>\n<p><\/p>\n<p><em>Andrey, jag har en fr\u00e5ga. \u00c4r de h\u00e4r fantastiska diagrammen du visade under presentationen resultatet av n\u00e5got av dina verktyg? Hur konstruerades diagrammen?<\/em><\/p>\n<p><\/p>\n<p>Detta \u00e4r en tj\u00e4nst <noindex><a rel=\"nofollow\" href=\"https:\/\/okmeter.io\/\">Okmeter<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><em>\u00c4r detta en kommersiell produkt?<\/em><\/p>\n<p><\/p>\n<p>Ja. Det \u00e4r en kommersiell produkt.<\/p>\n<p>K\u00e4lla: <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.4 - 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\/sv\/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.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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\/sv\/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\udd47Typiska fel i applikationer som leder till bloat i postgresql. Andrey Salnikov | ProHoster","description":"Jag f\u00f6resl\u00e5r att du bekantar dig med transkriptionen av f\u00f6redraget fr\u00e5n b\u00f6rjan av 2016 av Andrey Salnikov \"Typiska fel i applikationer som leder till bloat i postgresql\" I denna presentation kommer jag att g\u00e5 igenom huvudpunkterna.","canonical_url":"https:\/\/prohoster.info\/sv\/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":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/81089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=81089"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/81089\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/81090"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=81089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=81089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=81089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}