Postgres: bloat, pg_repack in odložene omejitve

Postgres: bloat, pg_repack in odložene omejitve

Učinek napihnjenosti tabel in indeksov je splošno znan in ni prisoten le v Postgresu. Obstajajo načini za takojšnje reševanje tega problema, na primer VACUUM FULL ali CLUSTER, vendar zaklenejo tabele med delovanjem in jih zato ni mogoče vedno uporabiti.

Članek bo vseboval malo teorije o tem, kako nastane napihnjenost, kako se lahko z njo borite, o odloženih omejitvah in težavah, ki jih prinašajo pri uporabi razširitve pg_repack.

Ta članek je napisan na podlagi moj govor na PgConf.Russia 2020.

Zakaj nastane napihnjenost?

Postgres temelji na modelu več različic (MVCC). Njegovo bistvo je, da ima lahko vsaka vrstica v tabeli več različic, medtem ko transakcije ne vidijo več kot eno od teh različic, vendar ne nujno iste. To omogoča, da več transakcij deluje hkrati in praktično nimajo vpliva ena na drugo.

Očitno je treba vse te različice shraniti. Postgres deluje s pomnilnikom stran za stranjo in stran je najmanjša količina podatkov, ki jih je mogoče prebrati z diska ali zapisati. Oglejmo si majhen primer, da bomo razumeli, kako se to zgodi.

Recimo, da imamo tabelo, v katero smo dodali več zapisov. Novi podatki so se pojavili na prvi strani datoteke, kjer je shranjena tabela. To so žive različice vrstic, ki so po potrditvi na voljo drugim transakcijam (zaradi poenostavitve bomo predpostavili, da je raven izolacije Read Committed).

Postgres: bloat, pg_repack in odložene omejitve

Nato smo posodobili enega od vnosov in s tem staro različico označili kot neustrezno.

Postgres: bloat, pg_repack in odložene omejitve

Korak za korakom, posodabljanje in brisanje različic vrstic, smo prišli do strani, na kateri je približno polovica podatkov »smeti«. Ti podatki niso vidni nobeni transakciji.

Postgres: bloat, pg_repack in odložene omejitve

Postgres ima mehanizem VAKUUM, ki počisti zastarele različice in naredi prostor za nove podatke. Če pa ni dovolj agresivno konfiguriran ali je zaposlen z delom v drugih tabelah, potem ostanejo »smeti«, za nove podatke pa moramo uporabiti dodatne strani.

Torej bo v našem primeru v nekem trenutku tabela sestavljena iz štirih strani, vendar bo le polovica vsebovala podatke v živo. Posledično bomo pri dostopu do tabele prebrali veliko več podatkov, kot je potrebno.

Postgres: bloat, pg_repack in odložene omejitve

Tudi če VACUUM zdaj izbriše vse nepomembne različice vrstic, se situacija ne bo bistveno izboljšala. Na straneh ali celo na celih straneh bomo imeli prosti prostor za nove vrstice, vendar bomo še vedno prebrali več podatkov, kot je potrebno.
Mimogrede, če bi bila popolnoma prazna stran (druga v našem primeru) na koncu datoteke, bi jo VACUUM lahko obrezal. Zdaj pa je v sredini, tako da se z njo ne da narediti nič.

Postgres: bloat, pg_repack in odložene omejitve

Ko število takšnih praznih ali zelo redkih strani postane veliko, kar imenujemo napihnjenost, začne to vplivati ​​na zmogljivost.

Vse zgoraj opisano je mehanika pojava napihnjenosti miz. V indeksih se to zgodi približno na enak način.

Ali imam napihnjenost?

Obstaja več načinov, kako ugotoviti, ali imate napihnjenost. Ideja prvega je uporaba interne statistike Postgres, ki vsebuje približne informacije o številu vrstic v tabelah, številu "živih" vrstic itd. V internetu lahko najdete številne različice že pripravljenih skriptov. Za osnovo smo vzeli skripta od strokovnjakov za PostgreSQL, ki lahko ocenijo povečane tabele skupaj z indeksi toast in bloat btree. Po naših izkušnjah je njegova napaka 10-20%.

