Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Saamaynta bararka ee miisaska iyo tusmooyinka ayaa si weyn loo yaqaan oo aan ku jirin oo keliya Postgres. Waxaa jira habab lagula tacaali karo oo ka baxsan sanduuqa, sida VACUUM FULL ama KULSTER, laakiin waxay qufulaan miisaska inta lagu jiro hawlgalka, sidaas darteed mar walba lama isticmaali karo.

Maqaalku wuxuu ka koobnaan doonaa aragti yar oo ku saabsan sida bararka u dhaco, sida aad ula dagaalami karto, caqabadaha dib loo dhigay iyo dhibaatooyinka ay u keenaan isticmaalka pg_repack kordhinta.

Maqaalkani waxa uu ku salaysan yahay hadalkayga ee PgConf.Russia 2020.

Waa maxay sababta bararku u dhaco?

Postgres waxay ku salaysan tahay nooc noocya badan leh (MVCC). Nuxurkeedu waa in saf kasta oo miiska ku yaal uu yeelan karo dhowr nooc, halka wax kala beddelashadu aanay arkayn wax ka badan mid ka mid ah noocyadan, laakiin maahan mid isku mid ah. Tani waxay u oggolaanaysaa dhowr macaamil ganacsi inay isla mar shaqeeyaan oo aan wax saameyn ah ku yeelanayn midba midka kale.

Sida cad, dhammaan noocyadaas waxay u baahan yihiin in la kaydiyo. Postgres waxay ku shaqeysaa bogga xusuusta bogga bogguna waa tirada ugu yar ee xogta laga akhrisan karo saxan ama qoraal. Aynu eegno tusaale yar si aan u fahanno sida tani u dhacdo.

Aynu nidhaahno waxaynu haynaa miis aan ku darnay diiwaanno dhawr ah. Xog cusub ayaa ka soo muuqatay bogga koowaad ee faylka halka miiska lagu kaydiyo. Kuwani waa noocyo toos ah oo saf ah oo diyaar u ah macaamilo kale ka dib ballan (fududeynta, waxaan u qaadaneynaa in heerka go'doominta uu yahay Akhris go'an).

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Ka dib waxaan cusbooneysiinay mid ka mid ah gelitaanka, si aan u calaamadeyno nuqulkii hore inuusan hadda khusayn.

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Talaabo talaabo ah, cusboonaysiinta iyo tirtirida noocyada safka ah, waxaanu ku soo afjarnay bog kaas oo ku dhawaad ​​kala badh xogta ay tahay "qashin". Xogtan uma muuqato wax kala iibsi

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Postgres waxay leedahay farsamo VACUUM, Kaas oo nadiifiya noocyo duugoobay oo u sahlaya xog cusub. Laakiin haddii aan loo habeynin si adag oo ku filan ama ay ku mashquulsan tahay inay ka shaqeyso miisaska kale, markaa "xogta qashinka" ayaa hadhay, waana inaan u isticmaalnaa bogag dheeraad ah xogta cusub.

Markaa tusaale ahaan, wakhti wakhti ka mid ah miisku wuxuu ka koobnaan doonaa afar bog, laakiin badh ka mid ah ayaa ku jiri doona xog toos ah. Natiijo ahaan, marka la gelayo miiska, waxaan akhrin doonaa xog aad uga badan inta loo baahan yahay.

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Xitaa haddii VACUUM ay hadda tirtirto dhammaan noocyada safka ah ee aan khusayn, xaaladdu si weyn uma hagaajin doonto. Waxaan haysan doonaa boos banaan oo bogag ah ama xitaa bogag dhan oo safaf cusub ah, laakiin waxaan wali akhrin doonaa xog ka badan intii loo baahnaa.
Jid ahaan, haddii bog gabi ahaanba madhan (kan labaad ee tusaalaheena) uu ku yaalo dhamaadka faylka, markaas VACUUM ayaa awood u yeelan doonta inay jarto. Laakiin hadda iyadaa dhexda ku jirta, sidaa awgeed waxba lagama qaban karo iyada.

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Marka tirada boggaga maran ama aadka u yar ay noqdaan kuwo weyn, oo loo yaqaan 'bloat', waxay bilaabataa inay saameyn ku yeelato waxqabadka.

