Forberedelse til SQL-intervju · leksjon

Deadlocker, låsing og MVCC

Hvordan databaser unngår konflikter, og avveiningene mellom låsing og øyeblikksbilder.

Leksjon 4 av 413 trinn

Deadlocker, låsing og MVCC er en gratis leksjon i Forberedelse til SQL-intervju på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Forberedelse til SQL-intervju, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Forberedelse til SQL-intervju inneholder totalt 4 leksjoner.

Slik håndhever databaser isolasjon i praksis

Isolasjonsnivåer er løftet; låsing og MVCC er mekanismene som oppfyller det. Intervjuere spør om dette for å se om du forstår hva som skjer under panseret når transaksjoner kolliderer.

Det finnes to overordnede strategier:

  • Pessimistisk (låsing): blokker motstridende tilgang til en lås frigjøres.
  • Optimistisk / MVCC: la alle lese et konsistent øyeblikksbilde og oppdag konflikter ved commit.

Denne leksjonen dekker låser, vranglåser og MVCC, samt avveiningene mellom dem.

Delte og eksklusive låser

Klassisk låsing bruker to hovedmodi:

  • Delt lås (S-lås) for lesing. Mange transaksjoner kan ha en delt lås på den samme raden samtidig.
  • Eksklusiv lås (X-lås) for skriving. Bare én transaksjon kan ha den, og den blokkerer alle andre låser på raden.

Regelen er at S er kompatibel med S, men X er kompatibel med ingenting. En skriver må vente på alle lesere, og lesere må vente på en skriver.

Eksplisitt låsing med SELECT FOR UPDATE

Du kan be om en skrivelås på rader du bare leser, for å hindre andre i å endre dem før du handler. Dette er standardmåten å unngå tapte oppdateringer i en les–endre–skriv-syklus.

SELECT ... FOR UPDATE tar eksklusive radlåser; radene forblir låst til du COMMIT eller ROLLBACK.

BEGIN;
-- lock the row so no one else can modify it concurrently
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;  -- lock released here

Hva er en vranglås?

En vranglås oppstår når to eller flere transaksjoner hver holder en lås den andre trenger. Det danner en syklus som gjør at ingen kan fortsette.

Det klassiske tilfellet er at T1 låser rad A og deretter vil ha rad B, mens T2 låser rad B og deretter vil ha rad A. Begge venter for alltid på hverandre.

Databaser oppdager dette ved hjelp av en wait-for-graf. Når en syklus blir funnet, velger motoren et offer og avbryter det. Deretter returneres en vranglåsfeil, slik at de andre kan fortsette.

Vranglås: tidslinje

Se hvordan låserekkefølgen krysser seg. T1 tar rad 1 og ber deretter om rad 2, mens T2 tar rad 2 og ber deretter om rad 1. Ingen av dem frigir låsen, så motoren avbryter én av dem.

Den avbrutte transaksjonen får en feil som deadlock detected og må prøve på nytt. Den andre transaksjonen committer normalt.

-- T1                                  | -- T2
BEGIN;                                 | BEGIN;
UPDATE accounts SET balance=balance-10  | UPDATE accounts SET balance=balance-10
  WHERE id=1;  -- locks row 1          |   WHERE id=2;  -- locks row 2
UPDATE accounts SET balance=balance+10  | UPDATE accounts SET balance=balance+10
  WHERE id=2;  -- waits for T2         |   WHERE id=1;  -- waits for T1 -> CYCLE
-- one transaction is chosen as victim and rolled back

Slik hindrer du vranglåser

Du kan ikke eliminere vranglåser helt, men du kan gjøre dem sjeldne. Standardsvar i intervjuer:

  • Konsekvent låserekkefølge: hent alltid rader i samme rekkefølge (for eksempel stigende id). Dette bryter syklusen.
  • Hold transaksjonene korte: hold låser så kort tid som mulig.
  • Lavere isolasjon når det er trygt: færre låser gir færre konflikter.
  • Legg til logikk for nye forsøk: transaksjoner som blir ofre for vranglåser, bør automatisk prøve på nytt.

Konsekvent rekkefølge er den mest effektive løsningen og den intervjuere først vil høre om.

Låsegranularitet

Låser kan tas på ulike nivåer, som innebærer en avveining mellom samtidighet og ressursbruk:

  • Radlåser gir høy samtidighet, men krever mer administrasjon.
  • Side- eller tabellåser er billigere å holde oversikt over, men blokkerer flere transaksjoner.

Noen motorer eskalerer fra radlåser til tabellåser når en transaksjon berører for mange rader (låseeskalering). Dette forklarer hvorfor en stor masse-UPDATE plutselig kan blokkere alle.