Drug način je uporaba razširitve pgstattuple, ki vam omogoča, da pogledate v notranjost strani in dobite ocenjeno in natančno vrednost napihnjenosti. Toda v drugem primeru boste morali pregledati celotno tabelo.

Štejemo majhno vrednost napihnjenosti, do 20 %, kot sprejemljivo. Lahko se obravnava kot analog faktorja polnjenja za mize и indeksов. Pri 50% in več se lahko začnejo težave z zmogljivostjo.

Načini za boj proti napihnjenosti

Postgres ponuja več načinov za boj proti napihnjenosti, ki pa niso vedno primerni za vsakogar.

Konfigurirajte AUTOVACUUM, da ne pride do napihnjenosti. Oziroma natančneje, da ostane na za vas sprejemljivi ravni. To se zdi kot "kapitanov" nasvet, a v resnici tega ni vedno lahko doseči. Na primer, imate aktiven razvoj z rednimi spremembami podatkovne sheme ali poteka nekakšna migracija podatkov. Posledično se lahko vaš profil obremenitve pogosto spreminja in se običajno razlikuje od mize do mize. To pomeni, da morate nenehno delati nekoliko naprej in prilagajati AVTOVAKUUM spreminjajočemu se profilu vsake mize. A očitno tega ni enostavno narediti.

Drug pogost razlog, zakaj AUTOVACUUM ne more slediti tabelam, je, da obstajajo dolgotrajne transakcije, ki mu preprečujejo čiščenje podatkov, ki so na voljo tem transakcijam. Tudi tukaj je priporočilo očitno - znebite se "visečih" transakcij in zmanjšajte čas aktivnih transakcij. Če pa je obremenitev vaše aplikacije hibrid OLAP in OLTP, potem imate lahko hkrati veliko pogostih posodobitev in kratkih poizvedb ter dolgoročne operacije – na primer sestavljanje poročila. V takšni situaciji je vredno razmišljati o porazdelitvi obremenitve na različne podlage, kar bo omogočilo bolj natančno nastavitev vsake od njih.

Še en primer - tudi če je profil homogen, vendar je baza podatkov zelo obremenjena, potem tudi najbolj agresiven AUTOVACUUM morda ne bo kos in bo prišlo do napihnjenosti. Skaliranje (navpično ali vodoravno) je edina rešitev.

Kaj storiti v primeru, da ste nastavili AVTOVAKUUM, a napihnjenost še naprej narašča.

Ekipa VAKUUM POLN obnovi vsebino tabel in indeksov ter v njih pusti samo ustrezne podatke. Za odpravo napihnjenosti deluje odlično, vendar se med njegovim izvajanjem zajame ekskluzivno zaklepanje tabele (AccessExclusiveLock), ki ne bo dovolilo izvajanja poizvedb na tej tabeli, celo selektira. Če si lahko privoščite zaustavitev storitve ali njenega dela za nekaj časa (od deset minut do nekaj ur, odvisno od velikosti baze podatkov in vaše strojne opreme), potem je ta možnost najboljša. Žal med načrtovanim vzdrževanjem nimamo časa zagnati VACUUM FULL, zato ta metoda za nas ni primerna.

Ekipa GROZD Ponovno zgradi vsebino tabel na enak način kot VACUUM FULL, vendar vam omogoča, da določite indeks, po katerem bodo podatki fizično urejeni na disku (vendar v prihodnosti vrstni red ni zagotovljen za nove vrstice). V določenih situacijah je to dobra optimizacija za številne poizvedbe – z branjem več zapisov po indeksu. Slabost ukaza je enaka kot pri VACUUM FULL - zaklene mizo med delovanjem.

Ekipa REINDEX podoben prejšnjima dvema, vendar znova zgradi določen indeks ali vse indekse tabele. Zaklepanja so nekoliko šibkejša: ShareLock na tabeli (preprečuje spremembe, vendar dovoljuje izbiro) in AccessExclusiveLock na indeksu, ki se ponovno gradi (blokira poizvedbe, ki uporabljajo ta indeks). Vendar se je v 12. različici Postgresa pojavil parameter SOČASNO, ki vam omogoča ponovno sestavo indeksa brez blokiranja sočasnega dodajanja, spreminjanja ali brisanja zapisov.

