Postgres: bloat, pg_repack ary teritery nahemotra

Postgres: bloat, pg_repack ary teritery nahemotra

Ny fiantraikan'ny bloat amin'ny latabatra sy ny index dia fantatra be ary tsy ao amin'ny Postgres ihany. Misy fomba hiatrehana izany ivelan'ny boaty, toy ny VACUUM FULL na CLUSTER, saingy manidy latabatra mandritra ny fandidiana izy ireo ka tsy azo ampiasaina foana.

Ny lahatsoratra dia ahitana teôlôjia kely momba ny firongatry ny bloat, ny fomba ahafahanao miady amin'izany, momba ny faneriterena nahemotra ary ny olana entin'izy ireo amin'ny fampiasana ny fanitarana pg_repack.

Ity lahatsoratra ity dia nosoratana mifototra amin'ny ny teniko ao amin'ny PgConf.Russia 2020.

Nahoana no mitranga ny bloat?

Ny Postgres dia mifototra amin'ny modely misy dikan-teny maro (MVCC). Ny tena maha izy azy dia ny andalana tsirairay ao amin'ny latabatra dia afaka manana dikan-teny maromaro, fa ny fifanakalozana dia tsy mahita mihoatra ny iray amin'ireo dikan-teny ireo, fa tsy voatery mitovy. Izany dia ahafahan'ny fifampiraharahana maromaro miasa miaraka ary saika tsy misy fiantraikany amin'ny tsirairay.

Mazava ho azy fa mila tehirizina ireo dikan-teny rehetra ireo. Ny Postgres dia miasa miaraka amin'ny pejy fitadidiana isaky ny pejy ary ny pejy iray dia ny habetsaky ny angona kely indrindra azo vakiana avy amin'ny kapila na soratana. Andeha isika hijery ohatra kely iray mba hahatakarana ny fomba nitrangan'izany.

Andeha atao hoe manana latabatra izay nampiana firaketana maromaro. Nipoitra ny angona vaovao eo amin'ny pejy voalohany amin'ny rakitra misy ny latabatra. Ireo dia dikan-teny mivantana amin'ny andalana azo alaina amin'ny fifampiraharahana hafa aorian'ny fanoloran-tena (ho an'ny fahatsorana dia hoheverinay fa ny haavon'ny fitokanana dia Read Committed).

Postgres: bloat, pg_repack ary teritery nahemotra

Nohavaozinay avy eo ny iray amin'ireo fidirana, ka nanamarika ny dikan-teny taloha ho tsy manan-danja intsony.

Postgres: bloat, pg_repack ary teritery nahemotra

Amin'ny dingana manaraka, fanavaozana sy famafana ny dikan-teny andalana, dia niafara tamin'ny pejy iray misy ny antsasaky ny angon-drakitra dia "fako". Ity angona ity dia tsy hita amin'ny fifanakalozana rehetra.

Postgres: bloat, pg_repack ary teritery nahemotra

Postgres dia manana mekanika vacuum, izay manadio ny dikan-teny efa lany andro ary manome toerana ho an'ny angona vaovao. Saingy raha toa ka tsy voarindra tsara izy io na sahirana miasa amin'ny latabatra hafa, dia mijanona ny "data fako", ary tsy maintsy mampiasa pejy fanampiny isika ho an'ny angona vaovao.

Ka amin'ny ohatra ataontsika, amin'ny fotoana iray dia hisy pejy efatra ny latabatra, fa ny antsasany ihany no ahitana angona mivantana. Vokatr'izany, rehefa miditra amin'ny latabatra isika dia hamaky angon-drakitra bebe kokoa noho ny ilaina.

Postgres: bloat, pg_repack ary teritery nahemotra

