Bagi siapa saja yang mencari dan mencoba memahami mengapa tabel drop mereka (atau drop foreign key atau menambahkan kunci asing) macet untuk waktu yang lama:
PostgreSQL (Saya melihat versi 9.4 hingga 13) kendala kunci asing sebenarnya diimplementasikan menggunakan pemicu di kedua ujung kunci asing .
Jika Anda memiliki tabel perusahaan (id sebagai primary key) dan tabel bank_account (id sebagai primary key, company_id sebagai foreign key yang menunjuk ke company.id), maka sebenarnya ada 2 trigger pada tabel bank_account dan juga 2 trigger pada perusahaan tabel.
nama_tabel | waktu | nama_pemicu | nama_fungsi |
---|---|---|---|
rekening bank | SETELAH PEMBARUAN | RI_ConstraintTrigger_c_1515961 | RI_FKey_check_upd |
rekening bank | SETELAH MASUKKAN | RI_ConstraintTrigger_c_1515960 | RI_FKey_check_ins |
perusahaan | SETELAH PEMBARUAN | RI_ConstraintTrigger_a_1515959 | RI_FKey_noaction_upd |
perusahaan | SETELAH DELETE | RI_ConstraintTrigger_a_1515958 | RI_FKey_noaction_del |
Pembuatan awal pemicu tersebut (saat membuat kunci foreing) memerlukan kunci SHARE ROW EKSKLUSIF pada tabel tersebut (dulu adalah kunci ACCESS EKSKLUSIF di versi 9.4 dan sebelumnya). Kunci ini tidak bertentangan dengan "kunci pembacaan data", tetapi akan bertentangan dengan semua kunci lainnya, misalnya INSERT/UPDATE/DELETE sederhana ke dalam tabel perusahaan.
Penghapusan pemicu tersebut (saat menjatuhkan kunci asing, atau seluruh tabel) memerlukan kunci ACCESS EKSKLUSIF pada tabel tersebut. Kunci ini bertentangan dengan setiap kunci lainnya!
Jadi bayangkan sebuah skenario, di mana Anda menjalankan transaksi A yang pertama kali melakukan SELECT sederhana dari tabel perusahaan (menyebabkannya menahan kunci ACCESS SHARE untuk tabel perusahaan hingga transaksi dilakukan atau dibatalkan) dan sekarang melakukan beberapa pekerjaan lain untuk 3 menit. Anda mencoba untuk menjatuhkan tabel bank_account dalam transaksi B. Ini membutuhkan kunci ACCESS EXCLUSIVE, yang harus menunggu sampai kunci ACCESS SHARE dilepaskan terlebih dahulu. Selain itu semua transaksi lain, yang ingin mengakses tabel perusahaan (cukup PILIH, atau mungkin INSERT/UPDATE/DELETE), akan antri untuk menunggu di kunci ACCESS EXCLUSIVE, yang menunggu di kunci ACCESS SHARE.
Transaksi yang berjalan lama dan perubahan DDL memerlukan penanganan yang cermat.