Đối với bất kỳ ai đang sử dụng googling và cố gắng tìm hiểu lý do tại sao drop table của họ (hoặc bỏ khóa ngoại hoặc thêm khóa ngoại) bị kẹt trong một thời gian dài:
PostgreSQL (Tôi đã xem xét các phiên bản 9.4 đến 13) các ràng buộc khóa ngoại thực sự được triển khai bằng cách sử dụng trình kích hoạt ở cả hai đầu của khóa ngoại .
Nếu bạn có bảng công ty (id là khóa chính) và bảng bank_account (id là khóa chính, company_id là khóa ngoại trỏ đến company.id), thì thực tế có 2 trình kích hoạt trên bảng bank_account và cũng có 2 trình kích hoạt trên công ty bảng.
table_name | thời gian | trigger_name | function_name |
---|---|---|---|
bank_account | SAU CẬP NHẬT | RI_ConstraintTrigger_c_1515961 | RI_FKey_check_upd |
bank_account | SAU KHI CHÈN | RI_ConstraintTrigger_c_1515960 | RI_FKey_check_ins |
công ty | SAU CẬP NHẬT | RI_ConstraintTrigger_a_1515959 | RI_FKey_noaction_upd |
công ty | SAU KHI XÓA | RI_ConstraintTrigger_a_1515958 | RI_FKey_noaction_del |
Việc tạo ban đầu các trình kích hoạt đó (khi tạo khóa phía trước) yêu cầu khóa SHARE ROW EXCLUSIVE trên các bảng đó (nó từng là khóa ACCESS EXCLUSIVE trong phiên bản 9.4 trở về trước). Khóa này không xung đột với "khóa đọc dữ liệu", nhưng sẽ xung đột với tất cả các khóa khác, ví dụ:CHÈN / CẬP NHẬT / XÓA đơn giản vào bảng công ty.
Việc xóa các trình kích hoạt đó (khi thả khóa ngoại hoặc toàn bộ bảng) yêu cầu khóa TRUY CẬP ĐỘC QUYỀN trên các bảng đó. Khóa này xung đột với mọi khóa khác!
Vì vậy, hãy tưởng tượng một tình huống, trong đó bạn có một giao dịch A đang chạy mà lần đầu tiên thực hiện một lệnh CHỌN đơn giản từ bảng công ty (khiến nó giữ khóa CHIA SẺ TRUY CẬP cho bảng công ty cho đến khi giao dịch được cam kết hoặc khôi phục) và bây giờ đang thực hiện một số công việc khác cho 3 phút. Bạn cố gắng bỏ bảng bank_account trong giao dịch B. Điều này yêu cầu khóa ACCESS EXCLUSIVE, điều này sẽ cần phải đợi cho đến khi khóa ACCESS SHARE được phát hành trước. hoặc có thể CHÈN / CẬP NHẬT / XÓA), sẽ được xếp hàng đợi trên khóa TRUY CẬP ĐỘC QUYỀN, đang chờ trên khóa CHIA SẺ TRUY CẬP.
Các giao dịch lâu dài và các thay đổi DDL yêu cầu xử lý tinh vi.