PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Lỗi trong cơ chế khóa PostgreSQL hoặc hiểu sai về cơ chế

Không có lỗi, và tôi không nghĩ rằng bạn đang hiểu sai bất cứ điều gì; bạn chỉ còn thiếu một vài mảnh ghép của câu đố.

Khóa ngoại được triển khai nội bộ bằng cách sử dụng khóa cấp hàng; bắt đầu từ Postgres 8.1 và lên đến 9.2, bất cứ khi nào bạn cập nhật bảng tham chiếu (apples trong trường hợp này), một truy vấn được kích hoạt SELECT FOR SHARE trên bảng được tham chiếu (trees ). Vì vậy, SELECT FOR UPDATE trong giao dịch đầu tiên chặn SELECT FOR SHARE về tính toàn vẹn tham chiếu cho giao dịch thứ hai. Đây là nguyên nhân gây ra khối trong lệnh thứ hai.

Bây giờ tôi nghe thấy bạn hét lên, "Chờ đã! Tại sao nó lại chặn lệnh thứ hai chứ không phải lệnh đầu tiên? Thực sự thì lời giải thích rất đơn giản - đó chỉ là vì có một tính năng tối ưu hóa đơn giản bỏ qua SELECT FOR SHARE nội bộ khi khóa không được sửa đổi. Tuy nhiên, điều này đơn giản ở chỗ nếu bạn cập nhật một tuple lần thứ hai, tính năng tối ưu hóa này sẽ không kích hoạt vì khó theo dõi các giá trị ban đầu hơn. Do đó bị tắc nghẽn.

Bạn cũng có thể thắc mắc tại sao tôi lại nói con số này lên đến 9.2 --- còn 9.3 thì sao? Sự khác biệt chính là trong 9.3 nó sử dụng SELECT FOR KEY SHARE , là một cấp độ khóa mới, nhẹ hơn; nó cho phép đồng thời tốt hơn. Nếu bạn thử ví dụ của mình trong 9.3 và cũng thay đổi SELECT FOR UPDATE thành SELECT FOR NO KEY UPDATE (là chế độ nhẹ hơn SELECT FOR UPDATE điều đó nói rằng bạn có thể sẽ cập nhật bộ tuple, nhưng bạn hứa sẽ không sửa đổi khóa chính và hứa không xóa nó), bạn sẽ thấy nó không chặn. (Ngoài ra, bạn có thể thử CẬP NHẬT trên hàng được tham chiếu và nếu bạn không sửa đổi khóa chính, thì khóa đó cũng sẽ không bị chặn.)

Nội dung 9.3 này được giới thiệu bởi một bản vá của bạn thực sự là http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0ac5ad5134f2769ccbaefec73844f8504c4d6182 và tôi nghĩ đó là một vụ hack khá hay (Thông báo cam kết có thêm một số chi tiết, nếu bạn quan tâm đến loại nội dung đó). Nhưng hãy cẩn thận, không sử dụng các phiên bản trước 9.3.4 vì bản vá đó rất phức tạp nên một số lỗi nghiêm trọng không được chú ý và chúng tôi chỉ sửa gần đây.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để thiết lập cơ sở dữ liệu Postgres cho dự án Rails cục bộ?

  2. Phương ngữ cần được cung cấp rõ ràng kể từ v4.0.0

  3. postgres đến MS Access

  4. postgresql kết hợp nhiều khoảng thời gian thành một

  5. cửa sổ trượt sql - tìm giá trị tối đa trong khoảng thời gian