Na dia esorin'ny VACUUM izao ny dikan-teny tsy misy ifandraisany amin'ny andalana rehetra dia tsy hihatsara be ny toe-draharaha. Hanana toerana malalaka amin'ny pejy na pejy iray manontolo mihitsy aza izahay ho an'ny andalana vaovao, saingy mbola hamaky angona bebe kokoa noho izay ilaina.
Raha ny marina, raha misy pejy tsy misy na inona na inona (ilay faharoa amin'ny ohatra asehontsika) eo amin'ny faran'ny rakitra, dia afaka manapaka azy ny VACUUM. Eo afovoany anefa izy izao, ka tsy misy azo atao aminy.

Postgres: bloat, pg_repack ary teritery nahemotra

Rehefa mihabetsaka ny isan'ireo pejy tsy misy na inona na inona, izay antsoina hoe bloat, dia manomboka misy fiantraikany amin'ny fampisehoana izany.

Ny zava-drehetra voalaza etsy ambony dia ny mekanika amin'ny fisehoan'ny bloat amin'ny latabatra. Amin'ny indexes dia mitranga amin'ny fomba mitovy.

Misy bloat ve aho?

Misy fomba maromaro hamaritana raha manana bloat ianao. Ny hevitry ny voalohany dia ny fampiasana ny antontan'isa Postgres anatiny, izay misy fampahalalana momba ny isan'ny andalana amin'ny tabilao, ny isan'ny andalana "mivantana", sns. Afaka mahita karazany maro amin'ny script efa vonona ianao amin'ny Internet. Noraisinay ho fototra teny avy amin'ny PostgreSQL Experts, izay afaka manombantombana ny latabatra mibontsina miaraka amin'ny toast sy bloat btree indexes. Raha ny traikefanay dia 10-20% ny fahadisoany.

Ny fomba iray hafa dia ny fampiasana ny fanitarana pgstattuple, izay ahafahanao mijery ny ao anatin'ny pejy ary mahazo sanda mitongilana tombanana sy marina. Fa amin'ny tranga faharoa, dia tsy maintsy scan ny latabatra manontolo.

Heverintsika ny sandan'ny bloat kely, hatramin'ny 20%, azo ekena. Azo heverina ho toy ny analogue ny fillfactor for latabatra и fanondroana. Amin'ny 50% sy ambony, mety hanomboka ny olana momba ny fampisehoana.

Fomba hiadiana amin'ny bloat

Ny Postgres dia manana fomba maro hiatrehana ny bloat ivelan'ny boaty, saingy tsy mety amin'ny rehetra izy ireo.

Ampifanaraho ny AUTOVACUUM mba tsy hisian'ny fivontosana. Na ny marimarina kokoa, mba hitazonana azy amin'ny ambaratonga mety aminao. Toa toro-hevitra "kapiteny" izany, saingy raha ny marina dia tsy mora foana izany. Ohatra, manana fivoarana mavitrika ianao miaraka amin'ny fanovana tsy tapaka amin'ny schema data, na misy karazana fifindra-monina data. Vokatr'izany dia mety hiova matetika ny mombamomba ny entanao ary miovaova isaky ny latabatra. Midika izany fa mila miasa kely aloha ianao ary manitsy ny AUTOVACUUM amin'ny mombamomba ny tabilao tsirairay. Saingy mazava ho azy fa tsy mora ny manao izany.

Antony iray hafa iraisan'ny AUTOVACUUM tsy maharaka latabatra dia satria misy ny fifampiraharahana maharitra izay manakana azy tsy hanadio ny angon-drakitra azon'ireo fifampiraharahana ireo. Miharihary ihany koa ny tolo-kevitra eto - esory ny fifampiraharahana "mihantona" ary manamaivana ny fotoanan'ny fifanakalozana mavitrika. Fa raha ny enta-mavesatra amin'ny fampiharana anao dia hybrid an'ny OLAP sy OLTP, dia afaka manana fanavaozam-baovao matetika sy fanontaniana fohy ianao, ary koa asa maharitra - ohatra, manangana tatitra. Amin'ny toe-javatra toy izany dia ilaina ny mieritreritra ny hanaparitahana ny enta-mavesatra amin'ny toby samihafa, izay ahafahana manatsara kokoa ny tsirairay amin'izy ireo.

Ohatra iray hafa - na dia homogeneous aza ny mombamomba azy, fa ny angon-drakitra dia eo ambanin'ny enta-mavesatra be dia be, na dia ny AUTOVACUUM mahery vaika indrindra aza dia mety tsy hiatrika, ary hitranga ny fivontosana. Ny scaling (mitsangana na mitsivalana) ihany no vahaolana.

Inona no tokony hatao amin'ny toe-javatra izay nanangana AUTOVACUUM, fa ny bloat dia mitombo hatrany.

ekipa FENO FENO manangana indray ny votoatin'ny tabilao sy ny fanondro ary tsy mamela afa-tsy angona mifandraika aminy. Mba hanafoanana ny bloat dia miasa tsara izy io, fa mandritra ny fanatanterahana azy dia misy hidin-trano tokana eo amin'ny latabatra (AccessExclusiveLock), izay tsy mamela ny fametrahana fanontaniana amin'ity latabatra ity, na dia mifidy aza. Raha azonao atao ny mampiato ny serivisy na ny ampahany amin'izany mandritra ny fotoana fohy (hatramin'ny folo minitra ka hatramin'ny ora maromaro miankina amin'ny haben'ny tahiry sy ny fitaovanao), dia ity safidy ity no tsara indrindra. Indrisy anefa fa tsy manam-potoana hamitana ny VACUUM FULL isika mandritra ny fikojakojana voalahatra, ka tsy mety amintsika io fomba io.

ekipa sampahom-boaloboka Manangana indray ny votoatin'ny latabatra amin'ny fomba mitovy amin'ny VACUUM FULL, fa mamela anao hamaritra index araka izay hanafatra ara-batana amin'ny kapila ny angon-drakitra (fa amin'ny ho avy dia tsy azo antoka ny baiko ho an'ny laharana vaovao). Amin'ny toe-javatra sasany, ity dia fanatsarana tsara ho an'ny fanontaniana maromaro - miaraka amin'ny famakiana rakitsoratra marobe amin'ny fanondroana. Ny tsy fahampian'ny baiko dia mitovy amin'ny an'ny VACUUM FULL - manidy ny latabatra mandritra ny fandidiana.

ekipa REINDEX mitovy amin'ny roa teo aloha, fa manangana fanondro manokana na tondro rehetra amin'ny latabatra. Ny hidin-trano dia somary malemy kokoa: ShareLock eo amin'ny latabatra (manakana ny fanovana, fa mamela ny safidy) ary ny AccessExclusiveLock amin'ny fanondro izay amboarina (manakana ny fanontaniana amin'ny fampiasana an'io fanondroana io). Na izany aza, tamin'ny andiany faha-12 an'ny Postgres dia nisy paramètre niseho amin'ny fotoana mitovy, izay ahafahanao manangana indray ny index nefa tsy manakana ny fanampiana, ny fanovana, na ny famafana ny rakitra miaraka.

Amin'ny dikan-teny teo aloha amin'ny Postgres, azonao atao ny mahazo vokatra mitovy amin'ny REINDEX CONCURRENTLY mampiasa MAMORONA INDEX MIARAKA. Mamela anao hamorona index tsy misy fanidiana henjana (ShareUpdateExclusiveLock, izay tsy manelingelina ny fanontaniana mifanandrify), avy eo soloy vaovao ny tondro taloha ary vonoy ny tondro taloha. Izany dia ahafahanao manafoana index bloat tsy manelingelina ny fampiharana anao. Zava-dehibe ny mandinika fa rehefa manangana indexes dia hisy entana fanampiny amin'ny subsystem kapila.

Noho izany, raha misy fomba hanesorana ny bloat "amin'ny lalitra" ho an'ny indeksa, dia tsy misy ny latabatra. Eto no misy ny fanitarana ivelany isan-karazany: pg_repack (pg_reorg taloha), pgcompact, pgcompacttable sy ny hafa. Amin'ity lahatsoratra ity dia tsy hampitaha azy ireo aho ary hiresaka momba ny pg_repack ihany, izay, aorian'ny fanovana sasany, dia mampiasa ny tenantsika isika.

Ahoana ny fiasan'ny pg_repack

Postgres: bloat, pg_repack ary teritery nahemotra
Andeha hatao hoe manana latabatra tsotra isika - misy index, fameperana ary, indrisy, miaraka amin'ny bloat. Ny dingana voalohany amin'ny pg_repack dia ny mamorona latabatra fitehirizana angona momba ny fanovana rehetra eo am-pandehanana. Ny trigger dia hamerina ireo fanovana ireo isaky ny mampiditra, manavao ary mamafa. Avy eo dia misy latabatra iray noforonina, mitovy amin'ny tany am-boalohany amin'ny rafitra, saingy tsy misy indexes sy fameperana, mba tsy hampiadana ny dingan'ny fampidirana data.

Manaraka, ny pg_repack dia mamindra ny angona avy amin'ny latabatra taloha mankany amin'ny latabatra vaovao, manivana ho azy ireo andalana tsy misy dikany rehetra, ary avy eo dia mamorona tondro ho an'ny latabatra vaovao. Mandritra ny fanatanterahana ireo asa rehetra ireo dia miangona ao amin'ny latabatra firaketana ny fiovana.

Ny dingana manaraka dia ny famindrana ny fanovana amin'ny latabatra vaovao. Ny fifindra-monina dia atao amin'ny famerimberenana maromaro, ary rehefa latsaky ny 20 ny fidirana ao amin'ny tabilao dia mahazo hidin-trano mafy ny pg_repack, mamindra ny angona farany indrindra, ary manolo ny latabatra taloha amin'ny vaovao ao amin'ny tabilao rafitra Postgres. Ity no fotoana tokana sy tena fohy izay tsy ahafahanao miasa miaraka amin'ny latabatra. Aorian'izany dia voafafa ny latabatra taloha sy ny latabatra misy logs ary malalaka ny habaka ao amin'ny rafi-drakitra. Vita ny dingana.

Toa tsara ny zava-drehetra amin'ny teoria, fa inona no mitranga amin'ny fampiharana? Nanandrana ny pg_repack tsy misy enta-mavesatra sy ambany entana izahay, ary nanamarina ny fiasan'izy io raha sendra mijanona aloha loatra (amin'ny teny hafa, mampiasa Ctrl+C). Ny fitiliana rehetra dia tsara avokoa.

