Tehingud InterSystems IRIS globaalsetes

Tehingud InterSystems IRIS globaalsetesInterSystems IRIS DBMS toetab huvitavaid andmete salvestamise struktuure – globaalseid. Sisuliselt on need mitmetasandilised võtmed, millel on erinevad lisamahud tehingute näol, kiired funktsioonid andmepuude läbimiseks, lukud ja oma ObjectScript keel.

Loe globaalsetest lähemalt artiklisarjast “Globalid on andmete salvestamise aaremõõgad”:

puud. 1. osa
puud. 2. osa
Hõredad massiivid. 3. osa

Mind hakkas huvitama, kuidas globaalsetes tehinguid realiseeritakse, mis funktsioone seal on. Lõppude lõpuks on see andmete salvestamiseks täiesti erinev struktuur kui tavalised tabelid. Palju madalam tase.

Nagu on teada relatsiooniandmebaaside teooriast, peab tehingute hea teostus vastama nõuetele ACID:

A - Aatomi (aatomilisus). Kõik tehingus tehtud või üldse mitte tehtud muudatused registreeritakse.

C – järjepidevus. Pärast tehingu lõpuleviimist peab andmebaasi loogiline olek olema sisemiselt ühtlane. Paljuski puudutab see nõue programmeerijat, SQL andmebaaside puhul aga ka võõrvõtmeid.

Mina – isoleerin. Paralleelselt toimuvad tehingud ei tohiks üksteist mõjutada.

D – vastupidav. Pärast tehingu edukat lõpetamist ei tohiks madalamate tasemete probleemid (näiteks elektrikatkestus) mõjutada tehinguga muudetud andmeid.

Globaalid on mitterelatsioonilised andmestruktuurid. Need olid loodud töötama ülikiiresti väga piiratud riistvaraga. Vaatame tehingute rakendamist globaalsetes kasutades ametlik IRISe dokkimispilt.

IRIS-is tehingute toetamiseks kasutatakse järgmisi käske: TSTART, KOMMITEE, TROLLBACK.

1. Aatomilisus

Lihtsaim viis kontrollida aatomilisust. Kontrollime andmebaasikonsoolist.

Kill ^a
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TCOMMIT

Siis järeldame:

Write ^a(1), “ ”, ^a(2), “ ”, ^a(3)

Saame:

1 2 3

Kõik on korras. Aatomilisus säilib: kõik muutused registreeritakse.

Teeme ülesande keerulisemaks, sisestame vea ja vaatame, kuidas tehing osaliselt või üldse mitte salvestatakse.

Kontrollime aatomilisust uuesti:

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3

Siis peatame konteineri jõuga, käivitame ja vaatame.

docker kill my-iris

See käsk on peaaegu samaväärne sundseiskamisega, kuna saadab SIGKILL-signaali protsessi viivitamatuks peatamiseks.

Võib-olla õnnestus tehing osaliselt salvestada?

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

- Ei, see pole säilinud.

Proovime tagasipööramiskäsku:

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TROLLBACK

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

Midagi pole ka säilinud.

2. Järjepidevus

Kuna globaalidel põhinevates andmebaasides tehakse võtmeid ka globaalsetel (tuletan meelde, et globaalne on madalama taseme struktuur andmete salvestamiseks kui relatsioonitabel), siis tuleb järjepidevuse nõude täitmiseks kaasata võtme muudatus. samas tehingus muutusega globaalses.

Näiteks on meil globaalne ^isik, kuhu salvestame isikud ja kasutame võtmena TIN-i.

^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
...

Perekonna- ja eesnime järgi kiireks otsimiseks tegime klahvi ^index.

^index(‘Kamenev’, ‘Sergey’, 1234567) = 1

Selleks, et andmebaas oleks järjepidev, peame lisama isiku järgmiselt:

TSTART
^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
^index(‘Kamenev’, ‘Sergey’, 1234567) = 1
TCOMMIT

Seetõttu peame kustutamisel kasutama ka tehingut:

TSTART
Kill ^person(1234567)
ZKill ^index(‘Kamenev’, ‘Sergey’, 1234567)
TCOMMIT

Teisisõnu, järjepidevuse nõude täitmine lasub täielikult programmeerija õlul. Aga mis puutub globaalsetesse asjadesse, siis on see nende madala taseme tõttu normaalne.

3. Isolatsioon

Siit saavad alguse metsikud loodused. Paljud kasutajad töötavad samaaegselt sama andmebaasiga, muutes samu andmeid.

Olukord on võrreldav sellega, kui paljud kasutajad töötavad samaaegselt sama koodihoidlaga ja proovivad samaaegselt teha muudatusi paljudes failides korraga.

Andmebaas peaks selle kõik reaalajas välja sorteerima. Arvestades, et tõsistes ettevõtetes on isegi spetsiaalne inimene, kes vastutab versioonikontrolli eest (filiaalide ühendamise, konfliktide lahendamise jms eest) ning andmebaas peab seda kõike tegema reaalajas, siis ülesande keerukus ja korrektsus. andmebaasi kujundus ja kood, mis seda teenindab.

