Data Buffer Cache, Log Buffer 존재 이유


- Data Buffer Cache : DB 의 최소 입출력 단위인 Block 이 상주하는 곳으로, 쿼리 수행시에 필요한 Data block 이 위치하는 메모리 영역.
- Log Buffer : 쿼리 수행시 변경사항 (DML) 에 의해 Data 의 변경이 발생한 내역을 Log 로 남겨 저장하는 메모리의 영역.
- Checkpoint : Data buffer cache 에서 Datafile 로 기록될때 실질적으로 발생.
- Commit : Checkpoint 이전에 발생할 수 있는 에러에 대비하여 Recovery 를 제공하는것.
           즉, Data 변경사항에 대하여 redo log 를 남기는 행위이며, checkpoint 는 Data buffer cache 의 변경된
           (dirty buffer) block 을 data file 에 기록하는 것.
- 결론 : DB 에서 Data 정합성을 유지하며, 나은 성능을 보장하기 위하여 Log buffer 와 Data buffer cache 가 존재.

Redo Log file의 개념

  • Redo log file은 Redo log buffer에 기록된 내용을 기록해 두는 파일.
  • Redo log buffer는 휘발성으로 LGWR을 통해 여러 조건에 맞을 때 안전하게 파일에 기록.
  • DB에 장애가 생겼을 때 redo log file이 없으면 데이터를 복구할 수가 없음.

Redo Log 목적

Database Recovery


- 물리적으로 Database 가 손상되었을 경우 복구하게 되며,
  이 부분은 백업부분을 restore 한 뒤에 장애가 나기전 시점, 혹은 원하는 시점까지
  recovery 하는 부분. Media recovery 라고 하며 이 경우 주로 Archive log 를 이용한다.

Cache Recovery(Instance Recovery)


- Instance 가 비정상 적으로 종료되고 재기동 하면 Online Redo 로그에 저장된 기록을
  읽어들어 마지막 체크포인트이후 부터 사고 직전까지 수행되었던 트랜잭션을 재현한다.
  Roll forward 단계라고 하며, 버퍼캐시에만 수정하고 데이터파일에는 반영되지 않았던
  변경사항들이 복구된다. 여기서는 트랜잭션 Commit 여부를 확인하지 않는다.
  
  이후 Transaction Recovery 가 시작되며, 여기서 UNDO 데이터를 이용한 Commit 여부를 체크한다.
  시스템이 비정상 종료 되는 시점에 Commit되지 않았던 트랜잭션을 모두 Rollback 진행하여
  데이터파일에는 커밋에 성공한 데이터만 남게 되며, 데이터베이스는 완전히 동기화 됩니다.

Fast Commit


- 변경된 메모리 버퍼 블록을 디스크 상의 데이터 블록에 기록하는 작업은 Random 액세스 방식으로 이루어지기 때문에 느림.
  반면 로그는 Append 방식으로 기록하므로 상대적으로 매우 빠름.
  따라서 트랜잭션 발생 시 건건이 데이터 파일에 기록하기보다 우선 변경사항을 Append방식으로 빠르게 로그 파일에 기록하고
  메모리 데이터 블록과 데이터 파일 간 동기화는 적절한 수단(DBWR Checkpoint)을 이용해 나중에 배치(Bach) 방식으로 일괄적으로 수행.
  사용자의 갱신사항을 메모리의 버퍼블록에만 기록한 채 아직 디스크에 기록되지 않았지만 Redo 로그를 믿고 빠르게 커밋한다고 의미에서 Fast Commit 이라고 부른다.

참고

Fast Commit 장점


1). DBWR 백그라운드 프로세스가 데이터버퍼 캐쉬의 변경된 데이터블록을 디스크에 기록하는 속도보다 LGWR백그라운드 프로세스가
    리두로그 버퍼의 로그를 리두 로그파일에 기록하는 속도가 더 빠르며 시스템 부하를 감소(Disk IO 감소)
2). 오라클은 데이터블록단위 I/O를 수행하므로 데이터버퍼캐쉬에 존재하는 데이터블록에 저장 된 하나의 로우만 변경되어도 전체
    데이터 블록을 디스크의 해당 블록에 기록되어야 한다. 리두로그버퍼는 데이터 블록 단위I/O가 아닌 변경 된 부분만을 기록하게
    되므로 적은 디스크 I/O를 발생(Disk IO 감소)