Wax kasta oo kor lagu sharaxay waa makaanikada dhacdooyinka bararka ee miisaska. Tusmooyinka tani waxay u dhacdaa si la mid ah.

barar ma iga qabaa?

Waxaa jira dhowr siyaabood oo lagu ogaan karo haddii aad leedahay dibiro. Fikradda ugu horreysa waa in la isticmaalo tirakoobyada Postgres gudaha, kaas oo ka kooban macluumaad qiyaas ah oo ku saabsan tirada safafka ee miisaska, tirada "nool" safafka, iwm. Waxaad ka heli kartaa kala duwanaansho badan oo qoraallo diyaar ah oo internetka ah. Waxaan u qaadanay sal qoraal ka khubarada PostgreSQL, kuwaas oo qiimeyn kara miisaska bloat oo ay la socdaan toastada iyo tusmooyinka btree bloat. Waayo-aragnimadayada, khaladkeedu waa 10-20%.

Hab kale ayaa ah in la isticmaalo kordhinta pgstattuple, kaas oo kuu ogolaanaya inaad eegto gudaha boggaga oo aad hesho labadaba qiyaasta iyo qiimaha bararka saxda ah. Laakiin kiiska labaad, waa inaad sawirto miiska oo dhan.

Waxaan tixgelineynaa qiimaha bararka yar, ilaa 20%, la aqbali karo. Waxaa loo tixgalin karaa sidii analooga ah ee buuxinta miisaska и tusmooyinka. 50% iyo wixii ka sareeya, dhibaatooyinka wax qabadku way bilaaban karaan.

Siyaabaha loola dagaallamo bararka

Postgres waxay leedahay siyaabo dhowr ah oo wax looga qabto bararka sanduuqa, laakiin had iyo jeer kuma habboona qof walba.

Habee AUTOVACUUM si aanay dibiro u dhicin. Ama si ka sii saxan, si aad ugu ilaaliso heer aad ku aqbali karto. Tani waxay u egtahay talada "captain's", laakiin dhab ahaantii tani mar walba ma fududa in la gaaro. Tusaale ahaan, waxaad leedahay horumar firfircoon oo is-beddel joogto ah ku leh qorshaha xogta, ama nooc ka mid ah socdaalka xogta ayaa dhacaya. Natiijo ahaan, xogtaada culeyska ayaa laga yaabaa inay si joogto ah isu beddesho oo caadi ahaan way ku kala duwanaan doontaa miis ilaa miiska. Tani waxay ka dhigan tahay inaad u baahan tahay inaad si joogto ah u shaqeyso wax yar ka hor oo aad ku hagaajiso AUTOVACUUM beddelka astaanta miis kasta. Laakiin sida iska cad tani ma fududa in la sameeyo.

Sababta kale ee caadiga ah ee AUTOVACUUM aysan ula socon karin miisaska ayaa ah sababtoo ah waxaa jira macaamil ganacsi oo dheer oo ka hortagaya in ay nadiifiso xogta la heli karo macaamilkaas. Talada halkan sidoo kale waa mid cad - ka takhalus macaamilada "jilicsan" oo yaree waqtiga macaamilada firfircoon. Laakiin haddii culeyska ku jira codsigaaga uu yahay isku-dhafan OLAP iyo OLTP, markaa waxaad isku mar heli kartaa cusbooneysiin badan oo joogto ah iyo weydiimo gaagaaban, iyo sidoo kale hawlgallo waqti dheer ah - tusaale ahaan, dhisidda warbixin. Xaaladdan oo kale, waxaa habboon in laga fekero in lagu faafiyo culeyska saldhigyo kala duwan, taas oo u oggolaan doonta in la hagaajiyo mid kasta oo iyaga ka mid ah.

Tusaale kale - xitaa haddii profile uu yahay mid isku mid ah, laakiin database-ku wuxuu ku hoos jiraa culeys aad u sarreeya, ka dibna xitaa AUTOVACUUM ugu daran ayaa laga yaabaa inaysan la qabsan karin, oo barar ayaa dhici doonta. Isku-beeridda (toos ama jiif) waa xalka kaliya.

Maxaa la sameeyaa haddii aad dejisay AUTOVACUUM, laakiin bararku wuu sii socdaa.