Andmebaas ei mõista kasutajate tegevuste tähendust, et vältida konflikte, kui nad töötavad samade andmetega. See saab tagasi võtta ainult ühe tehingu, mis on teisega vastuolus, või teostada need järjestikku.

Probleemiks on ka see, et tehingu sooritamise ajal (enne kinnistamist) võib andmebaasi olek olla ebaühtlane, mistõttu on soovitav, et teistel tehingutel ei oleks ligipääsu andmebaasi ebaühtlasele olekule, mis saavutatakse relatsiooniandmebaasides. mitmel viisil: hetktõmmiste loomine, mitme versiooniga read jne.

Tehinguid paralleelselt sooritades on meie jaoks oluline, et need üksteist ei segaks. See on isolatsiooni omadus.

SQL määratleb 4 isolatsioonitaset:

  • LOE KOHUSTUSTETA
  • LOE Pühendunud
  • KORDAV LUGEMINE
  • SERIALISEERITUD

Vaatame iga taset eraldi. Iga taseme rakendamise kulud kasvavad peaaegu plahvatuslikult.

LOE KOHUSTUSTETA - see on madalaim isolatsioonitase, kuid samal ajal ka kiireim. Tehingud saavad lugeda üksteise tehtud muudatusi.

LOE Pühendunud on isolatsiooni järgmine tase, mis on kompromiss. Tehingud ei saa lugeda üksteise muudatusi enne kinnistamist, kuid nad saavad lugeda kõiki pärast sidumist tehtud muudatusi.

Kui meil on pikk tehing T1, mille käigus toimusid commits tehingutes T2, T3 ... Tn, mis töötasid samade andmetega mis T1, siis T1-s andmeid küsides saame iga kord erineva tulemuse. Seda nähtust nimetatakse mittekordatavaks lugemiseks.

KORDAV LUGEMINE — sellel isolatsioonitasemel puudub meil kordumatu lugemise nähtus, kuna iga andmete lugemise päringu puhul luuakse tulemusandmetest hetktõmmis ja kui neid kasutatakse uuesti samas tehingus, siis hetktõmmise andmed. kasutatakse. Siiski on sellel isolatsioonitasemel võimalik lugeda fantoomandmeid. See viitab paralleelselt sooritatud tehingutega lisatud uute ridade lugemisele.

SERIALISEERITUD — kõrgeim isolatsioonitase. Seda iseloomustab asjaolu, et tehingus (lugemine või muutmine) mis tahes viisil kasutatud andmed muutuvad teistele tehingutele kättesaadavaks alles pärast esimese tehingu sooritamist.

Esiteks selgitame välja, kas tehingu toimingud on põhilõimest eraldatud. Avame 2 terminali akent.

Kill ^t

Write ^t(1)
2

TSTART
Set ^t(1)=2

Isolatsiooni pole. Üks lõime näeb, mida teeb teine, kes tehingu avas.

Vaatame, kas erinevate lõimede tehingud näevad, mis nende sees toimub.

Avame 2 terminaliakent ja avame paralleelselt 2 tehingut.

kill ^t
TSTART
Write ^t(1)
3

TSTART
Set ^t(1)=3

Paralleelsed tehingud näevad üksteise andmeid. Niisiis, saime kõige lihtsama, kuid ka kiireima isolatsioonitaseme, READ UNCOMMITED.

Põhimõtteliselt võiks seda eeldada globaalsete inimeste puhul, kelle jaoks jõudlus on alati olnud prioriteet.

Mis siis, kui vajame globaalsetel operatsioonidel suuremat isolatsioonitaset?

Siin tuleb mõelda, miks isolatsioonitasemeid üldse vaja on ja kuidas need toimivad.

Kõrgeim isolatsioonitase SERIALIZE tähendab, et paralleelselt sooritatud tehingute tulemus on samaväärne nende järjestikuse täitmisega, mis tagab kokkupõrgete puudumise.

Seda saame teha ObjectScripti nutikate lukkude abil, millel on palju erinevaid kasutusviise: käsuga saab teha tavalist, astmelist, mitmekordset lukustamist. LOCK.

Madalamad isolatsioonitasemed on kompromissid, mis on loodud andmebaasi kiiruse suurendamiseks.

Vaatame, kuidas me saame lukkude abil saavutada erineva isolatsioonitaseme.

See operaator võimaldab võtta mitte ainult andmete muutmiseks vajalikke eksklusiivseid lukke, vaid nn jagatud lukke, mis võivad võtta paralleelselt mitu lõime, kui neil on vaja lugeda andmeid, mida ei tohiks lugemisprotsessi käigus muud protsessid muuta.

Lisateave kahefaasilise blokeerimismeetodi kohta vene ja inglise keeles:

Kahefaasiline blokeerimine
Kahefaasiline lukustus

Raskus seisneb selles, et tehingu ajal võib andmebaasi olek olla ebaühtlane, kuid need vastuolulised andmed on teistele protsessidele nähtavad. Kuidas seda vältida?

Lukkude abil loome nähtavuse aknad, milles andmebaasi olek on ühtlane. Ja kogu juurdepääsu sellistele kokkulepitud oleku nähtavuse akendele kontrollitakse lukkude abil.

