PostgreSQL:n antipatterns: "kuolleiden" laumojen taistelu

PostgreSQL:n sisäisten mekanismien toimintatapa mahdollistaa sen, että se on joissakin tilanteissa erittäin nopea ja toisissa taas hitaampi. Tänään tarkastelemme klassista esimerkkiä ristiriidasta tietokannan hallintajärjestelmän toiminnan ja kehittäjän toiminnan välillä: UPDATE vs. MVCC -periaatteet.

Lyhyt juoni erinomainen artikkeli:

Kun riviä muokataan UPDATE-komennolla, suoritetaan itse asiassa kaksi toimintoa: DELETE ja INSERT. linjan nykyinen versio xmax asetetaan UPDATE-komennon suorittaneen tapahtuman numeroksi. Sitten se luodaan uusi versio samalla rivillä; sen xmin-arvo vastaa edellisen version xmax-arvoa.

Jonkin ajan kuluttua tämän tapahtuman valmistumisesta vanha tai uusi versio, riippuen COMMIT/ROOLBACK, tullaan tunnistamaan kuolleet tuplet ohittaessa VACUUM taulukon mukaan ja tyhjennetty.

PostgreSQL:n antipatterns: "kuolleiden" laumojen taistelu

Mutta tämä ei tapahdu heti, vaan ongelmia "kuolleiden" kanssa voidaan saada hyvin nopeasti - toistuvilla tai tietueiden massapäivitys suuressa pöydässä ja hieman myöhemmin kohtaavat tilanteen, jossa VAKUUMI ei pysty auttamaan.

#1: Tykkään liikutella sitä

Oletetaan, että liiketoimintalogiikkamenetelmäsi on käynnissä ja yhtäkkiä huomaa, että sen on päivitettävä kenttä X jossakin tietueessa:

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

Sitten suorituksen edetessä se huomaa, että myös Y-kenttä on päivitettävä:

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

...ja sitten on vielä Z – miksi vaivautua pieniin asioihin?

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

Kuinka monta versiota tästä merkinnästä meillä on nyt tietokannassa? Kyllä, neljä! Yksi niistä on ajan tasalla, ja kolme pitää siivota [auto]VACUUM-komennolla.

Älä tee niin! Käytä sitä! kaikkien kenttien päivittäminen yhdellä pyynnöllä — lähes aina metodin logiikkaa voidaan muuttaa näin:

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

#2: Käyttö ON ERILLISTÄ KUIN, Luke!

Joten halusit silti päivittää useita, monia tietueita taulukossa (esimerkiksi skriptiä tai muunninta käytettäessä). Ja skriptiin lisätään jotain tällaista:

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

Tämän muotoinen pyyntö kohtaa melko usein, ja lähes aina ei uuden tyhjän kentän täyttämiseksi, vaan joidenkin tietovirheiden korjaamiseksi. olemassa olevien tietojen oikeellisuutta ei oteta lainkaan huomioon – mutta turhaan! Eli merkintä on kirjoitettu uudelleen, vaikka se sisältäisi juuri sen, mitä halusin – mutta miksi vaivautua? Korjataanpa se:

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

Monet ihmiset eivät ole tietoisia tällaisen upean operaattorin olemassaolosta, joten tässä on lunttilappu IS DISTINCT FROM ja muita loogisia operaattoreita avuksi:
PostgreSQL:n antipatterns: "kuolleiden" laumojen taistelu
...ja hieman monimutkaisten operaatioiden suorittamisesta ROW()-lausekkeet:
PostgreSQL:n antipatterns: "kuolleiden" laumojen taistelu

#3: Tunnistan rakkaani… estämällä

He ovat käynnistämässä kaksi identtistä rinnakkaista prosessia, joista jokainen yrittää merkitä tallennuksen ”keskeneräiseksi”:

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

Vaikka nämä prosessit suorittaisivat itsenäisiä tehtäviä saman tunnuksen sisällä, toinen asiakas "lukitaan" tässä pyynnössä, kunnes ensimmäinen tapahtuma on suoritettu.

Ratkaisu nro 1: tehtävä supistuu edelliseen tehtävään

Lisätään se vielä uudestaan IS DISTINCT FROM:

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

Tässä muodossa toinen kysely ei yksinkertaisesti muuta mitään tietokannassa; kaikki on jo "niin kuin sen pitäisi olla" – joten estoa ei tapahdu. Sovellusalgoritmi käsittelee sitten sen, että tietuetta "ei löytynyt".

Ratkaisu nro 2: neuvoa-antavat lukot

Tämä on iso aihe erilliselle artikkelille, josta voit lukea siitä lisää. Soveltamismenetelmät ja neuvoa-antavan estämisen sudenkuopat.

Ratkaisu nro 3: tyhmiä puheluita

Mutta juuri näin pitäisi käydä sinulle. samanaikainen työskentely saman tietueen kanssaTai ehkä esimerkiksi mokasit asiakaspuolen liiketoimintalogiikan kutsualgoritmit? Mutta jos ajattelet asiaa...

Lähde: will.com

Osta luotettava isännöinti sivustoille, joissa on DDoS-suojaus, VPS VDS -palvelimet 🔥 Osta luotettavaa verkkosivustojen hostingia DDoS-suojauksella, VPS VDS -palvelimilla | ProHoster