데이터베이스(쉬운코드)
19. 요즘 concurrency control 기법 MVCC 1부 : 개념 & case study
youbing
2025. 1. 29. 14:51
본 내용은 유튜버 쉬운코드의 강의 "데이터베이스"를 참고하여 작성하였습니다.
MVCC
- Lock-based concurrency control : 동시에 처리할 수 있는 양이 줄어들어 성능이 좋지 않음 -> MVCC 등장
Lock-based concurrency control | read | write |
read | O | X |
write | X | X |
MVCC | read | write |
read | O | O |
write | O | X |
MVCC (multiversion concurrency control)
예제 : x = 10인 상태에서 x를 읽는 작업과 x를 50으로 바꾸는 작업을 동시에 실행한다.
- MVCC는 commit 된 데이터만 읽는다.
- recoverability를 위해 commit 할 때 write lock을 unlock 한다.
- tx2가 commit 된 이후 x를 다시 읽게 되면 tx1의 isolation level에 따라 값이 달라진다.
- read committed : read 하는 시간을 기준으로 그전에 commit 된 데이터를 읽음 -> x = 50
- repeatable read : tx 시작 시간 기준으로 그전에 commit 된 데이터를 읽음 -> x = 10
- read uncommitted : MVCC는 commit 된 데이터를 읽기 때문에 보통 적용 X (postgreSQL은 read uncommitted가 read committed처럼 동작)
- serializable : (mySQL) MVCC로 동작하기 보다는 lock으로 동작 / (postgreSQL) SSI(Serialzable Snapshot Isolation) 기법이 적용된 MVCC로 동작
- 데이터를 읽을 때 특정 시점 기준으로 가장 최근에 commit 된 데이터를 읽음. (특정 시점은 isiolation level에 따라 다름.)
- mySQL에서는 이를 consistent read라고 함.
- 데이터 변화(write) 이력을 관리함.
- read와 write는 서로를 block 하지 않음.
postgreSQL에서 lost update 문제와 해결
예제 : x = 50, y = 10인 상태에서 x가 y에 40을 이체하는 작업과 x에 30을 입금하는 작업을 실행한다. (두 tx 모두 isolation level이 read committed)
- 정상적으로 동작한다면 최종 결과는 x = 40, y = 50이 되어야 한다.
- 위의 사진과 같이 동작하면 x = 80, y = 50이 된다. -> lost update(tx1이 x에서 40을 뺀 과정이 누락됨.)
-> 이를 해결하기 위해 tx2의 isolation level을 repeatable read로 변경
- tx1이 commit 되는 순간까지는 동일함.
- tx2가 x = 80을 쓸 때 실패(-> rollback)가 뜸. -> tx1만 성공하고 작업 종료
- postgreSQL은 같은 데이터에 먼저 update한 tx가 commit 되면 나중 tx는 rollback 된다.
-> first-updater-win
Q. tx1이 read committed이어도 괜찮은가?
- 이를 확인하기 위해 tx2가 먼저 시작해봄.(왼쪽 사진) -> lost update 발생
- tx1도 repeatable read로 바꾸면 tx2가 commit 되고 tx1이 rollback 되면서 정상적으로 동작함.
mySQL에서 lost update 문제
- postgreSQL과 달리 repeatable read에서 rollback 하지 않으므로 lost update 문제가 해결되지 않음. -> 다음 강의에서 계속.