2013-07-04 7 views
1

Google의 복잡한 테이블 중 하나에서 교착 상태와 관련된 오류를 해결하려고합니다. 교착 상태에 대해 this SO question을 읽었으며 이해가되지만 쿼리 순서가 내 경우에는 원인이 아닌 것 같습니다. 여기 동일한 쿼리로 교착 상태가 발생했습니다.

SHOW ENGINE INNODB STATUS;의 축약 출력입니다 :

*** (1) TRANSACTION: 
TRANSACTION 1 2611184895, ACTIVE 0 sec, process no 17501, OS thread id 140516779579136 starting index read 
mysql tables in use 1, locked 1 
LOCK WAIT 2 lock struct(s), heap size 368, 1 row lock(s) 
MySQL thread id 211935717, query id 3146186174 [SERVER A] Searching rows for update 

UPDATE images_unread_comments 
    SET unread = 0 
    WHERE user_id = 1 AND comment_id IN(1,2,3) AND unread = 1 

*** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 404976 n bits 632 index `users_unread_comments` of table images_unread_comments trx id 1 2611184895 lock_mode X waiting 
Record lock, heap no 558 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d888; asc g ;; 

*** (2) TRANSACTION: 
TRANSACTION 1 2611184892, ACTIVE 0 sec, process no 17501, OS thread id 140516774520576 updating or deleting, thread declared inside InnoDB 494 
mysql tables in use 1, locked 1 
6 lock struct(s), heap size 1216, 11 row lock(s), undo log entries 1 
MySQL thread id 211935715, query id 3146186169 [SERVER B] Updating 

UPDATE images_unread_comments 
    SET unread = 0 
    WHERE user_id = 1 AND comment_id IN(1,2,3) AND unread = 1 
    *** (2) HOLDS THE LOCK(S): 
RECORD LOCKS space id 0 page no 404976 n bits 632 index users_unread_comments of table images_unread_comments trx id 1 2611184892 lock_mode X 
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 
0: len 8; hex 73757072656d756d; asc supremum;; 

Record lock, heap no 555 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67daf0; asc g ;; 

Record lock, heap no 556 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67dadb; asc g ;; 

Record lock, heap no 557 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d940; asc g @;; 

Record lock, heap no 558 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d888; asc g ;; 

*** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 0 page no 404976 n bits 632 index users_unread_comments of table images_unread_comments trx id 1 2611184892 lock_mode X locks gap before rec insert intention waiting 
Record lock, heap no 558 PHYSICAL RECORD: n_fields 3; compact format; info bits 32 
0: len 4; hex 0001461a; asc F ;; 1: len 1; hex 01; asc ;; 2: len 6; hex 00000e67d888; asc g ;; 

*** WE ROLL BACK TRANSACTION (1) 

내가 눈치 것은 두 SQL 문이 동일한 것입니다; 하나는 서버 A에서 실행되고 다른 하나는 서버 B에서 실행되는 이유와 관계없이 두 쿼리가 동일한 순서로 같은 키를 잠그면 왜 이렇게 교착 상태가 발생합니까? 또는 교착 상태의 우연을 오해하고 있습니까?

+0

이 전에 실행되는 다른 쿼리 (한 스레드 또는 두 스레드 모두) 행. 또한 상태 보고서를 조금 짧게 만들었습니다 - 대기중인 두 번째 트랜잭션과 보유하고있는 트랜잭션은 무엇입니까? – Vatev

+0

@Vatev 출력에 해당 섹션의 나머지 부분을 추가했습니다. – Graham

+0

나는 이것을 1 번에 알아야한다 ... 잠금 장치가 다른 테이블에있다 (images_unread_comments). 2 테이블과 관련된 트리거 또는 외래 키가 있습니까? – Vatev

답변

0

트랜잭션 1에서 인덱스에 갭을 잠그는 다른 작업 (삽입?)이 수행 된 것으로 보입니다. 트랜잭션 2는 ID 1로 레코드를 잠 갔기 때문에 트랜잭션 2가 업데이트를 수행하기를 기다리는 것보다 더 빠릅니다. 그러나 트랜잭션 1은 인덱스에 잠금을 보유하고 있기 때문에 트랜잭션 2를 진행할 수 없습니다. 이 작업으로 트랜잭션에 사용 된 모든 SQL 문을 분리 할 수 ​​있다면 교착 상태에 대한 정확한 이유를 알 수 있습니다.

관련 문제