MySQL과 Deadlock
MySQL 시스템의 Deadlock 감지와 복구
MySQL과 Deadlock
MySQL 과 Deadlock
1. MySQL Deadlock 탐지 방식
MySQL의 deadlock(교착 상태) 탐지는 InnoDB 스토리지 엔진 내부에서 수행되며, 기본적으로 wait-for graph 기반 사이클 탐지 알고리즘을 사용
1.1 기본 개념: Wait-for Graph
InnoDB는 트랜잭션 간 락 대기 관계를 그래프로 표현한다.
- 노드: 트랜잭션 (T1, T2, …)
- 간선: “T1 → T2” = T1이 T2가 가진 락을 기다리는 상태
이 그래프에서 사이클(cycle)이 발생하면 deadlock이다.
예시:
1
2
3
T1 → T2
T2 → T3
T3 → T1 ← cycle → deadlock
2. Deadlock 탐지 방식
2.1 즉시 탐지(Eager Detection)
InnoDB는 락을 기다리는 순간마다 deadlock을 검사한다.
어떤 트랜잭션이 lock wait 상태로 들어가면:
- wait-for graph에 edge 추가
- DFS 기반 cycle detection 수행
- 사이클 발견 시 deadlock 판단
즉, 주기적 검사(X), 이벤트 기반 검사(O)
탐지 알고리즘 (구현 관점)
핵심은 DFS 또는 트랜잭션 체인 추적이다.
- 트랜잭션 T1이 lock wait 발생
- T1이 기다리는 트랜잭션 T2 확인
- T2가 또 기다리는 대상 T3 확인
- 재귀적으로 탐색
- 다시 T1로 돌아오면 → cycle → deadlock
3. Deadlock 발생 시 처리
3.1 Victim 선택
하나의 트랜잭션을 강제로 rollback
선정 기준:
- undo log가 가장 작은 트랜잭션
- 즉, rollback cost 최소화
→ “least cost victim selection”
3.2 결과
victim 트랜잭션:
1
ERROR 1213 (40001): Deadlock found when trying to get lock
- 나머지 트랜잭션은 계속 진행
4. 설정 옵션
4.1 deadlock detection ON/OFF
1
innodb_deadlock_detect = ON
- ON (기본값): 즉시 deadlock 탐지
- OFF: 탐지 안 하고 timeout 기반 처리
timeout fallback
1
innodb_lock_wait_timeout = 50
deadlock detection이 꺼져 있거나 탐지 실패 시: → 일정 시간 후 timeout으로 rollback
5. 성능 관점
deadlock detection은 high contention 환경에서 wait-for graph 탐색이 빈번하게 발생
- high concurrency + hotspot row 환경에서는
- innodb_deadlock_detect = OFF
- timeout 방식으로 운영하기도 함
- 특히 write-heavy 시스템
6. 실제 로그 확인
1
SHOW ENGINE INNODB STATUS;
→ 가장 최근 deadlock 정보 출력
또는
1
SET GLOBAL innodb_print_all_deadlocks = ON;
- 모든 deadlock을 error log에 기록
- SHOW VARIABLES LIKE ‘log_error’;
- 결과 예: /var/log/mysql/error.log
This post is licensed under CC BY 4.0 by the author.