Nankany amin'ny fivarotana sakafo izahay - ary avy eo dia tsy nandeha araka ny nantenainay ny zava-drehetra.

Pancake voalohany amidy

Tamin'ny cluster voalohany dia nahazo lesoka momba ny fanitsakitsahana teritery tokana izahay:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

Ity famerana ity dia manana anarana namboarina ho azy index_16508 - noforonin'ny pg_repack. Mifototra amin'ireo toetra voarakitra ao anatin'izany, nofaritanay ny teritery "nay" mifanitsy amin'izany. Ny olana dia nipoitra fa tsy fetra tsotra fotsiny izany, fa nahemotra (faneriterena nahemotra), i.e. ny fanamarinana azy dia atao taty aoriana noho ny baiko sql, izay mitarika ho amin'ny vokany tsy ampoizina.

Faneriterena nahemotra: nahoana no ilaina sy ny fomba fiasan'izy ireo

Teoria kely momba ny fameperana nahemotra.
Andeha hodinihintsika ny ohatra tsotra: manana bokim-pijerena latabatra misy fiara misy toetra roa isika - ny anarana sy ny filaharan'ny fiara ao amin'ny lahatahiry.
Postgres: bloat, pg_repack ary teritery nahemotra

create table cars
(
  name text constraint pk_cars primary key,
  ord integer not null constraint uk_cars unique
);



