본문 바로가기
츄Log/기타 끄적

MVCC (Multi Version Concurrency Control)

by 츄츄🦭 2023. 12. 21.
728x90

 

안녕하세요. 오늘은 MVCC에 대해 알아보겠습니다.

 

MVCC는 레코드 레벨의 트랜잭션을 지원하는 DBMS가 제공하는 기능이고,

MVCC의 가장 큰 목적은 잠금을 사용하지 않고 일관된 읽기를 제공하는 데 있습니다.

 

MySQL의 InnoDB는 Undo Log를 이용해 이 기능을 구현합니다. 

멀티버전은 하나의 레코드에 대해 여러 개의 버전이 동시에 관리된다는 의미입니다.

 

MySQL의 격리수준에서 READ_COMMITTED 이상의 격리수준은 이 MVCC를 이용하여 잠금 없는 일관된 읽기(Non-Locking Consistent Read)를 제공합니다. 

 

 

아래 그림이 MySQL에서 UPDATE문장이 실행될 때 절차를 보여주는 그림입니다.

출처 : Real MySQL 8.0

 

격리 수준이 READ_UNCOMMITTED인 경우에는 InnoDB 버퍼 풀이 현재 가지고 있는 변경된 데이터를 읽어서 반환하지만,

그 이상의 격리 수준에서는 UPDATE 쿼리의 커밋 전까지는 변경되기 이전의 내용을 보관하고 있는 언두 영역의 데이터를 반환합니다.

커밋이 되었을 때 바로 언두 영역의 데이터를 삭제하는 것이 아니라, 이 언두 영역의 데이터를 필요료 하는 트랜잭션이 모두 끝났을 때 삭제되며, 만약 이 상태에서 커밋이 아닌 롤백이 된다면, 언두 영역에 있는 데이터를 InnoDB 버퍼 풀로 다시 복구하고 언두 영역의 내용을 삭제합니다. 

 

격리수준에 따라서 당연히 트랜잭션마다 언두로그에서 관리하는 예전 데이터들이 생기며,

해당 레코드에 대한 변경 트랜잭션이 길어진다면 이 언두로그에서 관리하는 데이터들 또한 삭제되지 못하기 때문에 언두 영역이 저장되는 시스템의 공간이 부족한 경우도 생기게 됩니다.

 

이렇게 하나의 레코드에 대해 N개의 버전이 유지되고 필요에 따라 어느 데이터가 보여지는지 달라지는 구조이므로 MVCC라고 표현합니다.

InnoDB 엔진은 이러한 MVCC 기술을 이용해 잠금을 걸지 않고 읽기 작업을 수행할 수 있게 됩니다.

그래서 격리수준 SERIALIZABLE이 아닌 그 이하의 격리수준에서는 INSERT와 연결 되지 않은 순수한 읽기(SELECT) 작업은 다른 트랜잭션의 변경 작업과 관계 없이 항상 잠금을 대기하지 않고 바로 실행됩니다.

 

특정 사용자가 레코드를 변경하고 아직 커밋을 하지 않았다고 하더라도 이 변경 트랜잭션이 다른 사용자의 SELECT 작업을 방해하지 않으며 이를 잠금 없는 일관된 읽기(Non-Locking Consistent Read)라고 표현합니다.

 

 

도움 : Real MySQL 8.0

728x90