본문 바로가기

Database

[Database] MVCC - 다중 버전 동시성 제어 (Multi Version Concurrency Control)

반응형

 

데이터베이스에서는 여러 사용자가 동시에 접근하여 데이터를 읽고, 변경할 수 있는 동시성이 중요하다.

또한, 동시성과 함께 데이터의 일관성이 보장되어야한다.

 

이 동시성을 제어하고 일관성을 보장해주는 방법 중 하나가 MVCC (Multi Version Concurrency Control) 다중 버전 동시성 제어이다.

 

 

■ 기존 Locking 방식의 문제점

Locking 방식의 경우, 쓰기 작업이 수행되는동안 해당 데이터를 읽거나 쓸 수 없어 동시성의 문제가 발생한다.

MVCC 를 통해 Locking 의 문제점을 해결할 수 있다.

 

 

■ MVCC 의 특징

ㆍ MVCC 는 데이터베이스의 snapshot 을 이용하여 구현된다.

사용자가 데이터를 변경하면 데이터를 바로 변경하는 것이 아니라 변경 전의 데이터(snapshot) 를 Undo 라는 영역에 생성한다.

ㆍ 쿼리를 수행한 시점 이후에 변경된 값을 발견하면, Undo 영역에 저장된 데이터를 복사 (CR Copy) 하고 그것을 읽는다.

이 snapshot 을 통해 하나의 데이터에 대해 여러 버전의 데이터를 관리할 수 있으며, 이를 통해 데이터에 대한 변경이 commit 되기 전까지의 변경 사항을 다른 사용자가 볼 수 없도록 하는 등의 제어가 가능하다.

ㆍ 또, 다른 트랜잭션에 영향을 주지 않고 해당 데이터를 접근할 수 있도록 하여 데이터베이스의 일관성을 보장한다.

 

 

■ MVCC 장점

ㆍ Lock 을 사용하지 않아 더 빠른 읽기/쓰기 작업을 할 수 있어 처리 속도가 향상된다.

 snapshot 을 이용하여 여러 트랜잭션을 동시에 실행할 수 있어 Lock 을 줄이고, 동시성이 향상된다.

ㆍ 각 트랜잭션마다의 snapshot 을 기록하기 때문에 동시 트랜잭션간 격리를 제공하여 일관성을 보장한다.

 

 

■ MVCC 단점

ㆍ 하나의 데이터에 대해 여러 버전의 데이터가 존재하기 때문에 스토리지 오버헤드가 증가할 수 있다.

ㆍ undo 블록 I/O, CR Copy 생성, CR 블록 캐싱 등과 같은 부가적인 작업의 오버헤드가 발생한다.

 

 

■ MySQL 의 MVCC

MySQL 의 InnoDB 에서는 Undo Log 를 사용하여 MVCC 기능을 구현한다.

(MyISAM 에서는 지원하지 않는다.)

 

아래와 같은 player 라는 테이블이 존재한다고 하자.

id charname level job
1 나는야전사 100 전사
2 나는야궁수 104 궁수

 

player 테이블에서 아래와 같은 UPDATE 쿼리를 실행해보자.

UPDATE player
SET level = 110
WHERE id = 1;

 

UPDATE 문이 실행된 순간,

MySQL 의 InnoDB 버퍼풀에 새로운 값으로 데이터가 변경이 된다.

id level
1 110

 

그리고 Undo 로그에는 변경 전의 데이터들이 복사(snapshot) 가 된다.

id level
1 100

 

 

위 상태에서 commit 을 하지 않은 상태라고 치자. 이때 다른 사용자가 해당 데이터를 조회하면 어떻게 될까?

 

이 결과는 트랜잭션 격리 수준(transaction isolation level) 에 따라 조금 달라질 수 있다.

READ UNCOMMITTED 라면 commit 되지 않은 InnoDB 버퍼풀의 변경된 데이터를 보여줄 것이고,

READ COMMITTED, REAPEATABLE READ, SERIALIZABLE 이라면 Undo 로그의 변경되기 전의 데이터를 보여줄 것이다.

 

Lock 을 사용했다면, 데이터를 볼 수 없었겠지만 MVCC 덕분에 commit 하지 않은 상태의 데이터를 볼 수 있는 것이다.

 

이 후 commit 을 하면 디스크에 변경 후 데이터로 덮어씌어진다.

만약, rollback 을 하면 Undo Log 에서 변경 이전의 데이터를 InnoDB 버퍼풀에 다시 이전 데이터로 덮어씌어질 것 이다.

 

 

■ SQL Server 의 MVCC

ㆍ SQL Server 는 기본적으로 Lock 기반의 동시성 제어 방식을 사용한다.

    트랜잭션이 데이터를 읽거나 쓸 때, 다른 트랜잭션이 동시에 해당 데이터에 접근하여 충돌이 발생하는 것을 방지하기 위해 Lock 을 사용한다.

    이 때 SQL Server 의 트랜잭션 격리 수준에 따라 달라질 수 있다.

그러나, SQL Server 의 격리 수준 중 Snapshot 격리 수준의 경우 MVCC 를 사용한다. 

     트랜잭션이 시작될 때 snapshot 을 생성하는데, 이는 트랜잭션이 진행되는 동안 다른 트랜잭션에 의해 변경된 데이터를 보지 않도록 한다.

ㆍ 이 때, 변경된 행의 이전 데이터는 tempdb 에 저장되며, 각 트랜잭션은 tempdb 에 저장된 snapshot 데이터를 보게 된다.

 

 

 

 

 

반응형