{"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\/sk\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","title":{"rendered":"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Pon\u00fakam na obozn\u00e1menie prepis spr\u00e1vy z za\u010diatku roku 2016 od Andreja Salnikova \"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v postgresql\"<\/strong><\/p>\n<p><\/p>\n<p>V tejto spr\u00e1ve rozoberiem z\u00e1kladn\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 vznikaj\u00fa v \u0161t\u00e1diu n\u00e1vrhu a p\u00edsania k\u00f3du aplik\u00e1cie. A vezmem len tie chyby, ktor\u00e9 ved\u00fa k bloatu v PostgreSQL. Zvy\u010dajne je to za\u010diatok konca v\u00fdkonu v\u00e1\u0161ho syst\u00e9mu ako celku, hoci na za\u010diatku neboli \u017eiadne predpoklady na to.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" 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>Te\u0161\u00ed ma, \u017ee v\u00e1s v\u0161etk\u00fdch v\u00edtam! T\u00e1to spr\u00e1va nie je tak technick\u00e1 ako predch\u00e1dzaj\u00faca spr\u00e1va od m\u00f4jho kolegu. Je orientovan\u00e1 hlavne na v\u00fdvoj\u00e1rov backendov\u00fdch syst\u00e9mov, preto\u017ee m\u00e1me dostato\u010dne ve\u013ek\u00e9 mno\u017estvo klientov. A v\u0161etci robia tie ist\u00e9 chyby. O nich v\u00e1m poviem. Vysvetl\u00edm, k \u010domu fat\u00e1lnemu a zl\u00e9mu tieto chyby ved\u00fa. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/c6c84dbafc595ae3068cd8bf804ccee7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pre\u010do sa chyby st\u00e1vaj\u00fa? St\u00e1vaj\u00fa sa z dvoch d\u00f4vodov: na n\u00e1hodu, m\u00f4\u017ee to vyjs\u0165, a z neznalosti ur\u010dit\u00fdch mechanizmov, ktor\u00e9 sa dej\u00fa na \u00farovni medzi datab\u00e1zou a aplik\u00e1ciou, ako aj v samotnej datab\u00e1ze. <\/p>\n<p><\/p>\n<p>Prinesiem v\u00e1m tri pr\u00edklady s hrozn\u00fdmi obr\u00e1zkami toho, ako to v\u0161etko dopadlo zle. V kr\u00e1tkosti vysvetl\u00edm mechanizmus, ktor\u00fd tam prebieha. A ako s nimi bojova\u0165, ke\u010f sa stali, a ak\u00e9 prevent\u00edvne met\u00f3dy pou\u017ei\u0165 na predch\u00e1dzanie chyb\u00e1m. Povedzme si o pomocn\u00fdch n\u00e1strojoch a poskytnem u\u017eito\u010dn\u00e9 odkazy. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/b0230d992f5b44f0e542df2e4b4d526f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pou\u017eil som testovaciu datab\u00e1zu, kde som mal dve tabu\u013eky. Jedna tabu\u013eka so z\u00e1kazn\u00edckymi \u00fa\u010dtami, druh\u00e1 s oper\u00e1ciami na t\u00fdchto \u00fa\u010dtoch. A s nejakou peri\u00f3dou aktualizujeme zostatky na t\u00fdchto \u00fa\u010dtoch.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/1d2a21278b095b07546e1bb870819dbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V\u00fdstupn\u00e9 d\u00e1ta tabu\u013eky: je dos\u0165 mal\u00e1, 2 MB. \u010cas odozvy datab\u00e1zy a konkr\u00e9tne tabu\u013eky je tie\u017e ve\u013emi dobr\u00fd. A dostato\u010dne dobr\u00e9 za\u0165a\u017eenie \u2013 2000 oper\u00e1ci\u00ed za sekundu na tabu\u013eke.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/dea5a4b1ac7952f8cfed0e2e1cfc10dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A cez t\u00fato spr\u00e1vu v\u00e1m budem ukazova\u0165 grafy, aby to bolo jasn\u00e9, \u010do sa deje. V\u017edy bud\u00fa dve sn\u00edmky s grafmi. Prv\u00e1 sn\u00edmka \u2013 to, \u010do sa deje vo v\u0161eobecnosti na serveri. <\/p>\n<p><\/p>\n<p>A v tejto situ\u00e1cii vid\u00edme, \u017ee skuto\u010dne m\u00e1me tabu\u013eku malej ve\u013ekosti. Index je mal\u00fd, 2 MB. Toto je prv\u00fd graf z\u013eava. <\/p>\n<p><\/p>\n<p>Priemern\u00fd \u010das odozvy na serveri je tie\u017e stabiln\u00fd, mal\u00fd. Toto je prav\u00fd horn\u00fd graf. <\/p>\n<p><\/p>\n<p>\u013dav\u00fd doln\u00fd graf zobrazuje najdlh\u0161ie transakcie. Vid\u00edme, \u017ee transakcie prebiehaj\u00fa r\u00fdchlo. A autovakuum tu e\u0161te nefunguje, preto\u017ee to bol testovac\u00ed \u0161tart. N\u00e1sledne za\u010dne fungova\u0165 a bude n\u00e1m prospe\u0161n\u00fd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e9b46acd9a878ff70ca4a7850adff09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Druh\u00fd sn\u00edmok bude v\u017edy venovan\u00fd sk\u00famanej tabu\u013eke. V tejto situ\u00e1cii neust\u00e1le aktualizujeme zostatky na \u00fa\u010dtoch klienta. A vid\u00edme, \u017ee priemern\u00fd \u010das odpovede na oper\u00e1ciu aktualiz\u00e1cie je dos\u0165 dobr\u00fd, menej ako milisekundu. Vid\u00edme, \u017ee procesorov\u00e9 zdroje (to je prav\u00fd horn\u00fd graf) s\u00fa vyu\u017e\u00edvan\u00e9 rovnomerne a s\u00fa dostato\u010dne n\u00edzke. <\/p>\n<p><\/p>\n<p>Prav\u00fd doln\u00fd graf ukazuje, ko\u013eko opera\u010dnej a diskovej pam\u00e4te preh\u013ead\u00e1vame pri h\u013eadan\u00ed potrebn\u00e9ho riadku pred jeho aktualiz\u00e1ciou. A po\u010det oper\u00e1ci\u00ed na tabu\u013eke - 2 000 za sekundu, ako som spom\u00ednal na za\u010diatku. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/84760d52716209b8dcfffb462c67a8e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A teraz sa n\u00e1m st\u00e1va trag\u00e9dia. Z nejak\u00e9ho d\u00f4vodu vznik\u00e1 dlh\u00e1 zabudnut\u00e1 transakcia. Pr\u00ed\u010diny s\u00fa zvy\u010dajne dos\u0165 ban\u00e1lne: <\/p>\n<p><\/p>\n<ul>\n<li>Jedna z najbe\u017enej\u0161\u00edch je, \u017ee sme v k\u00f3de aplik\u00e1cie za\u010dali komunikova\u0165 s externou slu\u017ebou. A t\u00e1to slu\u017eba n\u00e1m neodpoved\u00e1. T. j. otvor\u00edme transakciu, vykon\u00e1me zmenu v datab\u00e1ze a prejdeme \u010d\u00edta\u0165 e-maily alebo do inej slu\u017eby v r\u00e1mci na\u0161ej infra\u0161trukt\u00fary, a z nejak\u00e9ho d\u00f4vodu n\u00e1m neodpoved\u00e1. A m\u00e1me visiaciu rel\u00e1ciu v stave - nevieme, kedy sa to vyrie\u0161i.<\/li>\n<li>Druh\u00e1 situ\u00e1cia, ke\u010f sa v na\u0161om k\u00f3de z nejak\u00e9ho d\u00f4vodu vyskytla v\u00fdnimka. A vo v\u00fdnimke sme neinicializovali uzavretie transakcie. A m\u00e1me visiaciu rel\u00e1ciu s otvorenou transakciou. <\/li>\n<li>A posledn\u00e1 - to je tie\u017e dos\u0165 \u010dast\u00fd pr\u00edpad. Je to nekvalitn\u00fd k\u00f3d. Niektor\u00e9 frameworky otv\u00e1raj\u00fa transakciu. T\u00e1 vis\u00ed a mo\u017eno ani neviete v aplik\u00e1cii, \u017ee vis\u00ed. <\/li>\n<\/ul>\n<p><\/p>\n<p>K \u010domu ved\u00fa tak\u00e9to veci? <\/p>\n<p><\/p>\n<p>K tomu, \u017ee sa n\u00e1m za\u010dn\u00fa r\u00fdchlo rozrasta\u0165 tabu\u013eky a indexy. To je pr\u00e1ve ten efekt bloat. Pre datab\u00e1zu to bude znamen\u00e1\u0165, \u017ee sa n\u00e1m ve\u013emi r\u00fdchlo zv\u00fd\u0161i \u010das odpovede datab\u00e1zy, zv\u00fd\u0161i sa z\u00e1\u0165a\u017e na server datab\u00e1zy. A ako v\u00fdsledok bude trpie\u0165 aplik\u00e1cia. Preto\u017ee ak ste v k\u00f3de str\u00e1vili 10 milisek\u00fand na dotaz do datab\u00e1zy, 10 milisek\u00fand na svoju logiku, tak va\u0161a funkcia pracovala 20 milisek\u00fand. A teraz bude va\u0161a situ\u00e1cia \u00faplne smutn\u00e1. <\/p>\n<p><\/p>\n<p>Pozrime sa na to, \u010do sa deje. \u013dav\u00fd doln\u00fd graf ukazuje, \u017ee m\u00e1me dlh\u00fa transakciu. A ak sa pozrieme na \u013eav\u00fd horn\u00fd graf, vid\u00edme, \u017ee ve\u013ekos\u0165 tabu\u013eky zo 2 megabajtov prudko vzr\u00e1stla na 300 megabajtov. Po\u010det d\u00e1t v tabu\u013eke sa pritom nezmenil, t. j. tam je dostato\u010dn\u00e9 mno\u017estvo nepotrebn\u00fdch \u00fadajov.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/b1947f6487e440a770a1251a955e62d2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Celkov\u00e1 situ\u00e1cia oh\u013eadom priemern\u00e9ho \u010dasu odpovede servera sa tie\u017e zmenila o nieko\u013eko r\u00e1dov. T. j. v\u0161etky po\u017eiadavky na server za\u010dali v\u00fdrazne klesa\u0165. A pritom sa aktivovali vn\u00fatorn\u00e9 procesy Postgres v podobe autovakuumu, ktor\u00e9 sa pok\u00fa\u0161aj\u00fa nie\u010do robi\u0165 a spotreb\u00favaj\u00fa zdroje.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/8e91f035d1dd04e72e842d714cc611a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u010co sa teda deje s na\u0161ou tabu\u013ekou? To ist\u00e9. Priemern\u00fd \u010das odpovede na tabu\u013eku n\u00e1m vzr\u00e1stol o nieko\u013eko r\u00e1dov. \u010co sa t\u00fdka spotrebovan\u00fdch zdrojov, vid\u00edme, \u017ee sa v\u00fdrazne zv\u00fd\u0161ila z\u00e1\u0165a\u017e na procesor. To je prav\u00fd horn\u00fd graf. A zv\u00fd\u0161ila sa preto, lebo procesor mus\u00ed preh\u013ead\u00e1va\u0165 mno\u017estvo zbyto\u010dn\u00fdch riadkov v h\u013eadan\u00ed jedn\u00e9ho potrebn\u00e9ho. To je prav\u00fd doln\u00fd graf. A v\u00fdsledkom je, \u017ee po\u010det volan\u00ed za sekundu za\u010dal ve\u013emi prudko klesa\u0165, preto\u017ee datab\u00e1za nest\u00edha spracov\u00e1va\u0165 rovnak\u00e9 mno\u017estvo po\u017eiadaviek. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/424685ce852bc5f3ef77151f8d3d7289.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mus\u00edme sa vr\u00e1ti\u0165 k \u017eivotu. Vyskakujeme na internet a zist\u00edme, \u017ee dlh\u00e9 transakcie ved\u00fa k probl\u00e9mom. N\u00e1jdeme a zru\u0161\u00edme t\u00fato transakciu. A v\u0161etko sa vr\u00e1ti do norm\u00e1lu. V\u0161etko funguje ako m\u00e1. <\/p>\n<p><\/p>\n<p>Uvo\u013enili sme sa, ale po nejakej dobe za\u010d\u00edname poci\u0165ova\u0165, \u017ee aplik\u00e1cia nefunguje tak, ako pred hav\u00e1riou. Po\u017eiadavky sa spracov\u00e1vaj\u00fa st\u00e1le pomal\u0161ie, pri\u010dom podstatne pomal\u0161ie. V mojom pr\u00edpade je to o 1,5 a\u017e 2 kr\u00e1t pomal\u0161ie. Z\u00e1\u0165a\u017e na server je tie\u017e vy\u0161\u0161ia, ne\u017e bola pred hav\u00e1riou. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3037719a31f8d18fc42745716c4da5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A ot\u00e1zka: \u201e\u010co sa v tomto momente deje s datab\u00e1zou?\u201c. A s datab\u00e1zou sa deje nasledovn\u00e1 situ\u00e1cia. Na grafe transakci\u00ed vid\u00edte, \u017ee sa zastavila a naozaj tam nie s\u00fa \u017eiadne dlh\u00e9 transakcie. Ale ve\u013ekosti tabulky sa po\u010das hav\u00e1rie fat\u00e1lne zv\u00fd\u0161ili. A od vtedy sa nezmen\u0161ili. Priemern\u00fd \u010das na datab\u00e1zu sa stabilizoval. A odpovede akoby boli adekv\u00e1tne s prijate\u013enou r\u00fdchlos\u0165ou pre n\u00e1s. Autovakuum sa stalo akt\u00edvnej\u0161\u00edm a za\u010dalo nie\u010do robi\u0165 s tabu\u013ekou, preto\u017ee mus\u00ed prehodnocova\u0165 v\u00e4\u010d\u0161ie mno\u017estvo d\u00e1t. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/f6205242c4024dc3ed4cade5844dbf76.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pokia\u013e ide o sk\u00faman\u00fa tabu\u013eku s fakt\u00farami, kde men\u00edme zostatky: \u010das odozvy na po\u017eiadavku sa zjavne vr\u00e1til do norm\u00e1lu. Ale v skuto\u010dnosti je o 50 % vy\u0161\u0161\u00ed.<\/p>\n<p><\/p>\n<p>A \u010do sa t\u00fdka za\u0165a\u017eenia procesora, vid\u00edme, \u017ee za\u0165a\u017eenie procesora sa nevr\u00e1tilo na po\u017eadovan\u00fa \u00farove\u0148 pred hav\u00e1riou. Pr\u00ed\u010diny s\u00fa zakorenen\u00e9 pr\u00e1ve v pravom dolnom grafe. Je tam vidie\u0165, \u017ee doch\u00e1dza k prelomu nejak\u00e9ho mno\u017estva pam\u00e4te. T. j. na vyh\u013eadanie potrebn\u00e9ho riadka m\u00ed\u0148ame zdroje servera datab\u00e1zy pri preh\u013ead\u00e1van\u00ed zbyto\u010dn\u00fdch d\u00e1t. Po\u010det transakci\u00ed za sekundu sa stabilizoval. <\/p>\n<p><\/p>\n<p>Celkovo je to dobr\u00e9, ale situ\u00e1cia je hor\u0161ia, ako bola. Je zjavn\u00e1 degrad\u00e1cia datab\u00e1zy v d\u00f4sledku na\u0161ej aplik\u00e1cie, ktor\u00e1 s touto datab\u00e1zou pracuje. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/0dfc9cd453fd84bc639ffd99cf189fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A aby sme sa dostali do toho, \u010do sa tam deje, ak ste neboli na predch\u00e1dzaj\u00facej predn\u00e1\u0161ke, tak teraz tro\u0161ku te\u00f3rie. Te\u00f3ria o vn\u00fatornom procese. Na \u010do je autovakum a \u010do rob\u00ed?<\/p>\n<p><\/p>\n<p>Prakticky stru\u010dne pre pochopenie. V nejakom momente m\u00e1me tabu\u013eku. V tabu\u013eke s\u00fa riadky. Tieto riadky m\u00f4\u017eu by\u0165 akt\u00edvne, \u017eiv\u00e9, moment\u00e1lne potrebn\u00e9. Na obr\u00e1zku s\u00fa ozna\u010den\u00e9 zelenou farbou. A s\u00fa tu aj m\u0155tve riadky, ktor\u00e9 u\u017e boli spracovan\u00e9, boli aktualizovan\u00e9, boli na ne vytvoren\u00e9 nov\u00e9 z\u00e1znamy. A s\u00fa ozna\u010den\u00e9, \u017ee u\u017e nie s\u00fa pre datab\u00e1zu zauj\u00edmav\u00e9. Ale le\u017eia v tabu\u013eke kv\u00f4li osobitosti Postgres.<\/p>\n<p><\/p>\n<p>Na\u010do je autovakum potrebn\u00e9? Autovakum v nejakom momente pr\u00edde, obr\u00e1ti sa na datab\u00e1zu a p\u00fdta sa jej: \u201eDaj mi, pros\u00edm, id najstar\u0161ej transakcie, ktor\u00e1 je moment\u00e1lne otvoren\u00e1 v datab\u00e1ze.\u201c Datab\u00e1za vr\u00e1ti tento id. A autovakum sa opieraj\u00fac o neho prech\u00e1dza riadkami v tabu\u013eke. A ak vid\u00ed, \u017ee niektor\u00e9 riadky boli zmenen\u00e9 transakciami, ktor\u00e9 s\u00fa ove\u013ea star\u0161ie, m\u00e1 pr\u00e1vo ich ozna\u010di\u0165 ako riadky, ktor\u00e9 m\u00f4\u017eeme v bud\u00facnosti znovu vyu\u017ei\u0165, ke\u010f tam zap\u00ed\u0161eme nov\u00e9 \u00fadaje. Je to pozadov\u00fd proces.<\/p>\n<p><\/p>\n<p>V tom \u010dase pokra\u010dujeme v pr\u00e1ci s datab\u00e1zou, pokra\u010dujeme v vykon\u00e1van\u00ed nejak\u00fdch zmien v tabu\u013eke. A na tieto riadky, ktor\u00e9 m\u00f4\u017eeme znova vyu\u017ei\u0165, zapisujeme nov\u00e9 \u00fadaje. A t\u00fdmto sp\u00f4sobom m\u00e1me cyklus, t. j. neust\u00e1le sa tam objavuj\u00fa ak\u00e9si m\u0155tve star\u00e9 riadky, na ich miesto zapisujeme nov\u00e9 riadky, ktor\u00e9 potrebujeme. A to je norm\u00e1lny stav pre pr\u00e1cu PostgreSQL.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/98dd4451a7ca5f418775f72822c2840c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u010co sa stalo po\u010das hav\u00e1rie? Ako prebiehal tento proces?<\/p>\n<p><\/p>\n<p>Mali sme tabu\u013eku v nejakom stave, niektor\u00e9 riadky boli \u017eiv\u00e9, in\u00e9 m\u0155tve. Pri\u0161iel autovakuum. Sp\u00fdtal sa datab\u00e1zy, ktor\u00e1 je na\u0161a najstar\u0161ia transakcia, ak\u00e9 m\u00e1 ID. Z\u00edskal to ID, ktor\u00e9 m\u00f4\u017ee by\u0165 star\u00e9 nieko\u013eko hod\u00edn alebo aj desa\u0165 min\u00fat. To z\u00e1vis\u00ed od toho, ak\u00e9 siln\u00e9 za\u0165a\u017eenie m\u00e1te v datab\u00e1ze. A za\u010dal h\u013eada\u0165 riadky, ktor\u00e9 m\u00f4\u017ee ozna\u010di\u0165 ako znovu pou\u017eite\u013en\u00e9. A nena\u0161iel \u017eiadne tak\u00e9to riadky v na\u0161ej tabu\u013eke. <\/p>\n<p><\/p>\n<p>Ale v tomto \u010dase na\u010falej pracujeme s tabu\u013ekou. Nie\u010do rob\u00edme v nej, aktualizujeme, men\u00edme \u00fadaje. A \u010do m\u00e1 datab\u00e1za v tom \u010dase robi\u0165? Nem\u00e1 na v\u00fdber, ne\u017e prid\u00e1va\u0165 nov\u00e9 riadky na koniec existuj\u00facej tabu\u013eky. A t\u00fdm sa n\u00e1m ve\u013ekos\u0165 tabu\u013eky za\u010d\u00edna zvy\u0161ova\u0165. <\/p>\n<p><\/p>\n<p>Naozaj potrebujeme na pr\u00e1cu zelen\u00e9 riadky. Ale po\u010das takejto probl\u00e9movej situ\u00e1cie m\u00e1me za to, \u017ee percento zelen\u00fdch riadkov je extr\u00e9mne n\u00edzke v celkovom objeme tabu\u013eky. <\/p>\n<p><\/p>\n<p>A ke\u010f vykon\u00e1vame dotaz, datab\u00e1ze sa mus\u00ed prebehn\u00fa\u0165 cez v\u0161etky riadky: aj \u010derven\u00e9, aj zelen\u00e9, aby na\u0161la po\u017eadovan\u00fd riadok. A efekt zv\u00e4\u010d\u0161ovania tabu\u013eky zbyto\u010dn\u00fdmi d\u00e1tami sa naz\u00fdva \u201ebloat\u201c, ktor\u00fd taktie\u017e zaber\u00e1 na\u0161e diskov\u00e9 miesto. Pam\u00e4t\u00e1te, bolo 2 MB, stalo sa 300 MB? A teraz si vymeni\u0165 megabajty za gigabajty a r\u00fdchlo pr\u00eddete o v\u0161etky svoje diskov\u00e9 zdroje.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/fe7cb6b5c99610744ebcfe5ad7235d1e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ak\u00e9 m\u00f4\u017eu by\u0165 n\u00e1sledky pre n\u00e1s? <\/p>\n<p><\/p>\n<ul>\n<li>V mojom pr\u00edpade tabu\u013eka a index nar\u00e1stli 150-kr\u00e1t. U niektor\u00fdch na\u0161ich klientov sa vyskytli e\u0161te fat\u00e1lnej\u0161ie pr\u00edpady, kedy jednoducho miesto na disku za\u010dalo doch\u00e1dza\u0165. <\/li>\n<li>Ve\u013ekos\u0165 tabuliek sa sama o sebe nikdy nezmen\u0161\u00ed. Autovakuum v niektor\u00fdch pr\u00edpadoch m\u00f4\u017ee odstr\u00e1ni\u0165 koniec tabu\u013eky, ak s\u00fa tam len m\u0155tve riadky. Ale ke\u010f\u017ee doch\u00e1dza k neust\u00e1lej rot\u00e1cii, jeden zelen\u00fd riadok sa m\u00f4\u017ee na konci zasekn\u00fa\u0165 a neaktualizova\u0165, zatia\u013e \u010do v\u0161etky ostatn\u00e9 bud\u00fa zapisovan\u00e9 niekde na za\u010diatku tabu\u013eky. Ale to je tak m\u00e1lo pravdepodobn\u00e9, \u017ee sa va\u0161e tabu\u013eky samy od seba zmen\u0161ia, \u017ee sa na to netreba spolieha\u0165. <\/li>\n<li>Datab\u00e1ze treba prech\u00e1dza\u0165 cel\u00fdm hromaden\u00edm zbyto\u010dn\u00fdch riadkov. A my m\u00ed\u0148ame diskov\u00e9 zdroje, m\u00ed\u0148ame procesorov\u00e9 zdroje a elektrick\u00fa energiu. <\/li>\n<li>A to priamo ovplyv\u0148uje na\u0161u aplik\u00e1ciu, preto\u017ee ak na za\u010diatku sme tr\u00e1vili 10 milisek\u00fand na po\u017eiadavku, 10 milisek\u00fand na n\u00e1\u0161 k\u00f3d, po\u010das hav\u00e1rie sme za\u010dali tr\u00e1vit sekundu na po\u017eiadavku a 10 milisek\u00fand na k\u00f3d, t. j. v\u00fdkonnos\u0165 aplik\u00e1cie klesla poriadne. A ke\u010f sa hav\u00e1ria vyrie\u0161ila, za\u010dali sme tr\u00e1vi\u0165 20 milisek\u00fand na po\u017eiadavku, 10 milisek\u00fand na k\u00f3d. To znamen\u00e1, \u017ee sme st\u00e1le klesli v produktivite o polovicu. A to v\u0161etko kv\u00f4li jednej transakcii, ktor\u00e1 sa zablokovala, pravdepodobne kv\u00f4li na\u0161ej chybe. <\/li>\n<li>A ot\u00e1zka znie: \u201eAko v\u0161etko vr\u00e1ti\u0165 sp\u00e4\u0165?\u201c, aby sme sa mali dobre a po\u017eiadavky be\u017eali rovnako r\u00fdchlo, ako pred hav\u00e1riou. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/1bf46e8cd9b28ca2862f978f2ca85819.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na to existuje ur\u010dit\u00fd cyklus pr\u00e1c, ktor\u00fd sa vykon\u00e1va. <\/p>\n<p><\/p>\n<p>Najprv mus\u00edme n\u00e1js\u0165 probl\u00e9mov\u00e9 tabu\u013eky, ktor\u00e9 sa nadmerne zv\u00e4\u010d\u0161ili. Ch\u00e1peme, \u017ee v niektor\u00fdch tabu\u013ek\u00e1ch je z\u00e1pis akt\u00edvnej\u0161\u00ed, v in\u00fdch menej akt\u00edvny. A na to sa pou\u017e\u00edva roz\u0161\u00edrenie <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>. Nain\u0161talovan\u00edm tohto roz\u0161\u00edrenia m\u00f4\u017eete nap\u00edsa\u0165 po\u017eiadavky, ktor\u00e9 v\u00e1m pom\u00f4\u017eu n\u00e1js\u0165 tabu\u013eky, ktor\u00e9 sa zv\u00e4\u010d\u0161ili do zna\u010dnej miery. <\/p>\n<p><\/p>\n<p>Po tom, \u010do ste na\u0161li tieto tabu\u013eky, je potrebn\u00e9 ich zmen\u0161i\u0165. Na to existuj\u00fa u\u017e n\u00e1stroje. V na\u0161ej spolo\u010dnosti pou\u017e\u00edvame tri n\u00e1stroje. Prv\u00fd \u2013 zabudovan\u00fd VACUUM FULL. Je tvrd\u00fd, pr\u00edsny a krut\u00fd, ale niekedy je ve\u013emi u\u017eito\u010dn\u00fd. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Pg_repack<\/a><\/noindex> a <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex> \u2013 to s\u00fa extern\u00e9 n\u00e1stroje na zmen\u0161ovanie tabuliek. A s\u00fa \u0161etrnej\u0161ie k datab\u00e1ze. <\/p>\n<p><\/p>\n<p>Pou\u017e\u00edvaj\u00fa sa v z\u00e1vislosti od toho, \u010do v\u00e1m je pohodlnej\u0161ie. Ale o tom sa e\u0161te zmienim na konci. Hlavn\u00e9 je, \u017ee existuj\u00fa tri n\u00e1stroje. Je z \u010doho vybera\u0165. <\/p>\n<p><\/p>\n<p>Po tom, \u010do sme v\u0161etko opravili a uistili sa, \u017ee je v\u0161etko v poriadku, mus\u00edme vedie\u0165, ako v bud\u00facnosti predch\u00e1dza\u0165 tejto situ\u00e1cii:<\/p>\n<p><\/p>\n<ul>\n<li>Predch\u00e1dza\u0165 tomu sa d\u00e1 dos\u0165 \u013eahko. Treba sledova\u0165 d\u013a\u017eku rel\u00e1ci\u00ed na Master-serveri. <strong>Najnebezpe\u010dnej\u0161ie rel\u00e1cie s\u00fa v stave idle in transaction<\/strong>. To s\u00fa tie, ktor\u00e9 otvorili transakciu, nie\u010do spravili a odi\u0161li alebo sa jednoducho zablokovali, stratili sa v k\u00f3de. <\/li>\n<li>A pre v\u00e1s, ako pre v\u00fdvoj\u00e1rov, je d\u00f4le\u017eit\u00e9 testova\u0165 k\u00f3d v okamihu vzniku t\u00fdchto situ\u00e1ci\u00ed. Nie je to \u0165a\u017ek\u00e9. Bude to u\u017eito\u010dn\u00e1 kontrola. Vyhnete sa mno\u017estvu \u201edetsk\u00fdch\u201c probl\u00e9mov s\u00favisiacich s dlh\u00fdmi transakciami. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/d55465d96c4018db733954867d23aaba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na t\u00fdchto grafoch som v\u00e1m chcel uk\u00e1za\u0165, ako sa zmenila tabu\u013eka a spr\u00e1vanie datab\u00e1zy po tom, ako som v tomto pr\u00edpade vykonal VACUUM FULL na tabu\u013eke. Toto nie je produkcia.<\/p>\n<p><\/p>\n<p>Ve\u013ekos\u0165 tabu\u013eky sa okam\u017eite vr\u00e1tila do norm\u00e1lneho funk\u010dn\u00e9ho stavu na p\u00e1r megabajtov. Na priemern\u00fd \u010das odpovede servera to nemalo ve\u013ek\u00fd vplyv. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/cbb07ad24dba899395223d1ca25e438e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ale konkr\u00e9tne pri na\u0161ej sk\u00famanej tabu\u013eke, kde sme aktualizovali zostatky na \u00fa\u010dtoch, vid\u00edme, \u017ee priemern\u00fd \u010das odpovede na po\u017eiadavku na aktualiz\u00e1ciu \u00fadajov v tabu\u013eke sa skr\u00e1til na predkr\u00edzov\u00fa \u00farove\u0148. Prostriedky spotrebovan\u00e9 procesorom na vykonanie tohto dotazu tie\u017e klesli na predkr\u00edzov\u00fa \u00farove\u0148. A prav\u00fd doln\u00fd graf ukazuje, \u017ee teraz n\u00e1jdeme presne ten riadok, ktor\u00fd potrebujeme, ihne\u010f, bez preh\u013ead\u00e1vania mno\u017estva m\u0155tvych riadkov, ktor\u00e9 existovali pred zmr\u0161ten\u00edm tabu\u013eky. A priemern\u00fd \u010das dotazov zostal zhruba na tej istej \u00farovni. Ale tu m\u00e1m sk\u00f4r nepresnos\u0165 m\u00f4jho hardv\u00e9ru.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/c1d90c5442e02fce209dc40e048a8ca2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na tomto prvom pr\u00edbehu to kon\u010d\u00ed. Je to najbe\u017enej\u0161ie. A st\u00e1va sa to v\u0161etk\u00fdm, bez oh\u013eadu na sk\u00fasenosti klienta, ak\u00ed kvalifikovan\u00ed s\u00fa program\u00e1tori. Sk\u00f4r \u010di nesk\u00f4r sa to stane. <\/p>\n<p><\/p>\n<p>Druh\u00fd pr\u00edbeh, v ktorom rozde\u013eujeme z\u00e1\u0165a\u017e a optimalizujeme serverov\u00e9 zdroje<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/cda421c554d1329107ddc935045cc1b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>U\u017e sme vyr\u00e1stli a stali sme sa v\u00e1\u017enymi hr\u00e1\u010dmi. A ch\u00e1peme, \u017ee m\u00e1me replik\u00e1ciu a bolo by dobr\u00e9 vyv\u00e1\u017ei\u0165 z\u00e1\u0165a\u017e: p\u00edsa\u0165 na Master a \u010d\u00edta\u0165 z repliky. A t\u00e1to situ\u00e1cia obvykle nast\u00e1va, ke\u010f chceme pripravi\u0165 nejak\u00e9 spr\u00e1vy alebo ETL. A biznis z toho m\u00e1 ve\u013ek\u00fa rados\u0165. Ve\u013emi chce r\u00f4zne spr\u00e1vy s hromadou zlo\u017eit\u00fdch anal\u00fdz. <\/li>\n<li>Spr\u00e1vy trvaj\u00fa hodiny, preto\u017ee zlo\u017eit\u00fa anal\u00fdzu nevyhodnot\u00edte za milisekundy. My, ako \u0161ikovn\u00ed chlapci, p\u00ed\u0161eme k\u00f3d. Rob\u00edme v aplik\u00e1cii vklad, \u017ee z\u00e1znam vedieme na Master, spr\u00e1vy vykon\u00e1vame na replike. <\/li>\n<li>Rozde\u013eujeme z\u00e1\u0165a\u017e. <\/li>\n<li>V\u0161etko funguje skvele. Sme skvel\u00ed. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/e94c8c492197a5015ac8aae79389a4c2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A ako vyzer\u00e1 t\u00e1to situ\u00e1cia? Konkr\u00e9tne na t\u00fdchto grafoch som e\u0161te pridal trvanie transakci\u00ed z repliky. V\u0161etky ostatn\u00e9 grafy sa t\u00fdkaj\u00fa iba Master servera. <\/p>\n<p><\/p>\n<p>Tabu\u013eka s preh\u013eadmi sa mi zatia\u013e zv\u00e4\u010d\u0161ila. Je ich viac. Vid\u00edme, \u017ee priemern\u00fd \u010das odozvy servera je stabiln\u00fd. Na replike vid\u00edme dlh\u00fa transakciu, ktor\u00e1 prebieha u\u017e 2 hodiny. Vid\u00edme pokojn\u00fd chod autovakus, ktor\u00fd spracov\u00e1va m\u0155tve riadky. A v\u0161etko je v poriadku. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/2da8acf098d12d6f146ab9b9dcb54b81.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pokia\u013e ide o testovan\u00fa tabu\u013eku, na\u010falej aktualizujeme zostatky na \u00fa\u010dtoch. A m\u00e1me tie\u017e stabiln\u00fd \u010das odozvy na dopyt, stabiln\u00fa spotrebu zdrojov. V\u0161etko je v poriadku. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/3621ef723017bac6fb635caf0a5f4de6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V\u0161etko je dobr\u00e9, pok\u00fdm neza\u010dn\u00fa tieto preh\u013eady nar\u00e1\u017ea\u0165 na probl\u00e9my s replik\u00e1ciou. A nar\u00e1\u017eaj\u00fa na ne s pravidelnou periodicitou. <\/p>\n<p><\/p>\n<p>Pozrieme sa na internet a za\u010d\u00edname \u010d\u00edta\u0165, pre\u010do sa to deje. A n\u00e1jdeme rie\u0161enie. <\/p>\n<p><\/p>\n<p>Prv\u00e9 rie\u0161enie \u2013 zv\u00fd\u0161i\u0165 oneskorenie replik\u00e1cie. Vieme, \u017ee n\u00e1\u0161 preh\u013ead trv\u00e1 3 hodiny. Nastav\u00edme oneskorenie replik\u00e1cie na 3 hodiny. Spust\u00edme v\u0161etko, ale st\u00e1le m\u00e1me probl\u00e9my s t\u00fdm, \u017ee preh\u013eady niekedy nar\u00e1\u017eaj\u00fa. <\/p>\n<p><\/p>\n<p>Chceme, aby to v\u0161etko fungovalo perfektne. Ideme \u010falej. A n\u00e1jdeme na internete skvel\u00e9 nastavenie \u2013 hot_standby_feedback. Zapneme to. Hot_standby_feedback n\u00e1m umo\u017e\u0148uje pozdr\u017ea\u0165 pr\u00e1cu autovakua na hlavnom servery. T\u00fdmto sa \u00faplne zbav\u00edme konfliktov replik\u00e1cie. A v\u0161etko n\u00e1m dobre funguje s preh\u013eadmi.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3c315168bdd3f392d2e8a1c5861004.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A \u010do sa v tom \u010dase deje s hlavn\u00fdm serverom? Na hlavnom serveri sa deje tot\u00e1lna katastrofa. Teraz sledujeme grafy, ke\u010f som zapol oba tieto parametre. A vid\u00edme, \u017ee rel\u00e1cia na replike ak\u00fdmisi sp\u00f4sobmi ovplyvnila situ\u00e1ciu na hlavnom serveri. Naozaj ovplyv\u0148uje, preto\u017ee zastavila autovacuum, ktor\u00e9 \u010dist\u00ed m\u0155tve riadky. Na\u0161a ve\u013ekos\u0165 tabu\u013eky op\u00e4\u0165 vysko\u010dila do nebies. Priemern\u00fd \u010das vykon\u00e1vania dopytov v celej datab\u00e1ze tie\u017e vysko\u010dil do nebies. Autovakua sa tro\u0161ku zapotili. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/980611dcce8b189dc50f422ffd3d2d72.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pokia\u013e ide o na\u0161u tabu\u013eku, vid\u00edme, \u017ee aktualiz\u00e1cia \u00fadajov sa tie\u017e vynorila do nebies. Spotreba procesora sa rovnako dramaticky zv\u00fd\u0161ila. Op\u00e4\u0165 prech\u00e1dzame ve\u013ek\u00e9 mno\u017estvo m\u0155tvych, nepou\u017eite\u013en\u00fdch riadkov. A \u010das odozvy tejto tabu\u013eky, po\u010det transakci\u00ed klesol. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/a648fd313a5dccf45f0056dc13c54263.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ako to bude vyzera\u0165, ak nevieme, o \u010dom som hovoril predt\u00fdm?<\/p>\n<p><\/p>\n<ul>\n<li>Za\u010d\u00edname h\u013eada\u0165 probl\u00e9my. Ak sme sa v prvej \u010dasti stretli s probl\u00e9mami, vieme, \u017ee to m\u00f4\u017ee by\u0165 sp\u00f4soben\u00e9 dlh\u00fdmi transakciami a ideme na Master. Probl\u00e9my m\u00e1me na Masteri. Nezvl\u00e1da to. Prehrieva sa, jeho Load Average sa bl\u00ed\u017ei k stovke. <\/li>\n<li>\u017diadosti tam spoma\u013euj\u00fa, ale nevid\u00edme tam \u017eiadne dlh\u00e9 transakcie. A nevieme, \u010do je zl\u00e9ho. Nevieme, kde h\u013eada\u0165. <\/li>\n<li>Kontrolujeme serverov\u00e9 vybavenie. Mo\u017eno m\u00e1me rozpadnut\u00fd RAID. Mo\u017eno n\u00e1m zhorila pam\u00e4\u0165ov\u00e1 karta. \u010coko\u013evek sa m\u00f4\u017ee sta\u0165. Ale nie, servery s\u00fa nov\u00e9, v\u0161etko funguje skvele. <\/li>\n<li>Be\u017eia v\u0161etci: administr\u00e1tori, v\u00fdvoj\u00e1ri a riadite\u013e. Ni\u010d nepom\u00e1ha. <\/li>\n<li>A v istom momente sa v\u0161etko n\u00e1hodou za\u010dne sam\u00e9 opravova\u0165. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/7d4f6417bc5cb3cec33679d843c6661d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na replike n\u00e1m v tom \u010dase po\u017eiadavka prebehla a odi\u0161la. Dostali sme spr\u00e1vu. Biznis je st\u00e1le spokojn\u00fd. Ako vid\u00edme, tabu\u013eka n\u00e1m znova nar\u00e1stla a nepl\u00e1nuje sa zmen\u0161i\u0165. Na grafike so seden\u00edm som si nechal k\u00fasok z tejto dlhej transakcie z repliky, aby ste mohli pos\u00fadi\u0165, ak\u00fd dlh\u00fd \u010das prech\u00e1dza, k\u00fdm sa situ\u00e1cia stabilizuje. <\/p>\n<p><\/p>\n<p>Sedenie odi\u0161lo. A a\u017e po nejakom \u010dase sa server dost\u00e1va viac-menej do poriadku. A priemern\u00fd \u010das odpovede na po\u017eiadavky na Master serveri sa vracia do normy. Preto\u017ee kone\u010dne, autovakuum dostalo pr\u00edle\u017eitos\u0165 vy\u010disti\u0165, ozna\u010di\u0165 tieto m\u0155tve riadky. A za\u010dalo robi\u0165 svoju pr\u00e1cu. A ako r\u00fdchlo ju rob\u00ed, tak r\u00fdchlo sa dostaneme do poriadku.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/547d195e08de1566da818150a47218eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pod\u013ea sk\u00fa\u0161anej tabu\u013eky, kde aktualizujeme zostatky na \u00fa\u010dtoch, vid\u00edme presne tak\u00fd ist\u00fd obraz. Priemern\u00fd \u010das aktualiz\u00e1cie \u00fa\u010dtu sa postupne tie\u017e normalizuje. Zdrojov\u00e9 za\u0165a\u017eenie procesora sa tie\u017e zni\u017euje. A po\u010det transakci\u00ed za sekundu sa vracia do normy. Ale znova nie do takej normy, ako to bolo pred hav\u00e1riou. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/29372a5e9124690931485a7aea65befc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V ka\u017edom pr\u00edpade dost\u00e1vame pokles v\u00fdkonnosti ako v prvom pr\u00edpade, o jeden a pol a\u017e dva razy, a niekedy aj viac. <\/p>\n<p><\/p>\n<p>Vyzer\u00e1 to, \u017ee sme v\u0161etko urobili spr\u00e1vne. Rozdelili sme z\u00e1\u0165a\u017e. Vybavenie neost\u00e1va ne\u010dinne. Po rozumne sme rozdelili po\u017eiadavky, ale i tak to dopadlo zle. <\/p>\n<p><\/p>\n<ul>\n<li>Nezahr\u0148ova\u0165 hot_standby_feedback? \u00c1no, neodpor\u00fa\u010da sa ho bez z\u00e1va\u017en\u00e9ho d\u00f4vodu zap\u00edna\u0165. Preto\u017ee t\u00e1to funkcia priamo ovplyv\u0148uje hlavn\u00fd server a pozastavuje fungovanie autovakuum tam. Ak ho zapnete na nejakej replik\u00e1cii a zabudnete na to, m\u00f4\u017eete zabi\u0165 hlavn\u00fd server a narazi\u0165 na ve\u013ek\u00e9 probl\u00e9my s aplik\u00e1ciou. <\/li>\n<li>Zv\u00fd\u0161i\u0165 max_standby_streaming_delay? \u00c1no, pre reporty \u2013 to \u00e1no. Ak m\u00e1te trojhodinov\u00fd report a nechcete, aby zlyhal kv\u00f4li konfliktom replik\u00e1ci\u00ed, proste zv\u00fd\u0161te oneskorenie. Dlhodob\u00fd report nikdy nevy\u017eaduje d\u00e1ta, ktor\u00e9 pri\u0161li do datab\u00e1zy pr\u00e1ve teraz. Ak je trojhodinov\u00fd, znamen\u00e1 to, \u017ee ho sp\u00fa\u0161\u0165ate za nejak\u00e9 star\u00e9 obdobie d\u00e1t. A pre v\u00e1s, \u010di to bude tri hodiny oneskorenie alebo \u0161es\u0165 hod\u00edn, to nebude ma\u0165 \u017eiadny v\u00fdznam, ale vy budete stabilne dost\u00e1va\u0165 reporty a nebudete ma\u0165 probl\u00e9my so zlyhan\u00edm. <\/li>\n<li>Pr\u00edrodzene, je potrebn\u00e9 kontrolova\u0165 dlh\u00e9 rel\u00e1cie na replik\u00e1ch, najm\u00e4 ak ste sa rozhodli zapn\u00fa\u0165 hot_standby_feedback na replik\u00e1ch. Preto\u017ee sa m\u00f4\u017ee sta\u0165 \u010doko\u013evek. Dali ste t\u00fato replik\u00e1ciu v\u00fdvoj\u00e1rovi, aby otestoval dotazy. Nap\u00edsal bl\u00e1zniv\u00fd dotaz. Spustil ho a odi\u0161iel na \u010daj, a my sme dostali zaplnen\u00fd hlavn\u00fd server. Alebo sme na to pustili nespr\u00e1vnu aplik\u00e1ciu. Situ\u00e1ci\u00ed je r\u00f4znych. Rel\u00e1cie na replik\u00e1ch je potrebn\u00e9 kontrolova\u0165 rovnako d\u00f4kladne ako na hlavnom serveri. <\/li>\n<li>A ak m\u00e1te r\u00fdchle a dlh\u00e9 dotazy na replik\u00e1ch, v tomto pr\u00edpade je lep\u0161ie pre rozlo\u017eenie za\u0165a\u017eenia rozdeli\u0165 ich. Toto je odkaz na streaming_delay. Pre r\u00fdchle majte jednu replik\u00e1ciu s mal\u00fdm oneskoren\u00edm replik\u00e1cie. Na dlh\u00e9 dotazy reportov majte replik\u00e1ciu, ktor\u00e1 m\u00f4\u017ee ma\u0165 oneskorenie a\u017e 6 hod\u00edn alebo aj 24 hod\u00edn. To je \u00faplne norm\u00e1lna situ\u00e1cia. <\/li>\n<\/ul>\n<p><\/p>\n<p>Odstra\u0148ujeme n\u00e1sledky t\u00fdm ist\u00fdm sp\u00f4sobom:<\/p>\n<p><\/p>\n<ul>\n<li>N\u00e1jdeme naf\u00faknut\u00e9 tabu\u013eky.<\/li>\n<li>A komprimujeme ich najvhodnej\u0161\u00edm n\u00e1strojom, ktor\u00fd n\u00e1m vyhovuje. <\/li>\n<\/ul>\n<p><\/p>\n<p>Druh\u00fd pr\u00edbeh na tomto sa skon\u010dil. Prejdeme k tretiemu pr\u00edbehu. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/c8784e0be27883640cb8f6919a1c25e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tie\u017e dos\u0165 be\u017en\u00fd pre n\u00e1s, v ktorom rob\u00edme migr\u00e1ciu. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/a04b9cd88a0e7e8a3b960ef930eb2657.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Ka\u017ed\u00fd softv\u00e9rov\u00fd produkt rastie. Menia sa po\u017eiadavky na\u0148. My sa v ka\u017edom pr\u00edpade chceme rozv\u00edja\u0165. A st\u00e1va sa, \u017ee je potrebn\u00e9 aktualizova\u0165 d\u00e1ta v tabu\u013eke, teda vykona\u0165 update v r\u00e1mci na\u0161ej migr\u00e1cie pre nov\u00fa funkcionalitu, ktor\u00fa zav\u00e1dzame v r\u00e1mci n\u00e1\u0161ho rozvoja. <\/li>\n<li>Star\u00fd form\u00e1t d\u00e1t nevyhovuje. Predpokladajme, \u017ee teraz sa obr\u00e1time na druh\u00fa tabu\u013eku, kde m\u00e1m oper\u00e1cie s t\u00fdmito \u00fa\u010dtami. A predpokladajme, \u017ee boli v rub\u013eoch, a rozhodli sme sa zv\u00fd\u0161i\u0165 presnos\u0165 a robi\u0165 ich v kopejk\u00e1ch. Na to potrebujeme spravi\u0165 aktualiz\u00e1ciu: pole so sumou oper\u00e1cie vyn\u00e1sobi\u0165 sto. <\/li>\n<li>V modernom svete pou\u017e\u00edvame automatizovan\u00e9 prostriedky na kontrolu verzi\u00ed datab\u00e1zy. Predpokladajme, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a><\/noindex>. Uv\u00e1dzame tam na\u0161u migr\u00e1ciu. Testujeme ju na na\u0161ej testovacej datab\u00e1ze. V\u0161etko je skvel\u00e9. Aktualiz\u00e1cia prebieha. Blokuje pr\u00e1cu na nejak\u00fd \u010das, ale z\u00edskavame aktualizovan\u00e9 d\u00e1ta. A m\u00f4\u017eeme sp\u00fa\u0161\u0165a\u0165 nov\u00fd funk\u010dn\u00fd prvok na tomto. V\u0161etko sme otestovali, skontrolovali. V\u0161etko potvrdili. <\/li>\n<li>Prebehli pl\u00e1novan\u00e9 pr\u00e1ce, prebehla migr\u00e1cia. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e046583f7b1723fc1eaf61a03900918.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tu je migr\u00e1cia s aktualiz\u00e1ciou predstaven\u00e1 pred vami. Ke\u010f\u017ee ide o oper\u00e1cie na \u00fa\u010dtoch, tabu\u013eka mala 15 GB. A ke\u010f\u017ee aktualizujeme ka\u017ed\u00fa riadok, aktualiz\u00e1cia zdvojn\u00e1sobila tabu\u013eku, preto\u017ee sme prep\u00edsali ka\u017ed\u00fa riadok. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/06120c98ea43d0568045e71935c23592.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Po\u010das migr\u00e1cie sme s touto tabu\u013ekou nemohli robi\u0165 ni\u010d, preto\u017ee v\u0161etky po\u017eiadavky sa \u010dakali v rade a \u010dakali, k\u00fdm sa t\u00e1to aktualiz\u00e1cia dokon\u010d\u00ed. Ale tu chcem upriami\u0165 va\u0161u pozornos\u0165 na \u010d\u00edsla, ktor\u00e9 s\u00fa na vertik\u00e1lnej osi. To znamen\u00e1, \u017ee m\u00e1me priemern\u00fd \u010das po\u017eiadavky pred migr\u00e1ciou okolo 5 milisek\u00fand a za\u0165a\u017eenie procesora, po\u010det blokov\u00fdch oper\u00e1ci\u00ed pri \u010d\u00edtan\u00ed pam\u00e4te disku je menej ako 7,5. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/69a3ba4d1d0cec7d39284e09e9d3055b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Prebehla migr\u00e1cia a op\u00e4\u0165 sme dostali probl\u00e9my. <\/p>\n<p><\/p>\n<p>Migr\u00e1cia prebehla \u00faspe\u0161ne, ale:<\/p>\n<p><\/p>\n<ul>\n<li>Star\u00fd funk\u010dn\u00fd prvok za\u010dal prebieha\u0165 pomal\u0161ie. <\/li>\n<li>Tabu\u013eka op\u00e4\u0165 nabrala na ve\u013ekosti. <\/li>\n<li>Za\u0165a\u017eenie servera op\u00e4\u0165 vzr\u00e1stlo. <\/li>\n<li>A samozrejme, zatia\u013e sa zaober\u00e1me funk\u010dn\u00fdm prvkom, ktor\u00fd fungoval dobre, trochu sme ho vylep\u0161ili. <\/li>\n<\/ul>\n<p><\/p>\n<p>A toto je op\u00e4\u0165 bloat, ktor\u00fd n\u00e1m znovu kaz\u00ed \u017eivot. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/becd7cce3a1c8821c81c96257f41202b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tu demon\u0161trujem, \u017ee tabu\u013eka, ako v predch\u00e1dzaj\u00facich dvoch pr\u00edpadoch, nem\u00e1 v \u00famysle vr\u00e1ti\u0165 sa k predch\u00e1dzaj\u00facim rozmerom. Priemern\u00e9 za\u0165a\u017eenie servera sa zd\u00e1 by\u0165 primeran\u00e9. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/4d703a60d43a3460bc3782d49865b690.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A ak sa pozrieme na tabu\u013eku s \u00fa\u010dtami, vid\u00edme, \u017ee priemern\u00fd \u010das dopytu sa n\u00e1m zdvojn\u00e1sobil v tejto tabu\u013eke. Za\u0165a\u017eenie procesora a po\u010det prech\u00e1dzan\u00fdch riadkov v pam\u00e4ti vzr\u00e1stlo nad 7,5, zatia\u013e \u010do predt\u00fdm bolo ni\u017e\u0161ie. A zv\u00fd\u0161ilo sa to v pr\u00edpade procesorov dvojn\u00e1sobne, v pr\u00edpade blokov\u00fdch oper\u00e1ci\u00ed 1,5-n\u00e1sobne, teda sme zaznamenali degrad\u00e1ciu v\u00fdkonnosti servera. A v d\u00f4sledku toho aj degrad\u00e1ciu v\u00fdkonnosti na\u0161ej aplik\u00e1cie. Po\u010det volan\u00ed pritom zostal na pribli\u017ene rovnakej \u00farovni. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/80772afa0643b29f5314a2482c9dfe0d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A tu je d\u00f4le\u017eit\u00e9 pochopi\u0165, ako spr\u00e1vne realizova\u0165 tak\u00e9 migr\u00e1cie. A tie je potrebn\u00e9 robi\u0165. Tieto migr\u00e1cie uskuto\u010d\u0148ujeme pomerne pravidelne.<\/p>\n<p><\/p>\n<ul>\n<li>Tak\u00e9 ve\u013ek\u00e9 migr\u00e1cie nie s\u00fa automatick\u00e9. V\u017edy by mali by\u0165 pod kontrolou. <\/li>\n<li>Je potrebn\u00e1 kontrola zo strany znal\u00e9ho \u010dloveka. Ak m\u00e1te DBA v t\u00edme, nech to rob\u00ed DBA. To je jeho pr\u00e1ca. Ak nie, nech to rob\u00ed najsk\u00fasenej\u0161\u00ed \u010dlovek, ktor\u00fd vie, ako pracova\u0165 s datab\u00e1zami. <\/li>\n<li>Nov\u00fd sch\u00e9ma datab\u00e1zy, aj v pr\u00edpade, \u017ee aktualizujeme jeden st\u013apec, je v\u017edy pripravovan\u00e1 postupne, teda vopred, pred t\u00fdm, ako sa nasad\u00ed nov\u00e1 verzia aplik\u00e1cie:<\/li>\n<li>Prid\u00e1vaj\u00fa sa nov\u00e9 polia, do ktor\u00fdch budeme zapisova\u0165 pr\u00e1ve aktualizovan\u00e9 \u00fadaje. <\/li>\n<li>Pren\u00e1\u0161ame \u00fadaje zo star\u00e9ho po\u013ea do nov\u00e9ho po\u013ea po mal\u00fdch \u010dastiach. Pre\u010do to rob\u00edme? Predov\u0161etk\u00fdm, v\u017edy kontrolujeme proces po\u010das tohto procesu. Vieme, \u017ee sme preniesli u\u017e to\u013eko d\u00e1vok a zost\u00e1va n\u00e1m to\u013eko. <\/li>\n<li>A druh\u00fd pozit\u00edvny efekt spo\u010d\u00edva v tom, \u017ee medzi ka\u017edou takouto d\u00e1vkou uzatv\u00e1rame transakciu, otv\u00e1rame nov\u00fa, a to d\u00e1va pr\u00edle\u017eitos\u0165 autovakuumu spracova\u0165 tabu\u013eku, ozna\u010di\u0165 m\u0155tve riadky na op\u00e4tovn\u00e9 pou\u017eitie. <\/li>\n<li>Pre riadky, ktor\u00e9 sa bud\u00fa objavova\u0165 po\u010das pr\u00e1ce aplik\u00e1cie (na\u0161a star\u00e1 aplik\u00e1cia e\u0161te be\u017e\u00ed), prid\u00e1vame sp\u00fa\u0161\u0165a\u010d, ktor\u00fd zapisuje nov\u00e9 hodnoty do nov\u00fdch pol\u00ed. V na\u0161om pr\u00edpade \u2013 to je vyn\u00e1sobenie sto starou hodnotou. <\/li>\n<li>Ak sme naozaj tvrdohlav\u00ed a chceme to ist\u00e9 pole, tak po dokon\u010den\u00ed v\u0161etk\u00fdch migr\u00e1ci\u00ed a pred nasaden\u00edm novej verzie aplik\u00e1cie jednoducho premenov\u00e1me polia. Star\u00e9 na nejak\u00e9 vymyslen\u00e9 meno, a nov\u00e9 polia premenov\u00e1vame na star\u00e9. <\/li>\n<li>A a\u017e potom spust\u00edme nov\u00fa verziu aplik\u00e1cie. <\/li>\n<\/ul>\n<p><\/p>\n<p>A pritom nez\u00edskame bloat a nebudeme ma\u0165 pokles v\u00fdkonnosti. <\/p>\n<p><\/p>\n<p>Na tomto sa tretia hist\u00f3ria skon\u010dila. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" 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>A teraz trochu podrobnej\u0161ie o n\u00e1strojoch, ktor\u00e9 som spomenul v prvej hist\u00f3rii. <\/p>\n<p><\/p>\n<p>Pred t\u00fdm, ako za\u010dnete h\u013eada\u0165 bloat, je nevyhnutn\u00e9 nain\u0161talova\u0165 roz\u0161\u00edrenie. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Aby ste si nemuseli vym\u00fd\u0161\u013ea\u0165 dopyty, my sme u\u017e nap\u00edsali tieto dopyty vo svojej pr\u00e1ci. M\u00f4\u017eete ich pou\u017ei\u0165. Tu s\u00fa predstaven\u00e9 dva dopyty. <\/p>\n<p><\/p>\n<ul>\n<li>Prv\u00fd trv\u00e1 dos\u0165 dlho, ale uk\u00e1\u017ee v\u00e1m presn\u00e9 hodnoty bloat pod\u013ea tabu\u013eky. <\/li>\n<li>Druh\u00fd funguje r\u00fdchlej\u0161ie a je ve\u013emi efekt\u00edvny, ke\u010f treba r\u00fdchlo pos\u00fadi\u0165 \u2013 je bloat, alebo nie, pod\u013ea tabu\u013eky. A e\u0161te mus\u00edte pochopi\u0165, \u017ee bloat v tabu\u013eke Postgres je v\u017edy. To je \u0161pecifickos\u0165 jeho modelu MVCC. <\/li>\n<li>A 20 % bloat je v mnoh\u00fdch pr\u00edpadoch norm\u00e1lne pre tabu\u013eky. T. j. nemali by ste sa ob\u00e1va\u0165 a zmen\u0161ova\u0165 t\u00fato tabu\u013eku. <\/li>\n<\/ul>\n<p><\/p>\n<p>Ako identificova\u0165 tabu\u013eky, ktor\u00e9 m\u00e1me napu\u010dan\u00e9, sme si u\u017e vyjasnili, pri\u010dom sa to deje, ke\u010f napu\u010daj\u00fa zbyto\u010dn\u00fdmi \u00fadajmi. <\/p>\n<p><\/p>\n<p>Teraz o tom, ako opravi\u0165 bloat:<\/p>\n<p><\/p>\n<ul>\n<li>Ak m\u00e1me mal\u00fa tabu\u013eku a dobr\u00e9 disky, t. j. pre tabu\u013eku do jedn\u00e9ho gigabajtu, je celkom mo\u017en\u00e9 pou\u017ei\u0165 VACUUM FULL. Vezme si exkluz\u00edvnu blok\u00e1ciu na tabu\u013eku na nieko\u013eko sek\u00fand a je to v poriadku, zato r\u00fdchlo a d\u00f4kladne v\u0161etko urob\u00ed. \u010co rob\u00ed VACUUM FULL? Z\u00edska exkluz\u00edvnu blok\u00e1ciu na tabu\u013eku a z p\u00f4vodn\u00fdch tabuliek prep\u00ed\u0161e \u017eiv\u00e9 riadky do novej tabu\u013eky. A na konci ich vymen\u00ed. Star\u00e9 s\u00fabory vyma\u017ee, nov\u00e9 nahr\u00e1dzaj\u00fa star\u00e9. Ale po\u010das svojej pr\u00e1ce si z\u00edska exkluz\u00edvnu blok\u00e1ciu tabu\u013eky. To znamen\u00e1, \u017ee s touto tabu\u013ekou nebudete m\u00f4c\u0165 ni\u010d robi\u0165: ani do nej p\u00edsa\u0165, ani ju \u010d\u00edta\u0165, ani ju modifikova\u0165. A VACUUM FULL vy\u017eaduje dodato\u010dn\u00e9 miesto na disku na z\u00e1pis \u00fadajov.<\/li>\n<li>\u010eal\u0161\u00ed n\u00e1stroj <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">pg_repack<\/a><\/noindex>. Pod\u013ea svojho princ\u00edpu je ve\u013emi podobn\u00fd VACUUM FULL, preto\u017ee aj on prep\u00ed\u0161e \u00fadaje zo star\u00fdch s\u00faborov do nov\u00fdch a nahrad\u00ed ich v tabu\u013eke. Ale pritom si na za\u010diatku svojej pr\u00e1ce neberie exkluz\u00edvnu blok\u00e1ciu na tabu\u013eku, ale len v momente, ke\u010f u\u017e m\u00e1 pripraven\u00e9 \u00fadaje na to, aby nahradil s\u00fabory. Po\u017eiadavky na disky m\u00e1 podobn\u00e9 ako VACUUM FULL. Potrebujete dodato\u010dn\u00e9 miesto na disku, \u010do m\u00f4\u017ee by\u0165 niekedy kritick\u00e9, ak m\u00e1te terabajtov\u00e9 tabu\u013eky. A je celkom n\u00e1ro\u010dn\u00fd na procesor, preto\u017ee vedie akt\u00edvnu pr\u00e1cu s I\/O. <\/li>\n<li>Tret\u00ed n\u00e1stroj \u2013 to je <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex>Lieber sa \u0161etrnej\u0161\u00edm pr\u00edstupom k zdrojom, preto\u017ee funguje na trochu odli\u0161n\u00fdch princ\u00edpoch. Hlavn\u00e1 podstata pgcompacttable spo\u010d\u00edva v tom, \u017ee aktualiz\u00e1ciami v tabu\u013eke pren\u00e1\u0161a v\u0161etky \u017eiv\u00e9 riadky na za\u010diatok tabu\u013eky. A potom spust\u00ed v\u00e1kuum po tejto tabu\u013eke, preto\u017ee vieme, \u017ee na za\u010diatku s\u00fa \u017eiv\u00e9 a na konci m\u0155tve riadky. A v\u00e1kuum u\u017e samo odstra\u0148uje tento chvost, t. j. nevy\u017eaduje to ve\u013ea dodato\u010dn\u00e9ho diskov\u00e9ho priestoru. A pritom je e\u0161te mo\u017en\u00e9 ho z h\u013eadiska zdrojov zmen\u0161i\u0165. <\/li>\n<\/ul>\n<p><\/p>\n<p>V\u0161etko s n\u00e1strojmi. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrey Salynikov\" src=\"\/wp-content\/uploads\/2020\/05\/4187915e54e54a0b85a342fe0280f78f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ak v\u00e1s t\u00e1ma bloat zaujme a chcete sa pusti\u0165 hlb\u0161ie, tu s\u00fa niektor\u00e9 u\u017eito\u010dn\u00e9 odkazy:<\/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 to je predn\u00e1\u0161ka m\u00f4jho kolegu. Je to v\u0161eobecn\u00e9 o tom, kam zmizne miesto v Postgres po\u010das jeho pr\u00e1ce a \u017eivota. Obsahuje ve\u013emi ve\u013ek\u00fd a podrobn\u00fd technick\u00fd \u00fasek pre administr\u00e1torov datab\u00e1z o bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\">https:\/\/github.com\/dataegret\/pg-utils<\/a><\/noindex> \u2013 to je odkaz na n\u00e1\u0161 repozit\u00e1r, kde m\u00e1me mno\u017estvo u\u017eito\u010dn\u00fdch skriptov na kontrolu stavu datab\u00e1zy. Tam n\u00e1jdete skripty na vyh\u013ead\u00e1vanie bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Tretia<\/a><\/noindex> a <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">\u0161tvrt\u00e1<\/a><\/noindex> odkazy na n\u00e1stroje, ktor\u00e9 v\u00e1m pom\u00f4\u017eu zmen\u0161i\u0165 tabu\u013eky. <\/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 to je pr\u00edspevok m\u00f4jho kolegu. Tam pomerne v\u00e1\u017ene a podrobne technicky rozober\u00e1 bloat, konkr\u00e9tne na \u00farovni bl\u00edzkej k administr\u00e1torom. <\/li>\n<\/ul>\n<p><\/p>\n<p>Tu som sa sk\u00f4r sna\u017eil uk\u00e1za\u0165 hrozn\u00fd poh\u013ead pre v\u00fdvoj\u00e1rov, preto\u017ee s\u00fa na\u0161imi bezprostredn\u00fdmi klientmi datab\u00e1z a mali by rozumie\u0165, ak\u00e9 d\u00f4sledky maj\u00fa ich \u010dinnosti. D\u00fafam, \u017ee sa mi to podarilo. \u010eakujem za pozornos\u0165!<\/p>\n<p><\/p>\n<p>Ot\u00e1zky<\/p>\n<p><\/p>\n<p><em>\u010eakujem za predn\u00e1\u0161ku! Hovorili ste o tom, ako mo\u017eno odha\u013eova\u0165 probl\u00e9my. A ako ich m\u00f4\u017eeme predch\u00e1dza\u0165? M\u00e1m situ\u00e1ciu, ke\u010f sa po\u017eiadavky zadrh\u00e1vali nielen kv\u00f4li tomu, \u017ee sa obracali na nejak\u00e9 extern\u00e9 slu\u017eby. I\u0161lo o podivn\u00e9 joins. Boli tam mal\u00e9, ne\u0161kodn\u00e9 po\u017eiadavky, ktor\u00e9 sa zadrh\u00e1vali cel\u00fd de\u0148 a potom za\u010dali robi\u0165 nejak\u00e9 probl\u00e9my. Ve\u013emi to pripom\u00edna to, \u010do popisujete. Ako to sledova\u0165? Mus\u00edm neust\u00e1le sledova\u0165, ktor\u00e1 po\u017eiadavka sa zadrh\u00e1va? Ako tomu m\u00f4\u017eeme predch\u00e1dza\u0165?<\/em><\/p>\n<p><\/p>\n<p>V tomto pr\u00edpade je to \u00faloha pre administr\u00e1torov va\u0161ej spolo\u010dnosti, nie nutne pre DBA.<\/p>\n<p><\/p>\n<p><em>Som administr\u00e1tor.<\/em><\/p>\n<p><\/p>\n<p>V PostgreSQL existuje poh\u013ead pg_stat_activity, v ktorom s\u00fa zobrazen\u00e9 zadrhnut\u00e9 po\u017eiadavky. A m\u00f4\u017eete vidie\u0165, ako dlho tam vis\u00ed.<\/p>\n<p><\/p>\n<p><em>M\u00e1m ka\u017ed\u00fdch 5 min\u00fat chodi\u0165 kontrolova\u0165?<\/em><\/p>\n<p><\/p>\n<p>Nastavte cron a kontrolujte. Ak m\u00e1te dlh\u00fd dotaz, nap\u00ed\u0161te e-mail a to je v\u0161etko. T. j. nemus\u00edte sa na to pozera\u0165 o\u010dami, d\u00e1 sa to automatizova\u0165. Dostanete e-mail, na ktor\u00fd reagujete. A m\u00f4\u017eete to aj automaticky posiela\u0165 pre\u010d.<\/p>\n<p><\/p>\n<p><em>Existuj\u00fa jasn\u00e9 d\u00f4vody, pre\u010do sa to deje?<\/em><\/p>\n<p><\/p>\n<p>Niektor\u00e9 som spomenul. In\u00e9 s\u00fa zlo\u017eitej\u0161ie pr\u00edklady. A tam m\u00f4\u017ee by\u0165 diskusia dlh\u00e1.<\/p>\n<p><\/p>\n<p><em>\u010eakujem za spr\u00e1vu! Chcel som sa op\u00fdta\u0165 na n\u00e1stroj pg_repack. Ak nerob\u00ed exkluz\u00edvnu blok\u00e1ciu, tak\u2026<\/em><\/p>\n<p><\/p>\n<p>Rob\u00ed exkluz\u00edvnu blok\u00e1ciu. <\/p>\n<p><\/p>\n<p>\u2026 <em>tak m\u00f4\u017eem potenci\u00e1lne pr\u00eds\u0165 o d\u00e1ta. M\u00f4\u017ee moja aplik\u00e1cia ni\u010d zapisova\u0165 v tom \u010dase?<\/em><\/p>\n<p><\/p>\n<p>Nie, t\u00e1 pracuje bez probl\u00e9mov s tabu\u013ekou, t. j. pg_repack najprv presunie v\u0161etky \u017eiv\u00e9 riadky, ktor\u00e9 s\u00fa. Samozrejme, tam sa nie\u010do zapisuje do tabu\u013eky. Ten len prid\u00e1 ten posledn\u00fd k\u00fasok. <\/p>\n<p><\/p>\n<p><em>T. j. on nakoniec naozaj rob\u00ed?<\/em><\/p>\n<p><\/p>\n<p>Nakoniec vezme exkluz\u00edvnu blok\u00e1ciu, aby mohol zameni\u0165 tieto s\u00fabory. <\/p>\n<p><\/p>\n<p><em>Bude to r\u00fdchlej\u0161ie ako VACUUM FULL?<\/em><\/p>\n<p><\/p>\n<p>VACUUM FULL, hne\u010f ako za\u010dne, vezme exkluz\u00edvnu blok\u00e1ciu. A k\u00fdm to v\u0161etko nedokon\u010d\u00ed, nepust\u00ed ju. A pg_repack berie exkluz\u00edvnu blok\u00e1ciu len v momente v\u00fdmeny s\u00faborov. V tom okamihu tam ni\u010d nezap\u00ed\u0161ete, ale d\u00e1ta sa nestratia, v\u0161etko bude v poriadku. <\/p>\n<p><\/p>\n<p><em>Dobr\u00fd de\u0148! Hovorili ste o pr\u00e1ci autovaku. Bolo tam sch\u00e9ma s \u010derven\u00fdmi, \u017elt\u00fdmi a zelen\u00fdmi bunkami zaznamenan\u00fdmi. T. j. \u017elt\u00e9 \u2013 ozna\u010dil ich ako odstr\u00e1nen\u00e9. A n\u00e1sledne do nich m\u00f4\u017eem zap\u00edsa\u0165 nov\u00e9?<\/em><\/p>\n<p><\/p>\n<p>\u00c1no. Postgres neodstr\u00e1ni riadky. M\u00e1 tak\u00fa \u0161pecifik\u00e1ciu. Ak sme aktualizovali riadok, star\u00fd ozna\u010d\u00edme ako odstr\u00e1nen\u00fd. Potom sa tam vlo\u017e\u00ed id transakcie, ktor\u00e1 upravila tento riadok, a zapisujeme nov\u00fd riadok. A m\u00e1me rel\u00e1cie, ktor\u00e9 ich potenci\u00e1lne m\u00f4\u017eu \u010d\u00edta\u0165. V ur\u010ditom momente sa u\u017e stan\u00fa ve\u013emi star\u00fdmi. A podstata pr\u00e1ce autovaku spo\u010d\u00edva v tom, \u017ee prejde cez tieto riadky a ozna\u010d\u00ed ich ako nepotrebn\u00e9. A tam m\u00f4\u017eeme prep\u00edsa\u0165 d\u00e1ta. <\/p>\n<p><\/p>\n<p><em>Pochopil som. Ale ot\u00e1zka nie je \u00faplne o tom. Nedokon\u010dil som. Predpokladajme, \u017ee m\u00e1me tabu\u013eku. V nej s\u00fa polia s variabilnou ve\u013ekos\u0165ou. A ak sa pok\u00fasim vlo\u017ei\u0165 nie\u010do nov\u00e9, m\u00f4\u017ee sa sta\u0165, \u017ee to do star\u00e9ho po\u013ea jednoducho nevojde.<\/em> <\/p>\n<p><\/p>\n<p>Nie, v ka\u017edom pr\u00edpade sa aktualizuje cel\u00fd riadok. V Postgres s\u00fa dva modely ukladania d\u00e1t. Ten si vyber\u00e1 pod\u013ea typu d\u00e1t. Existuj\u00fa d\u00e1ta, ktor\u00e9 sa ukladaj\u00fa priamo v tabu\u013eke, a s\u00fa aj tos-d\u00e1ta. Toto s\u00fa ve\u013ek\u00e9 objemy d\u00e1t: text, json. Ukladaj\u00fa sa v samostatn\u00fdch tabu\u013ek\u00e1ch. A v t\u00fdchto tabu\u013ek\u00e1ch sa deje t\u00e1 ist\u00e1 hist\u00f3ria s bloat, t. j. \u00faplne to ist\u00e9. Jednoducho s\u00fa oddelen\u00e9. <\/p>\n<p><\/p>\n<p><em>\u010eakujem za prezent\u00e1ciu! Ako prijate\u013en\u00e9 je pou\u017e\u00edva\u0165 statement timeout na obmedzenie trvania dotazov?<\/em><\/p>\n<p><\/p>\n<p>Ve\u013emi prijate\u013en\u00e9. Pou\u017e\u00edvame to v\u0161ade. A ke\u010f\u017ee nem\u00e1me vlastn\u00e9 slu\u017eby, poskytujeme dia\u013ekov\u00fa podporu, tak\u017ee m\u00e1me pomerne rozmanit\u00fdch klientov. A v\u0161etk\u00fdch to celkom uspokojuje. T. j. m\u00e1me \u00falohy v cron, ktor\u00e9 to kontroluj\u00fa. Jednoducho sa s klientom dohodneme na d\u013a\u017eke rel\u00e1ci\u00ed, ktor\u00fa nepre\u0165a\u017eujeme. M\u00f4\u017ee to by\u0165 min\u00fata, m\u00f4\u017ee to by\u0165 10 min\u00fat. Z\u00e1vis\u00ed to od z\u00e1\u0165a\u017ee na datab\u00e1ze a jej cie\u013ea. Ale v\u0161etci pou\u017e\u00edvame pg_stat_activity.<\/p>\n<p><\/p>\n<p><em>\u010eakujem za prezent\u00e1ciu! Sna\u017e\u00edm sa prisp\u00f4sobi\u0165 va\u0161u prezent\u00e1ciu svojim aplik\u00e1ci\u00e1m. A zd\u00e1 sa, \u017ee v\u0161ade za\u010d\u00edname transakciu, v\u0161ade ju jasne kon\u010d\u00edme. Ak sa vyskytne nejak\u00fd exception, aj tak doch\u00e1dza k rollbacku. A tu som sa zamyslel. Ve\u010f transakcia sa m\u00f4\u017ee za\u010da\u0165 nejasne. To je asi n\u00e1poveda pre diev\u010da. Ak len aktualizujem z\u00e1znam, transakcia sa spust\u00ed v PostgreSQL a skon\u010d\u00ed sa a\u017e pri odpojen\u00ed spojenia?<\/em><\/p>\n<p><\/p>\n<p>Ak hovor\u00edte teraz o \u00farovni aplik\u00e1cie, tak to z\u00e1vis\u00ed od ovl\u00e1da\u010da, ktor\u00fd pou\u017e\u00edvate, od toho ORM, ktor\u00e9 sa pou\u017e\u00edva. Tam je ve\u013ea nastaven\u00ed. Ak m\u00e1te zapnut\u00e9 auto commit, tak sa tam transakcia za\u010dne a hne\u010f aj uzavrie.<\/p>\n<p><\/p>\n<p><em>T. j. uzavrie sa ihne\u010f po aktualiz\u00e1cii?<\/em><\/p>\n<p><\/p>\n<p>Z\u00e1vis\u00ed to od nastaven\u00ed. Jedno nastavenie som nazval. Je to auto commit. Je dos\u0165 roz\u0161\u00edren\u00e9. Ak je zapnut\u00e9, tak sa transakcia otvor\u00ed a uzavrie. Ak ste jasne nepovedali \u201estart transaction\u201c a \u201eend transaction\u201c, ale jednoducho ste spustili dotaz v rel\u00e1cii. <\/p>\n<p><\/p>\n<p><em>Dobr\u00fd de\u0148! \u010eakujem za prezent\u00e1ciu! Predstavme si, \u017ee m\u00e1me datab\u00e1zu, ktor\u00e1 neust\u00e1le rastie a na serveri sa kon\u010d\u00ed miesto. Existuj\u00fa nejak\u00e9 n\u00e1stroje, ktor\u00e9 by pomohli t\u00fato situ\u00e1ciu vyrie\u0161i\u0165?<\/em> <\/p>\n<p><\/p>\n<p>Miesto na serveri treba spr\u00e1vne monitorova\u0165. <\/p>\n<p><\/p>\n<p><em>Napr\u00edklad, DBA \u0161iel pi\u0165 \u010daj, bol na dovolenke at\u010f.<\/em><\/p>\n<p><\/p>\n<p>Ke\u010f sa vytv\u00e1ra s\u00faborov\u00fd syst\u00e9m, vytvor\u00ed sa tam minim\u00e1lne nejak\u00fd rezervn\u00fd priestor, kam sa nep\u00ed\u0161u d\u00e1ta. <\/p>\n<p><\/p>\n<p><em>A \u010do ak \u00faplne na nulu?<\/em><\/p>\n<p><\/p>\n<p>Tam sa to naz\u00fdva rezervovan\u00fd priestor, to znamen\u00e1, \u017ee ho m\u00f4\u017eete oslobodi\u0165 a v z\u00e1vislosti od toho, ak\u00fd ve\u013ek\u00fd ho vytvorili, dostali ste vo\u013en\u00e9 miesto. Predvolene neviem, ko\u013eko tam je. Inak treba doru\u010di\u0165 disky, aby ste mali miesto na vykonanie obnovovacej oper\u00e1cie. M\u00f4\u017eete odstr\u00e1ni\u0165 nejak\u00fa tabu\u013eku, ktor\u00e1 v\u00e1m s ur\u010ditos\u0165ou nie je potrebn\u00e1. <\/p>\n<p><\/p>\n<p><em>Nie s\u00fa in\u00e9 n\u00e1stroje?<\/em><\/p>\n<p><\/p>\n<p>Je to v\u017edy ru\u010dn\u00e1 pr\u00e1ca. A na mieste sa zis\u0165uje, \u010do tam je lep\u0161ie urobi\u0165, preto\u017ee s\u00fa tam kritick\u00e9 d\u00e1ta a nekritick\u00e9. A pre ka\u017ed\u00fd datab\u00e1zov\u00fd syst\u00e9m a aplik\u00e1ciu, ktor\u00e1 s \u0148ou pracuje, to z\u00e1vis\u00ed od podnikania. V\u017edy sa to rozhoduje na mieste. <\/p>\n<p><\/p>\n<p><em>\u010eakujem za predn\u00e1\u0161ku! M\u00e1m dve ot\u00e1zky. Po prv\u00e9, demon\u0161trovali ste sn\u00edmky, kde sa ukazovalo, \u017ee v pr\u00edpade visiacich transakci\u00ed rastie nielen objem tabu\u013ekov\u00e9ho priestoru, ale aj ve\u013ekos\u0165 indexu. A potom v predn\u00e1\u0161ke bolo mno\u017estvo util\u00edt, ktor\u00e9 balia tabu\u013eku. A \u010do s indexom?<\/em><\/p>\n<p><\/p>\n<p>Oni ich tie\u017e balia. <\/p>\n<p><\/p>\n<p><em>Ale vakuum sa nedot\u00fdka indexu?<\/em><\/p>\n<p><\/p>\n<p>Niektor\u00e9 pracuj\u00fa s indexom. Napr\u00edklad pg_rapack, pgcompacttable. Vakuum prekon\u0161truuje indexy, zasahuje do nich. U VACUUM FULL ide o to, aby v\u0161etko prep\u00edsal, to znamen\u00e1, \u017ee pracuje so v\u0161etk\u00fdm. <\/p>\n<p><\/p>\n<p><em>A moja druh\u00e1 ot\u00e1zka. Nech\u00e1pal som, pre\u010do spr\u00e1vy na replik\u00e1ch tak silno z\u00e1visia od samotnej replik\u00e1cie. Zdalo sa mi, \u017ee spr\u00e1vy s\u00fa \u010d\u00edtanie, a replik\u00e1cia je z\u00e1pis.<\/em> <\/p>\n<p><\/p>\n<p>V \u010dom vznik\u00e1 konflikt replik\u00e1cie? M\u00e1me Master, na ktorom prebiehaj\u00fa procesy. Prebieha n\u00e1m autokvakuum. Autokvakuum, \u010do vlastne rob\u00ed? Odstra\u0148uje niektor\u00e9 star\u00e9 riadky. Ak v tom \u010dase na replike prebieha dopyt, ktor\u00fd \u010d\u00edta tieto star\u00e9 riadky, a na Masteri nastala situ\u00e1cia, \u017ee autokvakuum ozna\u010dilo tieto riadky ako mo\u017en\u00e9 na prep\u00edsanie, potom sme ich prep\u00edsali. A dostali sme paket d\u00e1t, ke\u010f mus\u00edme prep\u00edsa\u0165 tie riadky, ktor\u00e9 s\u00fa potrebn\u00e9 dopytu na replike, teda proces replik\u00e1cie po\u010dk\u00e1 na ten \u010dasov\u00fd limit, ktor\u00fd ste nastavili. Potom PostgreSQL rozhodne, \u010do je pre\u0148 d\u00f4le\u017eitej\u0161ie. A replik\u00e1cia je pre\u0148 d\u00f4le\u017eitej\u0161ia ako dopyt a on zru\u0161\u00ed dopyt, aby vykonal tieto zmeny na replike. <\/p>\n<p><\/p>\n<p><em>Andrej, m\u00e1m ot\u00e1zku. Tieto \u00fa\u017easn\u00e9 grafy, ktor\u00e9 ste uk\u00e1zali po\u010das prezent\u00e1cie, s\u00fa v\u00fdsledkom va\u0161ich pr\u00e1c, nejakej va\u0161ej utilitky? \u010c\u00edm ste vytvorili grafy?<\/em><\/p>\n<p><\/p>\n<p>Toto je slu\u017eba <noindex><a rel=\"nofollow\" href=\"https:\/\/okmeter.io\/\">Okmeter<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><em>Je to komer\u010dn\u00fd produkt?<\/em><\/p>\n<p><\/p>\n<p>\u00c1no. Je to komer\u010dn\u00fd produkt.<\/p>\n<p>Zdroj: <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\/sk\/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=\"sk_SK\" \/>\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\/sk\/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\udd47Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL. Andrej Salnikov | ProHoster","description":"Navrhujem zozn\u00e1mi\u0165 sa s v\u00fdkladom spr\u00e1vy z za\u010diatku roka 2016 od Andreja Salnikova \"Typick\u00e9 chyby v aplik\u00e1ci\u00e1ch, ktor\u00e9 ved\u00fa k bloat v PostgreSQL\". V tejto spr\u00e1ve sa zameriam na hlavn\u00e9.","canonical_url":"https:\/\/prohoster.info\/sk\/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":"sk_SK","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\/sk\/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\/sk\/wp-json\/wp\/v2\/posts\/81089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/comments?post=81089"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/posts\/81089\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media\/81090"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/media?parent=81089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/categories?post=81089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sk\/wp-json\/wp\/v2\/tags?post=81089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}