https://d2.naver.com/helloworld/407507

 

위 D2 내용에서 트랜잭션과 WAL 에 대해 공부하고 정리함

 

 

< WAL 이란? >

 

WAL 은 Write-ahead logging 의 약자이다.

트랜잭션이 일어나기 전에 로그를 미리 기록하여 트랜잭션 undo, redo 를 할 수 있도록 한다.

 

위에 bold 처리한 트랜잭션, 로그, undo, redo 가 무엇인지 아래서 자세히 설명한다.

 

 

 

< 트랜잭션이란? >

 

트랜잭션이란, 하나의 논리적 작업 단위를 구성하는 일련의 연산들의 집합이다.

예를 들어, A 가 B 에게 1000원을 송금한다고 하자.

그 작업은 다음과 같은 일련의 작업이 될 것이다.

 

1. A 계좌에 1000원이 있는지 확인한다.

2. A 계좌에서 1000원을 뺀다.

3. B 계좌에 1000원을 추가한다.

 

위의 1,2,3 일련의 작업을 하나의 트랜잭션이라고 볼 수 있다.

 

트랜잭션은 ACID 성질이라고 하는 다음의 네 가지 성질로 설명된다.

- Atomicity (원자성)

  트랜잭션의 연산들은 모두 정상적으로 수행되거나 혹은 모두 수행되지 않아야 한다.

  위에 예를 든 트랜잭션의 2번 작업을 진행한 후에 갑자기 멈춰버린다면, A 는 1000원을 잃고 B 는 1000원을 받지 못한다.

  atomicity는 쉽게 'all or nothing' 특성으로 설명된다.

 

- Consistency(일관성)

  트랜잭션의 수행이 데이터베이스의 일관성을 보존해야 한다.

  즉, 성공적으로 수행된 트랜잭션은 정당한 데이터들만을 데이터베이스에 반영해야 한다.

  예시 : https://eyeballs.tistory.com/504

 

- Isolation(독립성)

  여러 트랜잭션이 동시에 수행되더라도 각각의 트랜잭션은 다른 트랜잭션의 수행에 영향을 받지 않고 독립적으로 수행되어야 한다.

   트랜잭션의 중간 결과가 다른 트랜잭션에게는 숨겨져야 한다는 의미이다.

  왜 서로 영향이 없어야 할까? 만약 isolation 성질이 보장되지 않으면 트랜잭션이 원래 상태로 되돌아갈 수 없기 때문이다.

  Isolation 성질을 보장할 수 있는 가장 쉬운 방법은 모든 트랜잭션을 순차적으로 수행하는 것이다.

  (먼저 온 것부터 차례대로 수행하는 FIFO 수행하는 것을 말 하는 듯)


- Durability(지속성)

  트랜잭션이 성공적으로 완료되어 커밋되고 나면,

  해당 트랜잭션에 의한 모든 변경은 (향후에 어떤 소프트웨어나 하드웨어 장애가 발생되더라도) 보존되어야 한다.

 

트랜잭션 실행 중에

- 잘못된 입력

- 일관성 제약 조건 위배

- 사용자 요청

- 타임 아웃

- 교착 상태

등 발생 가능한 여러가지 상황에 따라 트랜잭션이 철회될 수 있다.

트랜잭션을 철회하기 위해 (로그를 이용하여) undo 복구를 사용한다.

 

여기서 말하는 로그는 뭐고 undo 는 뭘까?

아래서 설명

 

 

< undo 복구, redo 복구 란? >

 

undo 복구란, 트랜잭션이 작업을 진행하기 전 데이터로 되돌리는 것을 말한다.

(실행중인 트랜잭션이 어떤 이유든 비정상적으로 종료되는 경우, 트랜잭션이 변경한 데이터들을 다시 원래대로 복구하는 작업)

 

undo 복구가 왜 필요할까?

트랜잭션 작업이 중간에 종료되었는데, 중간까지의 결과물이 디스크에 쓰여졌을 때

