MySQL InnoDB Lock

Minsu Kang·2023년 11월 25일

동시성 문제를 해결하기 위해 MySQL 스토리지 엔진(InnoDB) 은 Lock 기능을 제공합니다.
그 중 MySQL 디폴트 Isolation Level인 Repeatable Read 에서 사용되는 Record Lock, Gap Lock, Next-Key Lock 에 대하여 알아보겠습니다.

Record Lock

Record Lock 은 특정 레코드, 정확히 말하면 특정 인덱스에 Lock 을 거는 것입니다.
Record Lock 이 걸리면 다른 트랜잭션에서 Lock 이 걸린 인덱스에 insert, update ,delete 할 수 없습니다.
예를들어, 아래 쿼리를 실행 시켰다고 가정해 보겠습니다.

select * from student where age = 10 for update;

age 컬럼에 인덱스가 걸려있다면 age = 10 인 레코드에 대하여 다른 트랜잭션에서 update, insert, delete 를 실행할 경우 대기하게 됩니다.
만약 age 컬럼에 인덱스가 걸려있지 않다면 테이블 전체에 대하여 Lock 이 걸립니다.

Gap Lock

Gap Lock 은 조회한 인덱스 사이의 Gap 에 거는 Lock 입니다.
Gap Lock 이 걸리면 다른 트랜잭션에서 Lock 이 걸린 인덱스에 insert 를 할 수 없습니다. (update, delete 가능)
어떤 말인지 감이 안올 수 있는데 예시를 들어보겠습니다.

id(pk)nameage(index)
1minsu15
2kevin15
3tom15
4jack18
5suin19
6sangho19

위 테이블에서 아래의 Gap 이 생기게 됩니다.
() 소괄호: 초과, 미만
[] 대괄호: 이상, 이하

  • [-무한, 15)
  • (15, 18]
  • (18, 19]
  • (19, 무한]

select * from student where age = 18 for update;

age = 18 로 조회했을 때 해당 인덱스 범위 양끝 gap인 16 ~ 17, 19 에 Gap Lock 이 걸립니다.

select * from student where age = 19 for update;

age = 19 로 조회했을 때에는 20 ~ 무한 에 Gap Lock 이 걸립니다.

select * from student where age between 15 and 18 for update;

해당 조건에서는 -무한 ~ 14, 19 에 Gap Lock 이 걸립니다.

select * from student where age = 30 for update;

해당 조건에서는 20 ~ 무한 에 Gap Lock 이 걸립니다.

select * from student where id = 3 for update;

이렇게 조회했을 때는 어떨까요. 해당 케이스는 Gap Lock 이 걸리지 않습니다. pk 로 조회했기 떄문이죠. Primary Key 또는 Unique Key 로 where 조건을 설정한 경우 해당 범위를 벗어나는 곳에는 Gap Lock 이 걸리지 않습니다.

Next-Key Lock

Record Lock 과 Gap Lock 이 함께 사용되는 것을 Next-Key Lock 이라고 부릅니다.
Gap Lock 은 단독적으로 사용되지 않고 Next-Key Lock 의 일부로 사용됩니다.

select * from student where age between 15 and 18 for update;

해당 조건에서 -무한 ~ 14, 19 에는 Gap Lock 이 걸리고, 15 ~ 18 에는 Record Lock 이 걸립니다.

0개의 댓글