본문 바로가기
컴퓨터공학/데이터베이스(database)

[Recovery]Log-based recovery

by 바코94 2020. 6. 4.

log recored는 우선 buffer에 저장을 하게 된다. 적절한 시점이 되면 storage에 있는 log db에 저장하게 된다. 이 때 disk io단위는 block이고 log도 블락 단위로 저장이 된다. 버퍼가 꽉 차면 디스크에 써야하고 log force라면 commit시 저장을 하게 된다.  

 

비용을 줄이기 위해 가급적 log 버퍼를 블락만큼 채워서 디스크에 써야 할 것이다. 

 

로그 기록은 생성된 순서대로 저장이 되어야 한다.

Ti가 commit state가 되려면 <Ti commit>이 log db에 저장되어야 한다.

 

 

Logging

트랜잭션이 정상적으로 수행될 떄 기록되는 로그를 살펴보자.

 

Logging(during normal operation)

<Ti start> : 트랜잭션이 시작될 때

<Ti, Xj, V1, V2> : 업데이트가 될 때

<Ti commit> : commit 될 때 

 

Ti 을 롤백 명령을 하는 경우 (during normal operation)

정상적인 롤백 명령을 할 때 생성되는 로그이다.

<Ti start>

<Ti, Xj, V1, V2>

rollback 시점

 

rollback 시점으로 부터 백워드 스캐닝을 하면 처음 로그로 <Ti, Xj, V1, V2>을 만난다. Xj를 V1로 바꾸고 <Ti, Xj,V1,V2> 의 짝으로 <Ti, Xj, V1>를 log db에 남긴다. 이 로그 레코드를 compensation log record라고 한다.  compensation log는 이후에 살펴볼 redo에 필요하게 된다.

<Ti start>를 만나면 백워드 스캐닝을 멈추고 <Ti abort>를 로그레코드에 남긴다.

정리하면 rollback을 하면 스캐닝을 백워드로 진행. <Ti Xj Vx, Vy>로그를 만나면 Xj를 Vx로 바꾸고 log에 <Ti,Xj Vx> 추가. <Ti start>를 만나면 <Ti abort>를 추가하고 백워드스캐닝 종료.

 

따라서 위의 <Ti start> <Ti, Xj, V1, V2> 을 하고 롤백하면 다음과 같은 로그로 바뀐다.

<Ti start>

<Ti, Xj, V1, V2>

<Ti, Xj, V1>

<Ti abort>

 

만약 트랜잭션 하나가 더 추가되면 어떻게 될까?

<Ti start>

<Ti, Xj, V1, V2>

<Ti, Xj, V2, V3>

 

이렇게 되면 백워드 스캐닝을 하면서 앞서 설명한 규칙을 따른다. <Ti, Xj, V2, V3>을 가장 먼저 만나므로 Xj를 V2로 바꾸고 compensation log <Ti Xj V2>가 먼저 생성된다. 다음으로 <Ti, Xj, V1, V2>를 만나면 Xj를 V1으로 바꾸고 compensation log인 <Ti Xj V1>이 기록된다. <Ti start>에 대하여 <Ti abort> 가 기록되고 스캐닝이 종료된다.

백워드 스캐닝 결과는 다음과 같다.

<Ti start>

<Ti, Xj, V1, V2>

<Ti, Xj, V2, V3>

<Ti Xj V2>

<Ti Xj V1>

<Ti abort>

 

이것을 가지고 알고리즘을 진행한다. 핵심은 백워드 스캐닝을 하면서 로그를 순서상 뒤쪽에 추가하는 것이다. 로그의 순서도 신경써야 한다.

 

two phase recovery algorithm

redo phase: commited, aborted, imcomplete 트랜잭션은 모두 redo한다.

undo phase: incomplete 트랜잭션은 모두 undo한다.

 

redo phase에서 commited, aborted 트랜잭션은 정상적으로 수행됬기 때문에 redo하는 것이 당연하다. 하지만 incomplete는 redo하지만 정상적으로 수행되지 않았기 때문에 undo 해야한다.

 

redo phase

<checkpoint L>을 기준으로 포워드 스캐닝을 하면서 undo-list와 redo-list를 만든다.

undo-list는 L을 보고 만든다. L은 commit 당시에 commit되지 않은 트랜잭션이기 때문에 undo의 대상이 되는 것이다. checkpoint 시점 이후에 로그 레코드를 포워드 스캐닝을 하면서 <Ti, Xj, V1, V2>를 보면서 Xj를 V2로 write하여 redo 작업을 한다. 