kooxda VACUUM BUUXA waxay dib u dhistaa waxa ku jira miisaska iyo tusmooyinka waxayna ka tagtaa kaliya xogta la xidhiidha iyaga. Si loo baabi'iyo bararka, si fiican ayey u shaqeysaa, laakiin inta lagu guda jiro fulinta waxaa la qabtaa quful miiska saaran (AccessExclusiveLock), kaas oo aan u oggolaan doonin fulinta su'aalaha miiskan, xitaa dooro. Haddii aad awoodid inaad joojiso adeeggaaga ama qayb ka mid ah in muddo ah (laga bilaabo tobanaan daqiiqo ilaa dhowr saacadood iyadoo ku xiran cabbirka xogta iyo qalabkaaga), markaa doorashadani waa tan ugu fiican. Nasiib darro, ma haysanno wakhti aan ku socodsiino VACUUM FULL inta lagu jiro dayactirka jadwalka, markaa habkani naguma habboona.

kooxda XARAABI Waxay dib u dhistaa waxa ku jira miisaska si la mid ah VACUUM FULL, laakiin waxay kuu ogolaaneysaa inaad qeexdo tusaha iyadoo loo eegayo xogta jir ahaan loogu dalban doono diskka (laakiin mustaqbalka amarka lama dammaanad qaadayo safafka cusub). Xaaladaha qaarkood, tani waxay u wanagsan tahay dhowr su'aalood - iyadoo la akhriyo diiwaanno badan oo tusmaysan. Khasaaraha amarku wuxuu la mid yahay kan VACUUM FULL - wuxuu xiraa miiska inta lagu jiro hawlgalka.

kooxda REINDEX oo la mid ah labadii hore, laakiin waxay dib u dhistaa tusmo gaar ah ama dhammaan tusmooyinka miiska. Qufullada wax yar bay ka daciifsan yihiin: ShareLock miiska saaran (waxay ka hortagtaa wax ka beddelka, laakiin waxay oggolaataa xulashada) iyo AccessExclusiveLock ee tusmada oo dib loo dhisayo (waxay xannibaysaa weydiimaha iyadoo la adeegsanayo tusmadan). Si kastaba ha noqotee, nooca 12-aad ee Postgres waxaa soo muuqday halbeeg ISKU JOOGA, kaas oo kuu ogolaanaya inaad dib u dhisto tusaha adoon xannibin isku-darka, wax ka beddelka, ama tirtiridda diiwaannada.

Noocyadii hore ee Postgres, waxaad ku gaari kartaa natiijo la mid ah REINDEX ISKU SOCDAALKA AH U ABUUR INDEX SI ISKU JIR AH. Waxay kuu ogolaanaysaa inaad abuurto tusaha adigoon xidhin adag (ShareUpdateExclusiveLock, taas oo aan faragelinayn weydiimaha barbar socda), ka dibna ku beddel tusaha hore mid cusub oo tirtir tusmihii hore. Tani waxay kuu ogolaaneysaa inaad tirtirto xinjirowga index adoon faragelin codsigaaga. Waxaa muhiim ah in la tixgeliyo in marka dib-u-dhiska tusmooyinka ay jiri doonto culeys dheeraad ah oo ku saabsan nidaamka hoose ee diskka.

Sidaa darteed, haddii tusmooyinka ay jiraan siyaabo lagu baabi'iyo bararka "duqsigooda," ka dibna ma jiraan miisaska. Tani waa halka kordhinta dibadda ee kala duwan ay ka ciyaaraan: pg_repack (hore pg_reorg), pgcompact, pgcompactable iyo kuwo kale. Maqaalkan, ma barbardhigi doono oo kaliya waxaan ka hadli doonaa pg_repack, taas oo, ka dib wax ka beddelka, waxaan isticmaalnaa nafteena.

Sida pg_repack u shaqeyso

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay
Aynu sheegno inaan haysano miis caadi ah oo gebi ahaanba caadi ah - oo leh tusmooyin, xaddidaadyo iyo, nasiib daro, oo leh barar. Talaabada ugu horeysa ee pg_repack waa in la sameeyo miiska log si loo kaydiyo xogta ku saabsan dhammaan isbeddelada inta uu socdo. Kiciyeyaasha ayaa ku celcelin doona isbeddeladan gelinta, cusboonaysiinta iyo tirtirka kasta. Kadibna miis ayaa la sameeyaa, oo la mid ah kan asalka ah ee qaab-dhismeedka, laakiin aan lahayn tusmooyin iyo xaddidaadyo, si aan loo dhimin habka xogta gelinta.