Andeha hatao hoe mila nanakalo ny fiara voalohany sy faharoa. Ny vahaolana tsotra dia ny fanavaozana ny sanda voalohany amin'ny faharoa, ary ny faharoa amin'ny voalohany:

begin;
  update cars set ord = 2 where name = 'audi';
  update cars set ord = 1 where name = 'bmw';
commit;

Saingy rehefa mihazakazaka io fehezan-dalàna io isika dia manantena fanitsakitsahana teritery satria tokana ny filaharan'ny soatoavina eo amin'ny latabatra:

[23305] ERROR: duplicate key value violates unique constraint “uk_cars”
Detail: Key (ord)=(2) already exists.

Ahoana no ahafahako manao izany amin'ny fomba hafa? Safidy voalohany: ampio fanoloana sanda fanampiny amin'ny baiko azo antoka fa tsy hisy eo amin'ny latabatra, ohatra "-1". Amin'ny fandaharana dia antsoina hoe "fanakalozana ny sandan'ny variables roa amin'ny ampahatelony." Ny hany tsy fahampian'ity fomba ity dia ny fanavaozana fanampiny.

Safidy roa: Avereno amboary ny latabatra hampiasa karazana angona mitsingevana ho an'ny sandan'ny kaomandy fa tsy integer. Avy eo, rehefa manavao ny sanda avy amin'ny 1, ohatra, mankany amin'ny 2.5, ny fidirana voalohany dia "hijoro" ho azy eo anelanelan'ny faharoa sy fahatelo. Ity vahaolana ity dia miasa, saingy misy fetra roa. Voalohany, tsy mety aminao izany raha ampiasaina any amin'ny toerana misy ny interface ny sanda. Faharoa, miankina amin'ny fahamarinan'ny karazana data, dia hanana isa voafetra azo atao ianao alohan'ny hamerenanao ny sandan'ny rakitra rehetra.