Samade andmete jagatud lukud on korduvkasutatavad – mitmed protsessid võivad neid kasutada. Need lukud takistavad teistel protsessidel andmete muutmist, s.t. neid kasutatakse järjepideva andmebaasi oleku akende moodustamiseks.

Andmete muutmiseks kasutatakse eksklusiivseid lukke – sellise luku saab võtta ainult üks protsess. Eksklusiivse luku saab võtta:

  1. Mis tahes protsess, kui andmed on tasuta
  2. Ainult protsess, millel on nendel andmetel jagatud lukk ja mis taotles esimesena eksklusiivset lukku.

Tehingud InterSystems IRIS globaalsetes

Mida kitsam on nähtavusaken, seda kauem peavad teised protsessid seda ootama, kuid seda järjepidevam saab selles sisalduva andmebaasi olek olla.

READ_COMMITTED — selle taseme olemus seisneb selles, et näeme ainult muude lõimede seotud andmeid. Kui mõne teise tehingu andmeid pole veel sidunud, siis näeme selle vana versiooni.

See võimaldab meil luku vabastamise ootamise asemel tööd paralleelselt muuta.

Ilma eriliste nippideta ei näe me IRISis olevate andmete vana versiooni, seega tuleb lukkudega leppida.

Seetõttu peame kasutama jagatud lukke, et andmeid saaks lugeda ainult järjepidevuse hetkedel.

Oletame, et meil on kasutajabaas ^isik, kes üksteisele raha üle kannab.

Isikult 123 inimesele 242 ülemineku hetk:

LOCK +^person(123), +^person(242)
Set ^person(123, amount) = ^person(123, amount) - amount
Set ^person(242, amount) = ^person(242, amount) + amount
LOCK -^person(123), -^person(242)

Enne debiteerimist isikult 123 rahasumma küsimise hetkega peab kaasnema eksklusiivne plokk (vaikimisi):

LOCK +^person(123)
Write ^person(123)

Ja kui peate oma isiklikul kontol konto olekut näitama, saate kasutada jagatud lukku või mitte seda üldse kasutada:

LOCK +^person(123)#”S”
Write ^person(123)

Kui aga eeldada, et andmebaasitoimingud tehakse peaaegu koheselt (tuletan meelde, et globaalsed on palju madalama taseme struktuur kui relatsioonitabel), siis vajadus selle taseme järele väheneb.

KORDAV LUGEMINE - See eraldatuse tase võimaldab mitut andmete lugemist, mida saab samaaegsete tehingutega muuta.

Sellest lähtuvalt peame muudetavate andmete lugemisele ühisluku panema ja muudetavate andmete ainulukud.

Õnneks võimaldab LOCK operaator ühes avalduses üksikasjalikult loetleda kõik vajalikud lukud, mida võib olla palju.

LOCK +^person(123, amount)#”S”
чтение ^person(123, amount)

muud toimingud (praegu proovivad paralleelsed lõimed muuta ^person(123, summa), kuid ei saa)

LOCK +^person(123, amount)
изменение ^person(123, amount)
LOCK -^person(123, amount)

чтение ^person(123, amount)
LOCK -^person(123, amount)#”S”

Kui loetlete lukud komadega eraldatuna, võetakse need järjestikku, kuid kui teete seda:

LOCK +(^person(123),^person(242))

siis võetakse need kõik korraga ära.

SERIALISEERI — peame määrama lukud, et lõppkokkuvõttes teostataks kõik ühiste andmetega tehingud järjestikku. Selle lähenemisviisi jaoks peaksid enamik lukke olema eksklusiivsed ja toimima maailma väikseimates piirkondades.

Kui me räägime raha debiteerimisest globaalses ^inimeses, siis selle jaoks on vastuvõetav ainult SERIALIZE isolatsioonitase, kuna raha tuleb kulutada rangelt järjestikku, vastasel juhul on võimalik sama summa mitu korda kulutada.

4. Vastupidavus

Tegin katseid konteineri kõva lõikamisega kasutades

docker kill my-iris

Alus talus neid hästi. Probleeme ei tuvastatud.

Järeldus

Globaalsete ettevõtete jaoks on InterSystems IRIS-il tehingutugi. Need on tõeliselt aatomilised ja usaldusväärsed. Globaalidel põhineva andmebaasi järjepidevuse tagamiseks on vaja programmeerija jõupingutusi ja tehingute kasutamist, kuna sellel ei ole keerulisi sisseehitatud konstruktsioone, nagu võõrvõtmed.

Globaalide isolatsioonitase ilma lukke kasutamata on READ UNCOMMITED ning lukkude kasutamisel saab seda tagada kuni SERIALIZE tasemeni.

Globaalidel tehtavate tehingute õigsus ja kiirus sõltub suuresti programmeerija oskustest: mida laiemalt kasutatakse lugemisel jagatud lukke, seda kõrgem on isolatsioonitase ja mida kitsamalt eksklusiivseid lukke võtta, seda kiirem on jõudlus.

Allikas: www.habr.com

Lisa kommentaar