PostgreSQL Antipatterns: "hildakoen" horden aurka borrokatzea

PostgreSQL-ren barne-mekanismoen berezitasunek egoera batzuetan oso azkarra eta beste batzuetan "ez oso azkarra" izatea ahalbidetzen dute. Gaur DBMS baten funtzionamenduaren eta garatzaileak harekin egiten duenaren arteko gatazka baten adibide klasiko batean zentratuko gara - UPDATE vs MVCC printzipioak.

Istorio laburra artikulu bikaina:

UPDATE komando baten bidez errenkada bat aldatzen denean, bi eragiketa egiten dira benetan: DELETE eta INSERT. IN katearen egungo bertsioa xmax EGUNERAZIOA egin duen transakzioaren kopuruaren berdina ezartzen da. Orduan sortzen da bertsio berri bat lerro bera; bere xmin balioa aurreko bertsioaren xmax balioarekin bat dator.

Transakzio hau amaitu eta denbora batera, bertsio zaharra edo berria, arabera COMMIT/ROOLBACK, aitortuko da "hildako" (hildako tuplak) pasatzean VACUUM taularen arabera eta garbitu.

PostgreSQL Antipatterns: "hildakoen" horden aurka borrokatzea

Baina hori ez da berehala gertatuko, baina "hildakoen" arazoak oso azkar lor daitezke - errepikatu edo erregistroen eguneraketa masiboa mahai handi batean, eta pixka bat beranduago egoera berdinarekin topo egingo duzu VACUUMek ezin izango du lagundu.

#1: Mugitzea gustatzen zait

Demagun zure metodoa negozio-logikan lan egiten ari dela, eta bat-batean konturatzen dela X eremua erregistro batzuetan eguneratu beharko litzatekeela:

UPDATE tbl SET X = <newX> WHERE pk = $1;

Orduan, exekuzioa aurrera doan heinean, Y eremua ere eguneratu beharko litzateke:

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... eta gero Z ere - zergatik galdu denbora huskeriatan?

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

Disko honen zenbat bertsio ditugu orain datu-basean? Bai, 4 pieza! Horietatik bat garrantzitsua da, eta 3 garbitu beharko dira zure ondoren [auto]VACUUM bidez.

Ez egin horrela! Erabili eremu guztiak eskaera bakarrean eguneratzea β€” ia beti metodoaren logika honela alda daiteke:

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

#2: Erabilera DESBERDINTA DA, Luke!

Beraz, oraindik nahi zenuen eguneratu erregistro asko eta asko taula batean (gidoia edo bihurgailu bat erabiltzean, adibidez). Eta horrelako zerbait gidoian sartzen da:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

Gutxi gorabehera inprimaki honetako eskaera bat sarritan gertatzen da eta ia beti eremu berri hutsik ez betetzeko, datuetan akats batzuk zuzentzeko baizik. Aldi berean, bera dauden datuen zuzentasuna ez da batere kontuan hartzen - baina alferrik! Hau da, diskoa berridatzi egiten da, nahi zena zehatz-mehatz jaso bazuen ere, baina zergatik? Konpon dezagun:

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

Jende askok ez daki horrelako operadore zoragarri baten existentziaz, beraz, hona hemen iruzur orri bat IS DISTINCT FROM eta beste operadore logiko batzuk laguntzeko:
PostgreSQL Antipatterns: "hildakoen" horden aurka borrokatzea
... eta konplexuen gaineko eragiketei buruz apur bat ROW()-esamoldeak:
PostgreSQL Antipatterns: "hildakoen" horden aurka borrokatzea

#3: Nire maitea ezagutzen dut... blokeatzeagatik

martxan jartzen ari dira bi prozesu paralelo berdin, eta horietako bakoitzak sarrera "abian" dela markatzen saiatzen da:

UPDATE tbl SET processing = TRUE WHERE pk = $1;

Nahiz eta prozesu hauek gauza bata bestearengandik independente egiten dituzten, baina ID beraren barruan, bigarren bezeroa eskaera honetan "blokeatuta" egongo da lehenengo transakzioa burutu arte.

1. irtenbidea: ataza aurrekora murrizten da

Gehi dezagun berriro IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

Inprimaki honetan, bigarren eskaerak ez du datu-basean ezer aldatuko, dena behar den bezala dago jada; beraz, ez da blokeorik gertatuko. Ondoren, aplikatutako algoritmoan erregistroa "ez aurkitzea" prozesatzen dugu.

2. irtenbidea: aholkularitzako sarrailak

Aparteko artikulu baterako gai handi bat, zeinetan irakur dezakezun aplikazio-metodoak eta gomendioen blokeoaren "rakea"..

3. irtenbidea: dei ergelak

Baina horixe da zuri gertatu behar zaizuna aldibereko lana disko berdinarekin? Edo bezeroaren aldetik negozio-logikari deitzeko algoritmoekin nahastu zenuen, adibidez? Eta pentsatzen baduzu?...

Iturria: www.habr.com

Gehitu iruzkin berria