Câu trả lời:
Xem liên kết của Marko cho các bảng InnoDB và hãy cẩn thận.
Đối với MyISAM, không có giải pháp "đây là truy vấn vi phạm" dễ dàng. Bạn nên luôn luôn bắt đầu với một danh sách quy trình. Nhưng hãy chắc chắn bao gồm từ khóa đầy đủ để các truy vấn được in không bị cắt ngắn:
SHOW FULL PROCESSLIST;
Điều này sẽ cho bạn thấy một danh sách tất cả các quy trình hiện tại, truy vấn SQL và trạng thái của chúng. Bây giờ thông thường nếu một truy vấn duy nhất khiến nhiều người khác khóa thì nó sẽ dễ dàng được xác định. Các truy vấn bị ảnh hưởng sẽ có trạng thái Locked
và truy vấn vi phạm sẽ tự đứng ra, có thể đang chờ một cái gì đó chuyên sâu, như một bảng tạm thời.
Nếu điều đó không rõ ràng thì bạn sẽ phải sử dụng khả năng khấu trừ SQL của mình để xác định đoạn SQL vi phạm nào có thể là nguyên nhân gây ra tai ương của bạn.
Nếu bạn sử dụng InnoDB và cần kiểm tra các truy vấn đang chạy, tôi khuyên bạn nên
show engine innodb status;
như được đề cập trong liên kết của Marko. Điều này sẽ cung cấp cho bạn truy vấn khóa, có bao nhiêu hàng / bảng bị khóa bởi nó, v.v. Xem phần GIAO DỊCH.
Vấn đề với việc sử dụng SHOW PROCESSLIST
là bạn sẽ không thấy các khóa trừ khi các truy vấn khác đang xếp hàng.
Hãy thử SHOW OPEN TABLES
:
show open tables where In_Use > 0 ;
Không có câu trả lời nào có thể hiển thị tất cả các khóa hiện đang được giữ.
Làm điều này, ví dụ như trong mysql trong một thiết bị đầu cuối.
start transaction;
update someTable set name="foobar" where ID=1234;
-- but no rollback or commit - just let it sit there
Rõ ràng giao dịch ở trên giữ một khóa, bởi vì giao dịch vẫn còn hoạt động. Nhưng không có truy vấn nào đang diễn ra ngay bây giờ và không ai đang chờ khóa ở bất cứ đâu (ít nhất là).
INFORMATION_SCHEMA.INNODB_LOCKS
trống rỗng, điều này hợp lý khi được cung cấp tài liệu , bởi vì chỉ có một giao dịch và hiện tại không có ai chờ đợi bất kỳ khóa nào. Cũng INNODB_LOCKS
bị phản đối nào.
SHOW ENGINE INNODB STATUS
là vô dụng: hoàn toàn someTable
không được đề cập
SHOW FULL PROCESSLIST
trống rỗng, vì thủ phạm không thực sự chạy một truy vấn ngay bây giờ.
Bạn có thể sử dụng INFORMATION_SCHEMA.INNODB_TRX
, performance_schema.events_statements_history
và performance_schema.threads
trích xuất các truy vấn mà bất kỳ giao dịch hoạt động đã thực hiện trong quá khứ như được nêu trong câu trả lời khác của tôi , nhưng tôi đã không đi qua bất kỳ cách nào để thấy rằng someTable
bị khóa trong kịch bản trên.
Các đề xuất trong các câu trả lời khác cho đến nay sẽ không giúp được ít nhất.
Tuyên bố miễn trừ trách nhiệm: Tôi chưa cài đặt innotop và tôi không bận tâm. Có lẽ điều đó có thể làm việc.
AFAIK vẫn chưa có cách riêng trong MYSQL, nhưng tôi sử dụng innotop . Nó miễn phí và có nhiều chức năng khác.
Cũng xem liên kết này để biết thêm thông tin về việc sử dụng công cụ innotop.
Bạn có thể sử dụng tập lệnh dưới đây:
SELECT
pl.id
,pl.user
,pl.state
,it.trx_id
,it.trx_mysql_thread_id
,it.trx_query AS query
,it.trx_id AS blocking_trx_id
,it.trx_mysql_thread_id AS blocking_thread
,it.trx_query AS blocking_query
FROM information_schema.processlist AS pl
INNER JOIN information_schema.innodb_trx AS it
ON pl.id = it.trx_mysql_thread_id
INNER JOIN information_schema.innodb_lock_waits AS ilw
ON it.trx_id = ilw.requesting_trx_id
AND it.trx_id = ilw.blocking_trx_id