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

Bug dalam mekanisme penguncian PostgreSQL atau kesalahpahaman mekanisme

Tidak ada bug, dan saya rasa Anda tidak salah paham; Anda baru saja melewatkan beberapa keping teka-teki.

Kunci asing diimplementasikan secara internal menggunakan penguncian tingkat baris; mulai dari Postgres 8.1 dan hingga 9.2, setiap kali Anda memperbarui tabel referensi (apples dalam kasus ini), sebuah kueri dijalankan yang melakukan SELECT FOR SHARE pada tabel yang direferensikan (trees ). Sehingga SELECT FOR UPDATE di transaksi pertama blok SELECT FOR SHARE integritas referensial untuk transaksi kedua. Inilah yang menyebabkan blok pada perintah kedua.

Sekarang saya mendengar Anda berteriak, “Tunggu! Kenapa blok pada perintah kedua dan bukan yang pertama? Penjelasannya sederhana, sungguh -- itu hanya karena ada pengoptimalan sederhana yang melewatkan SELECT FOR SHARE internal ketika kunci tidak dimodifikasi. Namun, ini sederhana karena jika Anda memperbarui tupel untuk kedua kalinya, pengoptimalan ini tidak akan aktif karena lebih sulit untuk melacak nilai aslinya. Karenanya penyumbatan.

Anda mungkin juga bertanya-tanya mengapa saya mengatakan ini hingga 9,2 --- ada apa dengan 9,3? Perbedaan utamanya adalah pada 9.3 ia menggunakan SELECT FOR KEY SHARE , yang merupakan level kunci baru yang lebih ringan; itu memungkinkan untuk konkurensi yang lebih baik. Jika Anda mencoba contoh Anda di 9.3 dan juga mengubah SELECT FOR UPDATE untuk SELECT FOR NO KEY UPDATE (yang merupakan mode yang lebih ringan daripada SELECT FOR UPDATE yang mengatakan Anda mungkin akan memperbarui Tuple, tetapi Anda berjanji untuk tidak mengubah kunci utama dan berjanji untuk tidak menghapusnya), Anda akan melihatnya tidak memblokir. (Juga, Anda dapat mencoba UPDATE pada baris yang direferensikan dan jika Anda tidak mengubah kunci utama, maka itu juga tidak akan memblokir.)

Barang 9.3 ini diperkenalkan oleh tambalan oleh Anda benar-benar sebagai http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0ac5ad5134f2769ccbaefec73844f8504c4d6182 dan saya pikir itu adalah peretasan yang cukup keren (Pesan komit memiliki beberapa detail lebih lanjut, jika Anda peduli dengan hal-hal semacam itu). Namun berhati-hatilah, jangan gunakan versi sebelum 9.3.4 karena patch tersebut sangat rumit sehingga beberapa bug serius tidak diketahui dan kami baru saja memperbaikinya baru-baru ini.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres di Rails FATAL:database tidak ada

  2. Alternatif terbaik untuk mengatur skema PostgreSQL menggunakan PHP PDO

  3. FATAL:akar peran tidak ada

  4. Lakukan VACUUM FULL dengan JPA

  5. menghubungkan postgresql dan codeigniter