MVCC란?
MVCC는 Multi-Version Concurrency Control의 약자로 RDBMS에서 Lock을 사용하지 않고도 데이터의 읽기 일관성을 보장해주는 기법이다. MVCC는 데이터 항목의 여러 버전을 유지함으로써 읽기 작업이 쓰기 작업에 의해 차단되지 않도록 합니다.
MVCC의 핵심 원리는 데이터의 변경 이력을 버전별로 관리하여, 각 트랜잭션이 특정 시점의 일관된 데이터 스냅샷을 볼 수 있게 하는 것이다.
MVCC 작동 원리
- 트랜잭션 시작과 타임스탬프
- 트랜잭션이 시작되면 고유한 트랜잭션 ID가 할당 된다. 이 ID는 데이터 버전의 가시성을 결정하는 데 사용된다. MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여, 해당 ID보다 작은 트랜잭션 번호에서 변경된 데이터만 읽을 수 있게 한다.
- 데이터 버전 관리
- 행이 업데이트될 때마다해당 행의 새 버전이 생성된다. 이전 버전은 업데이트 이전에 시작된 트랜잭션이 접근할 수 있도록 유지된다. 이를 통해 각 트랜잭션은 자신의 시작 시점에 맞는 일관된 데이터를 볼 수 있다.
- 읽기 작업
- 트랜잭션이 데이터를 읽을 때, 자신의 시작 시간 이전에 커밋된 데이터 버전만 볼 수 있다. 이를 통해 다른 트랜잭션에서 아직 커밋되지 않은 변경사항을 읽지 않도록 보장한다.
- 쓰기 작업
- 트랜잭션이 데이터를 쓸 때, 새 버전의 데이터 항목을 생성한다. 이전 버전은 필요한 모든 트랜잭션이 완료될 때까지 유지된다.
MySQL의 MVCC 구현
MySQL의 InnoDB 스토리지 엔진은 MVCC를 행 수준 잠금과 버전 관리를 조합하여 구현하고 있다.
- Undo 로그 활용
- InnoDB는 Undo 로그를 유지하여 이전 버전의 데이터를 저장한다. 트랜잭션이 행을 수정하면 이전 버전이 Undo 로그에 저장되어 다른 트랜잭션이 필요할 경우 접근할 수 있다.
- 레고드가 변경되면 InnoDB의 버퍼 풀은 새 값으로 업데이트되지만, 이전 데이터는 Undo 로그에 백업된다. 이후 다른 트랜잭션이 해당 데이터를 읽을 때, 트랜잭션 격리 수준에 따라 적절한 버전의 데이터를 제공한다.
- 읽기 뷰(Read View)
- 각 트랜잭션은 자신이 시작된 시점의 데이터베이스 상태에 대한 읽기 뷰를 생성한다. 이 읽기 뷰는 트랜잭션의시작 타임스탬프와 다른 활성 트랜잭션의 타임스탬프를 기반으로 하며, 어떤 버전의 데이터가 해당 트랜잭션에게 보일지 결정한다.
- 잠금 없는 일관된 읽기(Non-Locking Consistent Read)
- MVCC를 통해 MySQL은 행을 잠그지 않고도 읽관된 읽기를 제공한다. SELECT 문은 트랜잭션 시작 시점의 데이터를 반환하므로, 진행 중인 업데이트에 관계없이 일관된 결과를 보장한다.
- Non-Locking Consistent Read는 읽기 작업이 다른 트랜잭션의 잠금에 대기하지 않고 바로 실행될 수 있게 한다. 이는 특히 읽기 작업이 많은 시스템에서 성능 향상에 크게 기여한다.
- Non-Locaking Consistent Read를 위해서는 Undo 로그를 지속적으로 유지해야 하므로, 활성 트랜잭션이 길어지면 MySQL 서버 성능이 저하될 수 있다. 따라서 트랜잭션을 시작했다면 가능한 빨리 롤백이나 커밋을 통해 트랜잭션을 완료하는 것이 좋다.
댓글 영역