이번 글에서는 MVCC(Multi Version Concurrency Control) 와 트랜잭션 격리 수준을 이해하기 위해, 먼저 꼭 알아야 할 MySQL의 기본 개념을 소개하겠다.
내용은 Real MySQL 책을 참고하였으며, 개인적인 학습을 위해 요약·재구성한 글입니다.
MySQL 엔진은
위와 같이 구조로 되어 있다.
크게
- MySQL 엔진
- 스토리지 엔진
으로 나뉘어 진다.
- 1) MySQL 엔진
MySQL 엔진은 클라이언트로부터의 접속, 쿼리 요청을 처리하는 커넥션 핸들러와
SQL 파서 및 전처리기, 쿼리의 최적화된 실행을 위한 옵티마이저로 이루어져 있다.
-> 한마디로 말하자면 SQL 실행을 설계, 결정하는 두뇌 역할을한다.
- 2) 스토리지 엔진
스토리지엔진은 데이터를 실제로 저장, 조회 등의 연산을 하는 역할을 하는데
스토리지 엔진은 3종류가 있다.
- InnoDB
- MyISAM
- Memory
스토리지 엔진에서 InnoDB, MyISAM, Memory 의 큰차이점이 있다.
그리고 보통 InnoDB를 많이 쓰는데 이유가 뭘까?
답은
- InnoDB는 트랜잭션을 지원한다는 것이다.
- InnoDB는 잠금을 사용하지 않는 일관된 읽기를 제공한다.
“어떻게 잠금을 사용하지 않고도 읽기의 일관성을 보장할 수 있을까?”
-> 바로 MVCC 기능이다.
MVCC(Multi Version Concurrency Control)
- 레코드 레벨의 트랜잭션을 지원하는 DBMS가 제공하는 기능이다.
- 가장 큰 목적은 잠금을 사용하지 않는 일관된 읽기를 제공한다.
MVCC의 핵심: Undo Log
InnoDB는 MVCC를 Undo Log를 활용해 구현한다.
데이터베이스가 이렇게 있다고 가정하자
일단 간단하게
이런 테이블이 있다고 가정하자
select * from person where id = 1;
쿼리 요청을 보내보자
그럼 데이터베이스 상태는 그림 아래처럼 되어 있다.
이 상태에서 아래와 같이 데이터를 수정한다고 해보자
UPDATE person set age = 20 where id = 1;
위에 처럼
- 커밋 실행 여부와 관계없이 버퍼 풀(Buffer Pool) 에는 age=20으로 변경된 값이 반영된다.
- 동시에 Undo Log에는 변경 전 값(기존 age 값)이 기록됩니다.
- 실제 디스크의 데이터 파일에는 바로 기록되지 않고, InnoDB의 백그라운드 쓰기 스레드(Write Thread) 가 일정 시점에 버퍼 풀의 데이터를 일괄적으로 기록합니다.
다시 말해, 쓰기 작업은 대부분 버퍼링되어 지연 처리된다.
조회 시 어떤 데이터를 볼까?
만약 아직 COMMIT 또는 ROLLBACK이 되지 않은 상태에서 다른 사용자가 아래 쿼리를 실행한다면 어디에 있는 데이터를 조회할까?
SELECT * FROM person WHERE id = 1;
이때는 어떤 데이터를 조회할지는 트랜잭션 격리 수준(Isolation Level) 에 따라 달라집니다.
다음 글에서는 이어서 트랜잭션 격리 수준과 MVCC의 연관성에 대해 이야기 해보겠다.