다중 버전 동시성 제어 (multiversion concurrency control)
쉽게 풀면
어떤 행을 수정할 때 원래 값을 지우지 않고 새 버전을 하나 더 만들어 둡니다. 그러면 수정 중인 트랜잭션이 있어도 읽기만 하는 트랜잭션은 자기가 시작한 시점의 옛 버전을 그대로 읽을 수 있습니다. 읽는 사람은 기다리지 않고, 쓰는 사람도 읽는 사람 때문에 막히지 않는 것이 핵심입니다.
왜 중요한가
읽기 작업이 압도적으로 많은 실제 서비스에서 잠금 대기를 없애 처리량을 크게 높여 줍니다. 각 트랜잭션이 일관된 스냅숏을 보게 되므로 읽는 도중 값이 바뀌는 현상도 자연스럽게 막힙니다. 오늘날 널리 쓰이는 주요 데이터베이스 대부분이 이 방식을 기본으로 채택하고 있어, 격리 수준의 동작을 이해하려면 반드시 알아야 합니다.
논문에서는 이렇게 쓰입니다
오래 열려 있는 트랜잭션 때문에 필요 없어진 옛 버전을 지우지 못해 저장 공간이 부풀었다는 뜻입니다.
조금 더 깊게 보면
각 버전에는 만든 트랜잭션과 삭제한 트랜잭션의 식별자 또는 타임스탬프가 붙어 있고, 읽는 쪽은 자신의 스냅숏 기준으로 보이는 버전 하나를 고릅니다. 더 이상 어떤 트랜잭션에도 보이지 않는 버전은 별도의 정리 작업으로 회수해야 하며, 이 정리가 밀리면 저장 공간과 성능 문제가 생깁니다. 스냅숏 격리만으로는 쓰기 왜곡 현상을 막지 못하므로 직렬화 가능 수준을 위해서는 충돌을 추적하는 직렬화 가능 스냅숏 격리 같은 추가 장치가 필요합니다.
주의할 점
트랜잭션 격리 수준이 어떤 이상 현상까지 허용할지를 정의하는 규격이라면, 이 기법은 그 수준을 구현하는 방법 중 하나입니다. 읽기가 쓰기를 막지 않는다는 성질이 모든 이상 현상을 없애 준다는 뜻은 아니라는 점을 특히 주의해야 합니다.