STUDY/database

[DB] MVCC 설명_1 (쉬운코드)

까미이모 2023. 12. 19. 16:23

MVCC (multiversion concurrency control)

  • 데이터를 읽을때 특정시점 기준으로 가장 최근에 commit된 데이터를 읽는다 → 이걸 MySQL에서 Consistent read 라 한다
  • 데이터 변화(write)이력을 관리한다 (추가적인 저장공간 사용)
  • read와 write는 서로를 block하지 않는다

 

예시1) x = 10

Transaction 1 : x를 읽는다

Transaction 2 : x를 50으로 바꾼다

Transaction 1 Transaction 2
  write(x = 50) (lock획득)
read(x) = 10  
  commit
read(x) = ?  

tx1의 두번째 read(x)값은 isolation레벨에 따라 다르다

read committed 레벨이면 x는 read하는 시간을 기준으로 그전에 commit된 데이터를 읽으므로 x = 50

repeatable read 이면 tx시작 기준으로 그전 commit데이터를 읽으므로 x = 10

 

참고 : recoverability를 위해 commit할때 write lock을 unlock한다

 

read committed level

read하는 시간을 기준으로 그전에 commit된 데이터를 읽는다

 

repeatable read level 

tx시작 시간 기준으로 그전에 commit된 데이터를 읽는다 (RDBMS마다 다를수 있다)

 

Serializable 레벨에서는 어떻게 동작할까?

결과로는 repeatable read 와 같고 동작방식엔 차이가 있다

MySQL : MVCC로 동작하기 보다는 lock으로 동작한다

PostgreSql : SSI(Serializable Snapshot Isolation) 기법이 적용된 MVCC로 동작한다

 

Read uncommitted?

MVCC는 committed된 데이터를 읽기 때문에 이 level에서는 보통 MVCC가 적용되지 않는다

 

PostgreSql 기준 예시

예시1) x = 50, y = 10

Transaction 1 : x가 y에 40을 이체한다

Transaction 2 : x에 30을 입금한다

Transaction 1 (Read committed) Transaction 2(Read committed)
read(x) = 50  
write(x = 10) (lock)  
  read(x) = 50
  write(x = 80) (기다림)
read(y) = 10  
write(y = 50)  
commit  
  write(x = 80)
  commit

결과는 x = 80, y = 50으로 lost update가 발생한다

 

같은 예제에서 tx2를 repeatable read 로 바꿔 보면?

Transaction 1 (Read committed) Transaction 2(repeatable read)
read(x) = 50  
write(x = 10) (lock)  
  read(x) = 50
  write(x = 80) (기다림)
read(y) = 10  
write(y = 50)  
commit  
  write(x = 80)
  rollback

PostgreSql의 repeatable read 규칙

- first-updater-win : 같은 데이터에 먼저 update한 tx가 commit되면 나중 tx는 rollback 된다

같은 예제로 tx1이 read committed일때는 여전히 lost update가 발생할 수 있다. 따라서 lost update를 해결하기 위해서는 연관있는 transaction 두개 다 repeatable read 여야 한다.

 

 

출처: 쉬운코드