Safidy fahatelo: ataovy nahemotra ny faneriterena mba hanamarinana azy amin'ny fotoanan'ny fanoloran-tena ihany:

create table cars
(
  name text constraint pk_cars primary key,
  ord integer not null constraint uk_cars unique deferrable initially deferred
);

Satria ny lojikan'ny fangatahanay voalohany dia miantoka fa ny soatoavina rehetra dia miavaka amin'ny fotoanan'ny fanoloran-tena, dia hahomby izany.

Ny ohatra resahina etsy ambony dia mazava ho azy fa tena sentetika, saingy manambara ny hevitra. Ao amin'ny fampiharanay, mampiasa teritery nahemotra izahay mba hampiharana ny lojika izay tompon'andraikitra amin'ny famahana ny disadisa rehefa miara-miasa amin'ny zavatra widget zaraina eo amin'ny solaitrabe ny mpampiasa. Ny fampiasana fameperana toy izany dia ahafahantsika manamora ny kaody fampiharana.

Amin'ny ankapobeny, miankina amin'ny karazana faneriterena, ny Postgres dia manana ambaratonga telo amin'ny fanamarinana azy ireo: ny laharana, ny fifampiraharahana ary ny haavon'ny fanehoana.
Postgres: bloat, pg_repack ary teritery nahemotra
Source: begriffs

CHECK sy NOT NULL dia voamarina hatrany amin'ny ambaratonga laharana; ho an'ny fameperana hafa, araka ny hita amin'ny tabilao, dia misy safidy samihafa. Afaka mamaky bebe kokoa ianao eto.

Raha fintinina fohifohy, ny faneriterena nahemotra amin'ny toe-javatra maromaro dia manome kaody mora vakiana kokoa sy baiko vitsy kokoa. Na izany aza, tsy maintsy mandoa izany ianao amin'ny alàlan'ny fanasarotra ny fizotran'ny debugging, satria ny fotoana nitrangan'ny hadisoana sy ny fotoana hahafantaranao azy dia misaraka ara-potoana. Olana iray hafa mety hitranga dia ny hoe tsy afaka manangana drafitra tsara indrindra foana ny mpandrindra raha toa ka misy faneriterena nahemotra ny fangatahana.

Fanatsarana ny pg_repack

Noresahintsika hoe inona ny teritery nahemotra, fa ahoana no ifandraisan'izy ireo amin'ny olana misy antsika? Ndeha hotadidintsika ny hadisoana azontsika teo aloha:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

Mitranga izany rehefa adika avy amin'ny tabilao diary mankany amin'ny latabatra vaovao. Toa hafahafa izany satria... ny angona ao amin'ny tabilao dia natao miaraka amin'ny angona ao amin'ny latabatra loharano. Raha mahafeno ny fetran'ny latabatra tany am-boalohany izy ireo, ahoana no ahafahan'izy ireo manitsakitsaka ireo teritery mitovy amin'ny tabilao vaovao?

Araka ny hita, ny fototry ny olana dia eo amin'ny dingana teo aloha amin'ny pg_repack, izay tsy mamorona afa-tsy index, fa tsy teritery: ny latabatra taloha dia nanana teritery tokana, ary ny vaovao dia namorona index tokana.

Postgres: bloat, pg_repack ary teritery nahemotra

Zava-dehibe ny manamarika eto fa raha ara-dalàna ny faneriterena ary tsy nahemotra, dia ny fanondro tokana noforonina fa tsy mitovy amin'io teritery io, satria Ny faneriterena tokana ao amin'ny Postgres dia ampiharina amin'ny famoronana tondro tokana. Fa raha misy faneriterena nahemotra dia tsy mitovy ny fitondran-tena, satria tsy azo ahemotra ny index ary voamarina foana amin'ny fotoana hanatanterahana ny baiko sql.

Noho izany, ny fototry ny olana dia mitoetra ao amin'ny "fahatarana" ny fanamarinana: ao amin'ny latabatra tany am-boalohany dia mitranga amin'ny fotoana fanolorana, ary ao amin'ny latabatra vaovao amin'ny fotoana hanatanterahana ny baiko sql. Midika izany fa mila manao izay hahazoana antoka fa mitovy ny fisavana amin'ireo tranga roa ireo: na tara foana, na avy hatrany.

