sql >> Database teknologi >  >> RDS >> PostgreSQL

Fejl i PostgreSQL-låsemekanismen eller misforståelse af mekanismen

Der er ingen fejl, og jeg tror ikke, du misforstår noget; du mangler lige et par brikker i puslespillet.

Fremmednøgler implementeres internt ved hjælp af række-niveau låsning; startende fra Postgres 8.1 og op til 9.2, hver gang du opdaterer referencetabellen (apples i dette tilfælde) udløses en forespørgsel, der gør SELECT FOR SHARE på den refererede tabel (trees ). Så SELECT FOR UPDATE i den første transaktion blokerer SELECT FOR SHARE af den referencemæssige integritet for den anden transaktion. Det er det, der forårsager blokeringen i den anden kommando.

Nu hører jeg dig råbe:"Vent! Hvorfor blokerer den for den anden kommando og ikke den første? Forklaringen er egentlig simpel -- det er bare fordi der er en simpel optimering, der springer den interne SELECT FOR SHARE over. når nøglen ikke bliver ændret. Dette er dog forenklet ved, at hvis du opdaterer en tuple en anden gang, vil denne optimering ikke udløses, fordi det er sværere at spore de oprindelige værdier. Derfor blokeringen.

Du undrer dig måske også over, hvorfor jeg sagde, at dette er op til 9,2 --- hvad er der med 9,3? Den største forskel er, at den i 9.3 bruger SELECT FOR KEY SHARE , som er et nyt, lettere låseniveau; det giver mulighed for bedre samtidighed. Hvis du prøver dit eksempel i 9.3 og også ændrer SELECT FOR UPDATE til SELECT FOR NO KEY UPDATE (som er en lettere tilstand end SELECT FOR UPDATE der siger, at du måske vil opdatere tuplen, men du lover ikke at ændre den primære nøgle og lover ikke at slette den), skal du se, at den ikke blokerer. (Du kan også prøve en OPDATERING på den refererede række, og hvis du ikke ændrer den primære nøgle, vil den heller ikke blokere.)

Dette 9.3-stof blev introduceret af en patch fra yours truly som http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0ac5ad5134f2769ccbaefec73844f8504c4d6182 og jeg synes, det var et ret sejt hack (Commit-beskeden har nogle flere detaljer, hvis du bekymrer dig om den slags). Men pas på, brug ikke versioner før 9.3.4, fordi den patch var så enormt kompleks, at nogle få alvorlige fejl gik ubemærket hen, og vi fik først rettet for nylig.




  1. DBMS_PARALLEL_EXECUTE og indirekte givet bevillinger på procedure

  2. Pgbackrest Gendan og gendan Delta

  3. RowGen v3 automatiserer generering af databasetestdata

  4. Kører Java-program fra Linux kommandolinje, der kræver en ekstra fil