MySQL InnoDB

devyu·2023년 10월 9일
0

💡Deep Dive to DB

목록 보기
1/8
post-thumbnail

Deep Dive to DB 시리즈는 현재 진행중인 DB DB Deep 스터디에서 학습하는 내용을 복습 및 정리하는 시리즈입니다.

MySQL의 스토리지 엔진 가운데 InnoDB만 트랜잭션을 지원하기 때문에, MySQL의 트랜잭션 격리는 곧InnoDB의 트랜잭션 격리와도 같다. (기본 스토리지 엔진으로 사용되기도 함)

InnoDB는 총 네 가지의 트랜잭션 격리 레벨을 제공한다. (이 중 REPEATABLE READ 가 InnoDB의 기본 트랜잭션 격리 수준 설정)

  • READ UNCOMMITTED
    • 한 트랜잭션의 변경된 내용을 커밋이나 롤백과 상관 없이 다른 트랜잭션에서 읽을 수 있는 격리 수준
    • 모든 부정합 문제 발생
  • READ COMMITTED
    • COMMIT이 완료된 데이터만 조회 가능한 격리 수준
    • 더티 리드 해결
  • REPEATABLE READ
    • 트랜잭션이 시작되기 전에 커밋된 내용에 관해서만 조회할 수 있는 격리 수준
    • NON-REPEATABLE-READ 해결
    • InnoDB에서는 PHANTOM READ 해결
  • SERIALIZABLE
    • 한 트랜잭션을 다른 트랜잭션으로부터 완전히 분리하는 격리 수준
    • 모든 부정합 문제 해결

Phantom Read

Phantom Read란, SELECT ... FOR UPDATE 쿼리와 같은 쓰기 잠금을 거는 경우 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 불규칙하게 보이는 현상을 말한다.

이를 해결하기 위해서 InnoDB 스토리지 엔진은 레코드 락과 갭 락을 합친 넥스트 키 락을 사용한다. 

t 테이블에 c1 = 13 , c = 17 인 두 레코드가 있다고 가정하자. 이때 SELECT c1 FROM t WHERE c1 BETWEEN 10 AND 20 FOR UPDATE 쿼리를 수행하면, 10 <= c1 <= 1214 <= c1 <= 1618 <= c1 <= 20 인 영역은 전부 갭 락에 의해 락이 걸려서 해당 영역에 레코드를 삽입할 수 없다. 또한 c = 13, c = 17인 영역도 레코드 락에 의해 해당 영역에 레코드를 삽입할 수 없다. 참고로 INSERT 외에 UPDATE, DELETE 쿼리도 마찬가지이다.

이러한 방식으로 InnoDB 스토리지 엔진은 넥스트 키 락을 이용하여 PHANTOM READ 문제를 해결한다.

추가적으로 MySQL에서 Phantom Read 처리를 하지 않을 경우 SELECT 성능에 대해 비교한 글이 있어, 참조하면 좋을 것 같다.

profile
티스토리와 벨로그 사이 줄타기....

0개의 댓글