Postgres – vsetko, co si chtel vediet, ale bal sa spytat svojho seniora, aby si nevypadal ako jelito 02 – vakuova pumpa
VACUUM je automaticky alebo rucny sposob, ako si precistit tabuulky od bloatu (nevadidnych spinavych zaznamov). Ako znie slavny bonmot – vakuujte, co to ide.
ako dochadza k bordelu
Postgres pouziva multi-version concurrency control pre zabezpecenie konzistencie dat v priebehu transakcneho zpracovania. Znamena to, ze kazda transakcia prebieha nad svojim vlastnym snapshotom databaze a preto pripadne delety neznamenaju hned vymazanie tuple, ale jeho oznacenie za nevalidny (a pri naslednom dotazovani dat sa aplikuje visibilty filter nad nevalidnymi datami; napr. Oracle to ma inak – ten starsie data zapise do undo logu). Potom sa spusti upratovacia rutina, ktora vsetky nevalidne tuples zlikviduje – a to je vacuum. Pokial sa vacuum nespusti, tak databaza funguje, dava validne vysledky, ale vyrazne rastie jej velkost kvoli mrtvym datam. A jej aj pomalsia, of course.
co je dead tuple?
Vzhladom k tomu, ze postgres “nemaze” tuples, ale vytvori ich “zmazanu” kopiu a zapise do t_xmax cislo transakcie, ktora to
co v skutocnosti vaccuming robi
4 veci:
- – oznaci dead rows za schopne zapisovat nove data (v skutocnosti ich samozrejme nemaze)
- – updatne visibility map
- – ochranuje pred problemom transaction ID wrapparound tym, ze robi freezing transaction IDs
- – spusta rutinu ANALYZE, ktora skuma zmenovost tabuliek a pripravuje planovac pre VACUUM. Sucast statistickeho kolektoru.
typy vakuovania
Samotny prikaz VACUUM (nei SQL standard) ma niekolko subcomandov (FULL, ANALYZE, VERBOSE…), v zasade sa ale daju rozdelit na 2 podstatne:
- VACUUM – standardna, casto pouzivana rutina, spustana i samotnym postgresom, kde je potreba (AUTOVACUUM). Dolezite je, ze umoznuje DB normalne produkcne fungovat, je to vlastne paralelene cistenie, funguje ako demon a kludne vo viacero procesoch. Uvolni tuples, ktore su nevalidne, ale len ich reusne, nezmensi velkost datovych fajlov
- VACUUM FULL – prebuduje kompletne tabulku, “strepe” velkost tabulkovych fajlov. Pozor!!! Pouziva exkluzivny lock na tabulku a preto sa neda pouzit pri normalnom nasadeni, je to last resort pri nudzovej udrzbe. Nikdy v beziacej produkcii!
Kedy prebehol VACUUM a akeho typu?
SELECT relname, last_vacuum, last_autovacuum, last_autoanalyze FROM pg_stat_user_tables;
autovacuum
Autovacuum je normalne vacuum, ktore ale pravidelne bezi na zaklade potrieb postgresu, je to rutinna operacia. Ma niekolko dolezitych parametrov, ktore ovplyvnuju dlzku, cas spustania, a I/O zataz na storage, ked autovacuum bezi (vasinou pekne tlaci na storage). Je to systemovy demon, ktory stale bezi ako backgroud worker (autovacuum launcher) a periodicky (parameter autovacuum_naptime) spusta jeden, alebo viac procesov (workerov), ktore simultanne prevadzkuju rutinny ANALYZE, alebo VACUUM (ak je treba) nad kazdou databazou a tabulkou. Pocet moznych procesov je obmedzeny parametrom autovacuum_max_workers. V pripade, ze spusti VACUUM (upratanie dead tuples) vzdy po svojom behu pusta aj ANALYZE, aby si osviezil statistiky, pac obsah tabulky sa zmenil (ANALYZE sa da spustat aj samostatne, casto sa spusta ako VACUUM ANALYZE (zvakuavanie a analyza).
je nutne vakuovat? ako su na tom data?
Pro posudzovani zabordelenia databaze se sleduje:
pocet bloatov v tabulkach (dead rows/tuples): SELECT relname, n_dead_tup FROM pg_stat_user_tables;
velkost 10 najvecsich tabuliek v DB na disku:
SELECT relname, pg_size_pretty(pg_table_size(C.oid))
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN (‘pg_catalog’, ‘information_schema’) AND nspname !~ ‘^pg_toast’ AND relkind IN (‘r’)
ORDER BY pg_table_size(C.oid)
DESC LIMIT 10;
bezna diagnostika spojena s vakuovou pumpou
bezi daemon autovacuum? – ps -ef | grep autovacuum
je povoleny autovacuum pre databazu? – SELECT name, setting FROM pg_settings WHERE name=’autovacuum’;
Je povoleny statisticky kolektor? – SELECT name, setting FROM pg_settings WHERE name=’track_counts’;
Pozor! Aj pri povolenom autovacuum v Db je mozne, ze su tam tabulky, ktore maju autovacuum zakazany. Ktore to su? – SELECT relname, reloptions FROM pg_class WHERE reloptions='{autovacuum_enabled=false}’;
Prehlad vsetkych parametrov autovacuumu (defalut i overajd) v systemovom katalogu – SELECT * from pg_settings where category like ‘Autovacuum’;
kedy sa spusta autovacuum?
1. Autovacuum sa spusta, ked pocet dead_rows (bloat tuples) dosiahne cislo X. Cislo X sa pocita formulou (k premennym vid predchadzajuci dotaz k parametrom autovacuumu):
X = autovacuum_vacuum_threshold + (autovacuum_vacuum_scale_factor * estimated number of rows in the table)
Co to znamena? Scale faktor som videl v produkcii nastaveny na 0.1 a 0.2. T.j. pokial je dead rows aspon 50 a je to jedna desatina/jedna patina poctu datovych rows, mal by sa spustit autovacuum.
Pre normalneho DBA stacia dva parametre v postgresql.conf pre ovplyvnenie autovacua:
autovacuum_vacuum_scale_factor = koeficient velkosti zaspinenosti dat (0.1 = 10%)
autovacuum_vacuum_cost_limit = kolko casu a nakladov ma autovacuum worker povolene pouzit (ak -1, tak neobmedzene)
2. Autovacuum sa spusta tiez, ak pocet tuplov insertnutych do tabulky od posledneho vacuua, prekroci threshold X, ktory sa pocita takto:
X = autovacuum_vacuum_insert_threshold + (autovacuum_vacuum_insert_scale_factor * number of tuples)
No dobre, ale preco je nutne zvysene vakuovat pro insertoch? Pri tych, narozdiel od delete/update nedochadza predsa k bloatu. Problem je v inom – vakkuje sa kvoli profylaktickemu predchadzaniu transaction wraparoundu.
niektoré parametre autovacuua
autovacuum_analyze(alebo vacuum)_scale_factor – nejaký zlomok počtu recordov, ktorý rozhodne o prahu spustenia vacua,alebo analyze
autovacuum_vacuum_cost_limit – sa používa na “spomalenie” vacua, nech nevyžere veľa prostriedkov.
VACUUM a locky
VACUUM (resp. autovacuum) principialne nekonflikti s inymi operaciami nad tabulkou, zaklada SHARE UPDATE EXCLUSIVE lock. V pripade, ze dojde ku konfliktu s nejakym procesom, tak je autovacuum prerusene. Toto neplati, ak bezi autovacuum v mode “to prevent wraparound”, kedy ma vacuum prioritu.
freezing
Freezovanie je (okrem upratovania dead tuples) druhou vyznamnou funkciou vakuovania. Freezing sa viaze na transakcie a jeho ucelom je oznacenie hodne starych transakcii specialnym flagom (txid=2 pre postgres<9.4.; XMIN_FROZEN pre postgres=>9.4.) tak, aby sa zamedzilo problemu wraparoundu.
special: pg_repack
Vacuum ma tu nevyhodu, ze nejakym sposobom na chvilu vzdy tabulku odstavi (rozne typy lockov) – v pripade vacuum full zamkne celu tabulku pre ready i writy. V realnom produkcnom prostredi tak napr. full vacuum nie je mozne spustit nikdy…
Existuje extension pg_repack, ktora pracuje tak, ze vytvori kopiu tabulky, zkopiruje do nej data zo starej tabulky (cim tu haldu “strepe” dole) a vytvori nad nou novy index. Potom switchne sessny na novu tabulku. to bez toho, aby tam bol nejaky lock nad tabulkou…
Dobry blog k nasadeniu pg_repack je na strankach percony.
SELECT
relname AS “relation”,
pg_size_pretty (
pg_total_relation_size (C .oid)
) AS “total_size”
FROM
pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C .relnamespace)
WHERE
nspname NOT IN (
‘pg_catalog’,
‘information_schema’
)
AND C .relkind ‘i’
AND nspname !~ ‘^pg_toast’
ORDER BY
pg_total_relation_size (C .oid) DESC
LIMIT 5;
john
24 Aug 20 at 8:09
pg_relation_size() = velkost tabulky
pg_database_size() = velkost databaze
pg_indexes_size() = velkost indexu (do zatvoriek nazov tabulky)
pg_tablespace_size() = velkost tablespacu
dobo
24 Aug 20 at 8:12
Spouštějte pravidelně vacuum analyze (třeba cronem), jelikož se stává, že když není tabulka změnová (data se jen čtou, nebo doplňují), tak autovacuum se nespouští a čistota tabulek trpí.
Čtivo: https://www.2ndquadrant.com/en/blog/postgresql-vacuum-and-analyze-best-practice-tips/
T.
15 Mar 21 at 15:53
https://www.percona.com/blog/2018/08/06/basic-understanding-bloat-vacuum-postgresql-mvcc/
ďobo
16 Aug 22 at 12:08