MVCC: øyeblikksbildetilnærmingen

MVCC (Multi-Version Concurrency Control) er måten Postgres, Oracle og InnoDB unngår de fleste leselåser på. I stedet for å låse beholder databasen flere versjoner av hver rad.

Hovedfordelen, og en favorittformulering i intervjuer, er: Lesere blokkerer ikke skrivere, og skrivere blokkerer ikke lesere.

Hver transaksjon ser et konsistent øyeblikksbilde fra et bestemt tidspunkt, mens skrivere oppretter nye radversjoner i stedet for å overskrive dem direkte.

Slik fungerer MVCC under panseret

Når en rad oppdateres, skriver MVCC en ny versjon og beholder den gamle. Hver versjon inneholder metadata for transaksjons-ID-en (i Postgres, xmin og xmax) som markerer når den ble synlig, og når den ble erstattet.

En transaksjons øyeblikksbilde avgjør hvilken versjon den ser. Gamle versjoner som ingen transaksjon lenger kan se, blir døde tupler og fjernes senere av en oppryddingsprosess. I Postgres er denne prosessen VACUUM; hvis den ikke kjøres, oppstår table bloat, et vanlig oppfølgingsspørsmål.

Låsing og MVCC: avveiningen

Oppsummer sammenligningen kort og presist:

  • Ren låsing: enkel korrekthet, men lesere og skrivere blokkerer hverandre, noe som svekker samtidigheten.
  • MVCC: svært god lesesamtidighet og ingen leselåser, men kostnaden er lagring av versjoner og opprydding (VACUUM, bloat), og det trengs fortsatt låser for konflikter mellom skrivere.

Selv MVCC-motorer låser ved skriving: To transaksjoner som oppdaterer den samme raden, må serialiseres. MVCC fjerner konkurransen mellom lesere og skrivere, ikke mellom skrivere.

Optimistisk låsing og versjonskolonner

I tillegg til MVCC på motornivå legger applikasjoner ofte til optimistisk låsing for lese–endre–skriv-operasjoner som strekker seg over lange brukerøkter. Du legger til en version-kolonne, leser den og krever ved oppdatering at versjonen stemmer, samtidig som den økes.

Hvis en annen transaksjon oppdaterte raden først, stemmer ikke versjonen lenger, ingen rader påvirkes, og koden din vet at den må laste inn raden på nytt og prøve igjen. Ingen låser holdes mens brukeren tenker, så samtidigheten forblir høy. Intervjuere liker dette som svar på spørsmålet «Hvordan håndterer du at to brukere redigerer den samme posten?».

-- read: SELECT id, data, version FROM items WHERE id = 1;  -- version = 7
UPDATE items
  SET data = 'new value', version = version + 1
  WHERE id = 1 AND version = 7;
-- if rows affected = 0, someone else changed it: reload and retry

Kort sjekk

Test den viktigste MVCC-formuleringen.

Oppsummering: låser, vranglåser og MVCC

Du kan nå forklare mekanismene bak isolasjon:

  • Delte og eksklusive låser koordinerer tilgang; SELECT FOR UPDATE tar eksplisitte skrivelåser.
  • Vranglåser er låsesykluser; motoren avbryter et offer, og en konsekvent låserekkefølge hindrer de fleste av dem.
  • MVCC beholder radversjoner slik at lesere og skrivere ikke blokkerer hverandre, på bekostning av opprydding (VACUUM, bloat).

Kombiner disse mekanismene med isolasjonsnivåene og anomaliene fra de tidligere leksjonene, så kan du håndtere et helt intervju om samtidighet fra start til slutt.

Gratis å komme i gang

Lær deg SQL med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
30
Leksjoner
120

Ofte stilte spørsmål

Er leksjonen «Deadlocker, låsing og MVCC» gratis?

Ja – hele teksten i «Deadlocker, låsing og MVCC» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Forberedelse til SQL-intervju-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Forberedelse til SQL-intervju inneholder totalt 4 leksjoner.

Hva lærer jeg i «Deadlocker, låsing og MVCC»?

Hvordan databaser unngår konflikter, og avveiningene mellom låsing og øyeblikksbilder. Du øver på Forberedelse til SQL-intervju med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Forberedelse til SQL-intervju?

Ingen tidligere erfaring er nødvendig. Forberedelse til SQL-intervju på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «Deadlocker, låsing og MVCC»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Forberedelse til SQL-intervju-leksjonen?

Ja. Alle Forberedelse til SQL-intervju-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. ACID-egenskapene forklart
  2. De fire isolasjonsnivåene
  3. Skitne, ikke-gjentakbare og fantomlesninger
  4. Deadlocker, låsing og MVCC
← Tilbake til Forberedelse til SQL-intervju