PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Hindari kunci akses eksklusif pada tabel yang direferensikan saat DROPping di PostgreSQL

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Skrip shell untuk menjalankan perintah pgsql dalam file

  2. Dapatkan daftar semua tabel yang digunakan dalam kueri SELECT Postgresql

  3. Oracle's OUTER JOIN (+) pada string - Migrasi PostgreSQL

  4. COPY CSV Postgres dari/impor tidak menghormati header CSV

  5. GROUP BY dan COUNT menggunakan ActiveRecord