V prejšnjih različicah Postgresa lahko dosežete rezultat, podoben REINDEX COCURRENTLY, z uporabo SOČASNO USTVARJANJE INDEKSA. Omogoča vam, da ustvarite indeks brez strogega zaklepanja (ShareUpdateExclusiveLock, ki ne moti vzporednih poizvedb), nato zamenjate stari indeks z novim in izbrišete stari indeks. To vam omogoča, da odpravite napihnjenost indeksa, ne da bi motili vašo aplikacijo. Pomembno je upoštevati, da bo pri ponovni izdelavi indeksov diskovni podsistem dodatno obremenjen.

Torej, če za indekse obstajajo načini za odpravo napihnjenosti "na letenje", potem jih za tabele ni. Tu pridejo v poštev različne zunanje razširitve: pg_repack (prej pg_reorg), pgcompact, pgcompacttable in drugi. V tem članku jih ne bom primerjal in bom govoril samo o pg_repacku, ki ga po nekaj predelavah uporabljamo tudi sami.

Kako deluje pg_repack

Postgres: bloat, pg_repack in odložene omejitve
Recimo, da imamo povsem navadno tabelo – z indeksi, omejitvami in na žalost z napihnjenostjo. Prvi korak pg_repack je ustvariti tabelo dnevnika za shranjevanje podatkov o vseh spremembah med izvajanjem. Sprožilec bo ponovil te spremembe za vsako vstavljanje, posodobitev in brisanje. Nato se ustvari tabela, po strukturi podobna prvotni, vendar brez indeksov in omejitev, da ne upočasnimo procesa vstavljanja podatkov.

Nato pg_repack prenese podatke iz stare tabele v novo tabelo, samodejno filtrira vse nepomembne vrstice in nato ustvari indekse za novo tabelo. Med izvajanjem vseh teh operacij se spremembe kopičijo v dnevniški tabeli.

Naslednji korak je prenos sprememb v novo tabelo. Selitev se izvaja v več iteracijah in ko je v dnevniški tabeli ostalo manj kot 20 vnosov, pg_repack pridobi močno zaklepanje, preseli najnovejše podatke in zamenja staro tabelo z novo v sistemskih tabelah Postgres. To je edini in zelo kratek čas, ko ne boste mogli delati z mizo. Po tem se stara tabela in tabela z dnevniki izbrišeta, v datotečnem sistemu pa se sprosti prostor. Postopek je končan.

V teoriji je vse videti super, kaj pa se zgodi v praksi? Preizkusili smo pg_repack brez obremenitve in pod obremenitvijo ter preverili njeno delovanje v primeru prezgodnje zaustavitve (z drugimi besedami, z uporabo Ctrl+C). Vsi testi so bili pozitivni.

Šli smo v trgovino s hrano - potem pa ni šlo vse, kot smo pričakovali.

Prva palačinka v prodaji

Na prvi gruči smo prejeli napako o kršitvi unikatne omejitve:

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

Ta omejitev je imela samodejno ustvarjeno ime index_16508 - ustvaril jo je pg_repack. Na podlagi atributov, ki so vključeni v njegovo sestavo, smo določili »našo« omejitev, ki ji ustreza. Težava se je izkazala v tem, da ne gre za povsem navadno omejitev, ampak za odloženo (odložena omejitev), tj. njegovo preverjanje se izvede pozneje kot ukaz sql, kar vodi do nepričakovanih posledic.

Odložene omejitve: zakaj so potrebne in kako delujejo

Malo teorije o odloženih omejitvah.
Razmislimo o preprostem primeru: imamo tabelo-referenčno knjigo avtomobilov z dvema atributoma - imenom in vrstnim redom avtomobila v imeniku.
Postgres: bloat, pg_repack in odložene omejitve

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



Recimo, da smo morali zamenjati prvi in ​​drugi avto. Preprosta rešitev je posodobiti prvo vrednost na drugo in drugo na prvo:

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

Toda ko zaženemo to kodo, pričakujemo kršitev omejitve, ker je vrstni red vrednosti v tabeli edinstven:

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

Kako lahko naredim drugače? Možnost ena: naročilu dodajte dodatno zamenjavo vrednosti, ki zajamčeno ne obstaja v tabeli, na primer »-1«. V programiranju se to imenuje "izmenjava vrednosti dveh spremenljivk s tretjo." Edina pomanjkljivost te metode je dodatna posodobitev.

