Dla każdego, kto googluje i próbuje zrozumieć, dlaczego ich tablica upuszczania (lub upuszczanie klucza obcego lub dodawanie klucza obcego) utknęła na długi czas:
PostgreSQL (Spojrzałem na wersje od 9.4 do 13) Ograniczenia klucza obcego są faktycznie implementowane przy użyciu wyzwalaczy na obu końcach klucza obcego .
Jeśli masz tabelę firmy (id jako klucz podstawowy) i tabelę bank_account (id jako klucz podstawowy, company_id jako klucz obcy wskazujący na company.id), to w rzeczywistości są 2 wyzwalacze w tabeli bank_account, a także 2 wyzwalacze w firmie tabela.
nazwa_tabeli | czas | nazwa_wyzwalacza | nazwa_funkcji |
---|---|---|---|
konto_bankowe | PO AKTUALIZACJI | RI_ConstraintTrigger_c_1515961 | RI_FKey_check_upd |
konto_bankowe | PO WSTAWIENNIU | RI_ConstraintTrigger_c_1515960 | RI_FKey_check_ins |
firma | PO AKTUALIZACJI | RI_ConstraintTrigger_a_1515959 | RI_FKey_noaction_upd |
firma | PO USUNIĘCIU | RI_ConstraintTrigger_a_1515958 | RI_FKey_noaction_del |
Początkowe tworzenie tych wyzwalaczy (podczas tworzenia klucza foreing) wymaga blokady SHARE ROW EXCLUSIVE na tych tabelach (wcześniej była to blokada ACCESS EXCLUSIVE w wersji 9.4 i wcześniejszych). Ta blokada nie powoduje konfliktu z „blokadami odczytu danych”, ale będzie powodować konflikty ze wszystkimi innymi blokadami, na przykład prostym INSERT/UPDATE/DELETE do tabeli firmowej.
Usunięcie tych wyzwalaczy (w przypadku usunięcia klucza obcego lub całej tabeli) wymaga blokady ACCESS EXCLUSIVE na tych tabelach. Ta blokada jest w konflikcie z każdą inną blokadą!
Wyobraź sobie więc scenariusz, w którym masz uruchomioną transakcję A, która najpierw wykonała prosty SELECT z tabeli firmowej (powodując, że utrzymuje blokadę ACCESS SHARE dla tabeli firmowej do czasu zatwierdzenia lub wycofania transakcji), a teraz wykonuje inną pracę dla 3 minuty. Próbujesz usunąć tabelę bank_account w transakcji B. Wymaga to blokady ACCESS EXCLUSIVE, która będzie musiała najpierw poczekać na zwolnienie blokady ACCESS SHARE. Dodatkowo wszystkie inne transakcje, które chcą uzyskać dostęp do tabeli firmowej (wystarczy SELECT, a może INSERT/UPDATE/DELETE), zostanie umieszczony w kolejce, aby czekać na blokadzie ACCESS EXCLUSIVE, która czeka na blokadzie ACCESS SHARE.
Długotrwałe transakcje i zmiany DDL wymagają delikatnej obsługi.