Marka xigta, pg_repack waxay ka wareejisaa xogta miiskii hore una wareejisay miiska cusub, iyadoo si toos ah u shaandhaysa dhammaan safafka aan khusayn, ka dibna waxay abuurtaa tusmooyinka miiska cusub. Inta lagu jiro fulinta dhammaan hawlgalladan, isbeddellada ayaa ku urura miiska log.

Talaabada xigta waa in isbedelada lagu wareejiyo miiska cusub. Socdaalku waxa lagu qabtaa dhawr jeer oo soo noqnoqosho ah, iyo marka ay wax ka yar 20 gelis ku haraan miiska log, pg_repack waxay helaysaa quful xoog leh, waxay guurtaa xogtii ugu dambaysay, waxayna ku beddeshaa miiskii hore mid cusub oo ku jira miisaska nidaamka Postgres. Tani waa wakhtiga kaliya ee aad u yar marka aadan awoodin inaad la shaqeyso miiska. Taas ka dib, miiskii hore iyo miiskii diiwaanka leh waa la tirtiray oo meel bannaan ayaa lagu sii daayay nidaamka faylka. Hawshu waa dhammaatay.

Wax walba waxay u muuqdaan kuwo aad u fiican aragti ahaan, laakiin maxaa dhacaya ficil ahaan? Waxaan tijaabinay pg_repack iyadoon rar la'aanteed iyo culeys saarnay, waxaanan hubinnay hawlgalkeeda haddii ay dhacdo joogsi degdeg ah (si kale loo dhigo, annaga oo adeegsanayna Ctrl+C). Dhammaan baaritaanada waxay ahaayeen kuwo togan.

Waxaan tagnay dukaanka cuntada - ka dibna wax walba uma dhicin sidii aan filaynay.

Canjeerada ugu horeysa ee iibka ah

Kooxdii kowaad waxa aanu ka helnay khalad ku saabsan ku xad gudubka xaddidaad gaar ah:

$ ./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.

Xaddidaaddan waxay lahayd magac si toos ah loo soo saaray index_16508 - waxaa sameeyay pg_repack. Iyada oo ku saleysan sifooyinka lagu soo daray halabuurka, waxaan go'aaminnay xaddidaadda "anaga" ee u dhigma. Dhibaatadu waxay noqotay in tani aysan ahayn xaddidaad caadi ah, laakiin mid dib loo dhigay (xannibaad dib loo dhigay), i.e. Xaqiijintiisa ayaa la sameeyaa ka dib amarka sql, taas oo keenta cawaaqib lama filaan ah.

Caqabadaha dib loo dhigay: sababta loogu baahan yahay iyo sida ay u shaqeeyaan

Aragti yar oo ku saabsan xayiraadaha dib loo dhigay.
Aynu tixgelinno tusaale fudud: waxaanu haynaa buug-tixraac baabuur oo leh laba sifo - magaca iyo nidaamka baabuurka ee tusaha.
Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

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



Aynu nidhaahno waxaan u baahanahay inaan beddelno baabuurta koowaad iyo labaad. Xalka tooska ah waa in la cusboonaysiiyo qiimaha koowaad kan labaad, kan labaadna kan koowaad:

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

Laakiin marka aan maamulno koodhkan, waxaan fileynaa xadgudub xaddidan sababtoo ah nidaamka qiyamka miiska waa mid gaar ah:

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

Sideen si ka duwan u samayn karaa? Doorashada koowaad: ku dar beddelka qiimaha dheeraadka ah ee amarka la dammaanad qaaday inaanu ka jirin shaxda, tusaale ahaan “-1”. Barnaamijyada, tan waxa loo yaqaan "isweydaarsiga qiyamka laba doorsoome illaa saddex meelood meel." Ciladda kaliya ee habkan waa cusbooneysiinta dheeraadka ah.

