InnoDB 락(Lock) 에 대해 알아보자.

Ilyoung Hwang·2023년 3월 5일
0
post-custom-banner

개요

InnoDB는 일관성동시성을 보장하기 위해 레코드(Row) 수준의 잠금 방식을 사용하는 MySQL의 스토리지 엔진중 하나이다. 여기서 레코드를 잠그는 것이 아니라 인덱스를 잠그는 방식이다. 예를 들어 변경할 레코드를 찾기 위해 검색 된 레코드들을 모두 락 처리 한다.

UPDATE users SET phone_number = 01099998888 WHERE first_name = 'Hong' AND last_name = 'GilDong';

위 쿼리는 이름이 GilDong 이고 성이 Hong 인 사람의 전화번호를 변경하는 쿼리이다. first_name 에만 인덱스가 있다고 하자. 그럼 "Hong" 에 대한 모든 레코드를 잠금 처리를 하게 된다. 그래서 인덱스 설계가 가장 중요한 포인트다.

InnoDB를 사용하는 경우, 명시적으로 잠금을 사용하는경우는 드물고, 트랜잭션을 사용할 땐 Isolation Level에 따라 묵시적으로 사용된다.

InnoDB의 레코드 잠금 유형은 크게 공유 잠금(Shared Lock)과 배타적 잠금(Exclusive Lock)으로 나뉠 수 있다.

1. 공유 잠금(Shared Lock)

공유 잠금(S)는 특정 레코드르 읽을 때 사용된다. 공유 잠금을 획득한 트랜잭션은 해당 레코드를 읽을 수 있지만, 수정할 수는 없다. 여러 트랜잭션이 동시에 같은 레코드를 읽을 수 있다.

#아래의 쿼리는 공유 잠금을 사용하는 예시 이다.

BEGIN;
SELECT * FROM users WHERE first_name = 'Hong' LOCK IN SHARE MODE; #8.0이하
SELECT * FROM users WHERE first_name = 'Hong' FOR SHARE; #8.0이상
COMMIT;

위의 예시에서 LOCK IN SHARE MODE는 해당 레코드에 Shared Lock을 요청하도록 하는 명령어이다. 따라서 위의 쿼리를 실행하면, 해당 레코드를 다른 트랜잭션에서 동시에 읽을 수는 있지만, 수정할 수는 없다.

2. 배타적 잠금(Exclusive Lock)

배타적 잠금(X)는 트랜잭션이 특정 레코드를 수정할 때 사용된다. 배타적 잠금(X)을 획득한 트랜잭션은 해당 레코드를 읽고 수정할 수 있지만, 다른 트랜잭션이 해당 레코드를 읽거나 수정할 수 없다.

#아래의 쿼리는 배타적 잠금을 사용하는 예시 이다.

BEGIN;
SELECT * FROM users WHERE id = 1 FOR UPDATE;
UPDATE users SET first_name = 'Hwang' WHERE id = 1;
COMMIT;

위의 예시에서 FOR UPDATE 는 해당 레코드에 대한 Exclusive Lock 를 요청하도록 하는 명령이다. 따라서 위의 쿼리를 실행하면, 해당 레코드를 다른 트랜잭션에서 동시에 읽거나 수정할 수 없다.

3.의도 잠금(Intention Lock)

Intention Lock은 InnoDB 엔진에서 사용되는 내부적인 락 모드 중에 하나로, 다른 락모드를 사용하기전에 필요한 락을 미리 요청하는 용도로 사용된다.

Intention Lock은 다른 락 모드와는 다르게, 특정 레코드에 직접 걸리는 것이 아니라 해당 페이지나 테이블에 대한 락을 걸기 위해 사용된다.

Intention Lock에는 Intention Shared Lock(IS), Intention Exclusive Lock(IX), Shared and Exclusive(SIX) 세가지 모드가 있다.

1.Intention Shared Lock(IS)

Intention Shared Lock(IS)은 트랜잭션이 해당 페이지나 테이블의 개별 행에 공유 잠금을 획득 하려는 락 이다. 다른 트랜잭션이 이미 Exclusive Lock을 걸고 있다면, Intention Shared Lock은 걸 수 없다.

2.Intention Exclusive Lock(IX)

Intention Exclusive Lock(IX)은 트랜잭션이 해당 페이지나 테이블의 개별 행에 배타적 잠금을 획득 하려는 락이다. 다른 트랜잭션이 이미 Shared Lock이나 Exclusive Lock을 걸고 있다면, Intention Exclusive Lock은 걸 수 없다.

예를 들어 위의 두가지 락은 SELECT ... FOR SHARE는 IS 잠금을 설정하고 SELECT ... FOR UPDATE는 IX 잠금을 설정한다.

3. Shared and Exclusive(SIX)

Shared and Exclusive(SIX)은 여러 개의 레코드를 동시에 락 걸 수 있고, 다수의 트랜잭션이 동시에 여러 개의 레코드를 수정하거나 조회하는 경우 유용하다.

SIX 락 모드는 주로 하나 이상의 레코드를 수정할때, 여러개의 레코드를 읽을때, 여러개의 레코드를 수정하거나 읽을때 주로 사용된다.

참고


https://www.letmecompile.com/mysql-innodb-lock-deadlock/
https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html

post-custom-banner

0개의 댓글