← 아티클 목록

MySQL 갭 락·넥스트키 락 — 데드락과 잠금 대기 진단

2028-01-31#database#MySQL#트랜잭션

분명히 다른 행을 INSERT했는데 데드락이 났거나, 존재하지도 않는 범위에서 Lock wait timeout이 떴다면 범인은 대부분 **갭 락(gap lock)**입니다. InnoDB는 기본 격리수준인 REPEATABLE READ에서 팬텀 읽기를 막기 위해 실제 행뿐 아니라 인덱스 행 사이의 빈 공간까지 잠급니다.

세 가지 잠금 구분

잠금잠그는 대상목적
레코드 락인덱스 레코드 1건그 행 변경 차단
갭 락인덱스 행 사이의 빈 구간그 구간에 INSERT 차단
넥스트키 락레코드 락 + 직전 갭팬텀 방지(기본 동작)

예를 들어 id10, 20, 30인 테이블에서 WHERE id BETWEEN 15 AND 25 FOR UPDATE를 실행하면, 존재하는 20 한 건만이 아니라 1030 사이 구간 전체에 넥스트키 락이 걸립니다. 그래서 다른 트랜잭션이 id = 17을 INSERT하려 하면 대기에 걸립니다.

데드락이 생기는 흐름

재현하려면 먼저 user_id에 인덱스가 있고 두 세션이 InnoDB·REPEATABLE READ인지 확인해야 합니다. 인덱스가 없으면 테이블 스캔과 잠금 범위가 달라져 아래 결과를 그대로 기대할 수 없습니다.

가장 흔한 패턴은 한 트랜잭션이 없는 키 범위를 잠근 뒤 다른 트랜잭션이 같은 범위에 접근하는 경우입니다.

SQL
-- 사전 조건: CREATE INDEX idx_orders_user_id ON orders(user_id);
-- 트랜잭션 A (REPEATABLE READ)
SELECT * FROM orders WHERE user_id = 7 FOR UPDATE;  -- user_id 7 없음 → 갭을 배타적으로 잠금
-- 트랜잭션 B
SELECT * FROM orders WHERE user_id = 7 FOR UPDATE;  -- A가 COMMIT/ROLLBACK할 때까지 대기
-- B가 대기 중인 동안 A가 INSERT하고 COMMIT하면 B의 SELECT가 재개됨

SELECT ... FOR UPDATE는 일반적인 공유 읽기가 아니라 잠금 읽기이므로, 같은 범위에 대한 두 번째 잠금 읽기는 먼저 잠근 트랜잭션이 끝날 때까지 대기합니다. 두 세션이 같은 갭에 각각 INSERT를 시도하는 복잡한 데드락은 실행 순서·제약조건·인덱스에 따라 달라지므로, 항상 재현된다고 단정하지 말고 SHOW ENGINE INNODB STATUS에서 실제 대기 그래프를 확인하세요.

진단과 완화

  1. 현재 잠금 확인 — 최신 MySQL은 성능 스키마로 본다.
SQL
SELECT * FROM performance_schema.data_locks;
SHOW ENGINE INNODB STATUS\G   -- LATEST DETECTED DEADLOCK 섹션
  1. 인덱스를 정확히 태운다 — 갭 락 범위는 옵티마이저가 사용한 인덱스에 좌우된다. 조회 조건이 인덱스를 못 타면 잠금 범위·대기 양상이 달라질 수 있다. 유니크 인덱스로 존재하는 단건(WHERE id = 20)을 조회하면 보통 레코드 락만 걸리지만, DBMS·조건·격리수준을 EXPLAIN과 잠금 메타데이터로 확인한다.

  2. 격리수준 조정READ COMMITTED로 낮추면 넥스트키 락 대신 레코드 락만 사용해 갭 락이 사실상 사라진다. 단 팬텀 읽기는 허용되므로 트레이드오프를 이해하고 적용한다.

  3. 트랜잭션을 짧게 — 잠금 구간을 좁히고, 여러 트랜잭션이 같은 순서로 행에 접근하도록 정렬해 교착 가능성을 줄인다.

요점 정리

  • REPEATABLE READ의 기본 잠금은 넥스트키 락 = 레코드 락 + 갭 락이다.
  • 없는 행을 조회해도 갭은 잠기므로, 같은 갭 INSERT 경쟁이 데드락의 단골 원인.
  • data_locksSHOW ENGINE INNODB STATUS로 실제 잠금을 확인한다.
  • 단건 유니크 조회·READ COMMITTED·짧은 트랜잭션으로 갭 락 영향을 줄인다.

갭 락을 직접 재현하고 data_locks 출력으로 잠금 범위를 확인하는 실습은 데이터베이스 트랙에서 회원가입 없이 무료로 할 수 있습니다.

관련 아티클