Ikhtiyaarka labaad: Dib u habee miiska si aad u isticmaasho nooca xogta dhibicda sabaynaysa qiimaha dalabka halkii aad ka isticmaali lahayd iskudarka. Kadib, marka la cusbooneysiiyo qiimaha laga bilaabo 1, tusaale ahaan, ilaa 2.5, gelitaanka koowaad wuxuu si toos ah u " istaagi doonaa" inta u dhaxaysa labaad iyo saddexaad. Xalkani wuu shaqeeyaa, laakiin waxaa jira laba xaddidaad. Marka hore, kuma shaqeyn doonto adiga haddii qiimaha loo isticmaalo meel ka mid ah interface-ka. Marka labaad, iyada oo ku xidhan saxnaanta nooca xogta, waxaad yeelan doontaa tiro xaddidan oo suurtogal ah oo la geli karo ka hor inta aanad dib u xisaabin qiyamka dhammaan diiwaannada.

Xulashada saddexaad: ka dhig xaddidaadda dib u dhigista si loo hubiyo kaliya wakhtiga ballan-qaadka:

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

Maaddaama caqli-galnimada codsigeena hore ay hubiso in dhammaan qiyamku ay yihiin kuwo gaar ah waqtiga ballan-qaadka, way guulaysan doontaa.

Tusaalaha kor lagu soo hadal qaaday, dabcan, aad buu u samaysan yahay, laakiin wuxuu muujinayaa fikradda. Codsigeena, waxaan u isticmaalnaa xannibaado dib loo dhigay si aan u hirgelino macquulka mas'uulka ka ah xallinta khilaafaadka marka isticmaalayaashu isku mar la shaqeeyaan walxaha widget-ka la wadaago ee guddiga. Isticmaalka xayiraadaha noocan oo kale ah waxay noo ogolaaneysaa inaan ka dhigno koodhka codsiga wax yar oo fudud.

Guud ahaan, iyada oo ku xidhan nooca xannibaadda, Postgres waxay leedahay saddex heer oo granularity si loo hubiyo iyaga: saf, macaamil ganacsi, iyo heerarka muujinta.
Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay
Source: caloolxumo

Hubinta iyo MA NULL ayaa had iyo jeer lagu eegaa heerka safka; xayiraadaha kale, sida laga arki karo miiska, waxaa jira doorashooyin kala duwan. Wax badan ayaad akhrin kartaa halkan.

Si kooban loo soo koobo, caqabadaha dib loo dhigay ee dhawr xaaladood ayaa bixiya kood la akhriyi karo iyo amarro yar. Si kastaba ha noqotee, waa inaad tan ku bixisaa adigoo adkeynaya habka qaladka, tan iyo markii uu khaladku dhaco iyo wakhtiga aad ogaanayso waxa la kala saarayaa waqtiga. Dhibaato kale oo suurtagal ah ayaa ah in jadwal-hayehu aanu mar walba awoodi karin inuu dhiso qorshe ugu fiican haddii codsigu ku lug yeesho xannibaad dib loo dhigay.

Horumarinta pg_repack

Waxaan daboolnay waxa ay yihiin xannibaadaha dib loo dhigay, laakiin sidee ayay ula xidhiidhaan dhibkayaga? Aynu xasuusanno khaladkii hore ee ina soo gaadhay:

$ ./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.

Waxay dhacdaa marka xogta laga soo guuriyo miiska loox oo la geeyo miis cusub. Tani waxay u muuqataa mid la yaab leh sababtoo ah... xogta ku jirta miiska log waxaa lagu go'aamiyay xogta ku jirta miiska isha. Haddii ay ku qancaan caqabadaha miiska asalka ah, sidee bay u jabin karaan xannibaado isku mid ah kan cusub?

Markay soo baxdo, asalka dhibaatadu waxay ku jirtaa tillaabadii hore ee pg_repack, taas oo abuurta tusmooyinka kaliya, laakiin aan xaddidnayn: miiskii hore wuxuu lahaa caqabad gaar ah, kan cusubna wuxuu abuuray index gaar ah.

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Waxaa muhiim ah in halkan lagu ogaado in haddii xannibaadda ay tahay mid caadi ah oo aan dib loo dhigin, ka dibna tusaha gaarka ah ee la sameeyay halkii uu u dhigmo xayiraaddan, sababtoo ah Caqabadaha gaarka ah ee Postgres waxaa lagu fuliyaa iyadoo la abuurayo tusmo gaar ah. Laakin xaalada xayiraadda dib loo dhigay, habdhaqanku isku mid maaha, sababtoo ah tusmada dib looma dhigi karo oo had iyo jeer waa la hubiyaa wakhtiga amarka sql la fulinayo.

