Điều gì gây ra khóa bảng trong MySQL?
Tất cả các bảng đang mở trong bộ nhớ cache của bảng đều được liệt kê, nhưng cột Show Tất cả các khóa trong MySQL đều không có bế tắc, ngoại trừ các bảng loại InnoDB và BDB. Điều này được quản lý bằng cách luôn yêu cầu tất cả các khóa cần thiết cùng một lúc khi bắt đầu truy vấn và luôn khóa các bảng theo cùng một thứ tự Các bảng loại InnoDB tự động có được các khóa hàng của chúng và các bảng loại BDB khóa trang của chúng trong quá trình xử lý các câu lệnh SQL, không phải khi bắt đầu giao dịch Phương thức khóa mà MySQL sử dụng cho các khóa VIẾT hoạt động như sau
Phương thức khóa mà MySQL sử dụng cho khóa READ hoạt động như sau
Khi khóa được giải phóng, khóa sẽ được cung cấp cho các luồng trong hàng đợi khóa ghi, sau đó đến các luồng trong hàng đợi khóa đọc Điều này có nghĩa là nếu bạn có nhiều bản cập nhật trên một bảng, câu lệnh SELECT sẽ đợi cho đến khi không còn bản cập nhật nào nữa Để giải quyết vấn đề này trong trường hợp bạn muốn thực hiện nhiều thao tác CHÈN và CHỌN trên một bảng, bạn có thể chèn các hàng vào một bảng tạm thời và thỉnh thoảng cập nhật bảng thực với các bản ghi từ bảng tạm thời Điều này có thể được thực hiện với đoạn mã sau mysql> LOCK TABLES real_table WRITE, insert_table WRITE; mysql> INSERT INTO real_table SELECT * FROM insert_table; mysql> TRUNCATE TABLE insert_table; mysql> UNLOCK TABLES; Bạn có thể sử dụng các tùy chọn LOW_PRIORITY với INSERT, UPDATE hoặc DELETE hoặc HIGH_PRIORITY với SELECT nếu bạn muốn ưu tiên truy xuất trong một số trường hợp cụ thể. Bạn cũng có thể bắt đầu mysqld với --low-priority-updates để có hành vi tương tự Sử dụng SQL_BUFFER_RESULT cũng có thể giúp khóa bảng ngắn hơn. Thấy Bạn cũng có thể thay đổi mã khóa trong Mã khóa bảng trong MySQL không có bế tắc MySQL sử dụng khóa bảng (thay vì khóa hàng hoặc khóa cột) trên tất cả các loại bảng, ngoại trừ bảng InnoDB và BDB, để đạt được tốc độ khóa rất cao. Đối với các bảng lớn, khóa bảng tốt hơn nhiều so với khóa hàng đối với hầu hết các ứng dụng, nhưng tất nhiên, vẫn có một số cạm bẫy Đối với các bảng InnoDB và BDB, MySQL chỉ sử dụng khóa bảng nếu bạn khóa bảng một cách rõ ràng bằng LOCK TABLES. Đối với các loại bảng này, chúng tôi khuyên bạn hoàn toàn không nên sử dụng LOCK TABLES vì InnoDB sử dụng khóa cấp độ hàng tự động và BDB sử dụng khóa cấp độ trang để đảm bảo cách ly giao dịch Trong phiên bản MySQL 3. 23. 7 trở lên, bạn có thể chèn hàng vào bảng MyISAM cùng lúc với các luồng khác đang đọc từ bảng. Lưu ý rằng hiện tại điều này chỉ hoạt động nếu không có lỗ hổng nào sau khi các hàng đã bị xóa trong bảng tại thời điểm chèn được thực hiện. Khi tất cả các lỗ đã được lấp đầy bằng dữ liệu mới, các lần chèn đồng thời sẽ tự động được bật lại Khóa bảng cho phép nhiều luồng đọc từ một bảng cùng một lúc, nhưng nếu một luồng muốn ghi vào bảng, trước tiên nó phải có quyền truy cập độc quyền. Trong quá trình cập nhật, tất cả các chủ đề khác muốn truy cập vào bảng cụ thể này sẽ đợi cho đến khi bản cập nhật sẵn sàng Vì các cập nhật trên bảng thường được coi là quan trọng hơn CHỌN, nên tất cả các câu lệnh cập nhật bảng đều có mức độ ưu tiên cao hơn các câu lệnh truy xuất thông tin từ bảng. Điều này sẽ đảm bảo rằng các bản cập nhật không bị 'bỏ đói' vì một bản phát hành rất nhiều truy vấn nặng đối với một bảng cụ thể. (Bạn có thể thay đổi điều này bằng cách sử dụng LOW_PRIORITY với câu lệnh thực hiện cập nhật hoặc HIGH_PRIORITY với câu lệnh SELECT. ) Bắt đầu từ MySQL Phiên bản 3. 23. 7, người ta có thể sử dụng biến max_write_lock_count để buộc MySQL tạm thời cung cấp cho tất cả các câu lệnh CHỌN chờ bảng có mức độ ưu tiên cao hơn sau một số lần chèn cụ thể trên bảng Tuy nhiên, khóa bảng không tốt lắm trong trường hợp sau
Một số giải pháp khả thi cho vấn đề này là
|