Gap Lock
Gap Lock이란
Gap Lock은 MySQL InnoDB에서 기존 레코드 자체가 아니라 인덱스 레코드 사이의 빈 구간을 잠그는 락이다.
예를 들어 인덱스 값이 10, 20, 30이라면 다음과 같은 구간을 생각할 수 있다.
(-∞, 10)(10, 20)(20, 30)(30, +∞)
Gap Lock은 이 구간에 새로운 값이 끼어드는 것을 막는다.
왜 필요한가
주된 목적은 팬텀 리드를 막는 것이다. 범위 조건으로 읽은 결과가 트랜잭션 도중 달라지지 않게 하려면, 현재 존재하는 행만 잠그는 것으로는 부족할 수 있다. 중간에 새로운 행이 삽입되면 결과 집합이 바뀌기 때문이다.
Record Lock, Gap Lock, Next-Key Lock
Record Lock: 기존 레코드 자체 잠금Gap Lock: 레코드 사이 빈 구간 잠금Next-Key Lock: Record Lock + Gap Lock
InnoDB는 범위 잠금에서 보통 Next-Key Lock 전략을 사용한다.
언제 자주 보나
SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE- 범위 조건이 있는
UPDATE,DELETE REPEATABLE READ격리 수준
인덱스가 매우 중요하다
Gap Lock은 결국 어떤 인덱스를 타고 어떤 범위를 읽는지와 연결된다. 적절한 인덱스가 없으면 예상보다 훨씬 넓은 범위를 잠그는 것처럼 보일 수 있다.
즉, 락 문제를 볼 때는 SQL만 보지 말고 실행 계획과 인덱스 구성을 같이 봐야 한다.
실무에서 헷갈리는 상황
- 특정 행만 읽은 줄 알았는데 insert가 막힘
- 단건 조회라 생각했는데 실제론 범위 스캔이었음
- 격리 수준을 바꾸니 현상이 달라짐
이런 문제는 대부분 “레코드를 잠근 줄 알았는데 사실은 gap까지 잠겼다”로 해석할 수 있다.
정리
Gap Lock은 레코드를 보호하기 위한 락이 아니라, 새로운 레코드가 끼어들어 읽기 결과가 흔들리는 것을 막기 위한 락이다. InnoDB 락 문제를 해석할 때는 record만 보지 말고, range와 index까지 함께 봐야 한다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.
댓글
아직 댓글이 없습니다