DBAtlas · 데이터베이스 운영 아틀라스

데드락 / 락 충돌 (ORA-00060, 1213, 40P01)

데드락이 발생했다(Oracle ORA-00060, MySQL 1213, PG 40P01, MSSQL 1205). 그래프를 수집하고, 패턴을 파악하고, 재발을 막는다. 데드락은 설계로 해결한다 — 목표는 빈도를 줄이는 것이다.

먼저 deadlock graph를 수집한다

어떤 두 개(또는 그 이상)의 세션이, 어떤 리소스에서, 어떤 락 모드로 충돌했는가? 이것을 보지 않고 맹목적인 수정을 적용하지 않는다.

-- Check the trace file referenced in the alert log (deadlock graph). For history:
SELECT * FROM dba_hist_active_sess_history WHERE event LIKE 'enq: TX%' ORDER BY sample_time DESC FETCH FIRST 20 ROWS ONLY;
  • 그래프 확보 — 두 트랜잭션이 리소스를 반대 순서로 잠근다
  • 많은 트랜잭션이 단일 행/테이블에 몰린다(hotspot)
  • 넓은 범위 락이 있다(많은 행이 잠김)

락을 거는 쿼리가 인덱스를 사용하는가?

인덱스가 없으면 UPDATE/DELETE가 WHERE 절을 만족시키기 위해 많은 행(심지어 테이블 전체)을 잠근다 → 데드락의 원인. 실행 계획을 확인한다.

EXPLAIN <the UPDATE/DELETE involved in the deadlock>;  -- type=ALL means a full scan, no index
  • 인덱스 없음 / full scan 수행
  • 인덱스는 있지만 여전히 충돌한다

근본 원인: 락 획득 순서 불일치

데드락의 가장 흔한 원인: 두 트랜잭션이 서로 다른 순서로 리소스에 접근한다. A→B와 B→A가 동시에 일어나면 데드락이 된다.

근본 원인: 인덱스 누락 → 넓은 락

인덱스 없는 UPDATE/DELETE는 필요 이상으로 많은 행을 잠가 데드락 가능성을 크게 높인다.

근본 원인: hotspot

많은 트랜잭션이 카운터 행/key 같은 단일 리소스에 동시에 몰린다.

DBAtlas에서 열기 →