3). 커밋외에도 다른조건에 의해 LGWR백그라운드 프로세스가 주기적으로 활동하며 커밋시 최소 단위의 내용만 기록한다.
    그러므로 트랜잭션이 변경하는 데이터의 양이 커밋 완료 속도에 영향을 미치지 않는다.

Fast Commit 지원 이유


- LGWR백그라운드 프로세스가 리두로그 버퍼의 로그를 리두로그파일에 기록하는 속도가 더 빠른 이유는 각각의 저장방식에의한 차이이다.
  LGWR백그라운드 포르세스는 지정된 데이터블록에 변경 내용을 저장하는 것이 아니라 리두로그파일에 순차적으로 기록하기 때문에 DBWR
  백그라운드 프로세스와는 달리 저장될 위치를 검색할 필요가 없기 때문이다.

Delayed 블록 클린아웃(Cleanout)

  • 트랜잭션이 갱신한 블록 개수가 총 버퍼 캐시 블록 개수의 1/10을 초과할 때 사용하는 방식.
    블록을 읽는 과정에서 Active 상태의 블록, 즉 다른 트랜잭션이 발생시킨 변경사항에
    대한 커밋 정보가 아직 1TL에 기록되지 않았다면 읽기 전에 먼저 블록 클린이웃을 시도
    한다. 1TL 슬롯에 기록된 트랜잭션 ID를 이용해 Undo 세그먼트 헤더에 있는 트랜잭션
    테이블 슬롯을 찾아가 트랜잭션의 현재 상태를 확인하고 커맛된 트랜잭션이라면 이를
    1TL 슬롯에 반영하고 로우 Lock 정보를 해제해 블록을 클린이웃시킨다. 블록 클린아웃
    을 위한 갱신내용도 Redo에 로깅 하며, 블록 SCN도 변경한다.

Write Ahead Logging

  • Buffer Cache 에 있는 블록버퍼를 갱신하기전에 먼저 Redo buffer 에 기록.
    (LGWR) Redo log buffer 기록되어 있는 해당 redo 엔트리를 모두 redo log file 에 기록 후에
    (DBWR) Buffer Cache 에 있는 Dirty 블록들을 디스크에 갱신할 수 있다.

LGWR가 Logfile에 기록하는 시점


1). 3초마다 DBWR프로세스로부터 신호를 받을 때.
2). 로그버퍼의 1/3이 차거나 기록 된 Rode레코드 양이 1MB가 넘을 때.
3). 사용자가 Commit 또는 Rollback을 날렸을 때.

설명

- 1)번과 2)번은 대량의 트랜잭션이 발생 해 이를 메모리에서 파일로 일괄 반영 할려고 할 때, 작업양이 한꺼번에 몰리는것을
  대비해 주기적으로 Dirty버퍼를 해소하고 로그버퍼를 비우도록 구현 된 부차적인 기능.
- 3)번은 Fast Commit 메커니즘의 핵심이며, 트랜잭션이 영속성을 보장 받으려면 최소한 커밋 시점에는 Redo정보가 메모리가 아닌
  디스크 상에 안전하게 저장되어 있음을 확인 해야 한다.

DBWR가 Dirty버퍼를 데이터파일에 기록하기 전에 로그 버퍼를 먼저 Redo 로그에 기록하는 이유?


- Instance Crash 발생 시 Redo 로그에 기록된 내용을 재현해 캐시 블록을 복구하고 최종적으로 커밋되지 않은 트랜잭션은 롤백하게
  되는데 Redo 로그에는 없는 변경내역이 이미 데이터 파일에 기록돼 있으면 사용자가 최종 커밋하지 않은 트랜잭션이 커밋되는 결과를
  초래하기 때문.

Fast Commit메커니즘 정리

1). 사용자가 커밋을 날림
2). LGWR은 커밋 레코드를 Redo 로그버퍼에 기록
3). 트랜잭션 로그 엔트리와 함께 redo로그 파일에 저장
4). 커밋을 수행한 트랜잭션에 "Success Code" 리턴

여기 까지 완료 하게 되면 아직 사용자의 갱신 내용이 메모리상의 데이터버퍼에만 기록되고 디스크에는 기록되지 않지만,
Instance Crash발생 하더라도 Redo로그를 이용해 언제든지 복구가 가능한 상태이므로 오라클은 안심하고 커밋을 완료 처리 한다.