Câu trả lời trực tiếp cho tiêu đề câu hỏi của bạn là Không.
Các truy vấn CHỌN có thể thực hiện các khóa trên gen_clust_index , còn gọi là Chỉ mục cụm.
Dưới đây là ba câu hỏi trao đổi ngăn xếp DBA mà tôi đã xem xét kỹ lưỡng với @RedBlueThing , người đã hỏi những câu hỏi này. @RedBlueThing tìm thấy công việc xung quanh câu hỏi của mình.
Chỉ cần giữ câu hỏi của bạn trong bối cảnh, khi bạn xem qua các câu trả lời này (đừng nhìn quá sâu, thậm chí tôi còn bị chóng mặt khi nhìn vào câu trả lời phức tạp của chính mình), rõ ràng là các truy vấn CHỌN có thể khóa dữ liệu.
Bạn cũng có các trường hợp đặc biệt của CHỌN nơi bạn có thể khóa các hàng cụ thể theo yêu cầu .
CẬP NHẬT 2011-08-08 16:49 EDT
Bạn đã hỏi câu hỏi biến thể: "Các ngoại lệ bế tắc của InnoDB có thể bị ném bởi CHỌN" Câu trả lời cho điều đó có thể là Có trong một điều kiện nhất định. Tình trạng đó là gì? Nếu chỉ một câu lệnh SQL được khôi phục do lỗi, một số khóa được đặt bởi câu lệnh có thể được giữ nguyên. Điều này xảy ra vì InnoDB lưu trữ các khóa hàng theo định dạng sao cho không thể biết sau đó khóa nào được đặt bởi câu lệnh nào .
Dựa trên tuyên bố đó, các chuỗi sự kiện gây ra điều này về mặt lý thuyết có thể như sau:
- SQL của bạn CẬP NHẬT một hàng duy nhất nhưng tạo ra lỗi
- CẬP NHẬT gây ra sự quay trở lại của một hàng
- Hàng có khóa kéo dài
Cá nhân, tuyên bố cuối cùng đó làm tôi sợ. Thật là tốt khi MySQL thông báo cho mọi người về điều này. Tuy nhiên, tuyên bố đó là từ Tài liệu MySQL. (Ồ vâng, Oracle sở hữu InnoDB)
CẬP NHẬT 2015-09-22 18:40 EST
Đầu năm ngoái, tôi đã biết rằng Percona có một kiểm tra Nagios thú vị để tìm ra những ổ khóa phiền phức này ẩn đằng sau các kết nối ngủ. Tất cả bạn phải làm bây giờ là chạy mã từ liên kết đó:
SELECT COALESCE(MAX(IF(p.command = 'Sleep', p.time, 0)), 0) AS idle_in_trx
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS b ON b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS r ON r.trx_id = w.requesting_trx_id
LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST AS p ON p.id = b.trx_mysql_thread_id;
Điều này sẽ chỉ hoạt động cho MySQL 5.5+. Nếu bạn có MySQL 5.1 hoặc trước đó, bạn phải hủy tất cả các kết nối đang ngủ để giải phóng các khóa.