Druga možnost: Preoblikujte tabelo tako, da bo za vrednost naročila namesto celih števil uporabljala podatkovni tip s plavajočo vejico. Potem, ko posodobite vrednost z 1, na primer na 2.5, bo prvi vnos samodejno "stal" med drugim in tretjim. Ta rešitev deluje, vendar obstajata dve omejitvi. Prvič, za vas ne bo delovalo, če je vrednost uporabljena nekje v vmesniku. Drugič, glede na natančnost vrste podatkov boste imeli omejeno število možnih vstavkov, preden ponovno izračunate vrednosti vseh zapisov.

Tretja možnost: naredite omejitev odloženo, tako da je preverjena samo v času potrditve:

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

Ker logika naše začetne zahteve zagotavlja, da so vse vrednosti edinstvene v času potrditve, bo uspela.

Zgoraj obravnavani primer je seveda zelo sintetičen, vendar razkriva idejo. V naši aplikaciji uporabljamo odložene omejitve za implementacijo logike, ki je odgovorna za reševanje konfliktov, ko uporabniki hkrati delajo s predmeti pripomočkov v skupni rabi na plošči. Uporaba takšnih omejitev nam omogoča, da nekoliko poenostavimo kodo aplikacije.

Na splošno ima Postgres glede na vrsto omejitve tri stopnje razdrobljenosti za njihovo preverjanje: ravni vrstice, transakcije in izraza.
Postgres: bloat, pg_repack in odložene omejitve
Vir: begriffs

CHECK in NOT NULL sta vedno označena na nivoju vrstice, za ostale omejitve, kot je razvidno iz tabele, obstajajo različne možnosti. Lahko preberete več tukaj.

Če na kratko povzamemo, odložene omejitve v številnih situacijah zagotavljajo bolj berljivo kodo in manj ukazov. Vendar pa morate za to plačati s kompliciranjem postopka odpravljanja napak, saj sta trenutek, ko se napaka pojavi, in trenutek, ko zanjo izveste, časovno ločena. Druga možna težava je, da razporejevalnik morda ne bo mogel vedno sestaviti optimalnega načrta, če zahteva vključuje odloženo omejitev.

Izboljšava pg_repack

Pokrili smo, kaj so odložene omejitve, toda kako so povezane z našo težavo? Spomnimo se napake, ki smo jo prej prejeli:

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

Pojavi se, ko se podatki kopirajo iz dnevne tabele v novo tabelo. To izgleda čudno, ker... podatki v tabeli dnevnika so odobreni skupaj s podatki v izvorni tabeli. Če izpolnjujejo omejitve prvotne tabele, kako lahko kršijo iste omejitve v novi?

Kot se je izkazalo, je koren težave v prejšnjem koraku pg_repack, ki ustvari samo indekse, ne pa tudi omejitev: stara tabela je imela edinstveno omejitev, nova pa je namesto tega ustvarila edinstven indeks.

Postgres: bloat, pg_repack in odložene omejitve

Tukaj je pomembno opozoriti, da če je omejitev običajna in ni odložena, potem je namesto tega ustvarjen enolični indeks enakovreden tej omejitvi, ker Edinstvene omejitve v Postgresu so implementirane z ustvarjanjem edinstvenega indeksa. Toda v primeru odložene omejitve vedenje ni enako, ker indeksa ni mogoče odložiti in je vedno preverjen v času, ko se izvede ukaz sql.

Tako je bistvo problema v »zakasnitvi« preverjanja: v originalni tabeli se to zgodi v času objave, v novi tabeli pa v času izvajanja ukaza sql. To pomeni, da moramo zagotoviti, da se preverjanja izvajajo enako v obeh primerih: vedno z zakasnitvijo ali vedno takoj.

Kakšne ideje smo torej imeli?

Ustvarite indeks, podoben odloženemu

