오래 못 할 짓 하지 않기

[ 데이터베이스 ] 18. MVCC 개념 본문

3학년 1학기/데이터베이스(DB)

[ 데이터베이스 ] 18. MVCC 개념

쫑알bot 2024. 2. 6. 14:12
728x90

 

Lock 기반으로 동작하는 경우에는

Read하는 Tx끼리만 동시에 동작이 가능하다.

 

 

 

MVCC 기반으로 동작하는 경우에는

Write만 동시에 동작하는 게 아니라면 다른 경우는 모두 동시에 동작이 가능하다.

 

 

(이제부터 예시에는 Write Lock 이런 거 표시 안 함. 그냥 Write하면 Lock된 거임)

(마찬가지로 Commit 되면 Unlock이 된 것)

 

 

Tx2에서 x를 50으로 바꾸는데,

이게 Lock이 풀리기 전까지는 Tx2에서만 알 수 있는 공간에 x=50으로 저장해둔다.

→ 이 다음에 Tx1이 x값을 읽으면 Tx2에서만 알 수 있는 값인 50이 아니라

     DB에 커밋되어있는 값인 10을 가져온다.

 

커밋되면 DB에도 50이 저장된다.

 

 

Commit 을 할 때 Unlock하는 이유 = Recoverability

 


저 Commit 이후에 다시 Tx1이 동작하면 읽는 값은 얼마일까?

Isolation 레벨에 따라 다른다.

 

 

● Read Committed

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

 

 

● Repeatable Read

 : Tx 시작 시간 기준으로 그 전에 commit된 데이터를 읽는다.

 

저 화살표가 있는 곳이 Tx시작 시간 기준이므로, 그 뒤에 Commit된 값이 50이고

그 전에 Commit된 건 10이다.

 

 

 MVCC 특징

 

1) 데이터를 읽을 때 특정 시점 기준으로 가장 최근에 Commit된 데이터를 읽는다.

   특정 시점 : Isolation Level에 따라 다르다.

 

2) 데이터 변화 이력을 관리한다.

 

3) Read 와 Write는 서로 Block하지 않음.

 

 

 

> Tx1에서 x값을 읽는다.

> x에서 40을 뺀다.

> Commit하지 않고, Tx1만 접근할 수 있는 공간에 x와 y값을 저장한다.

 

> Tx2에서 x값을 읽는다.= 50

> x에 30을 더했다. = 80

> 쓰려고 하는데 Write Lock을 획득하지 못하여 x=80을 쓰지 못하고 기다린다.

 

> Tx1에서 y값을 읽는다. = 10

> y값에 40을 더한다. = 50

 

Tx1는 할 거 다 했으니 Commit (= Unlock)

기다리고 있던 Tx2의 write가 80이란 값을 업데이트한다.

 

결과는 원래 x=40 , y=50 이어야하는데

x= 80 , y= 50이 된다.

 

x에 40을 뺀 업데이트가 없어진 거다.

이런 경우를 Lost Update라고 한다.

 

 

● 해결법 

 

- Isolation Level을 바꾼다.

 

Tx2의 Isolation Level을 Repeatable Read로 바꿔보자

 

Repeatable Read의 특징을 이용한다

First-updater-win

- 같은 데이터에 먼저 Update한 Tx가 Commit을 하면 나중에 오는 Tx는 Rollback된다.

 

 

 

 


 

Tx2에서 x값을 읽는다.    = 50

> Tx1에서 x값을 읽는다.         = 50 

> Tx2에서 x에 30을 더한다     = 80 ( Write Lock획득)

> Tx1에서 x에 40을 뺀 값을 쓰려고  하는데 ?? Lock 획득 X

> Tx2에서 Commit 

> Tx2에서 Lock 획득 후, x값 업데이트

> 뒤에 진행~~~

 

근데 Commit하기 전에 값을 읽고, 계산하고

그 값을 Commit된 뒤에 끄적끄적 하면

 

읽었을 때랑 Commit 되었을 때 값이 다를 수밖에 없을 것이다.

따라서 Tx1의 Isolation Level 도 바뀌어야 한다.

 

Tx1 의 Isolation Level이 Repeatable read라면

 

→ Tx2가 Commit한 뒤에 Tx1에서 읽으려고 할 때

 같은 데이터에 대해 먼저 업데이트 된 것이 있기 때문에 Roll-Back 실행

 

 

 

그럼 이걸 어떻게 해결해야할까?

 

다음 강의에서...

 

(출처)

유튜브 쉬운코드