Database Deadlock
Transaction들이 서로 보유한 Lock을 기다리는 순환 의존을 탐지·해소·예방하는 방법이다.
이 문서의 목차
Overview
Deadlock은 두 개 이상의 Transaction이 상대가 가진 Lock을 기다리는 Cycle이다. 단순한 긴 Lock 대기와 달리 모두가 계속 기다려도 스스로 해결되지 않는다.
발생 조건
계좌 A→B Transfer와 B→A Transfer가 각각 출발 계좌를 먼저 잠그면 서로 상대 계좌 Lock을 기다릴 수 있다.
sequenceDiagram; participant T1; participant A; participant B; participant T2; T1->>A: Lock A; T2->>B: Lock B; T1-->>B: Wait Lock B; T2-->>A: Wait Lock A
Database의 처리
InnoDB는 Wait-for Graph의 Cycle을 탐지하면 한 Transaction을 Victim으로 선택해 Rollback하고 나머지를 진행시킨다. 어떤 Transaction이 선택될지 Application이 가정하면 안 된다. 탐지를 끄면 Lock Wait Timeout까지 대기할 수 있다.
예방
- 같은 종류의 Row는 항상 정렬된 순서로 Lock을 획득한다.
- Transaction 범위와 처리 시간을 줄인다.
- 불필요하게 넓은 Range Lock을 만들지 않도록 Index와 조건을 점검한다.
- Batch와 Online Traffic이 같은 Row를 다른 순서로 변경하지 않게 설계한다.
- Deadlock 오류는 제한된 횟수와 Backoff로 전체 Transaction을 재시도한다.
증거 수집
오류 문장만 남기지 말고 양쪽 Transaction의 SQL, Lock 대상 Index/Record, 실행계획, Transaction 시작 시각, Application Trace를 함께 수집한다. 재시도 성공만 기록하면 원인이 반복된다.
Trade-off
Lock 순서를 통일하면 Deadlock은 줄지만 동시성이 낮아질 수 있다. Retry는 일시적 충돌을 흡수하지만 Idempotency가 없으면 부작용을 중복시킬 수 있다.
흔한 오해
- Deadlock과 Lock Wait Timeout은 같은 문제가 아니다.
- Isolation Level을 낮추면 모든 Deadlock이 사라지는 것은 아니다.
- Deadlock Retry는 원인 분석을 대신하지 않는다.
- 짧은 Query도 여러 Row를 다른 순서로 잠그면 Deadlock을 만들 수 있다.
Interview Questions
- Deadlock과 일반 Lock 대기의 차이는 무엇인가?
- 일관된 Lock 획득 순서가 Cycle을 줄이는 이유는 무엇인가?
- Deadlock Retry에서 전체 Transaction을 다시 실행해야 하는 이유는 무엇인가?
- Index 변경이 Lock 범위와 Deadlock에 어떤 영향을 줄 수 있는가?
Related Topics
Isolation과 MVCC, Index와 실행계획, Remote Partitioning과 연결해 Transaction 충돌 경계를 본다.
SOURCE REFERENCES
이 문서의 근거
본문은 Dev Atlas 안에서 완결되며, 검증이 필요할 때만 원문을 확인할 수 있습니다.