Prva ideja je, da oba preverjanja izvedete v takojšnjem načinu. To lahko ustvari več lažno pozitivnih omejitev, vendar če jih je malo, to ne bi smelo vplivati ​​na delo uporabnikov, saj so takšni konflikti zanje običajna situacija. Pojavijo se na primer, ko dva uporabnika hkrati začneta urejati isti gradnik, odjemalec drugega uporabnika pa nima časa prejeti informacije, da je gradnik že blokiran za urejanje s strani prvega uporabnika. V takšni situaciji strežnik zavrne drugega uporabnika, njegov odjemalec pa povrne spremembe in blokira gradnik. Malo kasneje, ko prvi uporabnik zaključi urejanje, bo drugi prejel informacijo, da pripomoček ni več blokiran in bo lahko ponovil svoje dejanje.

Postgres: bloat, pg_repack in odložene omejitve

Da zagotovimo, da so preverjanja vedno v neodloženem načinu, smo ustvarili nov indeks, podoben prvotni odloženi omejitvi:

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

V testnem okolju smo prejeli le nekaj pričakovanih napak. uspeh! Ponovno smo zagnali pg_repack v proizvodnji in v eni uri dela dobili 5 napak na prvi gruči. To je sprejemljiv rezultat. Vendar se je že na drugi gruči število napak močno povečalo in smo morali ustaviti pg_repack.

Zakaj se je to zgodilo? Verjetnost, da pride do napake, je odvisna od tega, koliko uporabnikov dela z istimi gradniki hkrati. Očitno je bilo v tistem trenutku pri podatkih, shranjenih na prvem grozdu, veliko manj konkurenčnih sprememb kot na ostalih, tj. imeli smo pač "srečo".

Ideja ni uspela. Na tej točki smo videli dve drugi rešitvi: prepisati kodo naše aplikacije, da se odrečemo odloženim omejitvam, ali "naučiti" pg_repack delati z njimi. Izbrali smo drugega.

Zamenjajte indekse v novi tabeli z odloženimi omejitvami iz izvirne tabele

Namen revizije je bil očiten - če ima izvirna tabela odloženo omejitev, potem morate za novo ustvariti takšno omejitev in ne indeksa.

Za preizkus naših sprememb smo napisali preprost test:

  • tabela z odloženo omejitvijo in enim zapisom;
  • vstavite podatke v zanko, ki so v nasprotju z obstoječim zapisom;
  • naredite posodobitev – podatki niso več v nasprotju;
  • potrdite spremembe.

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;

Prvotna različica pg_repack se je vedno zrušila ob prvem vstavljanju, spremenjena različica je delovala brez napak. Super.

Gremo v proizvodnjo in spet dobimo napako v isti fazi kopiranja podatkov iz tabele dnevnika v novo:

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

Klasična situacija: v testnih okoljih vse deluje, v produkciji pa ne?!

APPLY_COUNT in stičišče dveh paketov

Začeli smo analizirati kodo dobesedno vrstico za vrstico in odkrili pomembno točko: podatki se prenašajo iz tabele dnevnika v novo v paketih, konstanta APPLY_COUNT je označevala velikost paketa:

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

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

Težava je v tem, da lahko podatki iz prvotne transakcije, v kateri bi lahko več operacij potencialno kršilo omejitev, ob prenosu končajo na stičišču dveh paketov – polovica ukazov bo predanih v prvem paketu, druga polovica pa v drugem. In tukaj, odvisno od vaše sreče: če ekipe v prvi seriji ne prekršijo ničesar, potem je vse v redu, če pa že, pride do napake.

APPLY_COUNT je enako 1000 zapisom, kar pojasnjuje, zakaj so bili naši testi uspešni - niso zajeli primera "paketnega spoja". Uporabili smo dva ukaza - vstavi in ​​posodobi, tako da je bilo točno 500 transakcij dveh ukazov vedno postavljenih v paket in nismo imeli nobenih težav. Po dodajanju druge posodobitve je naše urejanje prenehalo delovati:

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;

Naslednja naloga je torej zagotoviti, da podatki iz originalne tabele, ki je bila spremenjena v eni transakciji, končajo v novi tabeli tudi znotraj ene transakcije.

Zavrnitev serij

In spet smo imeli dve rešitvi. Prvič: popolnoma opustimo particioniranje v pakete in prenesemo podatke v eni transakciji. Prednost te rešitve je bila njena preprostost - zahtevane spremembe kode so bile minimalne (mimogrede, v starejših različicah je pg_reorg deloval točno tako). Vendar obstaja težava - ustvarjamo dolgotrajno transakcijo in to, kot je bilo že rečeno, predstavlja grožnjo za nastanek novega napihnjenosti.

