데이터베이스

recoverability

승무_ 2023. 8. 26. 21:52

지난 포스팅에서 schedule과 serializable에 대해서 알아보았습니다.

지난 포스팅에 대해서 요약해봅시다.

schedule은 여러 트랜잭션이 실행될 때 각 트랜잭션에 속한 operation들의 실행 순서이며, 여러 케이스의 schedule이 존재한다고 했습니다.

그리고 schedule에는 nonserial schedule serial schedule이 존재하며, nonserial schedule은 비정상적인 결과를 도출할 수 있습니다.

하지만 nonserial schedule이 동시에 여러 트랜잭션을 처리할 수 있어 같은 시간동안 serial schedule에 비해 더 많은 트랜잭션을 처리할 수 있습니다.

그래서 nonserial schedule이 serial schedule과 equivalent(동등한)하다면 실행시키자고 결정했습니다.

nonserial schedule과 serial schedule이 equivalent함을 정의하기 위해서 conflict of two operation에 대해서도 언급했습니다.

nonserial schedule에서 모든 conflict of two operation의 순서가

serial schedule 중 하나라도 serial schedule의 모든 conflict of two operation의 순서와 동일하다면,

nonserial schedule은 serial schedule과 equivalent하며, confilct serializable하다고 했습니다.

따라서 이런 nonserial schedule은 serializability 속성을 갖기 때문에 정상적인 결과를 도출하여 이러한 nonserial schedule은 허용하기로 하였습니다.

Recoverability

이번 포스팅에서는 트랜잭션의 rollback과 관련해서 recoverability가 무엇인지 알아보겠습니다.

예시는 여전히 똑같이 이체를 예시로 하겠습니다.

A계좌 100만원, B계좌 200만원

transaction1: A가 B의 계좌에 20만원을 이체하는 작업

  1. r1(A): A의 계좌를 조회합니다.(DB read)
  2. w1(A): A의 계좌에서 20만원을 뺍니다.(DB write)
  3. r1(B): B의 계좌를 조회합니다.(DB read)
  4. w1(B): B의 계좌에 30만원을 더해줍니다(DB write)

transaction2: B가 자신의 계좌에 30만원을 입금하는 작업

  1. r2(B): B의 계좌를 조회합니다.(DB read)
  2. w2(B): B의 계좌에 30만원을 더해줍니다(DB write)

unrecoverable schedule

여기서 이러한 schedule이 있다고 생각해봅시다.

r1(A)-w1(A)-r2(B)-w2(B)-r1(B)-w1(B)-commit1

(tx1) A의 계좌를 조회하고 20만원을 빼는 작업 도중에 (A: 80)
(tx2) B의 계좌를 조회하고 30만원을 더해주는 작업이 진행됐습니다. (B: 230)
(tx1) 그리고 마저 B의 계좌를 읽고 20만원을 더해주는 작업을 진행 후 tx1은 commit을 했습니다. (B: 250)

tx2는 아직 commit하지 않았는데 이 tx2에 문제가 발생해서 이 시점에서 rollback을 해야합니다.

그래서 tx2를 시작하기 전 상태인 B의 계좌를 200만원으로 돌려놓습니다.

그럼 여기서 문제가 발생합니다.

tx1가 작업을 완료하면서 B의 계좌에 250만원을 업데이트 했는데 tx2가 rollback을 하는 바람에 B의 계좌가 200만원이 되어버렸습니다.

자 그리고, tx2는 문제가 생겨서 rollback을 했기 때문에 tx2가 했던 작업들은 이제 유효한 작업이 아닙니다.

그런데 tx1이 tx2에서 진행한 쓰기 작업(230만원으로 업데이트)한 값을 읽었습니다. 그러니까 유효하지 않은 작업을 통해서 만들어진 값을 tx1이 읽게 된 것입니다.

유효하지 않은 값은 tx1번이 읽었기 때문에 tx1에도 문제가 발생한 것이며 마찬가지로 tx1로 rollback을 해주어야 합니다.

하지만 ACID 포스팅에서 살펴보았듯이 durability 속성에 의해서 tx1은 commit 했기 때문에 rollback을 진행할 수 없습니다.

