1) MVCC(Multi Version Concurrency Control)이란?
- MVCC는 일반적으로 레코드 레벨의 트랜잭션을 지원하는 DBMS가 제공하는 기능이다.
MVCC의 가장 큰 목적은 잠금을 사용하지 않는 일관된 읽기를 제공하는데 있다.
InnoDB는 언두 로그(Undo log)를 이용해 이 기능을 구현한다.
- 여기서 멀티 버전이라 함은 하나의 레코드에 대해 여러 개의 버전이 동시에 관리된다는 의미다.
이해를 위해 격리 수준(Isolation level)이 READ_COMMITTED인 MySQL 서버에서
InnoDB 스토리지 엔진을 사용하는 테이블의 데이터 변경을 어떻게 처리하는지
그림으로 한 번 살펴보자.
- 우선 다음과 같은 테이블에 한 건의 레코드를 INSERT한 다음 UPDATE해서
발생하는 변경 작업 및 절차를 확인해보자.
mysql > CREATE TABLE member (
m_id INT NOT NULL,
m_name VARCHAR(20) NOT NULL,
m_area VARCHAR(100) NOT NULL,
PRIMARY KEY (m_id),
INDEX ix_area (m_area)
);
mysql > INSERT INTO member (m_id, m_name, m_area) VALUES (12, '홍길동', '서울');
mysql > COMMIT;
- INSERT문이 실행되면 데이터베이스의 상태는 아래와 같은 상태로 바뀐다.
- 다음은 INSERT된 값을 UPDATE 문장을 통해 업데이트해보자.
mysql > UPDATE member SET m_area='경기' WHERE m_id=12;
- UPDATE 문장이 실행되면 커밋 실행 여부와 관계없이 InnoDB의 버퍼 풀은 새로운 값인 '경기'로 업데이트된다.
그리고 디스크의 데이터 파일에는 체크포인트나 InnoDB의 Write 스레드에 의해
새로운 값으로 업데이트돼 있을 수도 있고 아닐 수도 있다.
- 아직 COMMIT이나 ROLLBACK이 되지 않은 상태에서
다른 사용자가 다음 같은 쿼리로 작업 중인 레코드를 조회하면 어디에 있는 데이터를 조회할까?
mysql > SELECT * FROM member WHERE m_id=12;
- 이 질문의 답은 MySQL 서버의 시스템 변수(transaction_isolation)에 설정된 격리 수준(Isolation level)에 따라 다르다.
격리 수준이 READ_UNCOMMITTED인 경우에는 InnoDB 버퍼 풀이나 데이터 파일로부터
변경되지 않은 데이터를 읽어서 반환한다.
즉, 데이터가 커밋됐든 아니든 변경된 상태듸 데이터를 반환한다.
- 그렇지 않고 READ COMMITTED 이상의 격리 수준인 경우에는 아직 커밋되지 않았기 때문에
InnoDB 버퍼 풀이나 데이터 파일에 있는 내용 대신 변경되기 이전의 내용을 보관하고 있는 언두 영역의 데이터를 반환한다.
이러한 과정을 DBMS에서는 MVCC라고 표현한다.
- 여기서는 한 개의 데이터만 가지고 설명했지만, 관리해야 하는 예전 버전의 데이터는 무한히 많아질 수 있다.
언두에서 관리하는 예전 데이터가 삭제되지 못하고 오랫동안 관리돼야 하며,
자연히 언두 영역이 저장되는 시스템 테이블스페이스의 공간이 많이 늘어나는 상황이 발생할 수도 있다.
- 참고자료
'Real MySQL 1권' 카테고리의 다른 글
[Real MySQL 1권] MySQL의 격리 수준 - READ UNCOMMITTED, READ COMMITTED (0) | 2024.12.18 |
---|---|
[Real MySQL 1권] InnoDB 버퍼 (0) | 2024.12.16 |
[Real MySQL 1권] 클러스터링 인덱스 (0) | 2024.08.25 |
[Real MySQL 1권] 인덱스와 잠금 (0) | 2024.06.28 |
[Real Mysql 1권] 슬로우 쿼리 로그 (0) | 2024.06.28 |