Loading...
MySQL 9.5 Reference Manual 9.5의 17.7.5 Deadlocks in InnoDB의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
17.7.5.1 An InnoDB Deadlock Example
17.7.5.2 Deadlock Detection
17.7.5.3 How to Minimize and Handle Deadlocks
deadlock은 여러 트랜잭션이 서로 진행할 수 없는 상황으로, 각 트랜잭션이 다른 트랜잭션에 의해 필요로 되는 락을 보유하고 있을 때 발생합니다. 관련된 모든 트랜잭션이 동일한 리소스가 사용 가능해지기를 기다리고 있기 때문에, 그 중 어느 것도 자신이 보유한 락을 해제하지 않습니다.
deadlock은 트랜잭션들이 여러 테이블의 행을 (예를 들어 UPDATE나 SELECT ... FOR UPDATE와 같은 구문을 통해) 서로 반대되는 순서로 락할 때 발생할 수 있습니다. 또한 이러한 구문이 인덱스 레코드와 갭의 범위를 락할 때, 각 트랜잭션이 타이밍 문제로 인해 어떤 락은 획득하고 어떤 락은 획득하지 못하면서 deadlock이 발생할 수 있습니다.
deadlock 예시는 Section 17.7.5.1, “An InnoDB Deadlock Example”를 참조하십시오.
deadlock 발생 가능성을 줄이려면, LOCK TABLES 구문 대신 트랜잭션을 사용하고, 데이터를 insert하거나 update하는 트랜잭션이 오랜 시간 동안 열린 상태로 남지 않을 정도로 작게 유지하십시오. 서로 다른 트랜잭션이 여러 테이블이나 넓은 범위의 행을 update하는 경우, 각 트랜잭션에서 동일한 작업 순서(예를 들어 SELECT ... FOR UPDATE와 같은)를 사용하십시오. 또한 SELECT ... FOR UPDATE와 UPDATE ... WHERE 구문에서 사용되는 컬럼에 인덱스를 생성하십시오.
deadlock 가능성은 격리 수준의 영향을 받지 않습니다. 격리 수준은 읽기 작업의 동작을 변경하는 반면, deadlock은 쓰기 작업 때문에 발생하기 때문입니다.
deadlock 상태를 피하고 복구하는 방법에 대한 자세한 내용은 Section 17.7.5.3, “How to Minimize and Handle Deadlocks”를 참조하십시오.
deadlock detection이 활성화되어 있을 때(기본값) deadlock이 실제로 발생하면, InnoDB는 이 상태를 감지하고 트랜잭션 중 하나(victim)를 롤백합니다. deadlock detection을 innodb_deadlock_detect 변수를 사용해 비활성화한 경우, InnoDB는 deadlock이 발생했을 때 innodb_lock_wait_timeout 설정에 의존해 트랜잭션을 롤백합니다.
따라서 애플리케이션 로직이 올바르더라도, 트랜잭션을 재시도해야 하는 상황을 반드시 처리해야 합니다. InnoDB 사용자 트랜잭션에서 마지막 deadlock을 확인하려면 SHOW ENGINE INNODB STATUS를 사용하십시오.
빈번한 deadlock이 트랜잭션 구조나 애플리케이션 오류 처리의 문제를 드러낸다면, innodb_print_all_deadlocks를 활성화하여 모든 deadlock 정보를 mysqld 에러 로그에 출력하십시오. deadlock이 자동으로 어떻게 감지되고 처리되는지에 대한 자세한 내용은 Section 17.7.5.2, “Deadlock Detection”를 참조하십시오.
17.7.4 Phantom Rows
17.7.6 Transaction Scheduling