그래서 결국 A의 계좌는 80만원인데, B의 계좌는 200만원이 되어버렸습니다.

  •  unrecoverable schedule이란

한 schedule에서 commit된 트랜잭션(tx1)이 rollback된 트랜잭션(tx2)이 수행한 write 작업을 읽는 schedule을 말합니다.

unrecoverable schedule은 rollback을 해도 이전 상태로 회복이 불가능할 수 있기 때문에(tx1 rollback을 진행할 수 없음) 이러한 schedule은 애초에 DBMS가 허용해서는 안 됩니다.

recoverable schedule

그러면 위의 예시를 recoverable schedule로 만들어 봅시다.

r1(A)-w1(A)-r2(B)-w2(B)-r1(B)-w1(B)

아직 tx1과 tx2가 둘 다 commit하지 않았습니다.

여기서 tx1은 tx2에 의존하고 있습니다.(tx2가 write한 데이터를 tx1가 읽고 있음)

tx1이 먼저 commit을 해버리면 tx2를 abort하여 rollback이 일어났을 때 tx1을 rollback할 수 없습니다.

즉 tx2를 먼저 rollback을 하든 commit을 하든 먼저 종료시켜주어야 tx1도 commit을 하든 rollback을 하든 할 수 있습니다.

  • recoverable schedule이란

schedule 내에서 그 어떤 트랜잭션(A)도 다른 트랜잭션(B)이 write한 데이터를 읽는 경우, B가 commit 혹은 rollback하여 트랜잭션을 종료하기 전에 자신(A)도 종료(commit)하지 않는 schedule을 말합니다.

트랜잭션 A, B로 예를 들었지만 다수의 트랜잭션을 의미하는 겁니다.

이러한 recoverable schedule은 rollback이 가능하여 온전히 돌아갈 수 있기 때문에 DBMS는 이러한 schedule만 허용해야 합니다.

그리고 아까 보았듯이 tx2가 rollback을 진행하면 tx2가 write한 데이터 역시 유효하지 않은 데이터이기 때문에

tx2가 write한 데이터를 읽는 tx1도 역시 rollback을 진행해주어야 합니다.

따라서 하나의 트랜잭션(tx1)이 다른 트랜잭션(tx2)에 의존하고 있는 경우 tx2가 rollback한다면 tx1도 rollback을 진행해주어야 합니다.

이러한 연쇄적 rollback을 cascading rollback이라고 합니다.

그런데 이러한 cascading rollback은 여러 트랜잭션을 다시 연쇄적으로 rollback하는 일이기 때문에 처리하는 비용이 많이 듭니다.

(지금은 tx1, tx2만 예로 들지만 schedule에 참여하는 트랜잭션이 많아지면 rollback 해야하는 트랜잭션들도 많아지겠죠)

cascadeless schedule

cascading rollback은 처리 비용이 많이 드는 작업입니다. 그러면 이를 어떻게 해결해야 할까요?

cascading rollback이 일어나지 않는 schedule이 있습니다. 이를 cascadeless schedule이라고 합니다.

  • cascadeless schedule은

schedule 내에서 어떤 트랜잭션도 commit 되지 않은 트랜잭션들이 write한 데이터는 읽지 않는 경우입니다.

즉, schedule 내에서 어떤 트랜잭션(A)이 다른 트랜잭션(B)에 의존하고 있을 때, B가 commit 혹은 rollback하여 트랜잭션이 종료된 후에 B가 write한 데이터를 A가 읽는 schedule을 말합니다.

트랜잭션 A, B로 예를 들었지만 다수의 트랜잭션을 의미하는 겁니다.
avoid casacding rollback이라고도 부릅니다.

r1(A)-w1(A)-r2(B)-w2(B)-commit2-r1(B)-w1(B)-commit1

이런식의 schedule을 의미합니다. 그리고 DBMS는 이러한 schedule만 허용하도록 하는 것입니다.

이렇게 하면 tx1은 tx2에 의존하지 않게 됩니다. tx2는 종료되었고, 이미 종료된 트랜잭션이 작업한 데이터를 읽고 있으니까요.