Sidaa darteed, nuxurka dhibaatadu waxay ku jirtaa "dib u dhigista" jeegga: shaxda asalka ah waxay ku dhacdaa wakhtiga ballan-qaadka, iyo miiska cusub ee wakhtiga sql amarka la fuliyay. Tani waxay ka dhigan tahay inaan u baahanahay inaan hubinno in hubinta la sameeyay isla labada xaaladood: had iyo jeer dib u dhac, ama had iyo jeer isla markiiba.

Haddaba fikradahee ayaan haysanay?

Samee tusmo la mid ah dib loo dhigay

Fikradda ugu horreysa waa in la sameeyo labada jeeg ee hab degdeg ah. Tani waxay dhalin kartaa dhowr xayiraad oo been abuur ah, laakiin haddii ay jiraan wax yar oo iyaga ka mid ah, tani waa inaysan saameyn ku yeelan shaqada isticmaalayaasha, maadaama isku dhacyada noocan oo kale ah ay yihiin xaalad caadi ah iyaga. Waxay dhacaan, tusaale ahaan, marka laba isticmaale ay bilaabaan tafatirka hal widget isku mid ah isku mar, oo macmiilka isticmaalaha labaad uusan haysan waqti uu ku helo macluumaadka in widget-ka uu horeyba u xannibay tafatirka isticmaaleha koowaad. Xaaladdan oo kale, server-ku wuu diidaa isticmaalaha labaad, macmiilkiisuna wuxuu dib u rogaa isbeddelada oo wuxuu xannibaa widget-ka. Wax yar ka dib, marka isticmaalaha ugu horreeya uu dhameeyo tafatirka, ka labaad wuxuu heli doonaa macluumaadka in widget-ka aan la xannibin oo uu awoodi doono inuu ku celiyo ficilkooda.

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Si loo hubiyo in jeegaggu ay had iyo jeer ku jiraan qaab aan dib loo dhigin, waxaanu abuurnay tusmo cusub oo la mid ah xannibaaddii dib loo dhigay:

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

Deegaanka imtixaanka, waxaan helnay kaliya dhowr khaladaad oo la filayo. Guul! Waxaan mar labaad ku orodnay pg_repack wax soo saarka waxaana ku helnay 5 khalad kooxihii ugu horeeyay saacad shaqo gudaheed. Tani waa natiijo la aqbali karo. Si kastaba ha ahaatee, mar hore kooxda labaad tirada khaladaadku si aad ah ayey u korodhay waxaana ku qasbanaaday inaan joojino pg_repack.

Maxay ku dhacday? Suurtagalnimada in qalad dhaco waxay kuxirantahay inta isticmaale ee ku shaqeeya aaladaha isku mar isku mar ah. Sida muuqata, wakhtigaas waxaa jiray isbeddelo tartan oo aad u yar oo xogta lagu kaydiyay kooxda koowaad marka loo eego kuwa kale, i.e. Waxaan ahayn kaliya "nasiib".

Fikirkii ma shaqayn. Halkaa marka ay marayso, waxaanu aragnay laba xal oo kale: dib u qor koodka arjigayaga si aan u bixino caqabadaha dib loo dhigay, ama "bar" pg_repack si aad ula shaqeyso. Midda labaad ayaan doorannay.

Ku beddel tusmooyinka shaxda cusub oo leh xaddidaadyo dib loo dhigay oo miiska asalka ah

Ujeedada dib u eegistu waxay ahayd mid cad - haddii miiska asalka ah uu leeyahay xannibaad dib loo dhigay, ka dibna kan cusub waxaad u baahan tahay inaad abuurto xannibaad noocaas ah, oo aanad ahayn index.

Si loo tijaabiyo isbeddelladayada, waxaanu qornay imtixaan fudud:

  • miiska oo leh xannibaad dib loo dhigay iyo hal rikoodh;
  • geli xogta loop ka soo horjeeda diiwaan jira;
  • samee cusbooneysiin - xogtu hadda ma khilaafsana;
  • samee isbedelada.

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;