Druga rešitev je bolj zapletena, a verjetno bolj pravilna: ustvarite stolpec v dnevniški tabeli z identifikatorjem transakcije, ki je dodala podatke v tabelo. Potem, ko kopiramo podatke, jih lahko združimo po tem atributu in zagotovimo, da se povezane spremembe prenesejo skupaj. Paket bo sestavljen iz več transakcij (ali ene velike), njegova velikost pa bo odvisna od tega, koliko podatkov je bilo v teh transakcijah spremenjenih. Pomembno je vedeti, da ker podatki iz različnih transakcij v tabelo dnevnika vstopajo v naključnem vrstnem redu, jih ne bo več mogoče brati zaporedno, kot je bilo prej. seqscan za vsako zahtevo s filtriranjem po tx_id je predrag, potreben je indeks, vendar bo tudi upočasnil metodo zaradi stroškov posodabljanja. Na splošno, kot vedno, morate nekaj žrtvovati.

Zato smo se odločili, da začnemo s prvo možnostjo, saj je preprostejša. Najprej je bilo treba razumeti, ali bi bila dolga transakcija resničen problem. Ker se tudi glavni prenos podatkov iz stare tabele v novo zgodi v eni dolgi transakciji, se je vprašanje spremenilo v "za koliko bomo povečali to transakcijo?" Trajanje prve transakcije je odvisno predvsem od velikosti mize. Trajanje novega je odvisno od tega, koliko sprememb se nabere v tabeli med prenosom podatkov, tj. na intenzivnost obremenitve. Zagon pg_repack se je zgodil v času minimalne obremenitve storitve in obseg sprememb je bil nesorazmerno majhen v primerjavi z izvirno velikostjo tabele. Odločili smo se, da lahko zanemarimo čas nove transakcije (za primerjavo, v povprečju je to 1 ura in 2-3 minute).

Poskusi so bili pozitivni. Začetek proizvodnje tudi. Za jasnost je tukaj slika z velikostjo ene od baz podatkov po zagonu:

Postgres: bloat, pg_repack in odložene omejitve

Ker smo bili s to rešitvijo popolnoma zadovoljni, nismo poskušali implementirati druge, vendar razmišljamo o možnostih pogovora z razvijalci razširitve. Naša trenutna revizija na žalost še ni pripravljena za objavo, saj smo težavo rešili le z edinstvenimi odloženimi omejitvami, za popoln popravek pa je treba zagotoviti podporo za druge vrste. Upamo, da nam bo to uspelo tudi v prihodnje.

Morda imate vprašanje, zakaj smo se sploh vključili v to zgodbo s spremembo pg_repack in nismo na primer uporabili njegovih analogov? Na neki točki smo tudi mi razmišljali o tem, vendar nas je pozitivna izkušnja prejšnje uporabe, na tabelah brez odloženih omejitev, motivirala, da smo poskušali razumeti bistvo problema in ga odpraviti. Poleg tega uporaba drugih rešitev zahteva tudi čas za izvedbo testov, zato smo se odločili, da bomo najprej poskušali odpraviti težavo v njej, in če bomo ugotovili, da tega ne moremo storiti v razumnem času, bomo začeli iskati analoge .

Ugotovitve

Kaj lahko priporočamo na podlagi lastnih izkušenj:

  1. Spremljajte svojo napihnjenost. Na podlagi podatkov spremljanja lahko razumete, kako dobro je konfiguriran avtovakuum.
  2. Prilagodite AUTOVAKUUM, da ohranite napihnjenost na sprejemljivi ravni.
  3. Če napihnjenost še narašča in je ne morete premagati z orodji, ki so že pripravljena, se ne bojte uporabiti zunanjih podaljškov. Glavna stvar je, da vse dobro preizkusite.
  4. Ne bojte se spremeniti zunanjih rešitev, da bodo ustrezale vašim potrebam – včasih je to lahko bolj učinkovito in celo lažje kot spreminjanje lastne kode.

Vir: www.habr.com

Dodaj komentar