본문 바로가기

Oracle DB

리두와 OWI

 

- 리두 개요

특별한 경우를 제외하면, DML에 의해 생긴 모든 변화에 대해서 리두 데이터를 생성한다. 리두 데이터를 생성하는 이유는 복구를 위한 것이다. 오라클은 "Write ahead rule"과 "Log force at commit"이라는 두 가지 메커니즘을 이용해 데이터의 복구를 보장한다.

Write ahead rule은 데이터를 변경시키기 전에 반드시 리두를 먼저 생성한다는 것이다. Write ahead rule은 DML에 의한 변화는 버퍼 캐시에 저장되기 전에 먼저 리두 버퍼에 저장되어야 하고, 버퍼 캐시의 더티 버퍼를 데이터파일에 기록하기 전에, 해당되는 리두 레코드를 리두 버퍼로부터 리두 로그에 파일로 기록한다는 원칙으로 이루어진다.

Log force at commit이란 사용자가 커밋을 요청하면, 반드시 관련된 모든 리두 레코드를 리두 로그 파일에 저장해야만 커밋이 종료된다는 의미이다. 이 두가지 메커니즘을 통해 사용자가 변경한 모든 데이터가 리두 영역에 성공적으로 저장되었음을 보장하고 인스턴스 장애시에 성공적으로 리두 로그 파일로부터 데이터를 복구할 수 있다.

리두 영역에는 언두 세그먼트 헤더, 언두 블록, 데이터 세그먼트 헤더, 데이터 블록의 네 가지 영역에 대한 변동 데이터가 저장된다. 또한 롤백을 수행하기 위한 언두 데이터에 대한 변동 사항도 같이 저장한다. Nologging과 Direct load operation은 데이터 블록에 대한 리두가 생성되지 않으며, 언두 데이터가 생성되지 않기 때문에 언두 블록에 대한 리두도 생성되지 않는다. 그러므로 대량의 데이터를 생성하는 작업에서는 위 옵션을 사용함으로써 큰 성능 개선효과를 얻을 수 있다. 단 이러한 작업에서도 딕셔너리 정보가 변경되는 경우에는 해당 정보에 한해서 리두가 생성된다. 또한 임시 테이블에 대해서도 리두가 생성되지 않는다. 하지만, 이것은 데이터 블록에 대해서만 적용된다.

 

 

- 리두 버퍼

데이터를 변경하려는 모든 프로세스는 반드시 리두 버퍼에 변동사항을 기록해야 한다. 데이터 변동 사항은 리두 레코드 단위로 저장되며, 리두 버퍼는 리두 레코드를 연속된 형태로 저장한다. 버퍼 캐시의 블록을 변경하기 전에 다음과 같은 과정을 거쳐 리두 레코드를 리두 버퍼에 저장한다.

1) 데이터 변동사항을 PGA에 체인지 벡터로 저장한다. 체인지 벡터들은 리두 레코드 포맷으로 리두 버퍼에 복사된다.

2) 현재 자신의 SCN이 모든 프로세스가 지닌 SCN 중 가장 높은 SCN인지 확인한다. 리두 버퍼는 SCN 순으로 리두 레코드를 쌓기 때문에 SCN의 순서가 보장되어야 한다.

3) redo allocation 래치를 획득한 후, 리두 버퍼 내에 리두 레코드를 저장할 공간을 확보한다. 만일 리두 버퍼에 여유 공간이 부족해지면 redo writing 래치를 획득하고 LGWR에게 리두 버퍼를 리두 로그 파일에 기록하고 여유 공간을 확보해줄 것을 요청한다. 필요한 공간이 확보되면 redo allocation 래치를 해제한다.

4) PGA에 생성한 체인지 벡터를 리두 레코드 형태로 리두 버퍼로 복사한다. 이 모든 과정이 끝나면 redo copy 래치를 해지한다.

오라클 10g 부터는 shared redo strands의 개수를 오라클이 동적으로 관리하고, private redo strands 기능(체인지 벡터가 아닌 Shared Pool의 한 영역으로, 여기서 곧바로 로그 파일에 기록됨)을 도입합으로써 래치 경합을 최소화 하면서 리두 데이터를 생성할 수 있다.

 

 

- 리두 로그

리두 버퍼의 내용은 명시적으로 또는 암묵적으로 리두 로그에 기록된다. 조건은 다음과 같다.

1) 3초마다

2) 리두 버퍼의 3분의 1 또는 1MB가 찼을 때

3) 사용자가 커밋 또는 롤백을 수행할 때

4) DBWR이 LGWR에 쓰기 요청을 할 때(Write ahead rule)

리두 로그 파일과 관련된 통계 값들을 정리하면 다음과 같다.

 

또한 오라클은 가능하면 여러 개의 커밋 요청을 모아서 한번에 기록한다. 동시에 여러 세션이 커밋 요청을 하는 경우, PL/SQL 블록에서 반복적으로 커밋을 수행하는 경우 등인데 이것을 그룹 커밋이라고 한다.

LGWR은 리두 버퍼가 전체 크기의 1/3 또는 1MB 만큼 쓰여지면 가장 마지막 기록 시점 이후의 리두 버퍼 변경 내용을 리두 로그로 기록한다. 이것을 백그라운드 기록(Background writes) 이라고 부른다 백그라운드 기록의 기준이 되는 크기는 LOG_IO_SIZE라는 히든 파라미터에 의해 결정된다. LOG_IO_SIZE의 기본값은 오라클 9i까지는 리두 버퍼의 1/3 이지만, 오라클 10g부터는 1/6 인데, LOG_ PARALLELIM_MAX 파라미터의 기본값이 2 인 것과 관련이 있다.

 

'Oracle DB' 카테고리의 다른 글

라이브러리 캐시(Library Cache)에서의 대기이벤트들  (0) 2021.04.02
버퍼 캐시에서의 대기 이벤트들  (0) 2021.04.02
I/O와 OWI  (0) 2021.04.02
세그먼트와 OWI  (0) 2021.04.02
트랜잭션과 OWI  (0) 2021.04.02