Inona àry no hevitra nananantsika?

Mamorona tondro mitovy amin'ny nahemotra

Ny hevitra voalohany dia ny manao fisavana roa amin'ny fomba avy hatrany. Mety hiteraka fameperana diso maro izany, fa raha vitsy amin'izy ireo dia tsy tokony hisy fiantraikany amin'ny asan'ny mpampiasa izany, satria toe-javatra mahazatra ho azy ireo ny fifandirana toy izany. Mitranga izy ireo, ohatra, rehefa manomboka manova ny widget mitovy amin'ny fotoana mitovy ny mpampiasa roa, ary ny mpanjifan'ny mpampiasa faharoa dia tsy manam-potoana handraisana vaovao fa efa voasakana ny widget ho an'ny mpampiasa voalohany. Amin'ny toe-javatra toy izany, mandà ny mpampiasa faharoa ny mpizara, ary ny mpanjifany dia mamerina ny fanovana ary manakana ny widget. Fotoana fohy taty aoriana, rehefa nahavita ny fanitsiana ny mpampiasa voalohany, ny faharoa dia hahazo vaovao fa tsy voasakana intsony ny widget ary afaka mamerina ny asany.

Postgres: bloat, pg_repack ary teritery nahemotra

Mba hahazoana antoka fa amin'ny fomba tsy nahemotra foana ny fisavana, dia namorona tondro vaovao mitovy amin'ilay teritery nahemotra tany am-boalohany izahay:

CREATE UNIQUE INDEX CONCURRENTLY uk_tablename__immediate ON tablename (id, index);
-- run pg_repack
DROP INDEX CONCURRENTLY uk_tablename__immediate;

Ao amin'ny tontolon'ny fitsapana, tsy nahazo afa-tsy fahadisoana andrasana vitsivitsy izahay. Fahombiazana! Nandeha pg_repack indray izahay tamin'ny famokarana ary nahazo lesoka 5 tamin'ny cluster voalohany tao anatin'ny adiny iray niasa. Vokatra azo ekena izany. Na izany aza, efa teo amin'ny cluster faharoa dia nitombo be ny isan'ny fahadisoana ary tsy maintsy nijanona ny pg_repack.

Nahoana no nitranga izany? Ny mety hisian'ny hadisoana dia miankina amin'ny isan'ny mpampiasa miasa miaraka amin'ny widgets mitovy amin'ny fotoana mitovy. Raha ny fahitana azy, tamin'io fotoana io dia nisy fiovana kely kokoa tamin'ny fifaninanana tamin'ny angon-drakitra voatahiry ao amin'ny cluster voalohany raha oharina amin'ny hafa, i.e. "tsara vintana" fotsiny izahay.

Tsy nety ilay hevitra. Tamin'izay fotoana izay dia nahita vahaolana roa hafa izahay: avereno soratana ny kaody fampiharana anay mba hialana amin'ny faneriterena nahemotra, na "mampianatra" pg_repack hiara-miasa amin'izy ireo. Nifidy ny faharoa izahay.

Soloy ny fanondro amin'ny tabilao vaovao miaraka amin'ny faneriterena nahemotra avy amin'ny latabatra voalohany

Ny tanjon'ny fanavaozana dia niharihary - raha misy faneriterena nahemotra ny latabatra tany am-boalohany, dia ho an'ny vaovao dia mila mamorona faneriterena toy izany ianao, fa tsy index.

Mba hitsapana ny fiovanay dia nanoratra fitsapana tsotra izahay:

  • latabatra misy faneriterena nahemotra sy firaketana iray;
  • ampidiro ao anaty tadivavarana mifanipaka amin'ny rakitra efa misy;
  • manaova fanavaozana - tsy mifanipaka intsony ny angon-drakitra;
  • manao ny fanovana.

create table test_table
(
  id serial,
  val int,
  constraint uk_test_table__val unique (val) deferrable initially deferred 
);

INSERT INTO test_table (val) VALUES (0);
FOR i IN 1..10000 LOOP
  BEGIN
    INSERT INTO test_table VALUES (0) RETURNING id INTO v_id;
    UPDATE test_table set val = i where id = v_id;
    COMMIT;
  END;
END LOOP;