Nooca asalka ah ee pg_repack had iyo jeer wuu ku burburay gelintii ugu horreysay, nooca la beddelay wuxuu shaqeeyay khaladaad la'aan. Wayn

Waxaan tagnaa wax soo saarka oo mar labaad hel qalad isla wejigii isku midka ah ee nuqul ka samaynta xogta miiska log ilaa mid cusub:

$ ./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.

Xaaladda caadiga ah: wax walba waxay ka shaqeeyaan jawi tijaabo ah, laakiin maaha wax soo saarka ?!

APPLY_COUNT iyo isku xirka labada qaybood

Waxaan bilownay inaan si toos ah u falanqeyno koodka iyadoo sadar ah, waxaana ogaanay qodob muhiim ah: xogta waxaa laga soo wareejiyaa miiska log ilaa mid cusub oo dufcooyin ah, APPLY_COUNT joogto ah ayaa tilmaamaya xajmiga dufcada:

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

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

Dhibaatadu waxay tahay in xogta laga helay macaamilkii asalka ahaa, kaas oo dhowr hawlgal oo suurtagal ah ay ku xadgudbi karaan xannibaadda, marka la wareejiyo, waxay ku dhammaan karaan isgoyska laba qaybood - kala badh amarrada ayaa la samayn doonaa qaybta hore, iyo qaybta kale tan labaad. Oo halkan, iyada oo ku xidhan nasiibkaaga: haddii kooxuhu aanay ku xadgudbin wax kasta oo ku jira dufcaddii ugu horeysay, markaa wax walba waa fiican yihiin, laakiin haddii ay sameeyaan, qalad ayaa dhacaya.

APPLY_COUNT waxay la mid tahay 1000 diiwaan, taasoo sharxaysa sababta imtixaanadayadu u najaxeen - kama ay soo bixin kiiska "isku xidhka dufcaddii". Waxaan isticmaalnay laba amar - gelis iyo cusbooneysiin, markaa sida saxda ah 500 xawaalad oo laba amar ah ayaa had iyo jeer lagu dhejiyay dufcad mana aanan la kulmin wax dhibaato ah. Ka dib markii aan ku daray cusbooneysiinta labaad, wax ka beddelkayagii ayaa joojiyay shaqadii:

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;

Markaa, hawsha xigta waa in la hubiyo in xogta laga helay miiska asalka ah, oo lagu beddelay hal macaamil ganacsi, ay ku dhammaato shaxda cusub sidoo kale hal macaamil gudaheed.

Diidmada duubista

Oo haddana waxaan helnay laba xal. Marka hore: aynu gabi ahaanba iska dhaafno qaybinta dufcadaha oo aynu xogta ku wareejino hal macaamil ganacsi. Faa'iidada xalkani waxay ahayd fududaantiisa - isbeddelada koodhka loo baahan yahay way yaraayeen (sida, qoraaladii hore ee pg_reorg si sax ah ayuu u shaqeeyay). Laakiin waxaa jira dhibaato - waxaan abuureynaa macaamil ganacsi oo dheer, tanina, sida hore loo sheegay, waxay khatar ku tahay soo bixitaanka bararka cusub.

Xalka labaad waa mid aad u adag, laakiin malaha waa saxsan yahay: ku samee tiir miiska log oo leh aqoonsiga macaamilka ee xogta ku daray miiska. Dabadeed, marka aan koobiyayno xogta, waxaan ku kooxeyn karnaa sifadan oo aan hubinno in isbeddellada la xiriira si wadajir ah loo wareejiyo. Dufcaddii ayaa laga samayn doonaa dhowr xawaalad (ama mid weyn) cabbirkeeduna wuu kala duwanaan doonaa iyadoo ku xidhan inta xog ee la beddelay wax kala iibsigan. Waxaa muhiim ah in la ogaado in mar haddii xogta laga helay macaamil ganacsiyo kala duwan ay u gasho miiska log in si aan kala sooc lahayn, mar dambe ma dhici doonto in si isku xigta loo akhriyo, sidii hore. seqscan codsi kasta oo leh shaandhaynta tx_id aad ayuu qaali u yahay, tusmaynta ayaa loo baahan yahay, laakiin sidoo kale waxay hoos u dhigi doontaa habka sababtoo ah dusha sare ee cusboonaysiinta. Guud ahaan, sida had iyo jeer, waxaad u baahan tahay inaad wax u hurto.

