Side 1 for Databaser DBS20 - Introduksjon til transaksjonsprosessering og teori søndag 29. mai 2016 21.15 Pensum: 20.1-20-6, side 745-776, untatt 2.5.4 og 2.5.5 20.1 Introduksjon til transaksjonsprosessering 20.1.1 Enkeltbruker vs. flerbrukersystem En DBMS er enkeltbruker hvis ikke mer enn én person kan bruke systemet samtidig og flerbruker hvis flere personer kan bruke systemet samtidig. Når flere prosesser kjøres samtidig, kan de egentlig kjøres "sammenflettet" (interleaved), også oppfattes det som at de kjøres parallelt. Hvis systemet har flere prosessorer er det mulig å kjøre prosessene parallelt. 20.1.2 Transaksjoner, data items, lese- og skriveoperasjoner og DBMS buffer En transaksjon gjør typisk sletting, innsetting, oppdatering eller henting. En read-only-transaksjon vil bare lese verdier, ellers er det en read-writetransaksjon. Når man skriver read(x) eller write(x), så er X et data item, og det kan være en post, en blokk eller et attributt-felt. Størrelsen til X kalles dens granularitet. Lesing krever én diskaksess og skriving krever to diskaksesser. Det er ikke alltid at skriving til disk skjer umiddelbart. 20.1.3 Derfor trenger man samtidighetskontroll Dirty read Når en transaksjon T1 leser en verdi som en annen transaksjon T2 nylig har skrevet men ikke committed (en "dirty" verdi). Hvis T2 skulle feile, vil T1 ha feil verdier. Lost update Når to transaksjoner leser samme verdi og gjør en endring samtidig, for så å skrive tilbake. Dette resulterer i at den ene oppdateringen går tapt, og den som blir skrevet sist blir lagret. Incorrect summary Hvis en transaksjon T1 skal utføre en aggregatutregning (data utledet fra annen data), og en annen transaksjon T2 gjør endringer på verdiene T1 allerede har lest, vil utregningen til T1 være feil, da den vil ha tatt utgangspunkt i gamle verdier. Unrepeatable read Hvis en transaksjon leser en verdi flere ganger, men en annen transaksjon har endret verdien i mellomtiden, slik at den første transaksjonen leser to forskjellige verdier.
Side 2 for Databaser 20.1.4 Derfor trengs gjenoppretting Når man sender en transaksjon til DBMS for utføring, så vil systemet sørge for at enten så blir alle operasjonene i transaksjonen og endringene blir lagret permanent i databasen - da blir transaksjonen committet, ellers så skal transaksjonen ikke ha noen effekt på databasen eller andre transaksjoner - den blir abortert. Grunner til at en transaksjon feiler: Datafeil, systemkrasj. Maskinvare, programvare eller nettverksfeil. Transaksjonsfeil. En operasjon i transaksjonen feiler (for eksempel division by zero), brukeren avbryter Lokale feil eller unntaksbetingelse. Data som ikke blir funnet, en betingelse i transaksjonen blir ikke møtt (for eksempel for lite penger på konto til å overføre). Samtidighetskontroll. Hvis en transaksjon ikke er serialiserbar, eller hvis det er deadlock mellom flere transaksjoner. Diskfeil. Lesing eller skrivingsfeil. Fysiske problemer og katastrofer. Strøm, AC, tyver, sabotasje, overskriving ved et uhell, brann 20.2 Transaksjon og systemkonsepter 20.2.1 Transaksjonstilstander og andre operasjoner DBMS trenger å vite om: BEGIN_TRANSACTION READ eller WRITE END_TRANSACTION COMMIT_TRANSACTION ROLLBACK (ABORT) Tilstander: Active: Gjør skrive- og leseoperasjoner. Partially Commited: Sjekker om alt går som det skal, og committer hvis det gjør det. Ellers aborteres det. Committed: Transaksjonen var vellykket, kan skrives til disk. Failed: Nødvendig rollback-operasjoner må gjøres. 20.2.2 Systemloggen Får gjenoppretting etter feil som påvirker transaksjoner, blir det opprettholdt en logg som holder styring på alle dataelementer påvirket av en transaksjon, i tillegg til annen relevant informasjon. Loggen er en sekvensiell, append-only fil som er på disk. Siste delen av loggen ligger typisk i log-buffer i minnet. Informasjon som blir skrevet til systemloggen: 1. [start_transaction, T] Transaksjonen T har startet
Side 3 for Databaser 2. 3. 4. 5. [write_item, T, X, old_value, new_value] Transaksjonen T har endret verdien på X. [read_item, T, X] Transaksjonen T har lest verdien X. [commit, T] Transaksjonen T var vellykket [abort, T] Transaksjonen T ble abortert. 20.2.3 Commit-point til en transaksjon En transaksjon har nådd commit-punktet når alle operasjoner som har tilgang til databasen er vellykket og alle transaksjonsoperasjoner er blitt logget. Da er transaksjonen committed, og må lagres permanent i databasen - da skrives [commit, T] inn i systemloggen. Ved feil kan man finne de transaksjonene som ble påbegynt, men ikke har [commit, T] i systemloggen - det kan være disse må rulles tilbake. Ved feil vil kun de delene av systemloggen som ligger i disken bli sett på, altså må loggbufferet skrives til disk før transaksjonen når commit-punktet. 20.2.4 DBMS-spesifikke buffererstatnings policies Hvis alle buffer er opptatt, og man må laste inn nye diskblokker i bufferet, finnes forskjellige page replacement policies. Domain Separation (DS)-metoden. Cache-minnet er delt opp i separate domener som behandler hver sin type diskblokker, og vanlilg LRU (least recently used) blir brukt i et domene. Dette er en statisk metode. Hot Set-metoden. Effektivt når man skal aksessere filer flere ganger (for eksempel JOIN-LOOP). Laster inn hele filen som skal aksesseres flere ganger, og fjerner den ikke før man er ferdig med den. DBMIN-metoden. Denne metoden bruker en modell kalt QLSM (query locality set model). Den tar utgangspunkt i algoritmer for operasjoner, ser hvilke filer som skal brukes og regner ut lokalitetssett for filene. Deretter allokkerer den bufferplass til filene basert på lokalitetssettet. 20.3 Ønskelige egenskaper ved en transaksjon ACID, egenskaper ved en transaksjon Atomicity Enten så skjer alle operasjoner i en transaksjon, ellers så skjer ingen av dem. Opprettholdes av Transaction Management Component. Den må tilbakerulle transaksjonen hvis det skjer feil og sørge for at alt som skal skrives til disk blir skrevet til disk. Consistency Korrekthet, data skal være riktig overalt hvis noe blir endret. I noen moderne databaser (for eksempel facebook, youtube) er dette en egenskap som går på kompromiss med det å få ut data så fort som mulig. Programmerere har ansvar for å lage databaser som er konsistente. Isolation Hvis flere transaksjoner blir gjort samtidig, så sørges det for at de blir utført som om det var serielt/det skal se ut som at en transaksjon blir utført alene, selv om flere transaksjoner blir utført samtidig. Opprettholdt av Concurrency Control Management. Durability
Side 4 for Databaser Endringer bør være permamente, og burde IKKE mistes på grunn av databasefeil. Recovery manager's ansvar. Nivåer av isolasjon: Nivå 0: Overskriver ikke dirty-reads til transaksjoner av høyere nivå. Nivå 1: Ingen lost updates Nivå 2: Ingen lost updates og ingen dirty reads Nivå 3: Har ingen unrepeatable reads, ingen lost updates og ingen dirty reads. 20.4 Karakterisering av historier basert på gjenopprettbarhet Når flere transaksjoner blir utført sammenflettet, er rekkefølgen av operasjoner en historie. 20.4.1 Transaksjonstilstander og andre operasjoner En historie med n transaksjoner er en sammenflettet ordning av operasjonene til transaksjonene. En transaksjons operasjoner må komme i samme rekkefølge i historien som de blir utført i transaksjonen. To operasjoner i en historie er i konflikt hvis 1) De tilhører forskjellige transaksjoner 2) De aksesserer samme dataelement X 3) Minst én av transaksjonene er en skriveoperasjon. En annen måte å si det på er at to operasjoner er i konflikt hvis man kan endre på rekkefølgen og få et annet resultat. Read-write-konflikt: Den ene transaksjonen leser X før eller etter at den andre transaksjonen har endret X. Write-write-konflikt: Den siste transaksjonen som skriver, "vinner". En historie er komplett hvis: 1) Operasjonene i historien er nøyaktig de samme som de i transaksjonene, i tillegg til commit og abort-operasjoner som siste operasjon for hver transaksjon. 2) For hvert par operasjoner fra en transaksjon T, så er den relative rekkefølgen i historien lik rekkefølgen i T. 3) For alle par operasjoner i konflikt, må én av operasjonene kommer før den andre i historien. Betingelse (3) sier at hvis to operasjoner ikke er i konflikt, trenger man ikke definere hvilken som skal komme først, som leder til definisjonen om at en historie er en delvis ordning av operasjonene i de n transaksjonene. Men en total ordning må spesifiseres for alle par operasjoner i konflikt og alle operasjoner i samme transaksjon. 20.4.2 Karakterisering av historier basert på gjenoppretting Gjenopprettbar historie: En gjenopprettbar historie skal aldri måtte rulles tilbake etter at den er committet. En historie H er gjenopprettbar hvis alle transaksjoner T' som har skrevet til et dataelement X må ha committet før T kan committe, når T har lest X. - En transaksjon T leser fra transaksjon T' i en historie hvis X først er skrevet av T' og senere lest av T. - T' bør ikke aborteres før T leser X, og det bør ikke være transaksjoner som skriver til X etter at T' har skrevet til X og T har lest X.
Side 5 for Databaser Hva er greia? Hvis en transaksjon T1 skriver til X, og T2 leser denne X- verdien, men committer før T1, så er det slik at hvis T1 aborterer, må man tilbakerulle T2, en transaksjon som allerede er committed, siden den har basert seg på en ugyldig verdi. Galopperende abort: En ikke-committed transaksjon må rulles tilbake, fordi den leste fra en transaksjon som feilet. En historie som unngår galopperende abort (ACA, avoid cascading abort) har transaksjoner som bare kan bare lese verdier som er committet av andre transaksjoner. Altså hvis T1 har skrevet til X, kan ikke T2 lese X før T1 har committet. Strikt historie: Transaksjoner kan verken lese eller skrive X hvis en annen transaksjon har skrevet til X, før den andre transaksjonen har committet. 20.5 Karakterisere historier basert på serialiserbarhet 20.5.1 Seriell, ikke-seriell og konfliktserialiserbare historier En seriell historie er slik at en transaksjon blir gjennomført i sin helhet før neste transaksjon blir det. Ulemper med å kjøre transaksjoner etter hverandre: 1) Begrenser samtidighet 2) Forårsaker bortkasta CPU kraft 3) Mindre transaksjoner må vente lenge på lange transaksjoner. Hvis man kjører transaksjoner parallelt (fletta) er det en sjanse for at vi får feil. Serialiserbar historie En historie H med n transaksjoner er serialiserbar hvis den er ekvivalent med en seriell historie av de samme n transaksjonene. Konfliktserialiserbar historie Hvis en historie er konfliktekvivalent med en seriell historie, så kaller vi den konfliktserialiserbar To historier er konfliktekvivalente hvis rekkefølgen på alle par operasjoner som gir konflikt er lik i begge historier. Konflikt: Samme variabel, forskjellige transaksjoner, minst én av operasjonene er en write-operasjon. 20.5.2 Teste for (konflikt)serialiserbarhet på en historie Man kan finne ut om en historie er konfliktserialiserbar ved å lage en presedensgraf. 1) Man har like mange noder som det er transaksjoner. 2) For hvert par operasjoner Oi og Oj som gir konflikt, lager vi en rettet kant fra i til j. For hver operasjon må man sjekke med alle senere operasjoner. 3) Hvis det finnes en sykel i grafen, så er historien ikke konfliktserialiserbar. En kant fra Ti til Tj betyr at transaksjonen Ti må gjøres før T2 i en seriell historie. Man kan merke kantene dataelementet som er involvert i
Side 6 for Databaser operasjonene, men dette har ikke noe å si - sykel er sykel. 20.5.3 Hvordan serialiserbarhet blir brukt i samtidighetskontroll Det er vanskelig å teste for serialiserbarhet - et (dårlig) alternativ er å teste etter at en historie er kjørt, og deretter abortere hvis historien ikke var konfliktserialiserbar. En vanlig måte er å designe protokoller som alle transaksjonene følger, slik at de blir konfliktserialiserbare. 20.6 Transaksjonsstøtte i SQL Det er ingen BEGIN_Transaction, dette er implisitt når man kommer til en SQL-statement. Men det må være END_TRANSACTON, som enten er COMMIT eller ROLLBACK. Egenskaper til en transaksjon: Access mode, READ ONLY eller READ WRITE. Default er READ WRITE, med mindre READ UNCOMMITTED er spesifisert (se under). Diagnostic area size, et heltall som spesifiserer antall betingelser i diagnostic area. https://dev.mysql.com/doc/refman/5.6/en/diagnostics-area.html. Isolasjonsnivå i SQL Isolasjonsnivå Dirty read Nonrepeatable read Phantom READ UNCOMMITTED Ja Ja Ja READ COMMITTED Nei Ja Ja REPEATABLE READ Nei Nei Ja SERIALIZABLE Nei Nei Nei Dirty read: En transaksjon T1 kan lese oppdateringen til T2, som ennå ikke er oppdatert. Hvis T2 feiler, så har T1 lest en ukorrekt verdi. Nonrepeatable read: En transaksjon T1 kan lese en gitt verdi fra en tabell. Hvis en transaksjon T2 seinere oppdaterer verdien og T1 leser den igjen, så vil T1 se en annen verdi. Phantoms: Hvis en transaksjon T1 leser flere rader i en tabell, og T2 legger inn en ny rad i tabellen, vet man ikke om T1 har lest raden eller ikke. Hvis den ekvivalente serielle historien er slik at T1 er før T2, er phantom-en ikke lest, ellers er den det. Snapshot isolation En transaksjon ser kun dataelementene som var til stedet i det transaksjonen startet.