이전 포스팅에서 timestamp ordering을 활용하여 트랜잭션 동시성을 어떻게 제어하는지 살펴봤습니다. 이번 포스팅에서는 multi version의 데이터를 활용해서 트랜잭션 동시성을 제어하는 MVCC에 대해서 살펴보겠습니다.
MVCC
MVCC(Multi-Version Concurrency Control)는 여러 버전의 데이터를 저장합니다. 트랜잭션은 해당 트랜잭션이 시작한 시점을 기준으로 가장 최근 버전의 데이터를 읽습니다. MVCC를 활용하면 데이터가 특정 시점에 어떻게 변경됐는지 확인할 수 있기 때문에 다양한 isolation level을 보장할 수 있습니다. 또한 특정 시점에 필요가 없는 버전은(더 이상 트랜잭션에 의해 참조되지 않는 데이터) 제거됩니다.
MVCC의 장점은 읽기 작업이 쓰기 작업을 blocking하지 않는 점과 쓰기 작업이 읽기 작업을 blocking하지 않는다는 점입니다. 읽기 작업은 해당 작업이 시작된 시점에 논리적으로 읽을 수 있는 버전의 데이터를 읽으면 되기 때문에 쓰기 작업을 blocking 하지 않습니다. 쓰기 작업은 데이터의 새로운 버전을 추가하기만 하면 되므로 읽기 작업을 blocking 하지 않습니다.
Design Principles
MVCC를 구현할 때 고려사항에 대해 살펴보겠습니다.
Version Storage
MVCC는 각 데이터(튜플)의 버전을 관리하기 위해 포인터를 활용합니다. 포인터는 버전이 다른 데이터를 연결하기 위해 사용됩니다. 구체적인 구현 방법은 다음과 같습니다.
Append-Only Storage
새로운 버전의 데이터는 기존 데이터가 존재하던 테이블 스페이스의 남는 영역에 저장됩니다. Append Only Storage 방식은 가장 최근 버전의 데이터를 version chain의 가장 앞에 저장할 것이냐(Newest-to-Oldest) 또는 가장 뒤에 저장할 것이냐(Oldest-to-Newest)에 따라 분류됩니다.
Time-Travel Storage
데이터가 업데이트될 때 메인테이블에 저장된 기존 데이터를 time travel 테이블 영역에 복사합니다. 새로운 데이터는 메인테이블에 반영합니다.
Delta Storage
수정된 부분의 기존 값만 delta record space에 복사되는 방식입니다. Delta를 역으로 적용함으로써 트랜잭션은 이전 버전의 데이터를 확인할 수 있습니다.
InnoDB MVCC
다음으로는 InnoDB에서 MVCC를 어떻게 구현하는지 살펴보겠습니다. InnoDB는 undo tablespace를 활용해서 데이터의 버전을 관리합니다.
InnoDB는 내부적으로 다음 정보를 데이터(row)와 함께 저장합니다.
- DB_TRX_ID: 데이터를 insert 또는 update 한 가장 최근의 transaction id
- DB_ROLL_PTR(roll pointer): 해당 데이터에 update가 수행되면 undo tablespace에 이전 버전의 데이터가 기록됩니다. DB_ROLL_PTR는 이전 버전의 데이터를 가리킵니다.
- DB_ROW_ID: 새로운 데이터(row)가 insert 될 때마다 1씩 증가하는 값입니다.
InnoDB의 undo log는 insert undo log와 update undo log로 나뉩니다.
- Insert undo log: Insert transaction이 rollback 되는 경우에만 필요합니다. 트랜잭션이 커밋되는 순간 해당 undo log는 삭제됩니다.
- Update undo log: Consistent read를 위해서 사용됩니다. 트랜잭션이 이전 버전의 데이터를 읽어야 하는 경우 활용합니다. 만약 update undo log에 기록된 로그 중 트랜잭션에 의해 참조되지 않는다면 삭제될 수 있습니다.
마무리
이번 포스팅을 통해 MVCC가 트랜잭션 동시성을 어떻게 제어하는지 살펴봤습니다. MVCC는 InnoDB에서도 활용하는 방식인 만큼 보편적으로 사용되는 기술입니다. 다음 포스팅에서는 데이터베이스 로그에 대해 살펴보겠습니다.
'Database > DBA급 개발자로' 카테고리의 다른 글
[Database] DBA급 개발자로 - #20 Database Recovery (0) | 2022.12.05 |
---|---|
[Database] DBA급 개발자로 - #19 Database Logging (0) | 2022.12.04 |
[Database] DBA급 개발자로 - #17 Timestamp Ordering Concurrency Control (0) | 2022.11.13 |
[Database] DBA급 개발자로 - #16 Two-Phase Locking (0) | 2022.11.06 |
[Database] DBA급 개발자로 - #15 Concurrency Control (0) | 2022.11.01 |