sql >> Databasteknik >  >> RDS >> PostgreSQL

Undvik exklusiva åtkomstlås på refererade tabeller när du DROPpar i PostgreSQL

För alla som googlar och försöker förstå varför deras släpptabell (eller släpp främmande nyckel eller lägg till främmande nyckel) har fastnat under en lång tid:

PostgreSQL (Jag tittade på version 9.4 till 13) Begränsningar för främmande nyckel implementeras faktiskt med hjälp av utlösare i båda ändarna av den främmande nyckeln .

Om du har en företagstabell (id som primärnyckel) och en bankkontotabell (id som primärnyckel, företags-id som främmande nyckel som pekar på företag.id), så finns det faktiskt 2 utlösare på bankkontotabellen och även 2 utlösare på företaget bord.

tabellnamn timing trigger_name funktionsnamn
bankkonto EFTER UPPDATERING RI_ConstraintTrigger_c_1515961 RI_FKey_check_upd
bankkonto EFTER INFOGA RI_ConstraintTrigger_c_1515960 RI_FKey_check_ins
företag EFTER UPPDATERING RI_ConstraintTrigger_a_1515959 RI_FKey_noaction_upd
företag EFTER DELETE RI_ConstraintTrigger_a_1515958 RI_FKey_noaction_del

Initialt skapande av dessa utlösare (när man skapar den första nyckeln) kräver SHARE ROW EXCLUSIVE-lås på dessa tabeller (det brukade vara ACCESS EXCLUSIVE-lås i version 9.4 och tidigare). Detta lås kommer inte i konflikt med "dataläsningslås", men kommer i konflikt med alla andra lås, till exempel en enkel INFOGA/UPPDATERA/RADERA i företagstabellen.

Radering av dessa utlösare (när den främmande nyckeln släpps, eller hela tabellen) kräver EXKLUSIVT ÅTKOMST lås på dessa tabeller. Detta lås är i konflikt med alla andra lås!

Så föreställ dig ett scenario där du har en transaktion A igång som först gjorde en enkel SELECT från företagstabell (som fick den att hålla ett ACCESS SHARE-lås för företagstabellen tills transaktionen har genomförts eller återställts) och nu gör en del annat arbete för 3 minuter. Du försöker släppa tabellen bank_account i transaktion B. Detta kräver ACCESS EXCLUSIVE-lås, som måste vänta tills ACCESS SHARE-låset släpps först. Utöver det alla andra transaktioner som vill komma åt företagstabellen (bara VÄLJ, eller kanske INSERT/UPDATE/DELETE), kommer att stå i kö för att vänta på ACCESS EXCLUSIVE-låset, som väntar på ACCESS SHARE-låset.

Långa transaktioner och DDL-ändringar kräver känslig hantering.



  1. Lägg till backticks i att skapa tabell till mysql med csv-filen -PHP

  2. Räkna förekomster baserat på flera villkor för två tabeller

  3. Hur man hämtar poster som innehåller alfanumeriska tecken + blanksteg

  4. ODBC 4.0