그럼 cascadeless schedule은 전혀 문제가 없을까요? 안타깝게도 그것도 아닙니다...

strict schedule

이번엔 다른 예시를 들어봅시다.

tx1. 피자집 사장님(A)이 피자 가격을 3만원에서 2만원으로 낮추려고 합니다.

tx2. 직원(B)는 이 얘기를 듣고 자신이 사장님 대신 2만원으로 낮추려다가 실수로 1만원으로 내려버린 겁니다.

이 두 트랜잭션이 겹쳐서 실행된다고 생각해봅시다.

그러면 이러한 schedule이 나올 수 있습니다.

w2(A) - w1(B) - commit1 - abort2(rollback)

잘 살펴보면

직원이 피자 가격을 1만원으로 내렸습니다. 그리고 사장님이 피자 가격을 2만원으로 내렸습니다.

그리고 tx1은 commit을 진행했습니다.

그런데 tx2에 문제가 발생해서 rollback을 진행합니다.

그러면 어떻게 될까요?

사장님이 업데이트했던 피자 값 2만원을 없어지고 피자 값이 다시 3만원이 됐습니다.

끔찍한 경우입니다. DB에 업데이트 한 값이 사라졌으니까요.

그런데 이 schedule은 cascadeless schedule입니다.

앞에서 언급한 cascadeless schedule을 그대로 복사해오겠습니다.

schedule 내에서 어떤 트랜잭션도 commit 되지 않은 트랜잭션들이 write한 데이터는 읽지 않는 경우입니다.

즉, schedule 내에서 어떤 트랜잭션(A)이 다른 트랜잭션(B)에 의존하고 있을 때, B가 commit 혹은 rollback한 후에 B가 write한 데이터를 A가 읽는 schedule을 말합니다.

그런데 위에 scehdule에서는 read 작업은 없습니다. 쓰기 작업만 있죠. 그래서 cascadeless schedule이 맞습니다.

  • strict schedule이란

schedule 내에서 어떤 트랜잭션도 commit 되지 않은 트랜잭션들이 write한 데이터는 읽지도 쓰지도 않는 경우입니다.

그래서 위에 살펴본 예시는 cascadeless schedule은 맞지만 strict schedule은 아닌겁니다.

자 그럼 위의 예시를 strict schedule로 바꿔봅시다.

w2(A) - commit2 -  w1(B) - commit1

tx2가 먼저 commit 혹은 rollback을 하고 tx1이 데이터를 읽든 쓰든 접근하는 겁니다.

strict schedule은 rollback 할 때 recovery가 쉽습니다.

그냥 transaction 이전 상태로 돌려놓기만 하면 됩니다.

정리

unrecoverable schedule은 rollback 할 때 회복이 불가능 할 수 있기 때문에 DBMS에서 허용하면 안됩니다.

그러면 어떻게 해야하나?

rollback 할 때 회복 가능한 recoverable schedule만 허용하면 됩니다.

recoverable schedule 중에 cascadeless schedule이 존재하며, 이것보다 더 엄격한 schedule을 strict schedule이라고 합니다.

그래서 결론적으로

어떤 schedule에서 txA가 commit되지 않은 txB가 write한 데이터를 읽는 경우,

txB가 commit하기 전까지 txA는 그 데이터를 읽지 않는 schedule을 recoverable 한 schedule이라고 하며,

이러한 schedule은 recoverability 속성을 가진다고도 말합니다.

자 그럼 concurrency control은 도대체 무엇인데 제목에 써놓기만 하고 말도 없는가?

concurrency control은 serializability와 recoverability를 가지는 schedule만 허용할 수 있도록 하는 기능이고, 이와 밀접하게 관련있는 트랜잭션 속성이 바로 Isolation입니다.

'데이터베이스' 카테고리의 다른 글

schedule, serializability  (0) 2023.08.25
Index  (0) 2023.07.07
Transaction  (0) 2023.07.06
DB구조 & 설계  (0) 2023.07.04
RDB와 NoSQL의 차이에 대해 설명해 주세요.  (0) 2023.06.23