[Real MySQL] 04. MVCC - 레코드 레벨 트랜잭션

김학성·2023년 5월 24일
0

Real MySQL

목록 보기
4/6
post-thumbnail

이 포스팅은 Real MySQL의 04장을 읽고 개인적으로 학습하고 이해한 내용입니다. 틀린 부분이 있다면 언제든 지적 부탁드립니다.

테이블에 특정 레코드를 수정하고 아직 COMMIT되지 않은 상태에서 다른 세션이 해당 레코드를 읽었을 때는 어떤 데이터를 어떻게 읽게되는걸까? 라는 생각을 했었는데요. MYSQL에서 지원하는 MVCC를 통해 살펴보도록 하겠습니다.

MVCC란?

MVCC는 Multi Version Concurrency Control의 약자로, 레코드에 대해 여러 버전이 동시에 관리되어 레코드 레벨 트랜잭션에서 일관된 읽기를 제공하는 기능입니다.

쉽게 말해 특정 레코드에 걸린 잠금을 기다리지않고 읽기 작업을 할 수 있다는 의미인데요. 이는 MySQL InnoDB 메모리 중 로그 버퍼에 존재하는 언두 로그로 가능한 부분입니다. 언두 로그는 변경되기전 데이터를 저장하는 임시 공간이며, 트랜잭션에서 rollback시 이전 데이터를 참고하는 곳이기도 합니다.

예제

실습을 위해서 테이블과 레코드를 아래와같이 추가했습니다.

CREATE TABLE student
(
    id INT NOT NULL PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    grade INT NOT NULL
);

INSERT INTO student VALUES (1, '고양이', 1);

추가한 레코드의 데이터 일부를 수정하는 쿼리를 실행했습니다.

UPDATE student SET name = '강아지' WHERE id = 1;

해당 쿼리 실행 후 변경되기 이전 데이터는 언두 로그에 저장하고 변경된 데이터는 버퍼 풀에 저장되지만 아직 커밋이 실행되지 않았기 때문에 디스크에는 기록되지 않았습니다.


이 때 다른 세션에서 해당 레코드의 데이터를 읽으면 어떻게 조회가 될까요?

SELECT * FROM student WHERE id = 1;

이럴 때는 언두 로그에 있는 데이터를 참조하여 변경되기 이전의 레코드를 조회할 수 있습니다.

물론 이 부분은 트랜잭션 격리 수준이 READ_COMMITTED 이상이라고 가정한 경우이며, 만약 READ_UNCOMMITTED인 경우에는 아직 커밋되지 않아도 버퍼 풀에 있는 변경된 데이터를 읽게 됩니다.

이후에 변경된 데이터를 커밋하게 되면 백그라운드 스레드에 의해 디스크에 데이터가 기록되며, 언두 로그에 있던 이전 데이터를 사용하는 트랜잭션이 없다고 판단되면 언두 로그에서 데이터가 삭제됩니다.

이렇게 MVCC 기능을 활용하여 트랙잭션으로 인하여 잠금이 걸린 레코드를 기다리지 않고 일관된 데이터를 읽음으로써 트랜잭션의 동시성과 격리성을 보장할 수 있게 됩니다.

profile
경험과 성장을 기록하는 개발자입니다

0개의 댓글