Markaa, waxaan go'aansanay inaan ku bilowno ikhtiyaarka koowaad, maadaama ay fududahay. Marka hore, waxay ahayd lagama maarmaan in la fahmo in macaamil ganacsi dheer uu noqon doono dhibaato dhab ah. Maaddaama wareejinta ugu weyn ee xogta miiska hore ee cusub ay sidoo kale ku dhacdo hal macaamil ganacsi dheer, su'aashu waxay isu beddeshay "intee in le'eg ayaan kordhin doonnaa macaamilkan?" Muddada macaamilka ugu horreeya waxay ku xiran tahay inta badan miisaanka miiska. Muddada mid cusubi waxay ku xidhan tahay inta isbeddel ee ku urura miiska inta lagu jiro wareejinta xogta, i.e. culeyska culeyska. Orodka pg_repack waxa uu dhacay wakhtiga adeega ugu yar, iyo mugga isbedeladu waxa uu ahaa mid yar marka loo eego cabbirka asalka ah ee miiska. Waxaan go'aansanay inaan dayaci karno wakhtiga macaamil ganacsi cusub (marka la barbardhigo, celcelis ahaan waa 1 saac iyo 2-3 daqiiqo).

Tijaabooyinku waxay ahaayeen kuwo togan. Sidoo kale bilow wax soo saarka Si loo caddeeyo, halkan waa sawir leh cabbirka mid ka mid ah xog-ururinta ka dib:

Postgres: barar, pg_repack iyo caqabadaha dib loo dhigay

Maaddaama aan si buuxda ugu qanacsanahay xalkan, iskuma aannu dayin inaan hirgelinno kan labaad, laakiin waxaan ka fiirsaneynaa suurtagalnimada inaan kala hadalno horumarinta kordhinta. Dib u eegisteena hadda, nasiib daro, wali diyaar uma aha daabacaadda, maadaama aan kaliya ku xalinay dhibaatada xaddidaadyo dib-u-dhigis oo gaar ah, iyo balastar dhammaystiran waa lagama maarmaan in la bixiyo taageero noocyo kale ah. Waxaan rajeyneynaa inaan awoodno inaan tan sameyno mustaqbalka.

Waxaa laga yaabaa inaad hayso su'aal, maxaan xitaa uga qayb qaadanay sheekadan iyada oo wax ka beddelka pg_repack, oo aynaan, tusaale ahaan, isticmaalin analoosheeda? Mararka qaarkood waxaan sidoo kale ka fekernay arrintan, laakiin waayo-aragnimada wanaagsan ee isticmaalka hore, miisaska iyada oo aan lahayn caqabado dib-u-dhac ah, ayaa nagu kallifay inaan isku dayno inaan fahamno nuxurka dhibaatada oo aan hagaajinno. Intaa waxaa dheer, isticmaalka xalalka kale waxay sidoo kale u baahan tahay waqti si loo sameeyo baaritaanno, sidaas darteed waxaan go'aansanay inaan marka hore isku dayno inaan xallino dhibaatada ku jirta, iyo haddii aan ogaanno inaanan tan ku sameyn karin waqti macquul ah, ka dibna waxaan bilaabi doonaa inaan eegno analogues. .

natiijooyinka

Waxa aan kugula talin karno iyadoo ku saleysan khibradeena:

  1. La soco bararkaaga Iyada oo ku saleysan xogta la socodka, waxaad fahmi kartaa sida ugu wanaagsan ee autovacuum loo habeeyey.
  2. Hagaajin AUTOVACUUM si aad u ilaaliso bararka heer la aqbali karo.
  3. Haddii bararka uu weli sii korayo oo aadan ka adkaan karin adigoo isticmaalaya qalab ka baxsan sanduuqa, ha ka baqin inaad isticmaasho kordhinta dibadda. Waxa ugu muhiimsan waa in wax walba si fiican loo tijaabiyo.
  4. Ha ka baqin inaad wax ka beddesho xalalka dibadda si ay ugu habboonaato baahiyahaaga - mararka qaarkood tani waxay noqon kartaa mid waxtar badan oo xitaa ka sahlan bedelida koodkaaga.

Source: www.habr.com

Add a comment