2012-07-04 29 views
10

Tôi đang cố gắng hiểu một bế tắc do MySQL tìm thấy trong các khách hàng đồng thời xử lý trên cùng một bảng. Đây là một phần thú vị của "HIỂN THỊ InnoDB TRẠNG THÁI" lệnh:Đang cố gắng hiểu về bế tắc MySQL trên bảng InnoDB

------------------------ 
LATEST DETECTED DEADLOCK 
------------------------ 
120704 16:17:51 
*** (1) TRANSACTION: 
TRANSACTION 0 3547576, ACTIVE 0 sec, process no 10886, OS thread id 140547111458560 inserting 
mysql tables in use 1, locked 1 
LOCK WAIT 2 lock struct(s), heap size 368, 1 row lock(s), undo log entries 1 
MySQL thread id 41941, query id 1725666 localhost testsuite update 
insert into `INode` (`status`,`_type`,`group`,`ctime`,`parent`,`shared`,`basename`,`_rowid`,`displayname`,`user`,`content_type`,`mtime`,`position`,`atime`,`size`) values ('Published','Group','12','2012-07-04 16:17:48.996869','2',null,'1','12','1','3','application/x-empty','2012-07-04 16:17:48.996896','1','2012-07-04 16:17:48.996914',null) 
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 5554 n bits 80 index `INodeparent_basename` of table `testsuite`.`INode` trx id 0 3547576 lock mode S waiting 
Record lock, heap no 12 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 80000002; asc  ;; 1: len 1; hex 31; asc 1;; 2: len 4; hex 8000000b; asc  ;; 

*** (2) TRANSACTION: 
TRANSACTION 0 3547575, ACTIVE 0 sec, process no 10886, OS thread id 140547107845888 inserting, thread declared inside InnoDB 493 
mysql tables in use 1, locked 1 
13 lock struct(s), heap size 3024, 17 row lock(s), undo log entries 21 
MySQL thread id 41940, query id 1725808 localhost testsuite update 
replace into `INode` (`status`,`_type`,`position`,`group`,`ctime`,`parent`,`basename`,`_rowid`,`displayname`,`user`,`content_type`,`mtime`,`shared`,`atime`,`size`) values ('Published','Group','0','2','2012-07-04 16:17:49','1','groups','2','admin','3','application/x-empty','2012-07-04 16:17:49',null,'2012-07-04 16:17:49',null),('Published','Group','1','11','2012-07-04 16:17:51.064074','2','1','11','1','3','inode/directory','2012-07-04 16:17:51.064074',null,'2012-07-04 16:17:51.064074',null) 
*** (2) HOLDS THE LOCK(S): 
RECORD LOCKS space id 0 page no 5554 n bits 80 index `INodeparent_basename` of table `testsuite`.`INode` trx id 0 3547575 lock_mode X locks rec but not gap 
Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 80000001; asc  ;; 1: len 6; hex 67726f757073; asc groups;; 2: len 4; hex 80000002; asc  ;; 

Record lock, heap no 12 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 80000002; asc  ;; 1: len 1; hex 31; asc 1;; 2: len 4; hex 8000000b; asc  ;; 

*** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 5554 n bits 80 index `INodeparent_basename` of table `testsuite`.`INode` trx id 0 3547575 lock_mode X waiting 
Record lock, heap no 12 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 80000002; asc  ;; 1: len 1; hex 31; asc 1;; 2: len 4; hex 8000000b; asc  ;; 

*** WE ROLL BACK TRANSACTION (1) 

Những gì tôi hiểu từ nhật ký này là các giao dịch (1) đang chờ đợi để có được một khóa chia sẻ trên các chỉ số INodeparent_basename của bảng testsuite. INode. Bây giờ, giao dịch (2) có một khóa độc quyền trên cùng một chỉ mục này. Nhưng điều kỳ lạ, đó là giao dịch (2) cũng đang chờ một khóa X trên bảng đã cho. Tại sao vậy? Nếu giao dịch (2) đã có khóa, tại sao nó chờ đợi?

(nói chung, tôi đã không tìm thấy bất kỳ tài liệu nào chính xác giải thích làm thế nào để đọc các đầu ra của lệnh tình trạng - nó sẽ rất thú vị nếu ai đó có thể chỉ ra rằng đối với tôi quá)

+0

Bạn có tìm thấy câu trả lời cho điều này không? Tôi có cùng một vấn đề. –

+0

Không, tôi không thể tìm thấy câu trả lời cho vấn đề này. Sau khi tôi đã thử một vài giờ để hiểu nó, tôi chỉ phải mã hóa các quy trình khác nhau và lập trình tuần tự hóa một phần truy cập vào cơ sở dữ liệu để tránh bất kỳ tình trạng bế tắc nào có thể được tìm thấy bởi MySQL. Hiệu suất khôn ngoan có lẽ tồi tệ hơn, nhưng tôi không có bất kỳ khả năng nào khác. – RedGlow

+0

Về cách dịch đầu ra lệnh trạng thái, bạn (hoặc bất kỳ người nào khác cần trợ giúp về điều này) có thể muốn kiểm tra blog này mà tôi đã tìm thấy https://www.percona.com/blog/2014/10/28/how- to-deal-with-mysql-deadlocks/ – CodeBurner

Trả lời

1

Trong trường hợp này, giao dịch 2 đã mua một khóa chia sẻ cho một tuyên bố trước đó (* (2) GIỮ KHÓA (S) :)

Sau đó, giao dịch 1 đã cố gắng để có được một khóa độc quyền trên cùng một hàng, và đang đợi khóa chia sẻ cần xóa.

Sau đó, giao dịch 2, trong một tuyên bố khác, đã cố gắng để có được một khóa độc quyền trên cùng một hàng. Đã xảy ra bế tắc.

+0

Không, (2) đã có khóa độc quyền. (1) đang cố gắng để có được một khóa chia sẻ ngươi. –

-1

Tôi không biết liệu nó có giúp ích hay không, nhưng một điều cần xem xét là chuỗi các hoạt động gây ra khóa. Dường như ở một địa điểm của ứng dụng bạn đang tạo ổ khóa như

Bảng 1 Bảng 2

và trong một làm

Bảng 2 Bảng 1 (chỉ là ví dụ)

Without nhìn thấy mã thực tế, tôi khuyên bạn nên xem xét những thứ như thế này và đảm bảo bạn thực hiện chúng trong cùng một chuỗi làm việc/cập nhật/chèn hồ sơ để tất cả chúng hoạt động giống như

chèn/cập nhật từ bảng 1 sau đó chèn/cập nhật bảng 2

Bằng cách này, khóa đầu tiên luôn luôn được cố gắng trên bảng 1 đầu tiên .. nếu không thể đi, sau đó nó thậm chí không thử bảng 2 cho đến khi bảng 1 được phát hành.

Sau đó, áp dụng bất kỳ thay đổi nào cho bảng 2 và hoàn tất giao dịch của bạn. Khi cả hai bảng 2 và 1 sau đó được phát hành, giao dịch tiếp theo chờ phát hành trên bảng 1 có thể tiến hành.

Các vấn đề liên quan