Ny dikan-teny voalohany amin'ny pg_repack dia nianjera foana tamin'ny fampidirana voalohany, ny dikan-teny novaina dia niasa tsy nisy hadisoana. Mahafinaritra.

Mandeha any amin'ny famokarana izahay ary mahazo lesoka indray amin'ny dingana mitovy amin'ny kopia ny angona avy amin'ny tabilao log mankany amin'ny iray vaovao:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

Toe-javatra mahazatra: miasa amin'ny tontolo fitsapana ny zava-drehetra, fa tsy amin'ny famokarana?!

APPLY_COUNT sy ny fihaonan'ny andiany roa

Nanomboka nanadihady ara-bakiteny andalana isaky ny andalana ny kaody izahay ary nahita teboka iray manan-danja: nafindra avy amin'ny latabatra firaketana mankany amina andiany vaovao ny angon-drakitra, ny APPLY_COUNT tsy miova dia manondro ny haben'ny andiany:

for (;;)
{
num = apply_log(connection, table, APPLY_COUNT);

if (num > MIN_TUPLES_BEFORE_SWITCH)
     continue;  /* there might be still some tuples, repeat. */
...
}

Ny olana dia ny angon-drakitra avy amin'ny fifampiraharahana tany am-boalohany, izay mety hanitsakitsaka ny teritery, rehefa nafindra, dia mety hiafara amin'ny fihaonan'ny andiany roa - ny antsasaky ny baiko dia hatao amin'ny andiany voalohany, ary ny antsasany hafa. amin'ny faharoa. Ary eto, miankina amin'ny vintanao: raha tsy manitsakitsaka na inona na inona ny ekipa amin'ny andiany voalohany, dia tsara ny zava-drehetra, fa raha manao izany izy ireo dia misy hadisoana.

APPLY_COUNT dia mitovy amin'ny firaketana 1000, izay manazava ny antony nahombiazan'ny andranay - tsy nandrakotra ny trangan'ny “fifandonan'ny batch” izy ireo. Nampiasa baiko roa izahay - ampidiro sy havaozina, noho izany dia 500 karama amin'ny baiko roa no napetraka ao anaty batch ary tsy nisy olana izahay. Taorian'ny nampiana ny fanavaozana faharoa dia nijanona tsy niasa ny fanitsianay:

FOR i IN 1..10000 LOOP
  BEGIN
    INSERT INTO test_table VALUES (1) RETURNING id INTO v_id;
    UPDATE test_table set val = i where id = v_id;
    UPDATE test_table set val = i where id = v_id; -- one more update
    COMMIT;
  END;
END LOOP;

Noho izany, ny asa manaraka dia ny hahazoana antoka fa ny angon-drakitra avy amin'ny latabatra tany am-boalohany, izay niova tamin'ny fifanakalozana iray, dia miafara amin'ny latabatra vaovao ihany koa ao anatin'ny fifampiraharahana iray.

Fandavana ny batching

Ary nanana vahaolana roa indray izahay. Voalohany: andao hiala tanteraka ny fizarazarana ho andiany ary hamindra angona amin'ny fifanakalozana iray. Ny tombony amin'ity vahaolana ity dia ny fahatsorany - ny fanovana kaody ilaina dia kely indrindra (amin'ny fomba, amin'ny dikan-teny taloha pg_reorg dia niasa toy izany). Saingy misy ny olana - mamorona fifampiraharahana maharitra isika, ary izany, araka ny voalaza teo aloha, dia loza mitatao amin'ny firongatry ny bloat vaovao.

Ny vahaolana faharoa dia sarotra kokoa, saingy mety ho marina kokoa: mamorona tsanganana ao amin'ny tabilao misy ny famantarana ny fifampiraharahana izay nanampy angona tamin'ny latabatra. Avy eo, rehefa mandika ny angona isika dia afaka manambatra azy amin'ity toetra ity ary miantoka fa ny fanovana mifandraika dia afindra miaraka. Ny andiany dia hiforona avy amin'ny fifampiraharahana maromaro (na iray lehibe) ary ny habeny dia hiova arakaraka ny habetsaky ny angon-drakitra niova tamin'ireo fifanakalozana ireo. Zava-dehibe ny manamarika fa satria ny angon-drakitra avy amin'ny fifampiraharahana samihafa dia miditra amin'ny latabatra filaharana amin'ny filaharana kisendrasendra, dia tsy ho azo atao intsony ny mamaky azy io araka ny teo aloha. seqscan ho an'ny fangatahana tsirairay miaraka amin'ny sivana amin'ny tx_id dia lafo loatra, ilaina ny fanondroana, fa hampiadana ihany koa ny fomba noho ny fandaniam-bola amin'ny fanavaozana azy. Amin'ny ankapobeny, toy ny mahazatra, mila manao sorona zavatra ianao.

