CS/개발지식

데이터베이스 시스템에서 동시성을 제어하는 방법?

순원이 2024. 12. 18. 18:10

대표적인 동시성 제어 방식으로 MVCC(Multi-Version Concurrency Control)Lock-Based Concurrency Control이 있습니다.

1. MVCC(Multi-Version Concurrency Control/ 잠금 없는 읽기)


MVCC는 데이터의 여러 버전을 유지하여 트랜잭션이 동시에 데이터를 읽고 쓸 수 있도록 하는 방식입니다. 각 트랜잭션은 자신만의 일관된 스냅샷(MySQL::언두 로그)을 기반으로 데이터를 읽어, 다른 트랜잭션의 변경 사항에 영향을 받지 않습니다.

데이터의 각 버전을 유지하여 읽기 작업이 쓰기 작업과 독립적으로 이루어질 수 있습니다. 트랜잭션은 시작 시점의 스냅샷을 기반으로 데이터를 읽어, 다른 트랜잭션의 변경 사항을 보지 못합니다.

또한 읽기 작업 시 잠금을 사용하지 않아 높은 동시성을 제공합니다. 읽기 작업이 잠금에 의해 지연되지 않아, 읽기 중심의 애플리케이션에서 우수한 성능을 보입니다. 읽기 작업 시 잠금을 사용하지 않으므로, 쓰기 작업과의 충돌이 줄어듭니다. 하지만 여러 버전의 데이터를 유지해야 하므로 저장 공간이 더 많이 필요할 수 있습니다.

트랜잭션이 시작된 시점의 데이터 상태를 기반으로 읽기 작업을 수행하여 일관성을 유지합니다. 또 갭락과 넥스트키 락을 통해 팬텀 리드를 방지합니다.

2. Lock-Based Concurrency Control


Lock-Based 방식은 데이터에 접근할 때 잠금(Lock) 을 사용하여 동시성을 제어합니다. 트랜잭션이 데이터를 읽거나 수정할 때 해당 데이터에 잠금을 걸어 다른 트랜잭션의 접근을 제한합니다. 즉, 잠금을 통해 데이터의 일관성과 무결성을 직접적으로 제어합니다.

데이터에 접근할 때 잠금을 걸어 다른 트랜잭션의 접근을 제한합니다. 읽기 작업은 공유 잠금을, 쓰기 작업은 배타 잠금을 사용하여 동시성을 제어합니다. 많은 다수의 트랜잭션이 동일한 데이터에 접근할 경우 성능 저하가 발생할 수 있습니다. 또 잘못된 잠금 순서나 설계로 인해 교착 상태(Deadlock)가 발생할 위험이 있습니다.

3. MVCC vs Lock-Based: 실제 시스템에서의 선택


실제 데이터베이스 시스템, 특히 MySQL의 InnoDB는 MVCC와 Lock-Based 방식의 장점을 결합하여 동시성 제어를 최적화합니다.

읽기 트랜잭션은 MVCC를 사용하여 일관된 스냅샷을 기반으로 데이터를 읽으므로, 잠금을 최소화하고 높은 동시성을 유지할 수 있습니다.

쓰기 트랜잭션은 잠금을 사용하여 데이터의 일관성과 무결성을 유지하면서, 동시에 데이터 충돌을 방지합니다.

4. MVCC와 트랜잭션 격리수준의 관계는?


MVCC는 동시성을 관리하기 위한 구현 기술이고, 트랜잭션 격리 수준은 동시성과 무결성에 대한 정책입니다. 이 둘은 종종 관련이 있지만, 혼동해서는 안 됩니다.

  • MVCC는 주로 Read CommittedRepeatable Read 격리 수준을 구현하는 데 사용됩니다.
  • Serializable과 같은 높은 격리 수준에서는 잠금 기반 방식이 주로 사용됩니다.
격리수준 MVCC의 기여
READ UNCOMMITTED MVCC 미사용. 데이터 버전 관리 없이 실시간 데이터를 읽음.
READ COMMITTED MVCC를 사용하여 가장 최근의 커밋된 버전을 읽음
REPEATABLE READ MVCC를 사용하여 트랜잭션 시작 시점의 스냅샷 데이터를 기준으로 읽기 작업을 수행함.
SERIALIZABLE 읽기 작업에서는 MVCC을 사용.
SELECT ... FOR UPDATE 또는 INSERT/UPDATE/DELETE 작업에서 레코드 잠금이나 범위 잠금을 통해 팬텀 리드 방지