1. 인스턴스리커버리 과정 이해하기
 



※ 일반적인 생각 : 리커버리할때, 커밋된 데이터만 찾아서 데이터파일에 붓는다(x)
 
정답 : ①커밋이 되던지 안되던지 상관없이, 무조건 데이터파일에 다 붓는다.(o)
         그다음 ②DB open하고 ③roll back 안된 것들 undo 뒤져서 다 roll back 시킨다.

 
cf.) insert할때 커밋 안날려도 즉시 데이터파일에 저장된다. 나중에 커밋or롤백이 들어오는대로 수행.
 → 우선 데이터파일에 쓴다. 예를들어 100만건 인서트를 했는데 메모리에만 내버려두고 커밋이 들어왔을때 데이터파일에 내려쓰게 되면 느리다.
    그래서 미리 데이터파일에 내려써놓고 커밋명령하면 즉시 커밋된다.(데이터,컨트롤파일 헤더에 커밋되었다고 적어주기만 하면된다.)
 
리두로그에는 UNDO 내용도 같이 들어간다. (Chang vector에 redo내용, undo내용이 다 들어가있다.)
예를들어 'update 홍길동→일지매' 도중 장애가 발생(정전등..)하여 DB가 꺼졌다고 가정하자.
다시 DB를 켤때 인스턴스 리커버리를 하게 되는데 특정한 순서(SCN)대로 그동안의 작업이 적혀있던, redo log의 내용을 참고하여 고치게 된다.
이때, undo(즉, 업데이트 도중 커밋전에 언두에 적혀있는 기존 정보)의 내용도 redo log에 적히게 되고 이것이 리커버리 된다.
 
인스턴스 리커버리시3단계의 과정을 거치게 되는데
① Roll forward
② open
③ Roll back

의 순서로 인스턴스 리커버리가 일어난다.
 
즉, Redo log에 기록되어 있는 내용대로 다시한번 수행하여 DATAFILE에 내용을 다 입력한 후 DB를 OPEN시킨다.
그후, roll back해야 하는 것들은 undo를 참고하여 roll back하면 인스턴스리커버리가 완료된다.

 
- Redo log에는 작업이 순서대로 정렬이 되어있다. 이것들 중 골라서 적용시키려면 오히려 시간이 더 오래 걸리게된다.
  그래서 우선 순서대로 다 적용후 오픈한후, 천천히 롤백 과정을 거치게 된다.

 
 
Ex) DATAFILE에 SCN이 100번, control file에 105
    Redo log 에 103,104,105
    Archive log 에 101, 102
    일때, 인스턴스 리커버리 가능한가?
    ▶ 불가능하다.
이유 : 인스턴스 리커버리는 REDO에 다 들어 있어야 한다. SMON이 고치다가 STOP하게 된다.
정리 : 인스턴스리커버리는 REDO의 내용만 가지고 한다.

 
 


2. Redo log의 생성 및 기록 원리 




 

- Change vector
 : 변경된 데이터를 나중에 복구를 할 목적으로 redo log에 기록할 변경된 데이터에 대한 모든 정보의 세트
 : redo log에 적기위해 만든다.
 : redo내용, undo내용이 다 들어가있다.

 
- PGA에서 Change vector를 생성한 후 Redo log buffer 에서 필요한 용량을 계산 한 후
  서버프로세스는 change vector를 redo log buffer에 복사하기 위해 적절한 latch를 획득해야 한다.
  ① 첫번째로 redo copy latch를 획득해야한다.(1차면접)
  ② 두번째로 redo allocation latch를 확보해야한다.
     (8i까지 1개밖에 없어서 속도 저하가 일어 났음.

      9i부터 Redo log buffer를 여러개의 공간으로 나누어서 각 공간별로 redo allocation latch를 할당해주는 shared redo strand 기능이 도입됨.
      10g부터 각 서버프로세스는 shared pool에 자신만의 private redo strand 공간을 만들어서 그곳에서 change vector를 생성 후
            필요할 경우 LGWR이 redo log file에 바로 기록(다른말로 = zero copy))


 
- Redo log Buffer에서 특정 상황이 되면 LGWR이 redo log buffer에 있는 내용중 일부를 redo log file에 기록한다.
  = 특정 server process가 아래의 상황이 되면 redo writing latch를 확보한 후
     LGWR에게 redo log buffer 에 있는 내용을 redo log file에 기록하라고 요청한다.
 
 1) 3초에 한번씩
 2) redo log buffer의 전체 크기의 1/3이 찼거나 1M가 넘을 경우
 3) 사용자가 commit(이경우를 Sync Write라고 함) 또는 rollback을 수행할때
 
 


※ 참고
1. 현재 시스템의 redo copy latch 현황 조회
SQL> col name for a13
SQL> select name, gets, misses, immediate_gets, wait_time
  2  from v$latch_children
  3  where name='redo copy';
 

2. 현재 redo allocation latch의 개수 조회
SQL> select count(*) from v$latch_children
  2  where name='redo alocation';
 

3. redo copy latch의 수 : _log_simultaneous_copies (히든파라미터 : 기본값은 cpu 개수*2개)

 
4. shared redo strand
  - Strand란 여러개로 분할된 영역을 의미 : LOG_PARALLELISM 파라미터 값으로 설정(기본값 1)
  - 10g부터 LOG_PARALLELISM 파라미터 가 _LOG_PARALLELISM 히든파라미터로 변경되고
     이 파라미터의 값을 오라클이 동적으로 관리하도록  _LOG_PARALLELISM_DYNAMIC 파라미터 추가
     (true로 설정할경우 오라클이 해당 strand 개수를 자동으로 제어. 오라클권장값은 cpu개수/8 이다.)
 


Posted by 딩구르
,