Noho izany, nanapa-kevitra ny hanomboka amin'ny safidy voalohany izahay, satria tsotra kokoa. Voalohany, nilaina ny nahatakatra raha tena olana tokoa ny fifampiraharahana maharitra. Koa satria ny famindrana angon-drakitra lehibe avy amin'ny latabatra taloha mankany amin'ny vaovao dia mitranga amin'ny fifampiraharahana lava, ny fanontaniana dia niova ho "hohatrinona no hampitomboinay ity varotra ity?" Ny faharetan'ny fifampiraharahana voalohany dia miankina indrindra amin'ny haben'ny latabatra. Ny faharetan'ny iray vaovao dia miankina amin'ny isan'ny fiovana miangona eo amin'ny latabatra mandritra ny famindrana angona, i.e. amin'ny hamafin'ny enta-mavesatra. Ny fihazakazahana pg_repack dia nitranga nandritra ny fotoanan'ny enta-mavesatry ny serivisy, ary ny habetsahan'ny fiovana dia kely tsy mitovy raha oharina amin'ny haben'ny latabatra. Nanapa-kevitra izahay fa afaka manao tsirambina ny fotoanan'ny fifampiraharahana vaovao (ho fampitahana, amin'ny antsalany dia adiny 1 sy 2-3 minitra).

Tsara ny fanandramana. Manomboka amin'ny famokarana ihany koa. Mba hanazavana, ity misy sary miaraka amin'ny haben'ny iray amin'ireo angona aorian'ny fandehanana:

Postgres: bloat, pg_repack ary teritery nahemotra

Koa satria afa-po tanteraka tamin'ity vahaolana ity izahay dia tsy nanandrana nampihatra ny faharoa, fa mandinika ny mety hisian'ny fifampiresahana amin'ireo mpamorona fanitarana. Indrisy fa tsy mbola vonona amin'ny famoahana ny fanavaozanay ankehitriny, satria ny olana amin'ny fameperana tsy manam-paharoa ihany no voavahanay, ary ho an'ny patch feno dia ilaina ny manome fanohanana ho an'ny karazana hafa. Manantena izahay fa ho afaka hanao izany amin'ny ho avy.

Angamba manana fanontaniana ianao, nahoana isika no nirotsaka tamin'ity tantara ity tamin'ny fanovana ny pg_repack, ary tsy nampiasa ny analogues, ohatra? Tamin'ny fotoana iray ihany koa dia nieritreritra an'izany izahay, fa ny traikefa tsara amin'ny fampiasana azy io teo aloha, teo amin'ny latabatra tsy misy faneriterena, dia nanosika anay hanandrana hahatakatra ny fototry ny olana sy hamaha izany. Ankoatr'izay, ny fampiasana vahaolana hafa dia mitaky fotoana hanaovana fitsapana, noho izany dia nanapa-kevitra izahay fa hiezaka hamaha ny olana ao anatiny aloha, ary raha tsapanay fa tsy afaka manao izany amin'ny fotoana mety izahay, dia hanomboka hijery ny analogues. .

hitany

Inona no azonay atolotra araka ny traikefanay manokana:

  1. Araho ny bloat anao. Miorina amin'ny angon-drakitra fanaraha-maso, azonao atao ny mahatakatra ny fomba tsara amboarina ny autovacuum.
  2. Ahitsio AUTOVACUUM mba hitazonana ny fivontosana amin'ny ambaratonga azo ekena.
  3. Raha mbola mitombo ny fivontosana ary tsy azonao atao ny mandresy azy amin'ny fampiasana fitaovana ivelan'ny boaty, aza matahotra ny mampiasa fanitarana ivelany. Ny tena zava-dehibe dia ny fitsapana tsara ny zava-drehetra.
  4. Aza matahotra ny manova vahaolana ivelany hifanaraka amin'ny filanao - indraindray mety hahomby kokoa izany ary mora kokoa noho ny manova ny kaody anao manokana.

Source: www.habr.com

Add a comment