<Ti start>를 보면 undo-list에 Ti를 넣는다. 즉 checkpoint 이후에 시작한 트랜잭션은 undo-list에 들어간다. 이후 Ti에 대해 <Ti commit>이나 <Ti abort>가 발견되면 undo-list에서 Ti를 뺸다.

이 알고리즘은 모든 트랜잭션에 대해서 update를 수행하기 때문에 redo-list 없이 undo-list만 만들어 낸다.

 

undo phase

redo phase에서 구한 undo-list를 사용한다.

failure 시점 기준으로 백워드 스캐닝을 하면서 <Ti, Xj, V1, V2>가 undo-list에 있다면 Xj를 V1으로 write한다. 이 작업을 하고 <Ti, Xj, V1>을 로그 레코드를 추가해야 한다.

스캐닝 중 <Ti start> 를 만나면 undo-list에서 지우고 <Ti abort>를 로그 레코드에 추가한다. 

 

 

undo phase에서 compensation log를 안 남기면 어떻게 될까? 

<Ti start> <Ti Xj V1 V2> 트랜잭션이 있는 부분을 복구한다고 해보자. 그러면 redo undo에 의해

<Ti start>

<Ti Xj V1 V2>

<Ti Xj V1>

<Ti abort>

와 같은 로그가 남을 것이다. 근데 compensation log를 안 남기면

<Ti start>

<Ti Xj V1 V2>

<Ti abort>

이런 로그가 남게 된다.

 

복구 도중 undo phase가 완료되지 않고 진행 중에 failure가 또 발생했다고 하자. 그러면 다시 복구를 진행하게 된다.

redo phase에서는 Xj를 V2로 바꾸게 된다. <Ti abort>를 만나게 되면 undo-list에서 빠지게 된다. undo phase에서 undo-list가 없기 때문에 아무것도 하지 않는다.

 하지만 정상적인 상황은 checkpoint 이후에 Ti가 시작되었기 때문에 Xj가 V1으로 바뀌어야 복구가 잘 된 것으로 볼 수 있다. 하지만, compensation log를 남기지 않아 Xj가 V2로 바뀌는 것으로 복구되었다.

compensation log를 남기면 어떻게 될까?

<Ti start>

<Ti Xj V1 V2>

<Ti Xj V1>

<Ti abort>

이렇게 되면 redo phase에서 <Ti Xj V1 V2>에 의해 Xj가 V2로 바뀌지만 <Ti Xj V1> 로그 레코드를 통해 V1으로 다시 바꿔준다. undo phase에서 Ti 트랜잭션이 없다고 하더라도 정상적인 복구의 결과가 된다. 

 

이 알고리즘의 핵심은 redo하면서 업데이트하고 undo에서는 incomplete한 트랜잭션을 처리하는 것이다.

 

 

redo pahse

4.checkpoint에서 시작하고 undo-list={T0, T1}로 시작한다.

5.에서 C을 600으로 write한다. 

6.T1을 undo-list에서 뺀다. undo-list={T0}

7.T2를 undo-list가 정상적으로 끝났는지 모르므로 일단 넣는다. undo-list={T0,T2} 

8.A에 400을 write

9.T0 가 어디선가 롤백 되었다는 것을 파악한다. crash 발생 전에 정상적인 롤백이 이루어졌음을 알 수 있다. 이것을 통해 old value로 업데이트하게 된다. B를 1900으로 write.

10.T0는 정상적으로 수행된 트랜잭션이므로 undo-list에서 뺀다. undo-list={T2}

11.C에 300 write

undo-list={T2}

 

undo phase

11. T2가 undo-list에 있으므로 C를 600으로 write. 

8. A를 500으로 write

7. T2 start만났으므로 undo-list에서 뺀다. undo-list가 비어있으므로 undo를 완료한다.

 

12,13,14는 undo phase의 11,8,7에서 생성된 log record이다. 

'컴퓨터공학 > 데이터베이스(database)' 카테고리의 다른 글

[Recovery] Failure of Nonvolatile Storage  (0) 2020.06.04
[Recovery] Fuzzy checkpointing  (0) 2020.06.04
[Recovery] Log  (0) 2020.06.04
[Recovery]disk i/o  (0) 2020.06.03
[Recovery] Overview  (0) 2020.06.03