undo 복구를 하지 않는다면 중간 결과물이 최종 결과물처럼 오해될 수 있기 때문이다.

위 ACID 의 Atomicity 원자성 부분 설명 예를 참고하자.

해당 예에서 중간에 트랜잭션이 종료되어 A 가 1000원을 잃어버리게 되는 상황이 왔을 때(중간 결과물이 디스크에 쓰여진 상황)

A 계좌에 다시 1000원을 증가시켜 원래대로 되돌리는 undo 복구를 진행한다.

 

redo 복구란, 트랜잭션이 작업을 진행한 후 상태로 되돌리는 것을 말한다.

(이미 커밋한 트랜잭션의 수정을 재반영하는 복구 작업)

 

redo 복구가 왜 필요할까?

트랜잭션 작업이 제대로 진행되었고 그 결과가 메모리에만 쓰여지고 디스크에는 쓰여지지 않았을 때

정전이 되어서 메모리가 날아가는 경우, 트랜잭션 작업 결과도 사라지게 된다.

이 경우, 트랜잭션 결과를 다시 복구하기 위해 (로그를 이용하여) redo 복구를 진행한다.

 

 

 

< 로그란? >

 

로그는 로그 레코드의 연속이며 데이터베이스의 모든 갱신 작업을 기록한다.

로그는 안정적 저장 매체(stable storage)에 기록되어야 한다.

로그는 덧붙이는(append) 방식으로 기록되며, 각 로그 레코드는 고유의 식별자를 갖는다.

(로그 레코드의 식별자를 LSN(Log Sequence Number) 혹은 LSA(Log Sequence Address)라고 부른다.)

로그는 항상 뒤에 덧붙이는 방식으로 쓰이기 때문에, 로그 식별자는 단조 증가하는 성질을 가진다.

 

로그는 다음과 같은 방법으로 저장된다.

 

- 물리적인 상태 로깅(physical state logging)
  트랜잭션의 실행 이전 데이터와 이후 데이터를 모두 로그에 기록한다.

  undo 복구를 하면 실행 이전 데이터를 반영하고

  redo 복구를 하면 실행 이후 데이터를 반영한다.

  DBMS에서 가장 널리 쓰이는 기본적인 로깅 방법이다.

 

- 물리적인 전이 로깅(physical transition logging)
  트랜잭션 이전과 이후 데이터의 XOR 차이점을 로그에 기록한다.

  로그에 기록된 XOR 차이점을 이용하여 UNDO 복구와 REDO 복구를 수행하게 된다.

 

- 논리적인 전이 로깅(logical transition logging)
  트랜잭션이 어떤 일을 했었는가를 기록하는 방식이다.

  예를 들어, a = 0; a = a + 1과 같은 연산을 로깅할 때

  물리적인 상태 로깅의 경우 이전 값 0, 이후 값 1을 물리적으로 기록하지만

  논리적인 전이 로깅의 경우 오퍼레이션(a = 0; a = a + 1 이라는 연산 그 자체)을 기록한다.

  redo 복구를 하면 로그에 기록된 오퍼레이션을 재수행하고

  undo 복구를 하면 역오퍼레이션을 수행한다.

  오퍼레이션 로깅(operation logging)으로도 불린다.

 

 

해당 업데이트가 데이터베이스에 써지기 전에 먼저 관련된 UNDO 정보가 로그에 써져야 한다. 

이 원칙을 WAL(Write Ahead Logging)이라고 부른다. 

어떤 경우에도 UNDO 복구가 되기 위해서는 반드시 WAL 규칙이 준수되어야 한다.

트랜잭션이 정상적으로 종료 처리되기 위해서는 먼저 REDO 정보가 로그에 써져야 한다. 

역시 어떤 경우에도 REDO 복구를 할 수 있기 위해서는 REDO 로그가 적어도 커밋 시점에는 써져야 한다.

 

로그는 복구를 위해 무조건적으로 안전한 저장소에 쓰여져야 한다.

 

 

 

 

 

 

참고

https://bourbonkk.tistory.com/86

 

 

 

 

+ Recent posts