woowacourse-study / talteco

"조조그린"의 면접 스터디
3 stars 0 forks source link

MySQL의 InnoDB 스토리지 엔진에서 락은 어떻게 동작하나요? #70

Open tonic523 opened 2 years ago

tonic523 commented 2 years ago

레코드 기반의 락을 사용합니다. 종류에는 레코드 락, 갭 락, 넥스트 키 락, 자동 증가 락이 있습니다. 레코드를 직접 락을 거는 것이 아닌 인덱스에 락을 걸게 됩니다.

InnoDB 스토리지 엔진 잠금

MySQL에서 제공하는 잠금과는 별개로 스토리지 엔진 내부에서 레코드 기반의 잠금 방식을 탑재하고 있다.

레코드 락

레코드 자체만을 잠그는 것을 레코드 락이라고 하며, 다른 상용 DBMS의 레코드 락과 동일한 역할을 한다.

중요한 차이는 InnoDB 스토리지 엔진은 레코드 자체가 아닌 인덱스의 레코드를 잠근다는 점이다.

갭 락

레코드가 자체가 아닌 레코드와 바로 인접한 레코드 사이의 간격만을 잠근다.

갭 락의 역할은 레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어한다.

넥스트 키 락

레코드 락 + 갭 락을 합쳐 놓은 형태의 잠금이다. InnoDB의 갭 락, 넥스트 키 락은 바이너리 로그에 기록되는 쿼리가 레플리카 서버에서 실행될 때 소스 서버에서 만들어 낸 결과와 동일한 결과를 만들어내도록 보장하는 것이 주목적이다.

자동 증가 락 (Auto increment lock)

InnoDB 스토리지 엔진에서는 레코드가 중복되지 않고 지정된 순서대로 증가하는 일련번호 값을 갖게 하기 위해 Auto increment lock 이라고 하는 테이블 수준의 잠금을 사용한다.

이 락은 아주 짧은 시간동안 걸렸다가 해제되는 잠금이라 대부분의 경우 문제가 되지 않는다고 한다.

인덱스와 잠금

앞서 InnoDB의 잠금은 레코드를 잠그는 것이 아닌 인덱스를 잠그는 방식으로 처리하게 된다. 즉, 변경해야 할 레코드를 찾기 위해 검색한 인덱스의 레코드를 모두 락으로 걸게 된다.

update member set name='updateName' where age=27

위 쿼리문이 실행된다면 age가 27인 레코드만 쓰기 락이 걸리는 것을 기대하게 된다. 하지만, age에 대한 인덱스가 없다면 member 테이블을 full scan하기 때문에 모든 레코드에 쓰기 락이 걸리게 된다.

따라서 인덱스를 조회 성능 개선을 위해서 뿐만 아니라 update, delete할 때 인덱스를 타는지도 확인해주어야 한다.

bugoverdose commented 2 years ago