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.