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

Undgå eksklusive adgangslåse på refererede tabeller ved DROPping i PostgreSQL

For alle, der googler og prøver at forstå, hvorfor deres drop-tabel (eller drop fremmednøgle eller tilføje fremmednøgle) har siddet fast i lang tid:

PostgreSQL (Jeg så på version 9.4 til 13) fremmednøglebegrænsninger implementeres faktisk ved hjælp af triggere i begge ender af fremmednøglen .

Hvis du har en virksomhedstabel (id som primærnøgle) og en bankkontotabel (id som primærnøgle, virksomheds-id som fremmednøgle, der peger på virksomhed.id), så er der faktisk 2 triggere på bankkontotabellen og også 2 triggere på virksomheden tabel.

tabelnavn timing trigger_name funktionsnavn
bankkonto EFTER OPDATERING RI_ConstraintTrigger_c_1515961 RI_FKey_check_upd
bankkonto EFTER INDSÆTNING RI_ConstraintTrigger_c_1515960 RI_FKey_check_ins
virksomhed EFTER OPDATERING RI_ConstraintTrigger_a_1515959 RI_FKey_noaction_upd
virksomhed EFTER SLETNING RI_ConstraintTrigger_a_1515958 RI_FKey_noaction_del

Indledende oprettelse af disse triggere (når du opretter foreing-nøglen) kræver SHARE ROW EXCLUSIVE-lås på disse tabeller (det plejede at være ACCESS EXCLUSIVE-lås i version 9.4 og tidligere). Denne lås er ikke i konflikt med "datalæselåse", men vil være i konflikt med alle andre låse, for eksempel en simpel INSERT/OPDATERING/SLET i firmatabel.

Sletning af disse triggere (når du taber fremmednøglen eller hele bordet) kræver EKSKLUSIV ADGANG lås på disse borde. Denne lås er i konflikt med hver anden lås!

Så forestil dig et scenarie, hvor du har en transaktion A kørende, der først lavede en simpel SELECT from company table (som fik den til at holde en ACCESS SHARE-lås for virksomhedstabellen, indtil transaktionen er forpligtet eller rullet tilbage) og nu udfører noget andet arbejde for 3 minutter. Du forsøger at droppe bankkontotabellen i transaktion B. Dette kræver ACCESS EXCLUSIVE-lås, som skal vente, indtil ACCESS SHARE-låsen frigives først. Derudover alle andre transaktioner, som ønsker at få adgang til firmatabellen (bare VÆLG, eller måske INSERT/UPDATE/DELETE), vil stå i kø for at vente på ACCESS EXCLUSIVE-låsen, som venter på ACCESS SHARE-låsen.

Langvarige transaktioner og DDL-ændringer kræver skånsom håndtering.



  1. MySQL slutter sig til to borde, find max antal og bestil efter

  2. Batch-indsatser med PHP

  3. Vil du oprette en lagret procedure, der skal tilføjes med automatisk stigning som primært felt?

  4. Forårsdataforespørgsel for localdate returnerer forkerte indtastninger - minus én dag