개발자로서 살아남기/데이터베이스

개발자가 반드시 알아야하는 데이터베이스 - MYSQL(InnoDB)에서 잠금된 데이터을 조회할 수 있는 이유

코드 살인마 2024. 6. 21. 14:48
728x90

개요

최근 mysql의 잠금에 대한 이슈를 많이 다루고 있는데, s-lock, x-lock된 데이터에 대해 단순 조회가 어떻게 가능할까 라는 생각이 들었다.

 

일차원적으로 당연히 lock이 되었으니, 읽기가 안되는 것이 아닌가? 라고 생각할 수 있지만, mysq은 비잠금읽기(Consistent NonLocking Reads)로 동작하여, 잠금된 데이터도 조회가 가능하다.

 

비잠금읽기에 대해 자세히 알아보자.

여담으로 mysql 8.0 책을 제대로 읽었다면, 해당 질문에 대한 답을 쉽게 할 수 있을 것이다.
(위 생각에 대해 구글링 중 undo를 보자마자 아맞다! 싶었다..)

비잠금읽기

비잠금읽기

mysql(InnoDB)는 기본적으로 비잠금 읽기(Consistent Nonlocking Reads)을 사용한다. 이는 select문이 실행될 때 트랜잭션 격리수준에 따라 특정 시점의 일관된 데이터를 읽는다는 의미이다.


비잠금읽기는 READ COMMITTED 또는 REPEATABLE READ 격리 수준에서 발생한다.

  • READ COMMITTED에서는 각 SELECT가 실행될 때마다 현재 커밋된 데이터를 읽음
  • REPEATABLE READ에서는 트랜잭션이 시작된 시점의 스냅샷을 사용

좀 더 자세히 들어가서 mysql은 일관된 데이터를 읽을 수 있는가에 대한 답은 undo 로그에 있다.

undo로그

일관된 읽기를 위해 InnoDB는 undo 로그를 사용하여 변경 전의 데이터를 보관한다.


이렇게 함으로써 트랜잭션이 시작된 시점 또는 SELECT가 실행된 시점의 일관된 데이터를 제공할 수 있다.

 

예를 들어, 어떤 트랜잭션이 row을 변경하였고, commit되기 전에 다른 트랜잭션이 해당 row에 접근한다면 undo로그에 있는 변경전 row을 읽어 일관된 읽기를 유지한다. (REPEATABLE READ)

잠금된 데이터를 조회할 수 있는 이유

본론으로 돌아가, 잠금된 데이터를 조회할 수 있는 이유가 무엇일까?

 

예를 들어, SELECT ... FOR UPDATE는 해당 행에 배타적 잠금을 설정하여 다른 트랜잭션이 접근하지 못한다.

 

하지만 SELECT 문은 이러한 배타적 잠금을 무시하고 일관된 스냅샷을 통해 데이터를 읽을 수 있다.

요약

  • InnoDB는 기본적으로 일관된 비잠금 읽기(Consistent Nonlocking Reads)를 통해 undo 로그를 사용하여 데이터를 읽는다.
  • SELECT ... FOR UPDATE는 해당 행에 배타적 잠금을 설정하여 다른 트랜잭션이 접근하지 못하게 한다.
  • 일반적인 SELECT 문은 이러한 배타적 잠금을 무시하고 일관된 스냅샷을 통해 데이터를 읽을 수 있다.

REFERENCE

MYSQL 공식문서